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

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.

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.

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.

┌──────────────────────────────────────────┐
│ 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.

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.

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.”
  • 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.