Skip to content

ADR: Ship new admin-api + admin-ui together — do not retrofit CodeIgniter

  • Status: Accepted (recommendation from Claude, confirmed by Jeffrey)
  • Date: 2026-04-23
  • Decider: Jeffrey Lambert
  • Project: Admin Dashboard Cloudflare Migration

Context

Jeffrey asked whether to (a) ship the new admin-api and admin-ui together, or (b) ship the admin-api first and point the existing CodeIgniter admin at it during a transition period. Option (b) would avoid a big-bang UI cutover but requires heavy modification of the CodeIgniter monolith.

Decision

Ship admin-api and admin-ui together as a parallel deployment, run alongside the legacy CodeIgniter admin, migrate operators cohort-by-cohort, then decommission CodeIgniter. Do not retrofit the CodeIgniter app to consume the new API.

Why not retrofit

A retrofit of the CodeIgniter app to call the new admin-api would:

  • Require rewriting the data-access layer in PHP (essentially a rewrite inside a soon-to-be-retired app).
  • Double the integration surface — both PHP and TypeScript/Hono consumers of the API at once.
  • Create regression risk in a system that's currently working, for no lasting value.
  • Not deliver the brand/UI refresh (the other half of the project's value).
  • End with the CodeIgniter app retired anyway.

The retrofit path's only benefit is avoiding a coordinated UI cutover. Cohort-based migration across the two running admins (old + new) solves the same problem more cheaply.

Deployment topology during transition

                ┌──────────────────────────────────────────┐
                │  Cloudflare Access (shared auth edge)    │
                └───────┬──────────────────────┬───────────┘
                        │                      │
                        ▼                      ▼
           ┌────────────────────┐  ┌────────────────────┐
           │ admin.legacy.*     │  │ admin.adventive.*  │
           │ (CodeIgniter, old) │  │ (Pages SPA, new)   │
           └─────────┬──────────┘  └──────────┬─────────┘
                     │                        │
                     ▼                        ▼
           ┌────────────────────┐  ┌────────────────────┐
           │ CodeIgniter DAL    │  │ admin-api Worker   │
           └─────────┬──────────┘  └──────────┬─────────┘
                     │                        │
                     └──────────┬─────────────┘
                    ┌─────────────────────┐
                    │ Shared billing /    │
                    │ customer DB         │
                    └─────────────────────┘

Both admins read/write the same database during the transition. Cohort-by-cohort, operators migrate from the legacy URL to the new one. When all operator workflows have parity coverage in the new admin, the legacy admin is frozen (read-only), then decommissioned.

Feature-parity gate

The new admin does not have to reach 100% parity before first operators move. Each operator workflow gets a parity checkbox:

  • Customer lookup ✓ → migrate customer-service operators
  • Service-level change ✓ → migrate account managers
  • Billing inquiry view ✓ → migrate billing-ops operators (but see: Stripe Billing Transition will reshape this surface)
  • Report X ✓ → migrate last users

Per-cohort migration also de-risks the brand/UI changes — the new admin gets real-world feedback before everyone is on it.

Consequences

Positive: - Clean separation: legacy PHP is never touched again, only replaced. - Brand/UI refresh ships in the same cutover as the architecture change. - Rollback is trivial — operators just go back to the legacy URL until the cohort has issues resolved. - No wasted engineering on a soon-to-be-retired codebase.

Negative / to-mitigate: - Two admins running simultaneously for a transition window → operator confusion risk (mitigate with clear rollout comms and per-cohort URLs). - Both admins writing to the same DB → schema changes during transition must be backward-compatible with CodeIgniter (or avoided entirely). - The transition window has to be bounded — define a decommission date up front, not "when we're done."

Follow-ups

  • Inventory operator workflows in the legacy admin to build the parity checklist (Claude Code work, once the admin repo is analyzed).
  • Define cohort migration order + success criteria per cohort.
  • Set a decommission date for the CodeIgniter admin (proposal: 60 days after final cohort migration).
  • Decide on DB schema-freeze policy during transition.