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.