From a3fc0cd0b349d771fe0655ca8259a766754be9bb Mon Sep 17 00:00:00 2001 From: Stefanni Brasil Date: Thu, 18 Jun 2026 14:02:37 -0600 Subject: [PATCH 01/11] bundle update rails --- Gemfile | 2 +- Gemfile.lock | 125 ++++++++++++++++++++++++++------------------------- 2 files changed, 65 insertions(+), 62 deletions(-) diff --git a/Gemfile b/Gemfile index 8cef6a7763..69f9803716 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,7 @@ source "https://rubygems.org" ruby "4.0.3" -gem "rails", "~> 8.0" +gem "rails", "~> 8.1" gem "after_party" # Post-deployment tasks gem "amazing_print" # Easier console reading diff --git a/Gemfile.lock b/Gemfile.lock index ffbfcc4f3f..2e6718ec41 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,29 +1,31 @@ GEM remote: https://rubygems.org/ specs: - actioncable (8.0.5) - actionpack (= 8.0.5) - activesupport (= 8.0.5) + action_text-trix (2.1.19) + railties + actioncable (8.1.3) + actionpack (= 8.1.3) + activesupport (= 8.1.3) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (8.0.5) - actionpack (= 8.0.5) - activejob (= 8.0.5) - activerecord (= 8.0.5) - activestorage (= 8.0.5) - activesupport (= 8.0.5) + actionmailbox (8.1.3) + actionpack (= 8.1.3) + activejob (= 8.1.3) + activerecord (= 8.1.3) + activestorage (= 8.1.3) + activesupport (= 8.1.3) mail (>= 2.8.0) - actionmailer (8.0.5) - actionpack (= 8.0.5) - actionview (= 8.0.5) - activejob (= 8.0.5) - activesupport (= 8.0.5) + actionmailer (8.1.3) + actionpack (= 8.1.3) + actionview (= 8.1.3) + activejob (= 8.1.3) + activesupport (= 8.1.3) mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (8.0.5) - actionview (= 8.0.5) - activesupport (= 8.0.5) + actionpack (8.1.3) + actionview (= 8.1.3) + activesupport (= 8.1.3) nokogiri (>= 1.8.5) rack (>= 2.2.4) rack-session (>= 1.0.1) @@ -31,46 +33,47 @@ GEM rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) useragent (~> 0.16) - actiontext (8.0.5) - actionpack (= 8.0.5) - activerecord (= 8.0.5) - activestorage (= 8.0.5) - activesupport (= 8.0.5) + actiontext (8.1.3) + action_text-trix (~> 2.1.15) + actionpack (= 8.1.3) + activerecord (= 8.1.3) + activestorage (= 8.1.3) + activesupport (= 8.1.3) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (8.0.5) - activesupport (= 8.0.5) + actionview (8.1.3) + activesupport (= 8.1.3) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (8.0.5) - activesupport (= 8.0.5) + activejob (8.1.3) + activesupport (= 8.1.3) globalid (>= 0.3.6) - activemodel (8.0.5) - activesupport (= 8.0.5) + activemodel (8.1.3) + activesupport (= 8.1.3) activemodel-serializers-xml (1.0.3) activemodel (>= 5.0.0.a) activesupport (>= 5.0.0.a) builder (~> 3.1) - activerecord (8.0.5) - activemodel (= 8.0.5) - activesupport (= 8.0.5) + activerecord (8.1.3) + activemodel (= 8.1.3) + activesupport (= 8.1.3) timeout (>= 0.4.0) - activestorage (8.0.5) - actionpack (= 8.0.5) - activejob (= 8.0.5) - activerecord (= 8.0.5) - activesupport (= 8.0.5) + activestorage (8.1.3) + actionpack (= 8.1.3) + activejob (= 8.1.3) + activerecord (= 8.1.3) + activesupport (= 8.1.3) marcel (~> 1.0) - activesupport (8.0.5) + activesupport (8.1.3) base64 - benchmark (>= 0.3) bigdecimal 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) securerandom (>= 0.3) @@ -276,7 +279,7 @@ GEM csv mini_mime (>= 1.0.0) multi_xml (>= 0.5.2) - i18n (1.15.0) + i18n (1.15.1) concurrent-ruby (~> 1.0) image_processing (1.14.0) mini_magick (>= 4.9.5, < 6) @@ -321,7 +324,7 @@ GEM net-imap net-pop net-smtp - marcel (1.1.0) + marcel (1.2.1) matrix (0.4.3) mcp (0.9.2) json-schema (>= 4.1) @@ -457,20 +460,20 @@ GEM rack (>= 1.3) rackup (2.3.1) rack (>= 3) - rails (8.0.5) - actioncable (= 8.0.5) - actionmailbox (= 8.0.5) - actionmailer (= 8.0.5) - actionpack (= 8.0.5) - actiontext (= 8.0.5) - actionview (= 8.0.5) - activejob (= 8.0.5) - activemodel (= 8.0.5) - activerecord (= 8.0.5) - activestorage (= 8.0.5) - activesupport (= 8.0.5) + rails (8.1.3) + actioncable (= 8.1.3) + actionmailbox (= 8.1.3) + actionmailer (= 8.1.3) + actionpack (= 8.1.3) + actiontext (= 8.1.3) + actionview (= 8.1.3) + activejob (= 8.1.3) + activemodel (= 8.1.3) + activerecord (= 8.1.3) + activestorage (= 8.1.3) + activesupport (= 8.1.3) bundler (>= 1.15.0) - railties (= 8.0.5) + railties (= 8.1.3) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -482,9 +485,9 @@ GEM rails-html-sanitizer (1.7.0) loofah (~> 2.25) 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 (8.0.5) - actionpack (= 8.0.5) - activesupport (= 8.0.5) + railties (8.1.3) + actionpack (= 8.1.3) + activesupport (= 8.1.3) irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) @@ -535,9 +538,9 @@ GEM json-schema (>= 2.2, < 7.0) railties (>= 5.2, < 8.2) rspec-core (>= 2.14) - rswag-ui (2.16.0) - actionpack (>= 5.2, < 8.1) - railties (>= 5.2, < 8.1) + rswag-ui (2.17.0) + actionpack (>= 5.2, < 8.2) + railties (>= 5.2, < 8.2) rubocop (1.84.2) json (~> 2.3) language_server-protocol (~> 3.17.0.2) @@ -684,7 +687,7 @@ GEM crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) websocket (1.2.11) - websocket-driver (0.8.0) + websocket-driver (0.8.1) base64 websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) @@ -761,7 +764,7 @@ DEPENDENCIES pundit rack-attack rack-cors - rails (~> 8.0) + rails (~> 8.1) rails-controller-testing request_store rexml From ad55d740bbd4a14204369b376dda7d247a60a465 Mon Sep 17 00:00:00 2001 From: Stefanni Brasil Date: Thu, 18 Jun 2026 14:11:52 -0600 Subject: [PATCH 02/11] reviewed files we want to keep --- bin/bundler-audit | 6 ++ config/bundler-audit.yml | 5 ++ config/environments/development.rb | 3 + .../initializers/content_security_policy.rb | 4 + config/initializers/inflections.rb | 2 +- .../new_framework_defaults_8_1.rb | 74 +++++++++++++++++++ config/puma.rb | 5 +- public/400.html | 31 ++++++-- public/406-unsupported-browser.html | 29 +++++++- public/422.html | 31 ++++++-- 10 files changed, 173 insertions(+), 17 deletions(-) create mode 100755 bin/bundler-audit create mode 100644 config/bundler-audit.yml create mode 100644 config/initializers/new_framework_defaults_8_1.rb diff --git a/bin/bundler-audit b/bin/bundler-audit new file mode 100755 index 0000000000..e2ef22690c --- /dev/null +++ b/bin/bundler-audit @@ -0,0 +1,6 @@ +#!/usr/bin/env ruby +require_relative "../config/boot" +require "bundler/audit/cli" + +ARGV.concat %w[ --config config/bundler-audit.yml ] if ARGV.empty? || ARGV.include?("check") +Bundler::Audit::CLI.start diff --git a/config/bundler-audit.yml b/config/bundler-audit.yml new file mode 100644 index 0000000000..e74b3af949 --- /dev/null +++ b/config/bundler-audit.yml @@ -0,0 +1,5 @@ +# Audit all gems listed in the Gemfile for known security problems by running bin/bundler-audit. +# CVEs that are not relevant to the application can be enumerated on the ignore list below. + +ignore: + - CVE-THAT-DOES-NOT-APPLY diff --git a/config/environments/development.rb b/config/environments/development.rb index 493e6fc73c..ac7c230e0a 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -77,6 +77,9 @@ config.action_controller.forgery_protection_origin_check = false end + # Uncomment if you wish to allow Action Cable access from any origin. + # config.action_cable.disable_request_forgery_protection = true + # Raise error when a before_action's only/except options reference missing actions. config.action_controller.raise_on_missing_callback_actions = false diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index b3076b38fe..d51d713979 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -20,6 +20,10 @@ # config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } # config.content_security_policy_nonce_directives = %w(script-src style-src) # +# # Automatically add `nonce` to `javascript_tag`, `javascript_include_tag`, and `stylesheet_link_tag` +# # if the corresponding directives are specified in `content_security_policy_nonce_directives`. +# # config.content_security_policy_nonce_auto = true +# # # Report violations without enforcing the policy. # # config.content_security_policy_report_only = true # end diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index e2fdd60539..0ce5929819 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -15,5 +15,5 @@ # inflect.acronym "RESTful" # end ActiveSupport::Inflector.inflections(:en) do |inflect| - inflect.acronym "DSS" # TODO what is this for? + inflect.acronym "DSS" end diff --git a/config/initializers/new_framework_defaults_8_1.rb b/config/initializers/new_framework_defaults_8_1.rb new file mode 100644 index 0000000000..5cc706343c --- /dev/null +++ b/config/initializers/new_framework_defaults_8_1.rb @@ -0,0 +1,74 @@ +# Be sure to restart your server when you modify this file. +# +# This file eases your Rails 8.1 framework defaults upgrade. +# +# Uncomment each configuration one by one to switch to the new default. +# Once your application is ready to run with all new defaults, you can remove +# this file and set the `config.load_defaults` to `8.1`. +# +# Read the Guide for Upgrading Ruby on Rails for more info on each option. +# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html + +### +# Skips escaping HTML entities and line separators. When set to `false`, the +# JSON renderer no longer escapes these to improve performance. +# +# Example: +# class PostsController < ApplicationController +# def index +# render json: { key: "\u2028\u2029<>&" } +# end +# end +# +# Renders `{"key":"\u2028\u2029\u003c\u003e\u0026"}` with the previous default, but `{"key":"

