Skip to content

G. Frontend Architecture Assessment

← Back to README


Two Frontends, One Being Modernized

The Soreto ecosystem has two separate frontend applications, both in active development:

App Status Tech (current) Tech (target) Purpose
reverb-react 🔄 Modernizing → Next.js 16 React 17/16, Babel 6, Webpack 4, Node 10 Next.js 16, React 19, TypeScript 6, Node 24 Admin + client portal (being modernized)
soreto-melissa ✅ Active development Next.js 13, React 18, TypeScript Next.js 16, React 19 Admin + client portal (new platform UI)

Both applications are live simultaneously and cross-reference each other. reverb-react is undergoing a controlled rewrite to Next.js 16 inside apps/legacy-portal/ — parallel to ongoing melissa development.


reverb-react Assessment

Cannot Be Upgraded In-Place — Rewrite Required

Attempting an in-place upgrade of reverb-react would require all of the following simultaneously, with compounding risk: 1. Babel 6 → Babel 7 (all presets and plugins must be updated) 2. Webpack 4 → Webpack 5 or Vite (config rewrite) 3. React 16/17 → React 19 (hooks audit, Concurrent Mode compatibility, React 19 new APIs) 4. react-router@3 + react-router-dom@4react-router@7 (two separate mismatches; complete API rewrite across 4 major versions) 5. Redux 3 → Redux Toolkit (Redux 5 requires a different pattern) 6. Remove Flux (Flux was abandoned by Meta in 2019) 7. @@PLACEHOLDER@@ config → proper env vars 8. Node 10 → 24

The correct approach is a controlled rewrite to Next.js 16 — starting on a clean scaffold inside apps/legacy-portal/, porting business logic while discarding the outdated tooling layer entirely. This avoids all compounding upgrade risks.

Recommendation: Modernize reverb-react to Next.js 16 + React 19 via a controlled rewrite inside apps/legacy-portal/. Do not attempt an in-place upgrade — the gaps are too large to bridge incrementally. See F — Version Standardization and K — Target Architecture for the full modernization target and effort estimate.

Next.js 16 Rewrite — Route & Feature Scope

The following areas need porting from the current reverb-react codebase into the Next.js 16 App Router scaffold. This is the input for the Phase 5 rewrite scope:

[ ] Admin dashboard (global)
[ ] Client dashboard and analytics
[ ] Campaign management
[ ] Campaign version management
[ ] A/B test management
[ ] Reward pool management
[ ] User management
[ ] Email template management
[ ] Affiliate configuration
[ ] Marketplace management
[ ] Report generation and export
[ ] User segmentation
[ ] By-channel analytics (BiAnalytics)
[ ] Zendesk lead management
[ ] Social sharing configuration
[ ] Asset management
[ ] Client user management

soreto-melissa Assessment

Architecture: Next.js 13 App Router

soreto-melissa correctly uses the Next.js 13 App Router with route groups:

app/
├── (client)/     ← role-guarded: CLIENT_USER, SAAS
├── (full-page)/  ← auth, subscribe, public
├── (landing)/    ← marketing
└── (main)/       ← admin routes

The role guard in (client)/layout.tsx is implemented as a client component that checks the StoreContext and redirects non-authorized users. This is appropriate for an admin portal.

SSR vs CSR Tradeoffs

Pattern Used in Melissa Assessment
Server Components Layouts, metadata ✓ Correct — static structure
Client Components ('use client') Interactive pages ✓ Correct — data-dependent pages
Server-side data fetching Not observed ⚠️ May be missing — some pages could fetch on server
API routes Not observed ⚠️ All calls go to reverb-backend directly

Opportunity: Admin dashboard pages that load large data tables could benefit from server-side data fetching (reducing client-side bundle size and first paint time). Currently all data fetching appears to be client-side via the service layer.

Next.js Version: 13.4.9 → Target 16

Version Status Notes
13.4.9 (current) Security patches limited Stable but 3 majors behind
14.x Stable App Router stable, Server Actions added
15.x Stable async/await request APIs, improved caching
16.2.6 (latest) Current stable ~87% faster startup, Turbopack default, AI-ready dev tools

Upgrade path: 13 → 14 is lower risk (image component change, minor breaking changes). 14 → 15 involves changes to how cookies(), headers(), and searchParams are accessed (now async). 15 → 16 requires reviewing Turbopack compatibility and updated error boundaries. Do not skip major versions. Start with 14 in the next 3 months.

State Management: React Context

The current Context approach is appropriate for this use case:

// store/Context.ts
type StoreContextType = {
  isAuthenticated: boolean;
  user: User | null;
  isAuthLoading: boolean;
  selectedCurrency: string;
  login: (email: string, password: string) => Promise<void>;
  logout: () => Promise<void>;
  passwordlessLogin: (email: string, token: string) => Promise<void>;
  changeSelectedCurrency: (currency: string) => void;
};

Auth state, user profile, and currency selection are the right things to put in Context. This is not over-engineered.

Watch for: As melissa grows, if multiple separate domains (campaigns, rewards, etc.) start needing global state, Context will become insufficient. At that point, consider Zustand (lightweight) or TanStack Query (for server state). Do not introduce Redux — it would be a regression from the current clean approach.

UI Library: PrimeReact 10.2.1

PrimeReact is consistently used across the soreto-melissa component tree. This is appropriate — an admin dashboard benefits from a comprehensive component library.

Version note: PrimeReact 10 introduced Tailwind CSS integration and changed styling significantly from v9. The current primeflex@3.3.0 provides the utility CSS layer.

Potential issue: reverb-react uses primereact@1.5.1 — if any component patterns need to be referenced or migrated from reverb-react to melissa, the APIs are completely incompatible.


Frontend Modernization Roadmap

Phase 1: stabilize melissa (0–3 months)

  • [ ] Add CI/CD pipeline (GitHub Actions: lint + type-check + test + build)
  • [ ] Confirm deployment target and document it
  • [ ] Fix jest.setup.ts reference (ensure file exists)
  • [ ] Remove or justify babel.config.js (may conflict with SWC)
  • [ ] Replace @rjsf/core@6.0.0-beta.10 with stable version when available
  • [ ] Evaluate react-force-graph vs react-force-graph-2d — remove unused one

Phase 2: reverb-react modernization (3–9 months)

  • [ ] Stand up Next.js 16 scaffold in apps/legacy-portal/ (Node 24, React 19, TypeScript 6)
  • [ ] Port admin + client route structure to Next.js App Router route groups
  • [ ] Migrate Redux 3 + Flux → Zustand (business logic preserved, rendering rewritten)
  • [ ] Migrate API calls from src/utils/services/@soreto/api-client typed service layer
  • [ ] Replace @@PLACEHOLDER@@ config tokens → process.env.NEXT_PUBLIC_*
  • [ ] Rewrite components to PrimeReact 10.9.8 (APIs are incompatible — must rewrite, not migrate)
  • [ ] Deploy WAF in front of existing Heroku reverb-react app during transition

Phase 3: cut over and decommission (9–12 months)

  • [ ] Cut over traffic from old Heroku reverb-react to modernized apps/legacy-portal/
  • [ ] Decommission original Heroku reverb-react app
  • [ ] Remove NEXT_PUBLIC_LEGACY_PORTAL_URL links pointing to old app from melissa's constants.ts

Do Not: Next.js for reverb-backend

reverb-backend is a pure API server. There is no benefit to adding Next.js API routes as a proxy — this would add complexity and a new process without providing value. The reverb-backend Express server should remain a dedicated API server.