From 93791908fb37907f2cade3c842804e5ea0c92dd7 Mon Sep 17 00:00:00 2001 From: Edimo Date: Tue, 3 Feb 2026 09:17:24 -0300 Subject: [PATCH 1/5] Update Ruby version to 3.4.8, add CLAUDE.md for development guidance, and update Docker configurations. Upgrade various gems including Puma and RuboCop, and add new dependencies for CSV support and connection pooling. --- backend/.ruby-version | 2 +- backend/CLAUDE.md | 113 +++++++ backend/Dockerfile | 2 +- backend/Gemfile | 20 +- backend/Gemfile.lock | 654 +++++++++++++++++++------------------ backend/docker-compose.yml | 4 +- 6 files changed, 466 insertions(+), 329 deletions(-) create mode 100644 backend/CLAUDE.md diff --git a/backend/.ruby-version b/backend/.ruby-version index bea438e..7921bd0 100644 --- a/backend/.ruby-version +++ b/backend/.ruby-version @@ -1 +1 @@ -3.3.1 +3.4.8 diff --git a/backend/CLAUDE.md b/backend/CLAUDE.md new file mode 100644 index 0000000..65ba340 --- /dev/null +++ b/backend/CLAUDE.md @@ -0,0 +1,113 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Development Commands + +All commands run inside Docker containers: + +```bash +# Setup (first time) +cp .env.example .env +docker compose build +docker compose up +docker compose exec web bundle install +docker compose exec web bin/rails db:setup + +# Start development +bin/dev # Start server on localhost:3000 + +# Run tests (note: -P flag needed to include pack specs) +docker compose exec web bundle exec bin/rspec -P ./*/**/*_spec.rb + +# Run single test file +docker compose exec web bundle exec bin/rspec spec/requests/api/v1/users_request_spec.rb + +# Lint (RuboCop with auto-fix + Reek) +docker compose exec web bundle exec bin/lint + +# Security scan (Brakeman) +docker compose exec web bundle exec bin/scan + +# Run both lint and security +docker compose exec web bundle exec bin/analyze + +# Check modular architecture +docker compose exec web bundle exec bin/packwerk check +``` + +## Architecture Overview + +Rails 7.1.3 API with Ruby 3.4.8, using Docker (PostgreSQL 15, Redis, Elasticsearch 8.10.2, Sidekiq). + +### Key Patterns + +**ServiceActor Pattern** - Business logic in `app/actors/`. Actors define typed `input`/`output`, use `fail!` for errors: +```ruby +class FetchSchools < Actor + input :school_index_contract + output :data + def call + self.data = fetch_schools + end +end +``` + +**Dry::Validation Contracts** - Input validation in `app/contracts/`. Extend `ApplicationContract`, raise `InvalidContractError` on failure: +```ruby +UserContracts::Create.call(permitted_params(:email, :password)) +``` + +**Pundit Authorization** - Policies in `app/policies/`. Controllers call `authorize(resource)` and include `after_action :verify_authorized`. + +**API Structure** - Controllers inherit from `Api::V1::ApiController` which provides: +- JWT authentication via `devise-api` (`authenticate_devise_api_token!`) +- Standard error handling for `Pundit::NotAuthorizedError`, `ActiveRecord::RecordInvalid`, `InvalidContractError` +- `permitted_params(*keys)` helper for parameter extraction +- PaperTrail audit trail (`set_paper_trail_whodunnit`) + +**Packwerk Modular Architecture** - Isolated modules in `packs/` directory (e.g., `demo_pack`, `oauth`). Each pack has its own controllers, actors, specs, and routes module. + +### Directory Structure + +- `app/actors/` - ServiceActor business logic +- `app/contracts/` - Dry::Validation input contracts +- `app/policies/` - Pundit authorization +- `app/chewy/` - Elasticsearch indices (Chewy) +- `app/sidekiq/` - Background jobs +- `app/graphql/` - GraphQL schema, types, mutations +- `packs/` - Packwerk modular packages + +### Testing + +RSpec with FactoryBot. Test helpers in `spec/support/`: +- `auth_headers_for(user)` - Generate Bearer token headers for authenticated requests +- `json_response` - Parse response body with indifferent access + +Request spec pattern: +```ruby +let(:headers) { auth_headers_for(user) } +before { get "/api/v1/users", headers: } +it { expect(response).to have_http_status(:ok) } +``` + +### Web Interfaces + +- API Docs (Swagger): http://localhost:3000/api-docs/index.html +- GraphQL IDE: http://localhost:3000/graphiql +- Sidekiq Dashboard: http://localhost:3000/sidekiq/ +- Admin Dashboard: http://localhost:3000/admin + +### Sidekiq Jobs + +After creating new jobs, rebuild the sidekiq container: +```bash +docker compose stop +docker compose up --build +``` + +### Code Style + +- Double quotes for strings +- Uses `frozen_string_literal: true` pragma +- RuboCop extensions: rubocop-rails, rubocop-rspec, rubocop-graphql, rubocop-performance diff --git a/backend/Dockerfile b/backend/Dockerfile index 3e3525c..08762c8 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -11,7 +11,7 @@ FROM base as build # Install packages needed to build gems RUN apt-get update -qq && \ - apt-get install --no-install-recommends -y build-essential git libpq-dev libvips pkg-config + apt-get install --no-install-recommends -y build-essential git libpq-dev libvips pkg-config libyaml-dev # RUN apt-get update -qq && apt-get install -y postgresql-client diff --git a/backend/Gemfile b/backend/Gemfile index 9b3267b..87fdb98 100644 --- a/backend/Gemfile +++ b/backend/Gemfile @@ -3,7 +3,7 @@ source "https://rubygems.org" git_source(:github) { |repo| "https://github.com/#{repo}.git" } -ruby "3.3.1" +ruby "3.4.8" # Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" gem "rails", "~> 7.1.3" @@ -15,7 +15,7 @@ gem "sprockets-rails" gem "pg" # Use the Puma web server [https://github.com/puma/puma] -gem "puma", "~> 5.0" +gem "puma", "~> 6.0" # Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails] gem "importmap-rails" @@ -32,6 +32,12 @@ gem "jbuilder" # Use Redis adapter to run Action Cable in production gem "redis" +# Pin connection_pool to 2.x for Rails 7.1 compatibility +gem "connection_pool", "~> 2.4" + +# CSV support (removed from stdlib in Ruby 3.4) +gem "csv" + # Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis] # gem "kredis" @@ -128,11 +134,11 @@ end group :development do # To ensure code consistency [https://docs.rubocop.org] - gem "rubocop", "1.56.2" - gem "rubocop-graphql", "~> 1.4" - gem "rubocop-performance", "1.19.0" - gem "rubocop-rails", "2.20.2" - gem "rubocop-rspec", "2.23.2" + gem "rubocop", "~> 1.69" + gem "rubocop-graphql", "~> 1.5" + gem "rubocop-performance", "~> 1.23" + gem "rubocop-rails", "~> 2.27" + gem "rubocop-rspec", "~> 3.3" # Use console on exceptions pages [https://github.com/rails/web-console] gem "web-console" diff --git a/backend/Gemfile.lock b/backend/Gemfile.lock index c28fb3e..8e0a9c3 100644 --- a/backend/Gemfile.lock +++ b/backend/Gemfile.lock @@ -1,9 +1,9 @@ GIT remote: https://github.com/nejdetkadir/devise-api.git - revision: 05ba4837c7689d9a57c94bd942d182fb0ee96e99 + revision: bd49310c4e96ec6e56ec38c2542754718b2f1c57 branch: main specs: - devise-api (0.1.3) + devise-api (0.2.0) devise (>= 4.7.2) dry-configurable (~> 1.0, >= 1.0.1) dry-initializer (>= 3.1.1) @@ -14,35 +14,36 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (7.1.3.3) - actionpack (= 7.1.3.3) - activesupport (= 7.1.3.3) + actioncable (7.1.6) + actionpack (= 7.1.6) + activesupport (= 7.1.6) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.1.3.3) - actionpack (= 7.1.3.3) - activejob (= 7.1.3.3) - activerecord (= 7.1.3.3) - activestorage (= 7.1.3.3) - activesupport (= 7.1.3.3) + actionmailbox (7.1.6) + actionpack (= 7.1.6) + activejob (= 7.1.6) + activerecord (= 7.1.6) + activestorage (= 7.1.6) + activesupport (= 7.1.6) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.1.3.3) - actionpack (= 7.1.3.3) - actionview (= 7.1.3.3) - activejob (= 7.1.3.3) - activesupport (= 7.1.3.3) + actionmailer (7.1.6) + actionpack (= 7.1.6) + actionview (= 7.1.6) + activejob (= 7.1.6) + activesupport (= 7.1.6) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp rails-dom-testing (~> 2.2) - actionpack (7.1.3.3) - actionview (= 7.1.3.3) - activesupport (= 7.1.3.3) + actionpack (7.1.6) + actionview (= 7.1.6) + activesupport (= 7.1.6) + cgi nokogiri (>= 1.8.5) racc rack (>= 2.2.4) @@ -50,83 +51,85 @@ GEM rack-test (>= 0.6.3) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - actiontext (7.1.3.3) - actionpack (= 7.1.3.3) - activerecord (= 7.1.3.3) - activestorage (= 7.1.3.3) - activesupport (= 7.1.3.3) + actiontext (7.1.6) + actionpack (= 7.1.6) + activerecord (= 7.1.6) + activestorage (= 7.1.6) + activesupport (= 7.1.6) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.1.3.3) - activesupport (= 7.1.3.3) + actionview (7.1.6) + activesupport (= 7.1.6) builder (~> 3.1) + cgi erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - active_model_serializers (0.10.14) + active_model_serializers (0.10.16) actionpack (>= 4.1) activemodel (>= 4.1) case_transform (>= 0.2) jsonapi-renderer (>= 0.1.1.beta1, < 0.3) - activejob (7.1.3.3) - activesupport (= 7.1.3.3) + activejob (7.1.6) + activesupport (= 7.1.6) globalid (>= 0.3.6) - activemodel (7.1.3.3) - activesupport (= 7.1.3.3) - activerecord (7.1.3.3) - activemodel (= 7.1.3.3) - activesupport (= 7.1.3.3) + activemodel (7.1.6) + activesupport (= 7.1.6) + activerecord (7.1.6) + activemodel (= 7.1.6) + activesupport (= 7.1.6) timeout (>= 0.4.0) - activestorage (7.1.3.3) - actionpack (= 7.1.3.3) - activejob (= 7.1.3.3) - activerecord (= 7.1.3.3) - activesupport (= 7.1.3.3) + activestorage (7.1.6) + actionpack (= 7.1.6) + activejob (= 7.1.6) + activerecord (= 7.1.6) + activesupport (= 7.1.6) marcel (~> 1.0) - activesupport (7.1.3.3) + activesupport (7.1.6) base64 + benchmark (>= 0.3) bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) connection_pool (>= 2.2.5) drb i18n (>= 1.6, < 2) + logger (>= 1.4.2) minitest (>= 5.1) mutex_m + securerandom (>= 0.3) tzinfo (~> 2.0) - acts_as_paranoid (0.10.0) - activerecord (>= 6.1, < 7.2) - activesupport (>= 6.1, < 7.2) - addressable (2.8.6) - public_suffix (>= 2.0.2, < 6.0) - administrate (0.20.1) - actionpack (>= 6.0, < 8.0) - actionview (>= 6.0, < 8.0) - activerecord (>= 6.0, < 8.0) - jquery-rails (~> 4.6.0) + acts_as_paranoid (0.11.0) + activerecord (>= 6.1, < 8.2) + activesupport (>= 6.1, < 8.2) + addressable (2.8.8) + public_suffix (>= 2.0.2, < 8.0) + administrate (1.0.0) + actionpack (>= 6.0, < 9.0) + actionview (>= 6.0, < 9.0) + activerecord (>= 6.0, < 9.0) kaminari (~> 1.2.2) - sassc-rails (~> 2.1) - selectize-rails (~> 0.6) annotate (3.2.0) activerecord (>= 3.2, < 8.0) rake (>= 10.4, < 14.0) - ast (2.4.2) - base64 (0.1.1) - bcrypt (3.1.20) - better_html (2.1.1) - actionview (>= 6.0) - activesupport (>= 6.0) + ast (2.4.3) + base64 (0.3.0) + bcrypt (3.1.21) + benchmark (0.5.0) + better_html (2.2.0) + actionview (>= 7.0) + activesupport (>= 7.0) ast (~> 2.0) erubi (~> 1.4) parser (>= 2.4) smart_properties - bigdecimal (3.1.8) + bigdecimal (4.0.1) bindex (0.8.1) - bootsnap (1.18.3) + bootsnap (1.22.0) msgpack (~> 1.2) - brakeman (6.1.2) + brakeman (8.0.1) racc - builder (3.2.4) - bullet (7.1.6) + builder (3.3.0) + bullet (8.1.0) activesupport (>= 3.0.0) uniform_notifier (~> 1.11) capybara (3.40.0) @@ -140,20 +143,22 @@ GEM xpath (~> 3.2) case_transform (0.2) activesupport + cgi (0.5.1) chewy (7.6.0) activesupport (>= 5.2) elasticsearch (>= 7.14.0, < 8) elasticsearch-dsl coderay (1.1.3) - concurrent-ruby (1.2.3) - connection_pool (2.4.1) - constant_resolver (0.2.0) - crack (1.0.0) + concurrent-ruby (1.3.6) + connection_pool (2.5.5) + constant_resolver (0.3.0) + crack (1.0.1) bigdecimal rexml crass (1.0.6) - date (3.3.4) - debug (1.9.2) + csv (3.3.2) + date (3.5.1) + debug (1.11.1) irb (~> 1.10) reline (>= 0.3.8) devise (4.9.4) @@ -162,100 +167,107 @@ GEM railties (>= 4.1.0) responders warden (~> 1.2.3) - diff-lcs (1.5.1) - docile (1.4.0) - dotenv (3.1.2) - dotenv-rails (3.1.2) - dotenv (= 3.1.2) + diff-lcs (1.6.2) + docile (1.4.1) + dotenv (3.2.0) + dotenv-rails (3.2.0) + dotenv (= 3.2.0) railties (>= 6.1) - drb (2.2.1) - dry-configurable (1.1.0) - dry-core (~> 1.0, < 2) + drb (2.2.3) + dry-configurable (1.3.0) + dry-core (~> 1.1) zeitwerk (~> 2.6) - dry-core (1.0.1) + dry-core (1.2.0) concurrent-ruby (~> 1.0) + logger zeitwerk (~> 2.6) - dry-inflector (1.0.0) - dry-initializer (3.1.1) - dry-logic (1.5.0) + dry-inflector (1.3.1) + dry-initializer (3.2.0) + dry-logic (1.6.0) + bigdecimal concurrent-ruby (~> 1.0) - dry-core (~> 1.0, < 2) + dry-core (~> 1.1) zeitwerk (~> 2.6) - dry-monads (1.6.0) + dry-monads (1.9.0) concurrent-ruby (~> 1.0) - dry-core (~> 1.0, < 2) + dry-core (~> 1.1) zeitwerk (~> 2.6) - dry-schema (1.13.4) + dry-schema (1.15.0) concurrent-ruby (~> 1.0) dry-configurable (~> 1.0, >= 1.0.1) - dry-core (~> 1.0, < 2) - dry-initializer (~> 3.0) - dry-logic (>= 1.4, < 2) - dry-types (>= 1.7, < 2) + dry-core (~> 1.1) + dry-initializer (~> 3.2) + dry-logic (~> 1.6) + dry-types (~> 1.8) zeitwerk (~> 2.6) - dry-types (1.7.2) - bigdecimal (~> 3.0) + dry-types (1.9.0) + bigdecimal (>= 3.0) concurrent-ruby (~> 1.0) dry-core (~> 1.0) dry-inflector (~> 1.0) dry-logic (~> 1.4) zeitwerk (~> 2.6) - dry-validation (1.10.0) + dry-validation (1.11.1) concurrent-ruby (~> 1.0) - dry-core (~> 1.0, < 2) - dry-initializer (~> 3.0) - dry-schema (>= 1.12, < 2) + dry-core (~> 1.1) + dry-initializer (~> 3.2) + dry-schema (~> 1.14) zeitwerk (~> 2.6) - elasticsearch (7.17.10) - elasticsearch-api (= 7.17.10) - elasticsearch-transport (= 7.17.10) - elasticsearch-api (7.17.10) + elasticsearch (7.17.11) + elasticsearch-api (= 7.17.11) + elasticsearch-transport (= 7.17.11) + elasticsearch-api (7.17.11) multi_json elasticsearch-dsl (0.1.10) - elasticsearch-transport (7.17.10) + elasticsearch-transport (7.17.11) + base64 faraday (>= 1, < 3) multi_json - erubi (1.12.0) - factory_bot (6.4.6) - activesupport (>= 5.0.0) - factory_bot_rails (6.4.3) - factory_bot (~> 6.4) - railties (>= 5.0.0) - faraday (2.9.0) - faraday-net_http (>= 2.0, < 3.2) - faraday-net_http (3.1.0) - net-http - ffi (1.16.3) - globalid (1.2.1) + erb (6.0.1) + erubi (1.13.1) + factory_bot (6.5.6) + activesupport (>= 6.1.0) + factory_bot_rails (6.5.1) + factory_bot (~> 6.5) + railties (>= 6.1.0) + faraday (2.14.0) + faraday-net_http (>= 2.0, < 3.5) + json + logger + faraday-net_http (3.4.2) + net-http (~> 0.5) + fiber-storage (1.0.1) + globalid (1.3.0) activesupport (>= 6.1) - graphiql-rails (1.10.0) + graphiql-rails (1.10.5) railties - graphql (2.3.4) + graphql (2.5.18) base64 - hashdiff (1.1.0) - hashie (5.0.0) - i18n (1.14.5) + fiber-storage + logger + hashdiff (1.2.1) + hashie (5.1.0) + logger + i18n (1.14.8) concurrent-ruby (~> 1.0) - importmap-rails (2.0.1) + importmap-rails (2.2.3) actionpack (>= 6.0.0) activesupport (>= 6.0.0) railties (>= 6.0.0) - io-console (0.7.2) - irb (1.13.1) + io-console (0.8.2) + irb (1.16.0) + pp (>= 0.6.0) rdoc (>= 4.0.0) reline (>= 0.4.2) - jbuilder (2.12.0) - actionview (>= 5.0.0) - activesupport (>= 5.0.0) - jquery-rails (4.6.0) - rails-dom-testing (>= 1, < 3) - railties (>= 4.2.0) - thor (>= 0.14, < 2.0) - json (2.7.2) - json-schema (4.3.0) - addressable (>= 2.8) + jbuilder (2.14.1) + actionview (>= 7.0.0) + activesupport (>= 7.0.0) + json (2.18.1) + json-schema (6.1.0) + addressable (~> 2.8) + bigdecimal (>= 3.1, < 5) jsonapi-renderer (0.2.2) - jwt (2.8.1) + jwt (3.1.2) base64 kaminari (1.2.2) activesupport (>= 4.1.0) @@ -269,171 +281,185 @@ GEM activerecord kaminari-core (= 1.2.2) kaminari-core (1.2.2) - language_server-protocol (3.17.0.3) - loofah (2.22.0) + language_server-protocol (3.17.0.5) + lint_roller (1.1.0) + logger (1.7.0) + loofah (2.25.0) crass (~> 1.0.2) nokogiri (>= 1.12.0) - mail (2.8.1) + mail (2.9.0) + logger mini_mime (>= 0.1.1) net-imap net-pop net-smtp - marcel (1.0.4) - matrix (0.4.2) + marcel (1.1.0) + matrix (0.4.3) method_source (1.1.0) mini_mime (1.1.5) - mini_portile2 (2.8.6) - minitest (5.23.1) - msgpack (1.7.2) - multi_json (1.15.0) - multi_xml (0.7.1) - bigdecimal (~> 3.1) - mutex_m (0.2.0) - net-http (0.4.1) - uri - net-imap (0.4.11) + minitest (6.0.1) + prism (~> 1.5) + msgpack (1.8.0) + multi_json (1.19.1) + multi_xml (0.8.1) + bigdecimal (>= 3.1, < 5) + mutex_m (0.3.0) + net-http (0.9.1) + uri (>= 0.11.1) + net-imap (0.6.2) date net-protocol net-pop (0.1.2) net-protocol net-protocol (0.2.2) timeout - net-smtp (0.5.0) + net-smtp (0.5.1) net-protocol - nio4r (2.7.3) - nokogiri (1.16.5) - mini_portile2 (~> 2.8.2) - racc (~> 1.4) - nokogiri (1.16.5-aarch64-linux) + nio4r (2.7.5) + nokogiri (1.19.0-aarch64-linux-gnu) racc (~> 1.4) - nokogiri (1.16.5-x86_64-linux) + nokogiri (1.19.0-x86_64-linux-gnu) racc (~> 1.4) - oauth2 (2.0.9) - faraday (>= 0.17.3, < 3.0) - jwt (>= 1.0, < 3.0) + oauth2 (2.0.18) + faraday (>= 0.17.3, < 4.0) + jwt (>= 1.0, < 4.0) + logger (~> 1.2) multi_xml (~> 0.5) rack (>= 1.2, < 4) - snaky_hash (~> 2.0) - version_gem (~> 1.1) - omniauth (2.1.2) + snaky_hash (~> 2.0, >= 2.0.3) + version_gem (~> 1.1, >= 1.1.9) + omniauth (2.1.4) hashie (>= 3.4.6) + logger rack (>= 2.2.3) rack-protection omniauth-github (2.0.1) omniauth (~> 2.0) omniauth-oauth2 (~> 1.8) - omniauth-oauth2 (1.8.0) - oauth2 (>= 1.4, < 3) + omniauth-oauth2 (1.9.0) + oauth2 (>= 2.0.2, < 3) omniauth (~> 2.0) - omniauth-rails_csrf_protection (1.0.2) + omniauth-rails_csrf_protection (2.0.1) actionpack (>= 4.2) omniauth (~> 2.0) omniauth-strava (1.0.0) omniauth (~> 2.0) omniauth-oauth2 (~> 1.0) orm_adapter (0.5.0) - packwerk (3.2.1) + packwerk (3.2.3) activesupport (>= 6.0) ast better_html bundler - constant_resolver (>= 0.2.0) + constant_resolver (>= 0.3) parallel parser prism (>= 0.25.0) sorbet-runtime (>= 0.5.9914) zeitwerk (>= 2.6.1) - paper_trail (15.1.0) - activerecord (>= 6.1) + paper_trail (17.0.0) + activerecord (>= 7.1) request_store (~> 1.4) - parallel (1.24.0) - parser (3.3.1.0) + parallel (1.27.0) + parser (3.3.10.1) ast (~> 2.4.1) racc - pg (1.5.6) - prism (0.29.0) + pg (1.6.3) + pg (1.6.3-aarch64-linux) + pg (1.6.3-x86_64-linux) + pp (0.6.3) + prettyprint + prettyprint (0.2.0) + prism (1.9.0) pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) - psych (5.1.2) + psych (5.3.1) + date stringio - public_suffix (5.0.5) - puma (5.6.8) + public_suffix (7.0.2) + puma (6.6.1) nio4r (~> 2.0) - pundit (2.3.2) + pundit (2.5.2) activesupport (>= 3.0.0) - racc (1.8.0) - rack (2.2.9) - rack-cors (2.0.2) - rack (>= 2.0.0) - rack-protection (3.2.0) + racc (1.8.1) + rack (3.2.4) + rack-cors (3.0.0) + logger + rack (>= 3.0.14) + rack-protection (4.2.1) + base64 (>= 0.1.0) + logger (>= 1.6.0) + rack (>= 3.0.0, < 4) + rack-session (2.1.1) base64 (>= 0.1.0) - rack (~> 2.2, >= 2.2.4) - rack-session (1.0.2) - rack (< 3) - rack-test (2.1.0) + rack (>= 3.0.0) + rack-test (2.2.0) rack (>= 1.3) - rackup (1.0.0) - rack (< 3) - webrick - rails (7.1.3.3) - actioncable (= 7.1.3.3) - actionmailbox (= 7.1.3.3) - actionmailer (= 7.1.3.3) - actionpack (= 7.1.3.3) - actiontext (= 7.1.3.3) - actionview (= 7.1.3.3) - activejob (= 7.1.3.3) - activemodel (= 7.1.3.3) - activerecord (= 7.1.3.3) - activestorage (= 7.1.3.3) - activesupport (= 7.1.3.3) + rackup (2.3.1) + rack (>= 3) + rails (7.1.6) + actioncable (= 7.1.6) + actionmailbox (= 7.1.6) + actionmailer (= 7.1.6) + actionpack (= 7.1.6) + actiontext (= 7.1.6) + actionview (= 7.1.6) + activejob (= 7.1.6) + activemodel (= 7.1.6) + activerecord (= 7.1.6) + activestorage (= 7.1.6) + activesupport (= 7.1.6) bundler (>= 1.15.0) - railties (= 7.1.3.3) - rails-dom-testing (2.2.0) + railties (= 7.1.6) + rails-dom-testing (2.3.0) activesupport (>= 5.0.0) minitest nokogiri (>= 1.6) - rails-html-sanitizer (1.6.0) + rails-html-sanitizer (1.6.2) loofah (~> 2.21) - nokogiri (~> 1.14) - railties (7.1.3.3) - actionpack (= 7.1.3.3) - activesupport (= 7.1.3.3) + nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) + railties (7.1.6) + actionpack (= 7.1.6) + activesupport (= 7.1.6) + cgi irb rackup (>= 1.0.0) rake (>= 12.2) thor (~> 1.0, >= 1.2.2) + tsort (>= 0.2) zeitwerk (~> 2.6) rainbow (3.1.1) - rake (13.2.1) - rdoc (6.7.0) + rake (13.3.1) + rdoc (7.1.0) + erb psych (>= 4.0.0) - redis (5.2.0) + tsort + redis (5.4.1) redis-client (>= 0.22.0) - redis-client (0.22.2) + redis-client (0.26.4) connection_pool - reek (6.3.0) - dry-schema (~> 1.13.0) + reek (6.5.0) + dry-schema (~> 1.13) + logger (~> 1.6) parser (~> 3.3.0) rainbow (>= 2.0, < 4.0) rexml (~> 3.1) - regexp_parser (2.9.2) - reline (0.5.7) + regexp_parser (2.11.3) + reline (0.6.3) io-console (~> 0.5) request_store (1.7.0) rack (>= 1.4) - responders (3.1.1) - actionpack (>= 5.2) - railties (>= 5.2) - rexml (3.2.8) - strscan (>= 3.0.9) - rspec-core (3.13.0) + responders (3.2.0) + actionpack (>= 7.0) + railties (>= 7.0) + rexml (3.4.4) + rspec-core (3.13.6) rspec-support (~> 3.13.0) - rspec-expectations (3.13.0) + rspec-expectations (3.13.5) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-mocks (3.13.1) + rspec-mocks (3.13.7) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-rails (6.0.4) @@ -444,123 +470,116 @@ GEM rspec-expectations (~> 3.12) rspec-mocks (~> 3.12) rspec-support (~> 3.12) - rspec-sidekiq (5.0.0) + rspec-sidekiq (5.2.0) rspec-core (~> 3.0) rspec-expectations (~> 3.0) rspec-mocks (~> 3.0) - sidekiq (>= 5, < 8) - rspec-support (3.13.1) - rswag (2.13.0) - rswag-api (= 2.13.0) - rswag-specs (= 2.13.0) - rswag-ui (= 2.13.0) - rswag-api (2.13.0) - activesupport (>= 3.1, < 7.2) - railties (>= 3.1, < 7.2) - rswag-specs (2.13.0) - activesupport (>= 3.1, < 7.2) - json-schema (>= 2.2, < 5.0) - railties (>= 3.1, < 7.2) + sidekiq (>= 5, < 9) + rspec-support (3.13.7) + rswag (2.17.0) + rswag-api (= 2.17.0) + rswag-specs (= 2.17.0) + rswag-ui (= 2.17.0) + rswag-api (2.17.0) + activesupport (>= 5.2, < 8.2) + railties (>= 5.2, < 8.2) + rswag-specs (2.17.0) + activesupport (>= 5.2, < 8.2) + json-schema (>= 2.2, < 7.0) + railties (>= 5.2, < 8.2) rspec-core (>= 2.14) - rswag-ui (2.13.0) - actionpack (>= 3.1, < 7.2) - railties (>= 3.1, < 7.2) - rubocop (1.56.2) - base64 (~> 0.1.1) + rswag-ui (2.17.0) + actionpack (>= 5.2, < 8.2) + railties (>= 5.2, < 8.2) + rubocop (1.84.1) json (~> 2.3) - language_server-protocol (>= 3.17.0) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) parallel (~> 1.10) - parser (>= 3.2.2.3) + parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 1.8, < 3.0) - rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.28.1, < 2.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.49.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.31.3) - parser (>= 3.3.1.0) - rubocop-capybara (2.20.0) - rubocop (~> 1.41) - rubocop-factory_bot (2.25.1) - rubocop (~> 1.41) - rubocop-graphql (1.5.1) - rubocop (>= 0.90, < 2) - rubocop-performance (1.19.0) - rubocop (>= 1.7.0, < 2.0) - rubocop-ast (>= 0.4.0) - rubocop-rails (2.20.2) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.49.0) + parser (>= 3.3.7.2) + prism (~> 1.7) + rubocop-graphql (1.5.6) + lint_roller (~> 1.1) + rubocop (>= 1.72.1, < 2) + rubocop-performance (1.26.1) + lint_roller (~> 1.1) + rubocop (>= 1.75.0, < 2.0) + rubocop-ast (>= 1.47.1, < 2.0) + rubocop-rails (2.34.3) activesupport (>= 4.2.0) + lint_roller (~> 1.1) rack (>= 1.1) - rubocop (>= 1.33.0, < 2.0) - rubocop-rspec (2.23.2) - rubocop (~> 1.33) - rubocop-capybara (~> 2.17) - rubocop-factory_bot (~> 2.22) + rubocop (>= 1.75.0, < 2.0) + rubocop-ast (>= 1.44.0, < 2.0) + rubocop-rspec (3.9.0) + lint_roller (~> 1.1) + rubocop (~> 1.81) ruby-progressbar (1.13.0) - rubyzip (2.3.2) - sassc (2.4.0) - ffi (~> 1.9) - sassc-rails (2.1.2) - railties (>= 4.0.0) - sassc (>= 2.0) - sprockets (> 3.0) - sprockets-rails - tilt - selectize-rails (0.12.6) + rubyzip (2.4.1) + securerandom (0.4.1) selenium-webdriver (4.16.0) rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) - service_actor (3.9.1) + service_actor (3.9.4) zeitwerk (>= 1.0) service_actor-rails (1.0.0) rails (>= 4.2) service_actor shoulda-matchers (5.3.0) activesupport (>= 5.2.0) - sidekiq (7.2.4) - concurrent-ruby (< 2) - connection_pool (>= 2.3.0) - rack (>= 2.2.4) - redis-client (>= 0.19.0) + sidekiq (8.0.10) + connection_pool (>= 2.5.0) + json (>= 2.9.0) + logger (>= 1.6.2) + rack (>= 3.1.0) + redis-client (>= 0.23.2) simplecov (0.22.0) docile (~> 1.1) simplecov-html (~> 0.11) simplecov_json_formatter (~> 0.1) - simplecov-html (0.12.3) + simplecov-html (0.13.2) simplecov_json_formatter (0.1.4) smart_properties (1.17.0) - snaky_hash (2.0.1) - hashie - version_gem (~> 1.1, >= 1.1.1) - sorbet-runtime (0.5.11391) - spring (4.2.1) + snaky_hash (2.0.3) + hashie (>= 0.1.0, < 6) + version_gem (>= 1.1.8, < 3) + sorbet-runtime (0.6.12913) + spring (4.4.0) spring-commands-rspec (1.0.4) spring (>= 0.9.1) - sprockets (4.2.1) + sprockets (4.2.2) concurrent-ruby (~> 1.0) + logger rack (>= 2.2.4, < 4) - sprockets-rails (3.4.2) - actionpack (>= 5.2) - activesupport (>= 5.2) + sprockets-rails (3.5.2) + actionpack (>= 6.1) + activesupport (>= 6.1) sprockets (>= 3.0.0) - stimulus-rails (1.3.3) - railties (>= 6.0.0) - stringio (3.1.0) - strscan (3.1.0) - thor (1.3.1) - tilt (2.3.0) - timeout (0.4.1) - turbo-rails (2.0.5) - actionpack (>= 6.0.0) - activejob (>= 6.0.0) + stimulus-rails (1.3.4) railties (>= 6.0.0) + stringio (3.2.0) + thor (1.5.0) + timeout (0.6.0) + tsort (0.2.0) + turbo-rails (2.0.23) + actionpack (>= 7.1.0) + railties (>= 7.1.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - unicode-display_width (2.5.0) - uniform_notifier (1.16.0) - uri (0.13.0) - version_gem (1.1.4) + unicode-display_width (3.2.0) + unicode-emoji (~> 4.1) + unicode-emoji (4.2.0) + uniform_notifier (1.18.0) + uri (1.1.1) + version_gem (1.1.9) warden (1.2.9) rack (>= 2.0.9) web-console (4.2.1) @@ -568,22 +587,21 @@ GEM activemodel (>= 6.0.0) bindex (>= 0.4.0) railties (>= 6.0.0) - webmock (3.23.1) + webmock (3.26.1) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - webrick (1.8.1) - websocket (1.2.10) - websocket-driver (0.7.6) + websocket (1.2.11) + websocket-driver (0.8.0) + base64 websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.14) + zeitwerk (2.7.4) PLATFORMS aarch64-linux - ruby x86_64-linux DEPENDENCIES @@ -596,6 +614,8 @@ DEPENDENCIES bullet capybara chewy + connection_pool (~> 2.4) + csv debug devise (~> 4.9) devise-api! @@ -615,7 +635,7 @@ DEPENDENCIES paper_trail pg pry (~> 0.14.2) - puma (~> 5.0) + puma (~> 6.0) pundit rack-cors rails (~> 7.1.3) @@ -624,11 +644,11 @@ DEPENDENCIES rspec-rails (~> 6.0.0) rspec-sidekiq rswag - rubocop (= 1.56.2) - rubocop-graphql (~> 1.4) - rubocop-performance (= 1.19.0) - rubocop-rails (= 2.20.2) - rubocop-rspec (= 2.23.2) + rubocop (~> 1.69) + rubocop-graphql (~> 1.5) + rubocop-performance (~> 1.23) + rubocop-rails (~> 2.27) + rubocop-rspec (~> 3.3) selenium-webdriver service_actor (~> 3.7) service_actor-rails (~> 1.0) @@ -645,7 +665,7 @@ DEPENDENCIES webmock RUBY VERSION - ruby 3.3.1p55 + ruby 3.4.8 BUNDLED WITH - 2.4.10 + 2.6.9 diff --git a/backend/docker-compose.yml b/backend/docker-compose.yml index 501d47c..3353b3c 100644 --- a/backend/docker-compose.yml +++ b/backend/docker-compose.yml @@ -1,10 +1,8 @@ -version: "3" - x-app: &app build: context: . args: - RUBY_VERSION: "3.3.1" + RUBY_VERSION: "3.4.8" PG_MAJOR: "15" NODE_MAJOR: "18" environment: &env From c7d912405adcee0472479ffcf20fd0da6287af96 Mon Sep 17 00:00:00 2001 From: Edimo Date: Tue, 3 Feb 2026 09:24:48 -0300 Subject: [PATCH 2/5] Update Redis configuration to use port 6380 across environment variables, Docker Compose, and application settings. --- backend/.env.example | 4 ++-- backend/config/cable.yml | 2 +- backend/config/initializers/sidekiq.rb | 2 +- backend/docker-compose.yml | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/backend/.env.example b/backend/.env.example index 053d8f6..1d5c4c5 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -1,5 +1,5 @@ -REDIS_URL=redis://redis:6379/0 -REDIS_CACHE_URL=redis://redis:6379/1 +REDIS_URL=redis://redis:6380/0 +REDIS_CACHE_URL=redis://redis:6380/1 POSTGRES_USER=postgres POSTGRES_PASSWORD=postgres POSTGRES_HOST=database diff --git a/backend/config/cable.yml b/backend/config/cable.yml index f39dc04..8c94c39 100644 --- a/backend/config/cable.yml +++ b/backend/config/cable.yml @@ -6,5 +6,5 @@ test: production: adapter: redis - url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> + url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6380/1" } %> channel_prefix: app_production diff --git a/backend/config/initializers/sidekiq.rb b/backend/config/initializers/sidekiq.rb index 316c3a8..09739b8 100644 --- a/backend/config/initializers/sidekiq.rb +++ b/backend/config/initializers/sidekiq.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -sidekiq_config = { url: ENV["REDIS_URL"] || "redis://localhost:6379/0" } +sidekiq_config = { url: ENV["REDIS_URL"] || "redis://localhost:6380/0" } Sidekiq.configure_server do |config| config.logger.level = Logger::ERROR diff --git a/backend/docker-compose.yml b/backend/docker-compose.yml index 3353b3c..fd422b6 100644 --- a/backend/docker-compose.yml +++ b/backend/docker-compose.yml @@ -73,11 +73,11 @@ services: redis: image: docker.io/redis:latest hostname: redis - command: redis-server + command: redis-server --port 6380 ports: - - "6379:6379" + - "6380:6380" healthcheck: - test: redis-cli ping + test: redis-cli -p 6380 ping interval: 1s timeout: 3s retries: 30 From c190a1071857928c0618cab59bf375c6f64613a5 Mon Sep 17 00:00:00 2001 From: Edimo Date: Tue, 3 Feb 2026 09:32:33 -0300 Subject: [PATCH 3/5] Upgrade Rails to 8.1.2, update Docker Compose ports for PostgreSQL and web services, and adjust Gemfile and Gemfile.lock for new Rails version compatibility. Modify schema.rb to reflect Rails version change and reorganize user table fields. --- backend/CLAUDE.md | 2 +- backend/Gemfile | 2 +- backend/Gemfile.lock | 146 ++++++++++++++++++------------------- backend/db/schema.rb | 37 +++++----- backend/docker-compose.yml | 4 +- 5 files changed, 91 insertions(+), 100 deletions(-) diff --git a/backend/CLAUDE.md b/backend/CLAUDE.md index 65ba340..bfd6212 100644 --- a/backend/CLAUDE.md +++ b/backend/CLAUDE.md @@ -38,7 +38,7 @@ docker compose exec web bundle exec bin/packwerk check ## Architecture Overview -Rails 7.1.3 API with Ruby 3.4.8, using Docker (PostgreSQL 15, Redis, Elasticsearch 8.10.2, Sidekiq). +Rails 8.1.2 API with Ruby 3.4.8, using Docker (PostgreSQL 15, Redis, Elasticsearch 8.10.2, Sidekiq). ### Key Patterns diff --git a/backend/Gemfile b/backend/Gemfile index 87fdb98..5493d11 100644 --- a/backend/Gemfile +++ b/backend/Gemfile @@ -6,7 +6,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby "3.4.8" # Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" -gem "rails", "~> 7.1.3" +gem "rails", "~> 8.0" # The original asset pipeline for Rails [https://github.com/rails/sprockets-rails] gem "sprockets-rails" diff --git a/backend/Gemfile.lock b/backend/Gemfile.lock index 8e0a9c3..4f74356 100644 --- a/backend/Gemfile.lock +++ b/backend/Gemfile.lock @@ -14,54 +14,49 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (7.1.6) - actionpack (= 7.1.6) - activesupport (= 7.1.6) + action_text-trix (2.1.16) + railties + actioncable (8.1.2) + actionpack (= 8.1.2) + activesupport (= 8.1.2) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.1.6) - actionpack (= 7.1.6) - activejob (= 7.1.6) - activerecord (= 7.1.6) - activestorage (= 7.1.6) - activesupport (= 7.1.6) - mail (>= 2.7.1) - net-imap - net-pop - net-smtp - actionmailer (7.1.6) - actionpack (= 7.1.6) - actionview (= 7.1.6) - activejob (= 7.1.6) - activesupport (= 7.1.6) - mail (~> 2.5, >= 2.5.4) - net-imap - net-pop - net-smtp + actionmailbox (8.1.2) + actionpack (= 8.1.2) + activejob (= 8.1.2) + activerecord (= 8.1.2) + activestorage (= 8.1.2) + activesupport (= 8.1.2) + mail (>= 2.8.0) + actionmailer (8.1.2) + actionpack (= 8.1.2) + actionview (= 8.1.2) + activejob (= 8.1.2) + activesupport (= 8.1.2) + mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (7.1.6) - actionview (= 7.1.6) - activesupport (= 7.1.6) - cgi + actionpack (8.1.2) + actionview (= 8.1.2) + activesupport (= 8.1.2) nokogiri (>= 1.8.5) - racc rack (>= 2.2.4) rack-session (>= 1.0.1) rack-test (>= 0.6.3) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - actiontext (7.1.6) - actionpack (= 7.1.6) - activerecord (= 7.1.6) - activestorage (= 7.1.6) - activesupport (= 7.1.6) + useragent (~> 0.16) + actiontext (8.1.2) + action_text-trix (~> 2.1.15) + actionpack (= 8.1.2) + activerecord (= 8.1.2) + activestorage (= 8.1.2) + activesupport (= 8.1.2) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.1.6) - activesupport (= 7.1.6) + actionview (8.1.2) + activesupport (= 8.1.2) builder (~> 3.1) - cgi erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) @@ -70,34 +65,34 @@ GEM activemodel (>= 4.1) case_transform (>= 0.2) jsonapi-renderer (>= 0.1.1.beta1, < 0.3) - activejob (7.1.6) - activesupport (= 7.1.6) + activejob (8.1.2) + activesupport (= 8.1.2) globalid (>= 0.3.6) - activemodel (7.1.6) - activesupport (= 7.1.6) - activerecord (7.1.6) - activemodel (= 7.1.6) - activesupport (= 7.1.6) + activemodel (8.1.2) + activesupport (= 8.1.2) + activerecord (8.1.2) + activemodel (= 8.1.2) + activesupport (= 8.1.2) timeout (>= 0.4.0) - activestorage (7.1.6) - actionpack (= 7.1.6) - activejob (= 7.1.6) - activerecord (= 7.1.6) - activesupport (= 7.1.6) + activestorage (8.1.2) + actionpack (= 8.1.2) + activejob (= 8.1.2) + activerecord (= 8.1.2) + activesupport (= 8.1.2) marcel (~> 1.0) - activesupport (7.1.6) + activesupport (8.1.2) base64 - benchmark (>= 0.3) bigdecimal - concurrent-ruby (~> 1.0, >= 1.0.2) + concurrent-ruby (~> 1.0, >= 1.3.1) connection_pool (>= 2.2.5) drb i18n (>= 1.6, < 2) + json logger (>= 1.4.2) minitest (>= 5.1) - mutex_m securerandom (>= 0.3) - tzinfo (~> 2.0) + tzinfo (~> 2.0, >= 2.0.5) + uri (>= 0.13.1) acts_as_paranoid (0.11.0) activerecord (>= 6.1, < 8.2) activesupport (>= 6.1, < 8.2) @@ -108,13 +103,12 @@ GEM actionview (>= 6.0, < 9.0) activerecord (>= 6.0, < 9.0) kaminari (~> 1.2.2) - annotate (3.2.0) - activerecord (>= 3.2, < 8.0) - rake (>= 10.4, < 14.0) + annotate (2.6.5) + activerecord (>= 2.3.0) + rake (>= 0.8.7) ast (2.4.3) base64 (0.3.0) bcrypt (3.1.21) - benchmark (0.5.0) better_html (2.2.0) actionview (>= 7.0) activesupport (>= 7.0) @@ -143,7 +137,6 @@ GEM xpath (~> 3.2) case_transform (0.2) activesupport - cgi (0.5.1) chewy (7.6.0) activesupport (>= 5.2) elasticsearch (>= 7.14.0, < 8) @@ -303,7 +296,6 @@ GEM multi_json (1.19.1) multi_xml (0.8.1) bigdecimal (>= 3.1, < 5) - mutex_m (0.3.0) net-http (0.9.1) uri (>= 0.11.1) net-imap (0.6.2) @@ -398,20 +390,20 @@ GEM rack (>= 1.3) rackup (2.3.1) rack (>= 3) - rails (7.1.6) - actioncable (= 7.1.6) - actionmailbox (= 7.1.6) - actionmailer (= 7.1.6) - actionpack (= 7.1.6) - actiontext (= 7.1.6) - actionview (= 7.1.6) - activejob (= 7.1.6) - activemodel (= 7.1.6) - activerecord (= 7.1.6) - activestorage (= 7.1.6) - activesupport (= 7.1.6) + rails (8.1.2) + actioncable (= 8.1.2) + actionmailbox (= 8.1.2) + actionmailer (= 8.1.2) + actionpack (= 8.1.2) + actiontext (= 8.1.2) + actionview (= 8.1.2) + activejob (= 8.1.2) + activemodel (= 8.1.2) + activerecord (= 8.1.2) + activestorage (= 8.1.2) + activesupport (= 8.1.2) bundler (>= 1.15.0) - railties (= 7.1.6) + railties (= 8.1.2) rails-dom-testing (2.3.0) activesupport (>= 5.0.0) minitest @@ -419,11 +411,10 @@ GEM rails-html-sanitizer (1.6.2) loofah (~> 2.21) nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) - railties (7.1.6) - actionpack (= 7.1.6) - activesupport (= 7.1.6) - cgi - irb + railties (8.1.2) + actionpack (= 8.1.2) + activesupport (= 8.1.2) + irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) thor (~> 1.0, >= 1.2.2) @@ -579,6 +570,7 @@ GEM unicode-emoji (4.2.0) uniform_notifier (1.18.0) uri (1.1.1) + useragent (0.16.11) version_gem (1.1.9) warden (1.2.9) rack (>= 2.0.9) @@ -638,7 +630,7 @@ DEPENDENCIES puma (~> 6.0) pundit rack-cors - rails (~> 7.1.3) + rails (~> 8.0) redis reek rspec-rails (~> 6.0.0) diff --git a/backend/db/schema.rb b/backend/db/schema.rb index bba1650..342ca7a 100644 --- a/backend/db/schema.rb +++ b/backend/db/schema.rb @@ -10,19 +10,19 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_05_26_124316) do +ActiveRecord::Schema[8.1].define(version: 2024_05_26_124316) do # These are extensions that must be enabled in order to support this database - enable_extension "plpgsql" + enable_extension "pg_catalog.plpgsql" create_table "devise_api_tokens", force: :cascade do |t| - t.string "resource_owner_type", null: false - t.bigint "resource_owner_id", null: false t.string "access_token", null: false - t.string "refresh_token" + t.datetime "created_at", null: false t.integer "expires_in", null: false - t.datetime "revoked_at" t.string "previous_refresh_token" - t.datetime "created_at", null: false + t.string "refresh_token" + t.bigint "resource_owner_id", null: false + t.string "resource_owner_type", null: false + t.datetime "revoked_at" t.datetime "updated_at", null: false t.index ["access_token"], name: "index_devise_api_tokens_on_access_token" t.index ["previous_refresh_token"], name: "index_devise_api_tokens_on_previous_refresh_token" @@ -31,30 +31,29 @@ end create_table "users", force: :cascade do |t| + t.boolean "admin", default: false, null: false + t.datetime "created_at", null: false + t.datetime "deleted_at" t.string "email", default: "", null: false t.string "encrypted_password", default: "", null: false - t.string "reset_password_token" - t.datetime "reset_password_sent_at" - t.datetime "remember_created_at" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false t.string "oauth_provider" t.string "oauth_uid" - t.boolean "admin", default: false, null: false - t.datetime "deleted_at" + t.datetime "remember_created_at" + t.datetime "reset_password_sent_at" + t.string "reset_password_token" + t.datetime "updated_at", null: false t.index ["deleted_at"], name: "index_users_on_deleted_at" t.index ["email"], name: "index_users_on_email", unique: true t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true end create_table "versions", force: :cascade do |t| - t.string "item_type", null: false - t.bigint "item_id", null: false + t.datetime "created_at" t.string "event", null: false - t.string "whodunnit" + t.bigint "item_id", null: false + t.string "item_type", null: false t.text "object" - t.datetime "created_at" + t.string "whodunnit" t.index ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id" end - end diff --git a/backend/docker-compose.yml b/backend/docker-compose.yml index fd422b6..828dab6 100644 --- a/backend/docker-compose.yml +++ b/backend/docker-compose.yml @@ -35,7 +35,7 @@ services: volumes: - database-data:/var/lib/postgresql/data ports: - - "5432:5432" + - "5433:5432" healthcheck: test: pg_isready -U postgres -h 127.0.0.1 interval: 5s @@ -60,7 +60,7 @@ services: <<: *backend hostname: web-app-container ports: - - "3000:3000" + - "3001:3000" depends_on: elasticsearch: condition: service_started From 754ae8cbda44a86899b8ac7fce8a2e7df62928a3 Mon Sep 17 00:00:00 2001 From: Edimo Date: Tue, 3 Feb 2026 10:12:55 -0300 Subject: [PATCH 4/5] Update RuboCop configuration, upgrade Ruby to 3.4.8, and modify Docker Compose port. Add new RuboCop dependencies in Gemfile and Gemfile.lock. Adjust error handling in API controller and clean up various files with minor formatting changes. --- backend/.rubocop.yml | 2 +- backend/.tool-versions | 2 +- backend/Gemfile | 2 ++ backend/Gemfile.lock | 8 ++++++++ backend/app/controllers/admin/application_controller.rb | 1 + backend/app/controllers/api/v1/api_controller.rb | 3 ++- backend/app/graphql/types/base_interface.rb | 1 + backend/config/initializers/content_security_policy.rb | 1 + backend/config/initializers/inflections.rb | 1 + backend/config/initializers/permissions_policy.rb | 1 + backend/config/routes.rb | 1 + backend/docker-compose.yml | 2 +- backend/spec/actors/fetch_schools_spec.rb | 1 - backend/spec/models/paper_trail/version_spec.rb | 2 +- backend/spec/rails_helper.rb | 2 +- 15 files changed, 23 insertions(+), 7 deletions(-) diff --git a/backend/.rubocop.yml b/backend/.rubocop.yml index 44f3dd8..8ddf94e 100644 --- a/backend/.rubocop.yml +++ b/backend/.rubocop.yml @@ -1,4 +1,4 @@ -require: +plugins: - rubocop-factory_bot - rubocop-capybara - rubocop-performance diff --git a/backend/.tool-versions b/backend/.tool-versions index 310dace..259d166 100644 --- a/backend/.tool-versions +++ b/backend/.tool-versions @@ -1,2 +1,2 @@ -ruby 3.2.2 +ruby 3.4.8 nodejs 20.7.0 diff --git a/backend/Gemfile b/backend/Gemfile index 5493d11..bcecfb6 100644 --- a/backend/Gemfile +++ b/backend/Gemfile @@ -135,6 +135,8 @@ end group :development do # To ensure code consistency [https://docs.rubocop.org] gem "rubocop", "~> 1.69" + gem "rubocop-capybara", "~> 2.21" + gem "rubocop-factory_bot", "~> 2.26" gem "rubocop-graphql", "~> 1.5" gem "rubocop-performance", "~> 1.23" gem "rubocop-rails", "~> 2.27" diff --git a/backend/Gemfile.lock b/backend/Gemfile.lock index 4f74356..2331cfd 100644 --- a/backend/Gemfile.lock +++ b/backend/Gemfile.lock @@ -496,6 +496,12 @@ GEM rubocop-ast (1.49.0) parser (>= 3.3.7.2) prism (~> 1.7) + rubocop-capybara (2.22.1) + lint_roller (~> 1.1) + rubocop (~> 1.72, >= 1.72.1) + rubocop-factory_bot (2.28.0) + lint_roller (~> 1.1) + rubocop (~> 1.72, >= 1.72.1) rubocop-graphql (1.5.6) lint_roller (~> 1.1) rubocop (>= 1.72.1, < 2) @@ -637,6 +643,8 @@ DEPENDENCIES rspec-sidekiq rswag rubocop (~> 1.69) + rubocop-capybara (~> 2.21) + rubocop-factory_bot (~> 2.26) rubocop-graphql (~> 1.5) rubocop-performance (~> 1.23) rubocop-rails (~> 2.27) diff --git a/backend/app/controllers/admin/application_controller.rb b/backend/app/controllers/admin/application_controller.rb index bb345ac..14e997f 100644 --- a/backend/app/controllers/admin/application_controller.rb +++ b/backend/app/controllers/admin/application_controller.rb @@ -15,6 +15,7 @@ class ApplicationController < Administrate::ApplicationController rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized include Pundit::Authorization + after_action :verify_authorized def authenticate_admin diff --git a/backend/app/controllers/api/v1/api_controller.rb b/backend/app/controllers/api/v1/api_controller.rb index 7b7d38c..49ae9cf 100644 --- a/backend/app/controllers/api/v1/api_controller.rb +++ b/backend/app/controllers/api/v1/api_controller.rb @@ -4,6 +4,7 @@ module Api module V1 class ApiController < ActionController::API include Pundit::Authorization + after_action :verify_authorized before_action :authenticate_devise_api_token! @@ -23,7 +24,7 @@ def render_unauthorized(message = "Unauthorized") end def render_unprocessable_entity(exception) - render json: { error: exception.message }, status: :unprocessable_entity + render json: { error: exception.message }, status: :unprocessable_content end def render_not_found(exception) diff --git a/backend/app/graphql/types/base_interface.rb b/backend/app/graphql/types/base_interface.rb index 1889938..3844aed 100644 --- a/backend/app/graphql/types/base_interface.rb +++ b/backend/app/graphql/types/base_interface.rb @@ -3,6 +3,7 @@ module Types module BaseInterface include GraphQL::Schema::Interface + edge_type_class(Types::BaseEdge) connection_type_class(Types::BaseConnection) diff --git a/backend/config/initializers/content_security_policy.rb b/backend/config/initializers/content_security_policy.rb index 691cfa1..53538c1 100644 --- a/backend/config/initializers/content_security_policy.rb +++ b/backend/config/initializers/content_security_policy.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + # Be sure to restart your server when you modify this file. # Define an application-wide content security policy. diff --git a/backend/config/initializers/inflections.rb b/backend/config/initializers/inflections.rb index 6c78420..9e049dc 100644 --- a/backend/config/initializers/inflections.rb +++ b/backend/config/initializers/inflections.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + # Be sure to restart your server when you modify this file. # Add new inflection rules using the following format. Inflections diff --git a/backend/config/initializers/permissions_policy.rb b/backend/config/initializers/permissions_policy.rb index 50bcf4e..810aade 100644 --- a/backend/config/initializers/permissions_policy.rb +++ b/backend/config/initializers/permissions_policy.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + # Define an application-wide HTTP permissions policy. For further # information see https://developers.google.com/web/updates/2018/06/feature-policy # diff --git a/backend/config/routes.rb b/backend/config/routes.rb index 339069e..a156038 100644 --- a/backend/config/routes.rb +++ b/backend/config/routes.rb @@ -10,6 +10,7 @@ end extend DemoPackRoutes extend OauthRoutes + mount GraphiQL::Rails::Engine, at: "/graphiql", graphql_path: "/graphql" if Rails.env.development? post "/graphql", to: "graphql#execute" mount Sidekiq::Web => "/sidekiq" diff --git a/backend/docker-compose.yml b/backend/docker-compose.yml index 828dab6..a58319a 100644 --- a/backend/docker-compose.yml +++ b/backend/docker-compose.yml @@ -60,7 +60,7 @@ services: <<: *backend hostname: web-app-container ports: - - "3001:3000" + - "3002:3000" depends_on: elasticsearch: condition: service_started diff --git a/backend/spec/actors/fetch_schools_spec.rb b/backend/spec/actors/fetch_schools_spec.rb index b90d97d..519c086 100644 --- a/backend/spec/actors/fetch_schools_spec.rb +++ b/backend/spec/actors/fetch_schools_spec.rb @@ -39,7 +39,6 @@ end context "when setup is valid" do - it "is successful" do expect(call.success?).to be true end diff --git a/backend/spec/models/paper_trail/version_spec.rb b/backend/spec/models/paper_trail/version_spec.rb index 9a13c06..755c4be 100644 --- a/backend/spec/models/paper_trail/version_spec.rb +++ b/backend/spec/models/paper_trail/version_spec.rb @@ -2,7 +2,7 @@ require "rails_helper" -RSpec.describe PaperTrail::Version, versioning: true do +RSpec.describe PaperTrail::Version, :versioning do let(:user) { create(:user, email: "user@email.com") } context "when create object in database" do diff --git a/backend/spec/rails_helper.rb b/backend/spec/rails_helper.rb index 41adbf7..f4f33e6 100644 --- a/backend/spec/rails_helper.rb +++ b/backend/spec/rails_helper.rb @@ -63,6 +63,6 @@ config.filter_rails_from_backtrace! # arbitrary gems may also be filtered via: # config.filter_gems_from_backtrace("gem name") - Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f } + Rails.root.glob("spec/support/**/*.rb").each { |f| require f } config.include JsonResponseHelper, type: :request end From bb9a35ca8c84062ebcce2e3bada6c4ebd3f10686 Mon Sep 17 00:00:00 2001 From: Edimo Date: Tue, 3 Feb 2026 10:43:37 -0300 Subject: [PATCH 5/5] Update Gemfile and Gemfile.lock to add OpenStruct support, upgrade Devise to version 5.0, and upgrade RSpec to version 7.0. Modify fixture path configuration in RSpec and simplify factory usage in tests. Adjust error messages in user request specs for clarity. --- backend/Gemfile | 4 ++-- backend/Gemfile.lock | 24 +++++++++---------- .../models/acts_as_paranoid_factories_spec.rb | 4 +--- backend/spec/rails_helper.rb | 2 +- .../requests/api/v1/users_request_spec.rb | 2 +- 5 files changed, 17 insertions(+), 19 deletions(-) diff --git a/backend/Gemfile b/backend/Gemfile index bcecfb6..6a4e488 100644 --- a/backend/Gemfile +++ b/backend/Gemfile @@ -57,7 +57,7 @@ gem "bootsnap", require: false # gem "image_processing", "~> 1.2" # Devise is a flexible authentication solution for Rails based on Warden [https://github.com/heartcombo/devise] -gem "devise", "~> 4.9" +gem "devise", "~> 5.0" # devise-api authenticate API requests [https://github.com/nejdetkadir/devise-api] gem "devise-api", github: "nejdetkadir/devise-api", branch: "main" @@ -159,7 +159,7 @@ end group :test do # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing] gem "capybara" - gem "rspec-rails", "~> 6.0.0" + gem "rspec-rails", "~> 7.0" gem "rspec-sidekiq" gem "selenium-webdriver" gem "shoulda-matchers", "~> 5.0" diff --git a/backend/Gemfile.lock b/backend/Gemfile.lock index 2331cfd..ef25cb7 100644 --- a/backend/Gemfile.lock +++ b/backend/Gemfile.lock @@ -154,10 +154,10 @@ GEM debug (1.11.1) irb (~> 1.10) reline (>= 0.3.8) - devise (4.9.4) + devise (5.0.0) bcrypt (~> 3.0) orm_adapter (~> 0.1) - railties (>= 4.1.0) + railties (>= 7.0) responders warden (~> 1.2.3) diff-lcs (1.6.2) @@ -453,14 +453,14 @@ GEM rspec-mocks (3.13.7) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-rails (6.0.4) - actionpack (>= 6.1) - activesupport (>= 6.1) - railties (>= 6.1) - rspec-core (~> 3.12) - rspec-expectations (~> 3.12) - rspec-mocks (~> 3.12) - rspec-support (~> 3.12) + rspec-rails (7.1.1) + actionpack (>= 7.0) + activesupport (>= 7.0) + railties (>= 7.0) + rspec-core (~> 3.13) + rspec-expectations (~> 3.13) + rspec-mocks (~> 3.13) + rspec-support (~> 3.13) rspec-sidekiq (5.2.0) rspec-core (~> 3.0) rspec-expectations (~> 3.0) @@ -615,7 +615,7 @@ DEPENDENCIES connection_pool (~> 2.4) csv debug - devise (~> 4.9) + devise (~> 5.0) devise-api! dotenv-rails dry-validation @@ -639,7 +639,7 @@ DEPENDENCIES rails (~> 8.0) redis reek - rspec-rails (~> 6.0.0) + rspec-rails (~> 7.0) rspec-sidekiq rswag rubocop (~> 1.69) diff --git a/backend/spec/models/acts_as_paranoid_factories_spec.rb b/backend/spec/models/acts_as_paranoid_factories_spec.rb index 1304e94..2a29688 100644 --- a/backend/spec/models/acts_as_paranoid_factories_spec.rb +++ b/backend/spec/models/acts_as_paranoid_factories_spec.rb @@ -5,8 +5,6 @@ RSpec.describe "ApplicationRecord" do FactoryBot.factories.each do |factory| - model_class = factory.build_class - - it_behaves_like "acts_as_paranoid", model_class + it_behaves_like "acts_as_paranoid", factory.build_class end end diff --git a/backend/spec/rails_helper.rb b/backend/spec/rails_helper.rb index f4f33e6..02564d5 100644 --- a/backend/spec/rails_helper.rb +++ b/backend/spec/rails_helper.rb @@ -33,7 +33,7 @@ end RSpec.configure do |config| # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures - config.fixture_path = Rails.root.join("spec/fixtures").to_s + config.fixture_paths = [Rails.root.join("spec/fixtures").to_s] # If you're not using ActiveRecord, or you'd prefer not to run each of your # examples within a transaction, remove the following line or assign false diff --git a/backend/spec/requests/api/v1/users_request_spec.rb b/backend/spec/requests/api/v1/users_request_spec.rb index 600d7d7..fb1ab51 100644 --- a/backend/spec/requests/api/v1/users_request_spec.rb +++ b/backend/spec/requests/api/v1/users_request_spec.rb @@ -55,7 +55,7 @@ it { expect(response).to have_http_status(:unauthorized) } it { - expect(response.parsed_body["error"]).to eq("not allowed to index? this User::ActiveRecord_Relation") + expect(response.parsed_body["error"]).to eq("not allowed to UserPolicy#index? this User::ActiveRecord_Relation") } end end