<>&"}` with the config +# set to `false`. +# +# Applications that want to keep the escaping behavior can set the config to `true`. +#++ +Rails.configuration.action_controller.escape_json_responses = false + +### +# Skips escaping LINE SEPARATOR (U+2028) and PARAGRAPH SEPARATOR (U+2029) in JSON. +# +# Historically these characters were not valid inside JavaScript literal strings but that changed in ECMAScript 2019. +# As such it's no longer a concern in modern browsers: https://caniuse.com/mdn-javascript_builtins_json_json_superset. +#++ +Rails.configuration.active_support.escape_js_separators_in_json = false + +### +# Raises an error when order dependent finder methods (e.g. `#first`, `#second`) are called without `order` values +# on the relation, and the model does not have any order columns (`implicit_order_column`, `query_constraints`, or +# `primary_key`) to fall back on. +# +# The current behavior of not raising an error has been deprecated, and this configuration option will be removed in +# Rails 8.2. +#++ +Rails.configuration.active_record.raise_on_missing_required_finder_order_columns = true + +### +# Controls how Rails handles path relative URL redirects. +# When set to `:raise`, Rails will raise an `ActionController::Redirecting::UnsafeRedirectError` +# for relative URLs without a leading slash, which can help prevent open redirect vulnerabilities. +# +# Example: +# redirect_to "example.com" # Raises UnsafeRedirectError +# redirect_to "@attacker.com" # Raises UnsafeRedirectError +# redirect_to "/safe/path" # Works correctly +# +# Applications that want to allow these redirects can set the config to `:log` (previous default) +# to only log warnings, or `:notify` to send ActiveSupport notifications. +#++ +Rails.configuration.action_controller.action_on_path_relative_redirect = :raise + +### +# Use a Ruby parser to track dependencies between Action View templates +#++ +Rails.configuration.action_view.render_tracker = :ruby + +### +# When enabled, hidden inputs generated by `form_tag`, `token_tag`, `method_tag`, and the hidden parameter fields +# included in `button_to` forms will omit the `autocomplete="off"` attribute. +# +# Applications that want to keep generating the `autocomplete` attribute for those tags can set it to `false`. +#++ +Rails.configuration.action_view.remove_hidden_field_autocomplete = true diff --git a/config/puma.rb b/config/puma.rb index a248513b24..38c4b86596 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -7,7 +7,8 @@ # # You can control the number of workers using ENV["WEB_CONCURRENCY"]. You # should only set this value when you want to run 2 or more workers. The -# default is already 1. +# default is already 1. You can set it to `auto` to automatically start a worker +# for each available processor. # # The ideal number of threads per worker depends both on how much time the # application spends waiting for IO operations and on how much you wish to @@ -33,7 +34,7 @@ # Allow puma to be restarted by `bin/rails restart` command. plugin :tmp_restart -# Run the Solid Queue supervisor inside of Puma for single-server deployments +# Run the Solid Queue supervisor inside of Puma for single-server deployments. plugin :solid_queue if ENV["SOLID_QUEUE_IN_PUMA"] # Specify the PID file. Defaults to tmp/pids/server.pid in development. diff --git a/public/400.html b/public/400.html index 282dbc8cc9..640de03397 100644 --- a/public/400.html +++ b/public/400.html @@ -35,12 +35,35 @@ font-weight: 400; letter-spacing: -0.0025em; line-height: 1.4; - min-height: 100vh; + min-height: 100dvh; place-items: center; text-rendering: optimizeLegibility; -webkit-text-size-adjust: 100%; } + #error-description { + fill: #d30001; + } + + #error-id { + fill: #f0eff0; + } + + @media (prefers-color-scheme: dark) { + body { + background: #101010; + color: #e0e0e0; + } + + #error-description { + fill: #FF6161; + } + + #error-id { + fill: #2c2c2c; + } + } + a { color: inherit; font-weight: 700; @@ -83,13 +106,11 @@ } main article br { - display: none; @media(min-width: 48em) { display: inline; } - } @@ -102,10 +123,10 @@
- +
-

The server cannot process the request due to a client error. Please check the request and try again. If you’re the application owner check the logs for more information.

+

The server cannot process the request due to a client error. Please check the request and try again. If you're the application owner check the logs for more information.

diff --git a/public/406-unsupported-browser.html b/public/406-unsupported-browser.html index 9532a9ccd0..43d2811e8c 100644 --- a/public/406-unsupported-browser.html +++ b/public/406-unsupported-browser.html @@ -35,12 +35,35 @@ font-weight: 400; letter-spacing: -0.0025em; line-height: 1.4; - min-height: 100vh; + min-height: 100dvh; place-items: center; text-rendering: optimizeLegibility; -webkit-text-size-adjust: 100%; } + #error-description { + fill: #d30001; + } + + #error-id { + fill: #f0eff0; + } + + @media (prefers-color-scheme: dark) { + body { + background: #101010; + color: #e0e0e0; + } + + #error-description { + fill: #FF6161; + } + + #error-id { + fill: #2c2c2c; + } + } + a { color: inherit; font-weight: 700; @@ -83,13 +106,11 @@ } main article br { - display: none; @media(min-width: 48em) { display: inline; } - } @@ -102,7 +123,7 @@
- +

Your browser is not supported.
Please upgrade your browser to continue.

diff --git a/public/422.html b/public/422.html index 8bcf06014f..f12fb4aa17 100644 --- a/public/422.html +++ b/public/422.html @@ -35,12 +35,35 @@ font-weight: 400; letter-spacing: -0.0025em; line-height: 1.4; - min-height: 100vh; + min-height: 100dvh; place-items: center; text-rendering: optimizeLegibility; -webkit-text-size-adjust: 100%; } + #error-description { + fill: #d30001; + } + + #error-id { + fill: #f0eff0; + } + + @media (prefers-color-scheme: dark) { + body { + background: #101010; + color: #e0e0e0; + } + + #error-description { + fill: #FF6161; + } + + #error-id { + fill: #2c2c2c; + } + } + a { color: inherit; font-weight: 700; @@ -83,13 +106,11 @@ } main article br { - display: none; @media(min-width: 48em) { display: inline; } - } @@ -102,10 +123,10 @@
- +
-

The change you wanted was rejected. Maybe you tried to change something you didn’t have access to. If you’re the application owner check the logs for more information.

+

The change you wanted was rejected. Maybe you tried to change something you didn't have access to. If you're the application owner check the logs for more information.

From 415251fea7472e6b940abd92b591c537af6acdf5 Mon Sep 17 00:00:00 2001 From: Stefanni Brasil Date: Thu, 18 Jun 2026 14:12:08 -0600 Subject: [PATCH 03/11] commit all to view changes in the browser, easier to compare --- config/environments/development.rb | 41 +++++++------------ config/environments/production.rb | 63 +++++++++++++----------------- config/environments/test.rb | 36 +++++------------ 3 files changed, 51 insertions(+), 89 deletions(-) diff --git a/config/environments/development.rb b/config/environments/development.rb index ac7c230e0a..885961f81a 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -20,33 +20,29 @@ if Rails.root.join("tmp/caching-dev.txt").exist? config.action_controller.perform_caching = true config.action_controller.enable_fragment_cache_logging = true - config.cache_store = :memory_store - config.public_file_server.headers = {"cache-control" => "public, max-age=#{2.days.to_i}"} + config.public_file_server.headers = { "cache-control" => "public, max-age=#{2.days.to_i}" } else config.action_controller.perform_caching = false - config.cache_store = :null_store end + # Change to :null_store to avoid any caching. + config.cache_store = :memory_store + # Store uploaded files on the local file system (see config/storage.yml for options). config.active_storage.service = :local # Don't care if the mailer can't send. - config.action_mailer.default_url_options = {host: "localhost", port: 3000} # Set localhost to be used by links generated in mailer templates. - config.action_mailer.delivery_method = :letter_opener - config.action_mailer.perform_deliveries = true + config.action_mailer.raise_delivery_errors = false + # Make template changes take effect immediately. config.action_mailer.perform_caching = false - config.action_mailer.raise_delivery_errors = false + + # Set localhost to be used by links generated in mailer templates. + config.action_mailer.default_url_options = { host: "localhost", port: 3000 } # Print deprecation notices to the Rails logger. config.active_support.deprecation = :log - # Raise exceptions for disallowed deprecations. - config.active_support.disallowed_deprecation = :raise - - # Tell Active Support which deprecation messages to disallow. - config.active_support.disallowed_deprecation_warnings = [] - # Raise an error on page load if there are pending migrations. config.active_record.migration_error = :page_load @@ -59,29 +55,20 @@ # Highlight code that enqueued background job in logs. config.active_job.verbose_enqueue_logs = true - # Suppress logger output for asset requests. - config.assets.quiet = true - config.assets.digest = false + # Highlight code that triggered redirect in logs. + config.action_dispatch.verbose_redirect_logs = true - # Prosopite N+1 query detection - config.prosopite_enabled = true - config.prosopite_min_n_queries = 5 # More lenient for development + # Raises error for missing translations. + # config.i18n.raise_on_missing_translations = true # Annotate rendered view with file names. config.action_view.annotate_rendered_view_with_filenames = true - config.hosts << ENV["DEV_HOSTS"] - config.hosts << ".app.github.dev" - - if ENV["CODESPACES"] === "true" - config.action_controller.forgery_protection_origin_check = false - end - # Uncomment if you wish to allow Action Cable access from any origin. # config.action_cable.disable_request_forgery_protection = true # Raise error when a before_action's only/except options reference missing actions. - config.action_controller.raise_on_missing_callback_actions = false + config.action_controller.raise_on_missing_callback_actions = true # Apply autocorrection by RuboCop to files generated by `bin/rails generate`. # config.generators.apply_rubocop_autocorrect_after_generate! diff --git a/config/environments/production.rb b/config/environments/production.rb index 7c310a9f9a..cb0241df64 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -1,25 +1,8 @@ +require "active_support/core_ext/integer/time" + Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. - # Set host to be used by links generated in mailer templates. - config.action_mailer.default_url_options = {host: ENV["DOMAIN"]} - # Ignore bad email addresses and do not raise email delivery errors. - # Set this to true and configure the email server for immediate delivery to raise delivery errors. - config.action_mailer.raise_delivery_errors = true - config.action_mailer.show_previews = ENV["APP_ENVIRONMENT"] != "production" - # Do not send emails in staging or qa - config.action_mailer.perform_deliveries = ENV["APP_ENVIRONMENT"] == "production" - config.action_mailer.delivery_method = :smtp - # Specify outgoing SMTP server. - config.action_mailer.smtp_settings = { - address: "smtp-relay.sendinblue.com", - port: 587, - user_name: ENV["SENDINBLUE_EMAIL"], - password: ENV["SENDINBLUE_PASSWORD"], - authentication: "login", - enable_starttls_auto: true - } - # Code is not reloaded between requests. config.enable_reloading = false @@ -32,30 +15,29 @@ # Turn on fragment caching in view templates. config.action_controller.perform_caching = true - # Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment - # key such as config/credentials/production.key. This key is used to decrypt credentials (and other encrypted files). - config.require_master_key = true - - # Enable static file serving from the `/public` folder (turn off if using NGINX/Apache for it). - config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? + # Cache assets for far-future expiry since they are all digest stamped. + config.public_file_server.headers = { "cache-control" => "public, max-age=#{1.year.to_i}" } # Enable serving of images, stylesheets, and JavaScripts from an asset server. # config.asset_host = "http://assets.example.com" # Store uploaded files on the local file system (see config/storage.yml for options). - config.active_storage.service = :microsoft + config.active_storage.service = :local + + # Assume all access to the app is happening through a SSL-terminating reverse proxy. + # config.assume_ssl = true # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. - config.force_ssl = true + # config.force_ssl = true # Skip http-to-https redirect for the default health check endpoint. # config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } } # Log to STDOUT with the current request id as a default log tag. - config.log_tags = [:request_id] - config.logger = ActiveSupport::TaggedLogging.logger($stdout) + config.log_tags = [ :request_id ] + config.logger = ActiveSupport::TaggedLogging.logger(STDOUT) - # Change to "debug" to log everything (including potentially personally-identifiable information!) + # Change to "debug" to log everything (including potentially personally-identifiable information!). config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info") # Prevent health checks from clogging up the logs. @@ -70,10 +52,21 @@ # Replace the default in-process and non-durable queuing backend for Active Job. # config.active_job.queue_adapter = :resque - # Use a real queuing backend for Active Job (and separate queues per environment). - config.active_job.queue_adapter = :delayed_job + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false + + # Set host to be used by links generated in mailer templates. + config.action_mailer.default_url_options = { host: "example.com" } - config.action_mailer.perform_caching = false + # Specify outgoing SMTP server. Remember to add smtp/* credentials via bin/rails credentials:edit. + # config.action_mailer.smtp_settings = { + # user_name: Rails.application.credentials.dig(:smtp, :user_name), + # password: Rails.application.credentials.dig(:smtp, :password), + # address: "smtp.example.com", + # port: 587, + # authentication: :plain + # } # Enable locale fallbacks for I18n (makes lookups for any locale fall back to # the I18n.default_locale when a translation cannot be found). @@ -82,8 +75,8 @@ # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false - # Inspect all attributes in production. New default is :id. - config.active_record.attributes_for_inspect = [:all] + # Only use :id for inspections in production. + config.active_record.attributes_for_inspect = [ :id ] # Enable DNS rebinding protection and other `Host` header attacks. # config.hosts = [ diff --git a/config/environments/test.rb b/config/environments/test.rb index 1b61cc7031..c2095b1174 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -7,9 +7,7 @@ # Settings specified here will take precedence over those in config/application.rb. # While tests run files are not watched, reloading is not necessary. - config.enable_reloading = ENV["CI"].blank? - - config.action_view.cache_template_loading = true + config.enable_reloading = false # Eager loading loads your entire application. When running a single test locally, # this is usually not necessary, and can slow down your test suite. However, it's @@ -18,15 +16,11 @@ config.eager_load = ENV["CI"].present? # Configure public file server for tests with cache-control for performance. - config.public_file_server.enabled = true - config.public_file_server.headers = { - "Cache-Control" => "public, max-age=#{1.hour.to_i}" - } + config.public_file_server.headers = { "cache-control" => "public, max-age=3600" } # Show full error reports. config.consider_all_requests_local = true - - config.action_controller.perform_caching = false + config.cache_store = :null_store # Render exception templates for rescuable exceptions and raise for other exceptions. config.action_dispatch.show_exceptions = :rescuable @@ -37,35 +31,23 @@ # Store uploaded files on the local file system in a temporary directory. config.active_storage.service = :test - config.action_mailer.perform_caching = false - # Tell Action Mailer not to deliver emails to the real world. # The :test delivery method accumulates sent emails in the # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test # Set host to be used by links generated in mailer templates. - config.action_mailer.default_url_options = {host: "localhost", port: 3000} + config.action_mailer.default_url_options = { host: "example.com" } # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr - # Rack Attack configuration - # Set IP_BLOCKLIST for testing. Can't stub in spec since environment variable - # gets read during application initialization. - ENV["IP_BLOCKLIST"] = "4.5.6.7, 9.8.7.6,100.101.102.103" - - # Raise exceptions for disallowed deprecations. - config.active_support.disallowed_deprecation = :raise - - # Tell Active Support which deprecation messages to disallow. - config.active_support.disallowed_deprecation_warnings = [] - # Raises error for missing translations. - config.i18n.raise_on_missing_translations = true + # config.i18n.raise_on_missing_translations = true - # Raise error when a before_action's only/except options reference missing actions. - config.action_controller.raise_on_missing_callback_actions = false + # Annotate rendered view with file names. + # config.action_view.annotate_rendered_view_with_filenames = true - config.secret_key_base = ENV["SECRET_KEY_BASE"] || "dummy_test_secret_key" + # Raise error when a before_action's only/except options reference missing actions. + config.action_controller.raise_on_missing_callback_actions = true end From 2bfa46236407db4678a1bc17f0a348a06051e4a4 Mon Sep 17 00:00:00 2001 From: Stefanni Brasil Date: Thu, 18 Jun 2026 14:24:54 -0600 Subject: [PATCH 04/11] keep previous config --- config/environments/development.rb | 39 +++++++++++++++++----- config/environments/production.rb | 52 ++++++++++++++++++++---------- config/environments/test.rb | 38 ++++++++++++++++++---- 3 files changed, 97 insertions(+), 32 deletions(-) diff --git a/config/environments/development.rb b/config/environments/development.rb index 885961f81a..d4fc67b336 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -20,29 +20,34 @@ if Rails.root.join("tmp/caching-dev.txt").exist? config.action_controller.perform_caching = true config.action_controller.enable_fragment_cache_logging = true + config.cache_store = :memory_store config.public_file_server.headers = { "cache-control" => "public, max-age=#{2.days.to_i}" } else config.action_controller.perform_caching = false + config.cache_store = :null_store end - # Change to :null_store to avoid any caching. - config.cache_store = :memory_store - # Store uploaded files on the local file system (see config/storage.yml for options). config.active_storage.service = :local # Don't care if the mailer can't send. config.action_mailer.raise_delivery_errors = false + config.action_mailer.default_url_options = {host: "localhost", port: 3000} # Set localhost to be used by links generated in mailer templates. + config.action_mailer.delivery_method = :letter_opener + config.action_mailer.perform_deliveries = true # Make template changes take effect immediately. config.action_mailer.perform_caching = false - # Set localhost to be used by links generated in mailer templates. - config.action_mailer.default_url_options = { host: "localhost", port: 3000 } - # Print deprecation notices to the Rails logger. config.active_support.deprecation = :log + # Raise exceptions for disallowed deprecations. + config.active_support.disallowed_deprecation = :raise + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + # Raise an error on page load if there are pending migrations. config.active_record.migration_error = :page_load @@ -59,16 +64,34 @@ config.action_dispatch.verbose_redirect_logs = true # Raises error for missing translations. - # config.i18n.raise_on_missing_translations = true + config.i18n.raise_on_missing_translations = true + + # Suppress logger output for asset requests. + config.assets.quiet = true + config.assets.digest = false # Annotate rendered view with file names. config.action_view.annotate_rendered_view_with_filenames = true + # Prosopite N+1 query detection + config.prosopite_enabled = true + config.prosopite_min_n_queries = 5 # More lenient for development + # Uncomment if you wish to allow Action Cable access from any origin. # config.action_cable.disable_request_forgery_protection = true # Raise error when a before_action's only/except options reference missing actions. - config.action_controller.raise_on_missing_callback_actions = true + config.action_controller.raise_on_missing_callback_actions = false + + # Uncomment if you wish to allow Action Cable access from any origin. + # config.action_cable.disable_request_forgery_protection = true + + config.hosts << ENV["DEV_HOSTS"] + config.hosts << ".app.github.dev" + + if ENV["CODESPACES"] === "true" + config.action_controller.forgery_protection_origin_check = false + end # Apply autocorrection by RuboCop to files generated by `bin/rails generate`. # config.generators.apply_rubocop_autocorrect_after_generate! diff --git a/config/environments/production.rb b/config/environments/production.rb index cb0241df64..f5675af94f 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -3,6 +3,25 @@ Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. + # Set host to be used by links generated in mailer templates. + config.action_mailer.default_url_options = {host: ENV["DOMAIN"]} + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + config.action_mailer.raise_delivery_errors = true + config.action_mailer.show_previews = ENV["APP_ENVIRONMENT"] != "production" + # Do not send emails in staging or qa + config.action_mailer.perform_deliveries = ENV["APP_ENVIRONMENT"] == "production" + config.action_mailer.delivery_method = :smtp + # Specify outgoing SMTP server. + config.action_mailer.smtp_settings = { + address: "smtp-relay.sendinblue.com", + port: 587, + user_name: ENV["SENDINBLUE_EMAIL"], + password: ENV["SENDINBLUE_PASSWORD"], + authentication: "login", + enable_starttls_auto: true + } + # Code is not reloaded between requests. config.enable_reloading = false @@ -15,6 +34,13 @@ # Turn on fragment caching in view templates. config.action_controller.perform_caching = true + # Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment + # key such as config/credentials/production.key. This key is used to decrypt credentials (and other encrypted files). + config.require_master_key = true + + # Enable static file serving from the `/public` folder (turn off if using NGINX/Apache for it). + config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? + # Cache assets for far-future expiry since they are all digest stamped. config.public_file_server.headers = { "cache-control" => "public, max-age=#{1.year.to_i}" } @@ -22,20 +48,20 @@ # config.asset_host = "http://assets.example.com" # Store uploaded files on the local file system (see config/storage.yml for options). - config.active_storage.service = :local + config.active_storage.service = :microsoft # Assume all access to the app is happening through a SSL-terminating reverse proxy. # config.assume_ssl = true # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. - # config.force_ssl = true + config.force_ssl = true # Skip http-to-https redirect for the default health check endpoint. # config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } } # Log to STDOUT with the current request id as a default log tag. - config.log_tags = [ :request_id ] - config.logger = ActiveSupport::TaggedLogging.logger(STDOUT) + config.log_tags = [:request_id] + config.logger = ActiveSupport::TaggedLogging.logger($stdout) # Change to "debug" to log everything (including potentially personally-identifiable information!). config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info") @@ -56,17 +82,9 @@ # Set this to true and configure the email server for immediate delivery to raise delivery errors. # config.action_mailer.raise_delivery_errors = false - # Set host to be used by links generated in mailer templates. - config.action_mailer.default_url_options = { host: "example.com" } - - # Specify outgoing SMTP server. Remember to add smtp/* credentials via bin/rails credentials:edit. - # config.action_mailer.smtp_settings = { - # user_name: Rails.application.credentials.dig(:smtp, :user_name), - # password: Rails.application.credentials.dig(:smtp, :password), - # address: "smtp.example.com", - # port: 587, - # authentication: :plain - # } + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false # Enable locale fallbacks for I18n (makes lookups for any locale fall back to # the I18n.default_locale when a translation cannot be found). @@ -75,8 +93,8 @@ # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false - # Only use :id for inspections in production. - config.active_record.attributes_for_inspect = [ :id ] + # Inspect all attributes in production. New default is :id. + config.active_record.attributes_for_inspect = [:all] # Enable DNS rebinding protection and other `Host` header attacks. # config.hosts = [ diff --git a/config/environments/test.rb b/config/environments/test.rb index c2095b1174..ed97c38a6e 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -6,8 +6,8 @@ Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. - # While tests run files are not watched, reloading is not necessary. - config.enable_reloading = false + config.enable_reloading = ENV["CI"].blank? + config.action_view.cache_template_loading = true # Eager loading loads your entire application. When running a single test locally, # this is usually not necessary, and can slow down your test suite. However, it's @@ -16,12 +16,17 @@ config.eager_load = ENV["CI"].present? # Configure public file server for tests with cache-control for performance. - config.public_file_server.headers = { "cache-control" => "public, max-age=3600" } + config.public_file_server.enabled = true + config.public_file_server.headers = { + "Cache-Control" => "public, max-age=#{1.hour.to_i}" + } # Show full error reports. config.consider_all_requests_local = true config.cache_store = :null_store + config.action_controller.perform_caching = false + # Render exception templates for rescuable exceptions and raise for other exceptions. config.action_dispatch.show_exceptions = :rescuable @@ -31,23 +36,42 @@ # Store uploaded files on the local file system in a temporary directory. config.active_storage.service = :test + config.action_mailer.perform_caching = false + # Tell Action Mailer not to deliver emails to the real world. # The :test delivery method accumulates sent emails in the # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test # Set host to be used by links generated in mailer templates. - config.action_mailer.default_url_options = { host: "example.com" } + config.action_mailer.default_url_options = {host: "localhost", port: 3000} # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr + # Rack Attack configuration + # Set IP_BLOCKLIST for testing. Can't stub in spec since environment variable + # gets read during application initialization. + ENV["IP_BLOCKLIST"] = "4.5.6.7, 9.8.7.6,100.101.102.103" + + # Raise exceptions for disallowed deprecations. + config.active_support.disallowed_deprecation = :raise + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + # Raises error for missing translations. - # config.i18n.raise_on_missing_translations = true + config.i18n.raise_on_missing_translations = true + + # Raise error when a before_action's only/except options reference missing actions. + + config.action_controller.raise_on_missing_callback_actions = true # Annotate rendered view with file names. - # config.action_view.annotate_rendered_view_with_filenames = true + config.action_view.annotate_rendered_view_with_filenames = true # Raise error when a before_action's only/except options reference missing actions. - config.action_controller.raise_on_missing_callback_actions = true + config.action_controller.raise_on_missing_callback_actions = false + + config.secret_key_base = ENV["SECRET_KEY_BASE"] || "dummy_test_secret_key" end From 7a75141fa5494f2c2ecf8f3a054caa67e13e0eb3 Mon Sep 17 00:00:00 2001 From: Stefanni Brasil Date: Thu, 18 Jun 2026 14:28:44 -0600 Subject: [PATCH 05/11] Rails 8: schema update (no functional change, reorder columns alphabetically) --- db/schema.rb | 406 +++++++++++++++++++++++++-------------------------- 1 file changed, 203 insertions(+), 203 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index b7639ab4a6..d7379a7e16 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,38 +10,38 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.0].define(version: 2026_04_14_132818) do +ActiveRecord::Schema[8.1].define(version: 2026_04_14_132818) do # These are extensions that must be enabled in order to support this database enable_extension "pg_catalog.plpgsql" create_table "action_text_rich_texts", force: :cascade do |t| - t.string "name", null: false t.text "body" - t.string "record_type", null: false - t.bigint "record_id", null: false t.datetime "created_at", null: false + t.string "name", null: false + t.bigint "record_id", null: false + t.string "record_type", null: false t.datetime "updated_at", null: false t.index ["record_type", "record_id", "name"], name: "index_action_text_rich_texts_uniqueness", unique: true end create_table "active_storage_attachments", force: :cascade do |t| - t.string "name", null: false - t.string "record_type", null: false - t.bigint "record_id", null: false t.bigint "blob_id", null: false t.datetime "created_at", precision: nil, null: false + t.string "name", null: false + t.bigint "record_id", null: false + t.string "record_type", null: false t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id" t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true end create_table "active_storage_blobs", force: :cascade do |t| - t.string "key", null: false - t.string "filename", null: false - t.string "content_type" - t.text "metadata" t.bigint "byte_size", null: false t.string "checksum" + t.string "content_type" t.datetime "created_at", precision: nil, null: false + t.string "filename", null: false + t.string "key", null: false + t.text "metadata" t.string "service_name", null: false t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true end @@ -54,65 +54,65 @@ create_table "additional_expenses", force: :cascade do |t| t.bigint "case_contact_id", null: false + t.datetime "created_at", null: false t.decimal "other_expense_amount" t.string "other_expenses_describe" - t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["case_contact_id"], name: "index_additional_expenses_on_case_contact_id" end create_table "addresses", force: :cascade do |t| t.string "content" - t.bigint "user_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.bigint "user_id", null: false t.index ["user_id"], name: "index_addresses_on_user_id" end create_table "all_casa_admins", force: :cascade do |t| + t.datetime "created_at", null: false t.string "email", default: "", null: false t.string "encrypted_password", default: "", null: false - t.string "reset_password_token" - t.datetime "reset_password_sent_at", precision: nil - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.string "invitation_token" - t.datetime "invitation_created_at", precision: nil - t.datetime "invitation_sent_at", precision: nil t.datetime "invitation_accepted_at", precision: nil + t.datetime "invitation_created_at", precision: nil t.integer "invitation_limit" + t.datetime "invitation_sent_at", precision: nil + t.string "invitation_token" t.integer "invited_by_id" t.string "invited_by_type" + t.datetime "reset_password_sent_at", precision: nil + t.string "reset_password_token" + t.datetime "updated_at", null: false t.index ["email"], name: "index_all_casa_admins_on_email", unique: true t.index ["invitation_token"], name: "index_all_casa_admins_on_invitation_token", unique: true t.index ["reset_password_token"], name: "index_all_casa_admins_on_reset_password_token", unique: true end create_table "api_credentials", force: :cascade do |t| - t.bigint "user_id", null: false - t.datetime "token_expires_at", default: -> { "(now() + 'PT7H'::interval)" } - t.datetime "refresh_token_expires_at", default: -> { "(now() + 'P30D'::interval)" } t.string "api_token_digest" - t.string "refresh_token_digest" t.datetime "created_at", null: false + t.string "refresh_token_digest" + t.datetime "refresh_token_expires_at", default: -> { "(now() + 'P30D'::interval)" } + t.datetime "token_expires_at", default: -> { "(now() + 'PT7H'::interval)" } t.datetime "updated_at", null: false + t.bigint "user_id", null: false t.index ["api_token_digest"], name: "index_api_credentials_on_api_token_digest", unique: true, where: "(api_token_digest IS NOT NULL)" t.index ["refresh_token_digest"], name: "index_api_credentials_on_refresh_token_digest", unique: true, where: "(refresh_token_digest IS NOT NULL)" end create_table "banners", force: :cascade do |t| - t.bigint "casa_org_id", null: false - t.bigint "user_id", null: false - t.string "name" t.boolean "active", default: false + t.bigint "casa_org_id", null: false t.datetime "created_at", null: false - t.datetime "updated_at", null: false t.datetime "expires_at" + t.string "name" + t.datetime "updated_at", null: false + t.bigint "user_id", null: false end create_table "casa_case_contact_types", force: :cascade do |t| - t.bigint "contact_type_id", null: false t.bigint "casa_case_id", null: false + t.bigint "contact_type_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["casa_case_id"], name: "index_casa_case_contact_types_on_casa_case_id" @@ -121,67 +121,67 @@ create_table "casa_case_emancipation_categories", force: :cascade do |t| t.bigint "casa_case_id", null: false - t.bigint "emancipation_category_id", null: false t.datetime "created_at", null: false + t.bigint "emancipation_category_id", null: false t.datetime "updated_at", null: false t.index ["casa_case_id"], name: "index_casa_case_emancipation_categories_on_casa_case_id" end create_table "casa_case_emancipation_options", force: :cascade do |t| t.bigint "casa_case_id", null: false - t.bigint "emancipation_option_id", null: false t.datetime "created_at", null: false + t.bigint "emancipation_option_id", null: false t.datetime "updated_at", null: false t.index ["casa_case_id", "emancipation_option_id"], name: "index_case_options_on_case_id_and_option_id", unique: true end create_table "casa_cases", force: :cascade do |t| - t.string "case_number", null: false - t.boolean "transition_aged_youth", default: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.bigint "casa_org_id", null: false + t.boolean "active", default: true, null: false t.datetime "birth_month_year_youth", precision: nil + t.bigint "casa_org_id", null: false + t.string "case_number", null: false t.datetime "court_report_due_date", precision: nil - t.boolean "active", default: true, null: false - t.datetime "court_report_submitted_at", precision: nil t.integer "court_report_status", default: 0 - t.string "slug" + t.datetime "court_report_submitted_at", precision: nil + t.datetime "created_at", null: false t.datetime "date_in_care" + t.string "slug" + t.boolean "transition_aged_youth", default: false + t.datetime "updated_at", null: false t.index ["casa_org_id"], name: "index_casa_cases_on_casa_org_id" t.index ["case_number", "casa_org_id"], name: "index_casa_cases_on_case_number_and_casa_org_id", unique: true t.index ["slug"], name: "index_casa_cases_on_slug" end create_table "casa_orgs", force: :cascade do |t| - t.string "name", null: false + t.boolean "additional_expenses_enabled", default: false + t.string "address" t.datetime "created_at", null: false - t.datetime "updated_at", null: false t.string "display_name" - t.string "address" t.string "footer_links", default: [], array: true - t.string "slug" + t.boolean "learning_topic_active", default: false + t.string "name", null: false + t.boolean "other_duties_enabled", default: true t.boolean "show_driving_reimbursement", default: true t.boolean "show_fund_request", default: false - t.string "twilio_phone_number" + t.string "slug" t.string "twilio_account_sid" - t.string "twilio_api_key_sid" t.string "twilio_api_key_secret" + t.string "twilio_api_key_sid" t.boolean "twilio_enabled", default: false - t.boolean "additional_expenses_enabled", default: false - t.boolean "learning_topic_active", default: false - t.boolean "other_duties_enabled", default: true + t.string "twilio_phone_number" + t.datetime "updated_at", null: false t.index ["slug"], name: "index_casa_orgs_on_slug", unique: true end create_table "case_assignments", force: :cascade do |t| - t.bigint "casa_case_id", null: false - t.bigint "volunteer_id", null: false t.boolean "active", default: true, null: false + t.boolean "allow_reimbursement", default: true + t.bigint "casa_case_id", null: false t.datetime "created_at", null: false - t.datetime "updated_at", null: false t.boolean "hide_old_contacts", default: false - t.boolean "allow_reimbursement", default: true + t.datetime "updated_at", null: false + t.bigint "volunteer_id", null: false t.index ["casa_case_id"], name: "index_case_assignments_on_casa_case_id" t.index ["volunteer_id"], name: "index_case_assignments_on_volunteer_id" end @@ -196,23 +196,23 @@ end create_table "case_contacts", force: :cascade do |t| - t.bigint "creator_id", null: false t.bigint "casa_case_id" - t.integer "duration_minutes" - t.datetime "occurred_at", precision: nil - t.datetime "created_at", null: false - t.datetime "updated_at", null: false t.boolean "contact_made", default: false + t.datetime "created_at", null: false + t.bigint "creator_id", null: false + t.datetime "deleted_at", precision: nil + t.integer "draft_case_ids", default: [], array: true + t.integer "duration_minutes" t.string "medium_type" + t.jsonb "metadata", default: {} t.integer "miles_driven", default: 0, null: false - t.boolean "want_driving_reimbursement", default: false t.string "notes" - t.datetime "deleted_at", precision: nil + t.datetime "occurred_at", precision: nil t.boolean "reimbursement_complete", default: false t.string "status", default: "started" - t.integer "draft_case_ids", default: [], array: true + t.datetime "updated_at", null: false t.string "volunteer_address" - t.jsonb "metadata", default: {} + t.boolean "want_driving_reimbursement", default: false t.index ["casa_case_id"], name: "index_case_contacts_on_casa_case_id" t.index ["creator_id"], name: "index_case_contacts_on_creator_id" t.check_constraint "miles_driven IS NOT NULL OR NOT want_driving_reimbursement", name: "want_driving_reimbursement_only_when_miles_driven" @@ -220,381 +220,381 @@ create_table "case_court_orders", force: :cascade do |t| t.bigint "casa_case_id", null: false + t.bigint "court_date_id" t.datetime "created_at", null: false - t.datetime "updated_at", null: false t.integer "implementation_status" - t.bigint "court_date_id" t.string "text" + t.datetime "updated_at", null: false t.index ["casa_case_id"], name: "index_case_court_orders_on_casa_case_id" t.index ["court_date_id"], name: "index_case_court_orders_on_court_date_id" end create_table "case_group_memberships", force: :cascade do |t| - t.bigint "case_group_id", null: false t.bigint "casa_case_id", null: false + t.bigint "case_group_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false end create_table "case_groups", force: :cascade do |t| t.bigint "casa_org_id", null: false - t.string "name" t.datetime "created_at", null: false + t.string "name" t.datetime "updated_at", null: false end create_table "checklist_items", force: :cascade do |t| - t.integer "hearing_type_id" - t.text "description", null: false t.string "category", null: false - t.boolean "mandatory", default: false, null: false t.datetime "created_at", null: false + t.text "description", null: false + t.integer "hearing_type_id" + t.boolean "mandatory", default: false, null: false t.datetime "updated_at", null: false end create_table "contact_topic_answers", force: :cascade do |t| - t.text "value" t.bigint "case_contact_id", null: false t.bigint "contact_topic_id" - t.boolean "selected", default: false, null: false t.datetime "created_at", null: false - t.datetime "updated_at", null: false t.datetime "deleted_at" + t.boolean "selected", default: false, null: false + t.datetime "updated_at", null: false + t.text "value" t.index ["case_contact_id"], name: "index_contact_topic_answers_on_case_contact_id" end create_table "contact_topics", force: :cascade do |t| - t.bigint "casa_org_id", null: false t.boolean "active", default: true, null: false - t.boolean "soft_delete", default: false, null: false + t.bigint "casa_org_id", null: false + t.datetime "created_at", null: false t.text "details" + t.boolean "exclude_from_court_report", default: false, null: false t.string "question" - t.datetime "created_at", null: false + t.boolean "soft_delete", default: false, null: false t.datetime "updated_at", null: false - t.boolean "exclude_from_court_report", default: false, null: false end create_table "contact_type_groups", force: :cascade do |t| + t.boolean "active", default: true t.bigint "casa_org_id", null: false - t.string "name", null: false t.datetime "created_at", null: false + t.string "name", null: false t.datetime "updated_at", null: false - t.boolean "active", default: true end create_table "contact_types", force: :cascade do |t| + t.boolean "active", default: true t.bigint "contact_type_group_id", null: false - t.string "name", null: false t.datetime "created_at", null: false + t.string "name", null: false t.datetime "updated_at", null: false - t.boolean "active", default: true t.index ["contact_type_group_id"], name: "index_contact_types_on_contact_type_group_id" end create_table "court_dates", force: :cascade do |t| - t.datetime "date", precision: nil, null: false t.bigint "casa_case_id", null: false + t.datetime "court_report_due_date", precision: nil t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "date", precision: nil, null: false t.bigint "hearing_type_id" t.bigint "judge_id" - t.datetime "court_report_due_date", precision: nil + t.datetime "updated_at", null: false t.index ["casa_case_id"], name: "index_court_dates_on_casa_case_id" end create_table "custom_org_links", force: :cascade do |t| - t.bigint "casa_org_id", null: false - t.string "text", null: false - t.string "url", null: false t.boolean "active", default: true, null: false + t.bigint "casa_org_id", null: false t.datetime "created_at", null: false + t.string "text", null: false t.datetime "updated_at", null: false + t.string "url", null: false t.index ["casa_org_id"], name: "index_custom_org_links_on_casa_org_id" end create_table "delayed_jobs", force: :cascade do |t| - t.integer "priority", default: 0, null: false t.integer "attempts", default: 0, null: false + t.datetime "created_at" + t.datetime "failed_at", precision: nil t.text "handler", null: false t.text "last_error" - t.datetime "run_at", precision: nil t.datetime "locked_at", precision: nil - t.datetime "failed_at", precision: nil t.string "locked_by" + t.integer "priority", default: 0, null: false t.string "queue" - t.datetime "created_at" + t.datetime "run_at", precision: nil t.datetime "updated_at" end create_table "emancipation_categories", force: :cascade do |t| - t.string "name", null: false - t.boolean "mutually_exclusive", null: false t.datetime "created_at", null: false + t.boolean "mutually_exclusive", null: false + t.string "name", null: false t.datetime "updated_at", null: false t.index ["name"], name: "index_emancipation_categories_on_name", unique: true end create_table "emancipation_options", force: :cascade do |t| + t.datetime "created_at", null: false t.bigint "emancipation_category_id", null: false t.string "name", null: false - t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["emancipation_category_id", "name"], name: "index_emancipation_options_on_emancipation_category_id_and_name", unique: true end create_table "flipper_features", force: :cascade do |t| - t.string "key", null: false t.datetime "created_at", null: false + t.string "key", null: false t.datetime "updated_at", null: false t.index ["key"], name: "index_flipper_features_on_key", unique: true end create_table "flipper_gates", force: :cascade do |t| + t.datetime "created_at", null: false t.string "feature_key", null: false t.string "key", null: false - t.text "value" - t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.text "value" t.index ["feature_key", "key", "value"], name: "index_flipper_gates_on_feature_key_and_key_and_value", unique: true end create_table "followups", force: :cascade do |t| t.bigint "case_contact_id" - t.bigint "creator_id" - t.integer "status", default: 0 t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.text "note" + t.bigint "creator_id" t.bigint "followupable_id" t.string "followupable_type" + t.text "note" + t.integer "status", default: 0 + t.datetime "updated_at", null: false t.index ["case_contact_id"], name: "index_followups_on_case_contact_id" end create_table "fund_requests", force: :cascade do |t| - t.text "submitter_email" - t.text "youth_name" - t.text "payment_amount" t.text "deadline" - t.text "request_purpose" + t.text "extra_information" + t.text "impact" + t.text "other_funding_source_sought" t.text "payee_name" + t.text "payment_amount" + t.text "request_purpose" t.text "requested_by_and_relationship" - t.text "other_funding_source_sought" - t.text "impact" - t.text "extra_information" + t.text "submitter_email" t.text "timestamps" + t.text "youth_name" end create_table "healths", force: :cascade do |t| + t.datetime "created_at", null: false t.datetime "latest_deploy_time", precision: nil t.integer "singleton_guard" - t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["singleton_guard"], name: "index_healths_on_singleton_guard", unique: true end create_table "hearing_types", force: :cascade do |t| - t.bigint "casa_org_id", null: false - t.string "name", null: false t.boolean "active", default: true, null: false + t.bigint "casa_org_id", null: false t.string "checklist_updated_date", default: "None", null: false + t.string "name", null: false end create_table "judges", force: :cascade do |t| + t.boolean "active", default: true t.bigint "casa_org_id", null: false t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.boolean "active", default: true t.string "name" + t.datetime "updated_at", null: false end create_table "languages", force: :cascade do |t| - t.string "name" t.bigint "casa_org_id", null: false t.datetime "created_at", null: false + t.string "name" t.datetime "updated_at", null: false end create_table "learning_hour_topics", force: :cascade do |t| - t.string "name", null: false t.bigint "casa_org_id", null: false - t.integer "position", default: 1 t.datetime "created_at", null: false + t.string "name", null: false + t.integer "position", default: 1 t.datetime "updated_at", null: false end create_table "learning_hour_types", force: :cascade do |t| + t.boolean "active", default: true t.bigint "casa_org_id", null: false + t.datetime "created_at", null: false t.string "name" - t.boolean "active", default: true t.integer "position", default: 1 - t.datetime "created_at", null: false t.datetime "updated_at", null: false end create_table "learning_hours", force: :cascade do |t| - t.bigint "user_id", null: false - t.string "name", null: false - t.integer "duration_minutes", null: false + t.datetime "created_at", null: false t.integer "duration_hours", null: false + t.integer "duration_minutes", null: false + t.bigint "learning_hour_topic_id" + t.bigint "learning_hour_type_id" + t.string "name", null: false t.datetime "occurred_at", precision: nil, null: false - t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.bigint "learning_hour_type_id" - t.bigint "learning_hour_topic_id" + t.bigint "user_id", null: false t.index ["user_id"], name: "index_learning_hours_on_user_id" end create_table "login_activities", force: :cascade do |t| - t.string "scope" - t.string "strategy" - t.string "identity" - t.boolean "success" - t.string "failure_reason" - t.string "user_type" - t.bigint "user_id" - t.string "context" - t.string "ip" - t.text "user_agent" - t.text "referrer" t.string "city" - t.string "region" + t.string "context" t.string "country" + t.datetime "created_at" + t.string "failure_reason" + t.string "identity" + t.string "ip" t.float "latitude" t.float "longitude" - t.datetime "created_at" + t.text "referrer" + t.string "region" + t.string "scope" + t.string "strategy" + t.boolean "success" + t.text "user_agent" + t.bigint "user_id" + t.string "user_type" end create_table "mileage_rates", force: :cascade do |t| t.decimal "amount" + t.bigint "casa_org_id", null: false + t.datetime "created_at", null: false t.date "effective_date" t.boolean "is_active", default: true - t.bigint "user_id" - t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.bigint "casa_org_id", null: false + t.bigint "user_id" end create_table "notes", force: :cascade do |t| t.string "content" + t.datetime "created_at", null: false t.bigint "creator_id" - t.string "notable_type" t.bigint "notable_id" - t.datetime "created_at", null: false + t.string "notable_type" t.datetime "updated_at", null: false end create_table "noticed_events", force: :cascade do |t| - t.string "type" - t.string "record_type" - t.bigint "record_id" - t.jsonb "params" t.datetime "created_at", null: false - t.datetime "updated_at", null: false t.integer "notifications_count" + t.jsonb "params" + t.bigint "record_id" + t.string "record_type" + t.string "type" + t.datetime "updated_at", null: false end create_table "noticed_notifications", force: :cascade do |t| - t.string "type" + t.datetime "created_at", null: false t.bigint "event_id", null: false - t.string "recipient_type", null: false - t.bigint "recipient_id", null: false t.datetime "read_at", precision: nil + t.bigint "recipient_id", null: false + t.string "recipient_type", null: false t.datetime "seen_at", precision: nil - t.datetime "created_at", null: false + t.string "type" t.datetime "updated_at", null: false t.index ["recipient_type", "recipient_id"], name: "index_noticed_notifications_on_recipient" end create_table "notifications", force: :cascade do |t| - t.string "recipient_type", null: false - t.bigint "recipient_id", null: false - t.string "type", null: false + t.datetime "created_at", null: false t.jsonb "params" t.datetime "read_at", precision: nil - t.datetime "created_at", null: false + t.bigint "recipient_id", null: false + t.string "recipient_type", null: false + t.string "type", null: false t.datetime "updated_at", null: false end create_table "other_duties", force: :cascade do |t| + t.datetime "created_at", null: false t.bigint "creator_id", null: false t.string "creator_type" - t.datetime "occurred_at", precision: nil t.bigint "duration_minutes" t.text "notes" - t.datetime "created_at", null: false + t.datetime "occurred_at", precision: nil t.datetime "updated_at", null: false end create_table "patch_note_groups", force: :cascade do |t| - t.string "value", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.string "value", null: false t.index ["value"], name: "index_patch_note_groups_on_value", unique: true end create_table "patch_note_types", force: :cascade do |t| - t.string "name", null: false t.datetime "created_at", null: false + t.string "name", null: false t.datetime "updated_at", null: false t.index ["name"], name: "index_patch_note_types_on_name", unique: true end create_table "patch_notes", force: :cascade do |t| + t.datetime "created_at", null: false t.text "note", null: false - t.bigint "patch_note_type_id", null: false t.bigint "patch_note_group_id", null: false - t.datetime "created_at", null: false + t.bigint "patch_note_type_id", null: false t.datetime "updated_at", null: false end create_table "placement_types", force: :cascade do |t| - t.string "name", null: false t.bigint "casa_org_id", null: false t.datetime "created_at", null: false + t.string "name", null: false t.datetime "updated_at", null: false end create_table "placements", force: :cascade do |t| + t.bigint "casa_case_id", null: false + t.datetime "created_at", null: false + t.bigint "creator_id", null: false t.datetime "placement_started_at", null: false t.bigint "placement_type_id", null: false - t.bigint "creator_id", null: false - t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.bigint "casa_case_id", null: false end create_table "preference_sets", force: :cascade do |t| - t.bigint "user_id" t.jsonb "case_volunteer_columns", default: "{}", null: false t.datetime "created_at", null: false - t.datetime "updated_at", null: false t.jsonb "table_state", default: {} + t.datetime "updated_at", null: false + t.bigint "user_id" t.index ["user_id"], name: "index_preference_sets_on_user_id" end create_table "sent_emails", force: :cascade do |t| - t.bigint "user_id" t.bigint "casa_org_id", null: false - t.string "mailer_type" t.string "category" - t.string "sent_address" t.datetime "created_at", null: false + t.string "mailer_type" + t.string "sent_address" t.datetime "updated_at", null: false + t.bigint "user_id" end create_table "sms_notification_events", force: :cascade do |t| - t.string "name" - t.string "user_type" t.datetime "created_at", null: false + t.string "name" t.datetime "updated_at", null: false + t.string "user_type" end create_table "supervisor_volunteers", force: :cascade do |t| - t.bigint "supervisor_id", null: false - t.bigint "volunteer_id", null: false t.datetime "created_at", null: false - t.datetime "updated_at", null: false t.boolean "is_active", default: true + t.bigint "supervisor_id", null: false + t.datetime "updated_at", null: false + t.bigint "volunteer_id", null: false t.index ["supervisor_id"], name: "index_supervisor_volunteers_on_supervisor_id" t.index ["volunteer_id"], name: "index_supervisor_volunteers_on_volunteer_id" end @@ -604,64 +604,64 @@ end create_table "user_languages", force: :cascade do |t| - t.bigint "user_id" - t.bigint "language_id" t.datetime "created_at", null: false + t.bigint "language_id" t.datetime "updated_at", null: false + t.bigint "user_id" t.index ["language_id", "user_id"], name: "index_user_languages_on_language_id_and_user_id", unique: true end create_table "user_reminder_times", force: :cascade do |t| - t.bigint "user_id", null: false t.datetime "case_contact_types" - t.datetime "no_contact_made" t.datetime "created_at", null: false + t.datetime "no_contact_made" t.datetime "updated_at", null: false + t.bigint "user_id", null: false t.index ["user_id"], name: "index_user_reminder_times_on_user_id" end create_table "user_sms_notification_events", force: :cascade do |t| - t.bigint "user_id", null: false - t.bigint "sms_notification_event_id", null: false t.datetime "created_at", null: false + t.bigint "sms_notification_event_id", null: false t.datetime "updated_at", null: false + t.bigint "user_id", null: false end create_table "users", force: :cascade do |t| - t.string "email", default: "", null: false - t.string "encrypted_password", default: "", null: false - t.string "reset_password_token" - t.datetime "reset_password_sent_at", precision: nil - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.boolean "active", default: true t.bigint "casa_org_id", null: false + t.datetime "confirmation_sent_at" + t.string "confirmation_token" + t.datetime "confirmed_at" + t.datetime "created_at", null: false + t.datetime "current_sign_in_at", precision: nil + t.string "current_sign_in_ip" + t.datetime "date_of_birth" t.string "display_name", default: "", null: false - t.string "invitation_token" - t.datetime "invitation_created_at", precision: nil - t.datetime "invitation_sent_at", precision: nil + t.string "email", default: "", null: false + t.string "encrypted_password", default: "", null: false t.datetime "invitation_accepted_at", precision: nil + t.datetime "invitation_created_at", precision: nil t.integer "invitation_limit" - t.string "invited_by_type" - t.bigint "invited_by_id" + t.datetime "invitation_sent_at", precision: nil + t.string "invitation_token" t.integer "invitations_count", default: 0 - t.string "type" - t.boolean "active", default: true - t.integer "sign_in_count", default: 0, null: false - t.datetime "current_sign_in_at", precision: nil + t.bigint "invited_by_id" + t.string "invited_by_type" t.datetime "last_sign_in_at", precision: nil - t.string "current_sign_in_ip" t.string "last_sign_in_ip" + t.boolean "monthly_learning_hours_report", default: false, null: false + t.string "old_emails", default: [], array: true t.string "phone_number", default: "" - t.boolean "receive_sms_notifications", default: false, null: false t.boolean "receive_email_notifications", default: true - t.string "confirmation_token" - t.datetime "confirmed_at" - t.datetime "confirmation_sent_at" - t.string "unconfirmed_email" - t.string "old_emails", default: [], array: true t.boolean "receive_reimbursement_email", default: false - t.boolean "monthly_learning_hours_report", default: false, null: false - t.datetime "date_of_birth" + t.boolean "receive_sms_notifications", default: false, null: false + t.datetime "reset_password_sent_at", precision: nil + t.string "reset_password_token" + t.integer "sign_in_count", default: 0, null: false + t.string "type" + t.string "unconfirmed_email" + t.datetime "updated_at", null: false t.index ["casa_org_id"], name: "index_users_on_casa_org_id" t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true t.index ["email"], name: "index_users_on_email", unique: true From 688ca5b339316b1fe4cc901cf9f3b3d7286b668d Mon Sep 17 00:00:00 2001 From: Stefanni Brasil Date: Thu, 18 Jun 2026 14:39:37 -0600 Subject: [PATCH 06/11] bring these back --- config/environments/development.rb | 2 +- config/environments/production.rb | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/config/environments/development.rb b/config/environments/development.rb index d4fc67b336..cd8e628947 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -21,7 +21,7 @@ config.action_controller.perform_caching = true config.action_controller.enable_fragment_cache_logging = true config.cache_store = :memory_store - config.public_file_server.headers = { "cache-control" => "public, max-age=#{2.days.to_i}" } + config.public_file_server.headers = {"cache-control" => "public, max-age=#{2.days.to_i}"} else config.action_controller.perform_caching = false config.cache_store = :null_store diff --git a/config/environments/production.rb b/config/environments/production.rb index f5675af94f..c76e06bd5b 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -78,6 +78,11 @@ # Replace the default in-process and non-durable queuing backend for Active Job. # config.active_job.queue_adapter = :resque + # Use a real queuing backend for Active Job (and separate queues per environment). + config.active_job.queue_adapter = :delayed_job + + config.action_mailer.perform_caching = false + # Ignore bad email addresses and do not raise email delivery errors. # Set this to true and configure the email server for immediate delivery to raise delivery errors. # config.action_mailer.raise_delivery_errors = false From c54e22ff4a4154cf6300cdbd1f0b391b5ecd72f2 Mon Sep 17 00:00:00 2001 From: Stefanni Brasil Date: Thu, 18 Jun 2026 15:10:38 -0600 Subject: [PATCH 07/11] Keep random date simple After the upgrade, this test was raising this error: ``` Failure/Error: ActiveRecord::Tasks::DatabaseTasks.load_seed ArgumentError: cannot load complex into simple # ./db/seeds/db_populator.rb:143:in 'block in DbPopulator#create_cases' # ./db/seeds/db_populator.rb:137:in 'Integer#times' # ./db/seeds/db_populator.rb:137:in 'DbPopulator#create_cases' ``` Keeping the date to a simpler rand generation solves the problem. --- db/seeds/db_populator.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/db/seeds/db_populator.rb b/db/seeds/db_populator.rb index a5080cd4a7..f4fccbc067 100644 --- a/db/seeds/db_populator.rb +++ b/db/seeds/db_populator.rb @@ -139,7 +139,6 @@ def create_cases(casa_org, options) court_date = generate_court_date court_report_submitted = index.even? - new_casa_case = CasaCase.find_by(case_number: case_number) birth_month_year_youth = @case_fourteen_years_old ? ((Date.today - 18.year)..(Date.today - CasaCase::TRANSITION_AGE.year)).to_a.sample : ((Date.today - 18.year)..(Date.today - 1.year)).to_a.sample new_casa_case ||= CasaCase.find_or_create_by!( casa_org_id: casa_org.id, @@ -147,7 +146,7 @@ def create_cases(casa_org, options) court_report_submitted_at: court_report_submitted ? Date.today : nil, court_report_status: court_report_submitted ? :submitted : :not_submitted, birth_month_year_youth: birth_month_year_youth, - date_in_care: Date.today - (rand * 1500) + date_in_care: Date.today - rand(1500) ) new_court_date = CourtDate.find_or_create_by!( casa_case: new_casa_case, From decca8d5837fcaabcdf47213694b3f5b8c4556b5 Mon Sep 17 00:00:00 2001 From: Stefanni Brasil Date: Thu, 18 Jun 2026 15:23:28 -0600 Subject: [PATCH 08/11] linter --- config/environments/production.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/environments/production.rb b/config/environments/production.rb index c76e06bd5b..bf55bcbc53 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -42,7 +42,7 @@ config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? # Cache assets for far-future expiry since they are all digest stamped. - config.public_file_server.headers = { "cache-control" => "public, max-age=#{1.year.to_i}" } + config.public_file_server.headers = {"cache-control" => "public, max-age=#{1.year.to_i}"} # Enable serving of images, stylesheets, and JavaScripts from an asset server. # config.asset_host = "http://assets.example.com" From 6cd4c2fcb0474f9deca5b3c3ef497850f70fee5c Mon Sep 17 00:00:00 2001 From: Stefanni Brasil Date: Mon, 22 Jun 2026 17:19:19 -0600 Subject: [PATCH 09/11] we do not use rubocop --- config/environments/development.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/config/environments/development.rb b/config/environments/development.rb index cd8e628947..03ea247338 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -92,7 +92,4 @@ if ENV["CODESPACES"] === "true" config.action_controller.forgery_protection_origin_check = false end - - # Apply autocorrection by RuboCop to files generated by `bin/rails generate`. - # config.generators.apply_rubocop_autocorrect_after_generate! end From cb7f7c1fc30322716c6afb89332e827eb5a49459 Mon Sep 17 00:00:00 2001 From: Stefanni Brasil Date: Mon, 22 Jun 2026 17:22:01 -0600 Subject: [PATCH 10/11] bring comment back --- config/environments/test.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/environments/test.rb b/config/environments/test.rb index ed97c38a6e..33b0b360f9 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -6,7 +6,9 @@ Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. + # While tests run files are not watched, reloading is not necessary. config.enable_reloading = ENV["CI"].blank? + config.action_view.cache_template_loading = true # Eager loading loads your entire application. When running a single test locally, From 1cc0946a4040c352f416b793a162b999bafbbae6 Mon Sep 17 00:00:00 2001 From: Stefanni Brasil Date: Thu, 2 Jul 2026 16:12:54 -0600 Subject: [PATCH 11/11] Fully enable Rails 8.1 config defaults This version new defaults do not seem to impact this app. --- config/application.rb | 2 +- .../new_framework_defaults_8_1.rb | 74 ------------------- 2 files changed, 1 insertion(+), 75 deletions(-) delete mode 100644 config/initializers/new_framework_defaults_8_1.rb diff --git a/config/application.rb b/config/application.rb index 05007743a9..a469df8893 100644 --- a/config/application.rb +++ b/config/application.rb @@ -9,7 +9,7 @@ module Casa class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 8.0 + config.load_defaults 8.1 # Please, add to the `ignore` list any other `lib` subdirectories that do # not contain `.rb` files, or that should not be reloaded or eager loaded. diff --git a/config/initializers/new_framework_defaults_8_1.rb b/config/initializers/new_framework_defaults_8_1.rb deleted file mode 100644 index 5cc706343c..0000000000 --- a/config/initializers/new_framework_defaults_8_1.rb +++ /dev/null @@ -1,74 +0,0 @@ -# Be sure to restart your server when you modify this file. -# -# This file eases your Rails 8.1 framework defaults upgrade. -# -# Uncomment each configuration one by one to switch to the new default. -# Once your application is ready to run with all new defaults, you can remove -# this file and set the `config.load_defaults` to `8.1`. -# -# Read the Guide for Upgrading Ruby on Rails for more info on each option. -# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html - -### -# Skips escaping HTML entities and line separators. When set to `false`, the -# JSON renderer no longer escapes these to improve performance. -# -# Example: -# class PostsController < ApplicationController -# def index -# render json: { key: "\u2028\u2029<>&" } -# end -# end -# -# Renders `{"key":"\u2028\u2029\u003c\u003e\u0026"}` with the previous default, but `{"key":"

