Skip to content

Rails upgrade#302

Open
kylefritz wants to merge 42 commits intoholiday_menus2from
codex/motzi-rails-upgrade
Open

Rails upgrade#302
kylefritz wants to merge 42 commits intoholiday_menus2from
codex/motzi-rails-upgrade

Conversation

@kylefritz
Copy link
Owner

@kylefritz kylefritz commented Feb 27, 2026

Progress Update (March 1, 2026 — audit hardening pass)

Completed a best-practices cleanup/audit pass after the Rails 7.2 + Solid Queue migration work.

What was tightened

  • Release task correctness
    • fixed Sentry deploy URL/release handling in lib/tasks/release.rake.
  • Gem hygiene
    • removed stale minitest < 6 pin.
    • upgraded rack-mini-profiler to Rack-3-compatible ~> 4.0.
  • Rails defaults + queue bootstrap reliability
    • moved config.load_defaults to 7.2.
    • hardened solid_queue:bootstrap to validate all queue schema tables, not just sentinel tables.
  • Queue UX/observability
    • moved demo job to dedicated demo queue.
    • reduced Mission Control log noise in dev by only wiring MissionControl::Jobs.logger in production.
  • Frontend dependency/code cleanup
    • pruned unused ActionCable JS wiring (app/javascript/channels/*).
    • refreshed Rails JS deps (kept actively-used packages current).
    • removed dead react-stripe-elements TS shim.
  • Dead/legacy config cleanup
    • removed obsolete PG coder initializer used only for pre-7.1.
    • removed stale pre-cutover queue comments/requires in development.rb.
    • centralized Solid Queue retention policy in app config and removed duplicate queue cleanup path from cleanup:trim_analytics.
    • removed redundant RAILS_LOG_TO_STDOUT from app.json (logging now explicitly configured in env files).

Commit map (audit pass)

  • 23b7339 Fix release task Sentry deploy release identifier
  • 5e31e47 Remove legacy minitest version pin
  • 2b51e4e Load Rails 7.2 framework defaults
  • f45bfed Validate full Solid Queue schema during bootstrap
  • dd4e658 Upgrade rack-mini-profiler to Rack 3 compatible release
  • 452d3e8 Move queue demo job onto dedicated demo queue
  • 6a2be35 Limit Mission Control logger wiring to production
  • b263644 Prune unused ActionCable JS and refresh Rails frontend deps
  • 6df9102 Remove obsolete PG coder compatibility initializer
  • e918717 Drop dead react-stripe-elements TypeScript shim
  • 1ca077a Remove stale pre-cutover queue config comments
  • dde144f Centralize Solid Queue retention and trim redundant env config

Validation snapshots

  • Rails tests passing: 215 runs, 0 failures
  • Bun tests passing: 46 pass, 0 fail
  • Typecheck passing: bun run typecheck

Safety tag

  • Added and pushed tag: before_audit -> 88b8864c0a1665109f35e9102e625266bac65e90

Progress Update (March 1, 2026)

Completed in this PR branch since the initial plan post:

  • Phase 3 (Solid Queue cutover)
    • switched worker process to Solid Queue (bin/jobs), removed Sidekiq runtime wiring, added Mission Control Jobs admin link and demo job trigger.
    • added Solid Queue cleanup in cleanup:trim_analytics.
  • Phase 4 (Redis removal)
    • switched production ActionCable adapter to async.
    • removed Redis runtime initializer and Redis dependency from app/runtime docs.
  • Phase 5A (React ecosystem modernization)
    • migrated Stripe checkout from react-stripe-elements to @stripe/react-stripe-js / @stripe/stripe-js.
    • removed Material UI usage in builder components and removed @material-ui/* dependencies.
  • Phase 5B (React 18 core)
    • upgraded to React 18 / ReactDOM 18 and migrated entrypoints from ReactDOM.render to createRoot.
  • Phase 6 (hardening + docs)
    • updated README/runbook notes for Solid Queue and async ActionCable.
    • stabilized app TypeScript checks with tsconfig.app.json and app typing fixes (bun run typecheck now passes).

Recent commit map:

  • 371cc9d Stabilize app TypeScript checks after React 18 migration
  • c090201 Update README for Solid Queue and async Action Cable
  • cb39cde Remove unused react-is dependency
  • fb5bc86 Upgrade React to 18 and migrate entrypoints to createRoot
  • 9819633 Replace Material UI builder components with local styled UI
  • c5ea276 Migrate checkout Stripe integration to stripe-js Elements
  • 2a1fce5 Remove Redis runtime dependency and use async Action Cable
  • e7a4153 Bootstrap Solid Queue tables during setup and release

Validation snapshots on this branch:

  • Rails tests passing (213 runs, 0 failures)
  • Bun tests passing (46 pass, 0 fail)
  • App typecheck passing (bun run typecheck)

Motzi Upgrade Plan: Rails + React + Queue Stack

1) Goals

  • Upgrade Rails to the newest version that is realistic without a major rewrite.
  • Upgrade React to the newest version that is realistic without a major rewrite.
  • Remove Sidekiq + Redis from the core app stack.
  • Keep admin workflows stable (ActiveAdmin is the highest-risk area).
  • Ship incrementally with production-safe checkpoints.

2) Recommended Targets

Primary target (recommended)

  • Rails: 7.2.x
  • ActiveAdmin: 3.4.x (or latest compatible 3.x)
  • React: 18.x
  • Queue backend: solid_queue (database-backed ActiveJob)
  • ActionCable backend: async (if real-time is unused) or solid_cable (if durability/multi-instance needed)

3) Current State Snapshot

  • Rails pinned to 6.1: gem 'rails', '~> 6.1.7.3' in Gemfile.
  • ActiveAdmin pinned to 2.13.1 and lockfile constrains railties < 7.1.
  • React is 16.x with ReactDOM.render entrypoints.
  • JS deps include blockers for React 18:
    • react-stripe-elements (legacy)
    • @material-ui/core v4 (supports React 16/17)
    • testing libs pinned for pre-18 behavior
  • Sidekiq + Redis wired in:
    • queue adapter config (ShopConfig.shop.queue_adapter)
    • sidekiq initializer
    • /sidekiq route mount
    • worker process in Procfile and Procfile.dev
    • sidekiq/deploy hook in release task
    • Redis cable adapter in production config/cable.yml

4) Scope and Non-Goals

In scope

  • Dependency and framework upgrades.
  • Queue backend migration and Redis removal.
  • Admin and ordering flow compatibility fixes.
  • Test and deploy pipeline updates required by upgrades.

Out of scope (for this cycle)

  • UI redesign / broad component rearchitecture.
  • Business logic refactors unrelated to compatibility.
  • Rails 8 / React 19 migration.

5) Delivery Strategy

  • Use commits and ship in phases.
  • Each phase must be deployable and rollback-safe.
  • Treat admin paths and checkout/email flows as release gates.
  • Do not combine Rails major hop + React major hop + queue migration in one PR.

6) Work Plan (Detailed)

Phase 0: Baseline, Safety Nets, and Branching

Objectives

  • Establish a stable baseline and avoid regressions.

Tasks

  • Create upgrade branch: upgrade-rails-react-queue.
  • Capture baseline versions:
    • bundle list | rg 'rails|activeadmin|sidekiq|redis'
    • cat package.json | rg 'react|material|stripe|testing-library'
  • Run and record baseline checks:
    • bundle exec rails test
    • bun test
    • bun run typecheck
  • Add/confirm CI jobs for Ruby + JS checks.
  • Document critical manual flows for QA (see section 9).

Exit criteria

  • Baseline test pass/fail documented.
  • Known failing tests listed with owner (if any).
  • Manual QA script agreed.

Phase 1: ActiveAdmin Upgrade (Unlock Rails 7.1+)

Why first

  • Current ActiveAdmin lock blocks Rails > 7.0 (railties < 7.1).
  • Upgrading ActiveAdmin first isolates admin-specific breakage before Rails hops.

Tasks

  • Update gems:
    • activeadmin to latest 3.x compatible with target Rails.
    • align ransack, inherited_resources, kaminari if needed. we are not concerned about ransack search safety since it's admin only; ok to patch.
  • Resolve DSL and rendering differences in:
    • app/admin/menus.rb
    • app/admin/users.rb
    • app/admin/bakery.rb
    • config/initializers/active_admin.rb
  • Verify custom components:
    • GonFooter view factory registration.
  • Re-run admin integration/unit tests and add targeted regression tests where behavior changed.

Risk hotspots

  • member_action custom flows and redirects.
  • custom controller do ... overrides (especially destroy batch logic).
  • partial rendering from ActiveAdmin contexts.

Exit criteria

  • Admin pages load without runtime errors.
  • Critical admin actions pass manual QA:
    • open menu
    • test email
    • copy-from menu
    • user batch delete safeguards
    • pickup list page

Phase 2: Rails Upgrade Path (6.1 -> 7.0 -> 7.1 -> 7.2)

Strategy

  • Upgrade one minor train at a time; run full test suite at each hop.
  • Keep config.load_defaults changes separate from gem version bump when possible.

Phase 2A: Rails 6.1 -> 7.0

Tasks:

  • bump Rails gems to ~> 7.0.x.
  • run bin/rails app:update and apply only required config changes.
  • resolve deprecations and keyword argument changes.
  • review:
    • Devise compatibility
    • Sprockets/jsbundling integration
    • Zeitwerk/autoload edge cases

Exit criteria:

  • app boots, tests run, admin + order checkout flow verified.

Phase 2B: Rails 7.0 -> 7.1

Tasks:

  • bump Rails to ~> 7.1.x.
  • regenerate/update framework defaults file for 7.1 and adopt toggles explicitly.
  • verify ActiveStorage queue names and job config.
  • verify puma, sentry, newrelic, paper_trail, ahoy_* compatibility.

Exit criteria:

  • no production-blocking deprecations for 7.1.

Phase 2C: Rails 7.1 -> 7.2

Tasks:

  • bump Rails to ~> 7.2.x.
  • apply 7.2 defaults cautiously (separate commit).
  • verify assets pipeline + esbuild output and digesting.
  • rerun full test + manual QA.

Exit criteria:

  • production candidate stable on Rails 7.2.

Phase 3: Replace Sidekiq/Redis with DB-backed Queue

Recommended implementation

  • Use solid_queue for ActiveJob.
  • Keep a worker process, but no Redis dependency.

Tasks

  • Add solid_queue gem and run installer/migrations.
  • Add mission_control-jobs gem for web UI (replaces Sidekiq Web):
    • mount MissionControl::Jobs::Engine at /jobs in routes.
    • protect behind admin auth (same guard as the old /sidekiq mount).
    • provides queue inspection, job retry/discard, pause/unpause, recurring task management.
  • Switch queue adapter:
    • remove dynamic adapter switch in config/shop.yml and set explicit adapter by env.
    • set config.active_job.queue_adapter = :solid_queue in production.
  • Keep existing queue names (default, mailers, active_storage) or map them explicitly in Solid Queue config.
  • Update process model:
    • replace Sidekiq worker command in Procfile / Procfile.dev with Solid Queue worker command.
  • Remove Sidekiq-specific code:
    • config/initializers/sidekiq.rb
    • require 'sidekiq/web' and route mount /sidekiq (replaced by /jobs Mission Control mount)
    • require "sidekiq/deploy" and Sidekiq::Deploy.mark! call in release task
    • gem 'sidekiq' and gem 'redis' (after cable migration decision)

Cutover plan

  • Pause scheduler jobs briefly during deploy window.
  • Drain Sidekiq queues to zero before cutover (no in-flight loss).
  • Deploy Solid Queue worker process.
  • Resume scheduler jobs and watch queue drain metrics.

Exit criteria

  • deliver_later and perform_later jobs execute reliably.
  • no Redis requirement for background jobs.

Phase 4: Remove Redis Dependency from ActionCable

Decision point

  • If real-time features are not actively used, set production cable adapter to async and remove Redis.
  • If real-time or multi-instance cable is needed, migrate to solid_cable.

Tasks

  • Audit actual channel usage (currently only boilerplate channel files appear present).
  • Option A (likely): set config/cable.yml production adapter to async.
  • Option B: install/configure solid_cable.
  • Remove config/initializers/redis.rb if unused globally.
  • Remove Heroku Redis addon from infra config once queue + cable no longer depend on it.

Exit criteria

  • No runtime attempts to connect to Redis in production.
  • Cable behavior accepted for chosen adapter strategy.

Phase 5: React Upgrade Path (16 -> 18)

Why phased

  • React 18 is blocked by current Stripe and Material UI dependencies.
  • Upgrade ecosystem first, then React core.

Phase 5A: Dependency modernization (while app still stable)

Tasks:

  • Stripe:
    • replace react-stripe-elements with @stripe/react-stripe-js + @stripe/stripe-js.
    • refactor payment components from injectStripe/StripeProvider to hooks + Elements API.
    • update tests to mock new Stripe API.
  • Material UI:
    • migrate @material-ui/core / @material-ui/icons to MUI v5+ (@mui/material, @mui/icons-material).
    • update styling API usages (makeStyles/legacy imports where needed).
  • Testing stack:
    • upgrade @testing-library/react and peers to React 18 compatible versions.
    • align react-test-renderer with target React.

Exit criteria:

  • JS tests and typecheck pass before React core bump.

Phase 5B: React 18 core migration

Tasks:

  • bump react and react-dom to 18.x.
  • replace ReactDOM.render entrypoints with createRoot.
  • validate event behavior, state batching, and test async timing changes.
  • optionally enable StrictMode after functional parity is confirmed.

Exit criteria:

  • all entrypoints render via createRoot.
  • checkout/menu/builder/credits flows verified manually and via tests.

Phase 6: Hardening, Deploy, and Cleanup

Tasks

  • Remove dead code and old shims.
  • Update docs:
    • README.md (remove Redis requirement)
    • deployment notes / runbooks
    • scheduler and worker commands
  • Performance and reliability checks:
    • job latency
    • mail throughput
    • admin response times
  • Final dependency audit and lockfile cleanup.

Exit criteria

  • Production stable for at least 1 release cycle.
  • No Sidekiq/Redis references remain in app/runtime config.

7) PR Breakdown (Suggested)

  1. PR-01: Baseline tests + upgrade harness docs.
  2. PR-02: ActiveAdmin 3.x upgrade and admin fixes.
  3. PR-03: Rails 7.0.
  4. PR-04: Rails 7.1 + defaults.
  5. PR-05: Rails 7.2 + defaults.
  6. PR-06: Solid Queue introduction (keep Sidekiq still present, dark launch if needed).
  7. PR-07: Switch queue adapter, remove Sidekiq runtime.
  8. PR-08: ActionCable Redis removal (async or solid_cable).
  9. PR-09: Stripe migration to modern React Stripe SDK.
  10. PR-10: MUI migration + test tooling updates.
  11. PR-11: React 18 bump + createRoot entrypoint migration.
  12. PR-12: Docs/infrastructure cleanup and final remove-redis pass.

8) Risk Register

High risk

  • ActiveAdmin upgrade regressions in custom admin actions and partials.
  • Payment flow migration from react-stripe-elements.
  • Queue cutover timing (in-flight jobs).

Mitigations:

  • keep admin + checkout smoke tests mandatory for every phase.
  • schedule queue cutover during low traffic window.
  • drain and verify before removing old worker.

Medium risk

  • Rails defaults toggles changing subtle behavior.
  • test timing changes on React 18.

Mitigations:

  • apply defaults in isolated commits.
  • update flaky tests intentionally, not ad hoc.

9) Manual QA Checklist (Release Gates)

  • Admin:
    • login/logout
    • dashboard load
    • menu CRUD + copy-from
    • open menu for orders
    • send test menu email
    • user batch delete behavior
    • pickup list view
  • Customer:
    • view menu
    • add/remove cart items
    • place order (credit card + credit flow)
    • update order
    • receive confirmation email
  • Jobs:
    • SendWeeklyMenuJob enqueues and processes
    • reminder tasks execute and send mail
    • ActiveStorage analysis/purge jobs execute

10) Definition of Done

  • Rails on 7.2.x.
  • ActiveAdmin on 3.x, all admin critical flows passing.
  • React on 18.x with no ReactDOM.render usage.
  • Sidekiq and Redis removed from app runtime dependencies.
  • Background jobs running on Solid Queue in production.
  • README/runbooks updated and deployment stable.

@kylefritz kylefritz changed the base branch from master to holiday_menus2 February 27, 2026 20:01
@kylefritz kylefritz changed the title Update holiday menu and admin workflows for Rails 6.1 upgrade Rails upgrade Mar 1, 2026
Repository owner deleted a comment from chatgpt-codex-connector bot Mar 1, 2026
@kylefritz kylefritz temporarily deployed to motzi-pr-302 March 2, 2026 15:55 Inactive
Older migrations load the Menu model before the menu_type column exists.
Rails 7.2 requires an explicit attribute declaration for enums not yet
backed by a database column.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant