L. Migration Feasibility & Phased Plan
Migration Principles
- No big-bang. Each phase is independently deployable and shippable.
- Product work continues in parallel. The migration is infrastructure work — feature development does not pause.
- Security before structure. Phase 0 (security fixes) blocks all other phases.
- Melissa migrates first. It is the cleanest codebase and the one receiving the most active development.
- Legacy portal is modernized, not frozen. reverb-react moves to
apps/legacy-portal/as a Next.js 16 rewrite — business logic is preserved, rendering and tooling layers are replaced. - No business logic changes during structural migration. If you change behavior during a structural move, you cannot attribute bugs correctly.
Phase 0 — Security Fixes (Week 1)
Blocks all other phases. Non-negotiable.
| Task | Owner | Notes |
|---|---|---|
Revoke GitHub PAT in soreto-zoe/package.json |
Any engineer | GitHub → Settings → Developer Settings → PATs |
| Audit PAT scope (what repos did it have access to?) | Security lead | Review GitHub PAT audit log |
Replace soreto-arena GitHub dep |
Backend engineer | Use upstream bull-arena or bull-board from npm |
Verify SESSION_SECRET, TOKEN_SECRET, COOKIE_SECRET are set in all envs |
DevOps | Check Heroku config vars |
| Check git history for other embedded secrets | Any engineer | git log -S "password" --all |
| Rotate any analytics tokens (Mixpanel, GA) if exposed | DevOps | Check what's in git history |
Exit criteria: No secrets in source code. All environment variables verified. PAT revoked and replacement strategy in place.
Phase 1 — Foundation (Weeks 2–6)
Goal: Stop the bleeding on immediate risks before restructuring.
Node Version Stabilization
[ ] Add .nvmrc to reverb-backend (current: 14 — document, don't upgrade yet)
[ ] Add .nvmrc to reverb-react (current: 10 — modernization target: 24)
[ ] Add .nvmrc to soreto-melissa (current: 22 — already correct)
[ ] Add .nvmrc to soreto-zoe (current: 16 — document, don't upgrade yet)
CI/CD
[ ] Add GitHub Actions to soreto-melissa
- steps: install, typecheck, lint, test, build
[ ] Add GitHub Actions to soreto-zoe
- steps: install, typecheck, build
[ ] Migrate reverb-backend from Travis CI to GitHub Actions
[ ] Migrate reverb-react from Travis CI to GitHub Actions (build only — until Next.js rewrite is ready)
Dependency Quick Wins
[ ] Replace node-sass with sass in reverb-backend
[ ] Remove universal-analytics from reverb-backend (GA UA is dead)
[ ] Remove Google+ sharing code from reverb-react
[ ] Upgrade soreto-zoe: knex@0.16.3 → 0.21.x (first increment)
[ ] Run full reverb-backend test suite, fix any failures
Documentation Start
[ ] Create docs/spec/DOMAIN_MODEL.md (entity definitions)
[ ] Create docs/dependencies/UPGRADE_BLOCKERS.md (from audit)
[ ] Create docs/migration/REVERB_REACT_PARITY.md (feature checklist)
Exit criteria: All repos on GitHub Actions CI. soreto-melissa and soreto-zoe have working test/build pipelines. knex upgrade started on zoe. No deprecated integrations sending to dead APIs.
Phase 2 — Monorepo Bootstrap (Weeks 6–12)
Goal: Create the target structure. Migrate the cleanest app first.
Scaffold Creation
[ ] Create soreto-platform/ repository
[ ] Configure npm workspaces (workspaces field in root package.json)
[ ] Add Turborepo (turbo.json with build/test/lint pipeline)
[ ] Create apps/, packages/, tooling/, docs/ directories
[ ] Create root .nvmrc (24), .gitignore, root package.json
[ ] Create root CLAUDE.md (system overview)
First Package: @soreto/types
[ ] Extract types from soreto-melissa/types/
[ ] Extract ROLES, COUNTRIES, CAMPAIGN_TYPES from soreto-melissa/shared/constants.ts
[ ] Add type definitions for API response envelopes (ApiResponse<T>, PaginatedResponse<T>)
[ ] Add types for core entities: User, Campaign, CampaignVersion, Order, Reward, SharedUrl
[ ] Validate types against reverb-backend API responses
[ ] Publish as @soreto/types@1.0.0
First Tooling: @soreto/eslint-config and @soreto/tsconfig
[ ] Create shared ESLint config (extends recommended + TypeScript rules)
[ ] Create shared tsconfig base (strict, ES2022, NodeNext modules)
[ ] Create Next.js-specific tsconfig extension
Migrate soreto-melissa → apps/platform-ui/
[ ] Use git subtree or git mv to preserve history
[ ] Update package.json to use npm workspace protocol for @soreto/* deps
[ ] Update tsconfig to extend @soreto/tsconfig/nextjs.json
[ ] Update ESLint config to extend @soreto/eslint-config
[ ] Replace soreto-melissa/types/ usage with @soreto/types imports
[ ] Confirm CI passes in new location
[ ] Update deployment to point to apps/platform-ui/
Modernize reverb-react → apps/legacy-portal/ (Next.js 16 rewrite)
[ ] Move reverb-react into apps/legacy-portal/ (structural move, keep existing code intact)
[ ] Stand up Next.js 16 scaffold alongside existing src/ (parallel structure during rewrite)
[ ] Add CLAUDE.md: "Modernizing to Next.js 16 + React 19. Do not add features to src/ — add to app/ instead."
[ ] Port admin + client routes to Next.js App Router route groups
[ ] Migrate Redux 3 + Flux → Zustand (preserve business logic, replace state management)
[ ] Replace @@PLACEHOLDER@@ tokens → process.env.NEXT_PUBLIC_* variables
[ ] Rewrite components to PrimeReact 10.9.8 (API incompatible — rewrite, not migrate)
[ ] Deploy WAF in front of original Heroku reverb-react app during transition window
[ ] Target CI: GitHub Actions with typecheck + lint + build on Next.js scaffold
Exit criteria: soreto-platform monorepo exists. soreto-melissa successfully migrated and deploying from new location. @soreto/types available as a package.
Phase 3 — Backend Modernization (Weeks 12–20)
Goal: Migrate reverb-backend and begin TypeScript adoption.
Node Upgrade: reverb-backend 14 → 24
[ ] Replace node-sass with sass (prerequisite)
[ ] Upgrade connect-redis@3 → connect-redis@6 (API breaking change)
[ ] Upgrade Express 4.x → 5.x (now default on npm; run CI to catch API changes)
[ ] Test full suite on Node 16
[ ] Upgrade to Node 18 LTS — run CI — fix failures
[ ] Upgrade passport@0.3.2 → 0.7.x
[ ] Test seneca on Node 18 (may work without changes)
[ ] Upgrade to Node 20, then 22, then 24 — run CI at each step
Migrate reverb-backend → apps/platform-api/
[ ] Move into monorepo with git subtree (preserve history)
[ ] Update CI to run within Turborepo pipeline
[ ] Update package.json to reference @soreto/types for shared types
[ ] Update package.json: replace local_modules/soreto-cookie-jam with @soreto/auth-utils
TypeScript Introduction (Phased)
[ ] Add tsconfig.json (extends @soreto/tsconfig/node.json)
[ ] Enable "allowJs": true — no existing code breaks
[ ] Add JSDoc type annotations to new service files only
[ ] Convert AbstractService.js → AbstractService.ts
[ ] Convert new routes to TypeScript as they are written
[ ] Do NOT rewrite existing services — convert when touched
OpenAPI Specification
[ ] Add express-openapi-validator or swagger-ui-express
[ ] Document existing API routes iteratively
[ ] Publish @soreto/api-client based on OpenAPI spec
Exit criteria: reverb-backend in monorepo, Node 22, TypeScript introduced for new files, @soreto/api-client published with typed client methods.
Phase 4 — Zoe Modernization (Weeks 16–24)
Goal: Migrate soreto-zoe and eliminate the legacy TypeScript patterns.
Prerequisite: Complete Knex Upgrade
[ ] 0.16.3 → 0.21.x (from Phase 1)
[ ] 0.21.x → 0.95.7 (match reverb-backend)
[ ] 0.95.7 → 2.x
[ ] 2.x → 3.x (current)
[ ] Run full integration validation at each step
Node Upgrade: soreto-zoe 16 → 24
[ ] Upgrade puppeteer@9 → 25.x (16 major versions — significant API changes; test each processor individually)
[ ] Upgrade bull@3 → bullmq@5 (BullMQ 5.76.x is current; or keep bull@3 if no failures)
[ ] Upgrade Node 16 → 18 → 20 → 22 → 24 incrementally
TypeScript Refactor: AMD → ES Modules
[ ] Remove "module": "amd" and "outFile" from tsconfig.json
[ ] Convert namespace Zoe.* {} → import/export ES module syntax
[ ] Update module: to "NodeNext" or "CommonJS"
[ ] Remove two-tsconfig setup (tsconfig + tsconfig.service.json)
[ ] Update build script: tsc → single output
Type the Processors
[ ] Add ProcessorInput and ProcessorOutput interfaces to @soreto/types
[ ] Add JSDoc to processor files (do not rewrite — annotate)
[ ] Replace require('reverb') with require('@soreto/api-client')
Migrate soreto-zoe → apps/zoe/
[ ] Move into monorepo with git subtree
[ ] Update CI to run within Turborepo pipeline
[ ] Replace local_modules/reverb with @soreto/api-client
[ ] Replace config.js with @soreto/config
Exit criteria: soreto-zoe in monorepo, Node 24, ES module TypeScript, using @soreto/api-client instead of local_modules/reverb.
Phase 5 — Legacy Portal Cut-over (Weeks 20–36)
Goal: Complete the Next.js 16 rewrite of reverb-react and cut over production traffic.
[ ] Complete all route groups in apps/legacy-portal/ Next.js scaffold
[ ] Full QA pass: admin dashboard, client dashboard, campaign management, user management
[ ] Confirm feature completeness against reverb-react src/ (see docs/migration/REVERB_REACT_PARITY.md)
[ ] Deploy modernized apps/legacy-portal/ to Heroku (or new host)
[ ] Gradual traffic cut-over: 10% → 50% → 100%
[ ] Monitor error rates for 2 weeks post-cut-over
[ ] Decommission original reverb-react Heroku app (old Node 10 app)
[ ] Remove NEXT_PUBLIC_LEGACY_PORTAL_URL from melissa's env (if legacy portal URL changes)
[ ] Remove old src/ folder from apps/legacy-portal/ (rewrite complete)
Exit criteria: Modernized Next.js 16 legacy-portal is live on Node 24. Old Heroku reverb-react (Node 10) is decommissioned. All active code in apps/legacy-portal/ is TypeScript on Next.js 16.
Phase Dependencies
Phase 0 ──► All other phases (security blocks everything)
Phase 1 ──► Phase 2 (CI needed before monorepo migration)
Phase 1 ──► Phase 3 (node-sass removal needed before Node upgrade)
Phase 2 ──► Phase 3 (monorepo scaffold needed before adding platform-api)
Phase 2 ──► Phase 4 (@soreto/api-client needed before zoe migration)
Phase 3 ──► Phase 4 (API client published before zoe replaces local_modules/reverb)
Phase 4 ──────────── can overlap with Phase 3 (after scaffold is ready)
Phase 5 ──────────── can start once melissa is stable (Phase 2 exit)
Risk Register for Migration
| Risk | Phase | Mitigation |
|---|---|---|
| seneca breaks on Node 18 | 3 | Test on Node 18 before upgrading; have replacement plan ready |
| knex upgrade breaks zoe migrations | 1/4 | Staging database upgrade first; run migration validation |
| puppeteer API changes break affiliate processors | 4 | Test each processor individually; keep old version as fallback |
| reverb-react modernization scope expands | 5 | Time-box at 10 weeks; prioritize admin + client routes; defer edge features to Phase 5+ |
| Monorepo CI becomes slow | 2+ | Turborepo caching from day 1; always use --filter=[HEAD^1] in CI |