<>&"}` with the config -# set to `false`. -# -# Applications that want to keep the escaping behavior can set the config to `true`. -#++ -Rails.configuration.action_controller.escape_json_responses = false - -### -# Skips escaping LINE SEPARATOR (U+2028) and PARAGRAPH SEPARATOR (U+2029) in JSON. -# -# Historically these characters were not valid inside JavaScript literal strings but that changed in ECMAScript 2019. -# As such it's no longer a concern in modern browsers: https://caniuse.com/mdn-javascript_builtins_json_json_superset. -#++ -Rails.configuration.active_support.escape_js_separators_in_json = false - -### -# Raises an error when order dependent finder methods (e.g. `#first`, `#second`) are called without `order` values -# on the relation, and the model does not have any order columns (`implicit_order_column`, `query_constraints`, or -# `primary_key`) to fall back on. -# -# The current behavior of not raising an error has been deprecated, and this configuration option will be removed in -# Rails 8.2. -#++ -Rails.configuration.active_record.raise_on_missing_required_finder_order_columns = true - -### -# Controls how Rails handles path relative URL redirects. -# When set to `:raise`, Rails will raise an `ActionController::Redirecting::UnsafeRedirectError` -# for relative URLs without a leading slash, which can help prevent open redirect vulnerabilities. -# -# Example: -# redirect_to "example.com" # Raises UnsafeRedirectError -# redirect_to "@attacker.com" # Raises UnsafeRedirectError -# redirect_to "/safe/path" # Works correctly -# -# Applications that want to allow these redirects can set the config to `:log` (previous default) -# to only log warnings, or `:notify` to send ActiveSupport notifications. -#++ -Rails.configuration.action_controller.action_on_path_relative_redirect = :raise - -### -# Use a Ruby parser to track dependencies between Action View templates -#++ -Rails.configuration.action_view.render_tracker = :ruby - -### -# When enabled, hidden inputs generated by `form_tag`, `token_tag`, `method_tag`, and the hidden parameter fields -# included in `button_to` forms will omit the `autocomplete="off"` attribute. -# -# Applications that want to keep generating the `autocomplete` attribute for those tags can set it to `false`. -#++ -Rails.configuration.action_view.remove_hidden_field_autocomplete = true