05 — Appendix¶
References¶
Cloudflare documentation¶
| Resource | URL | Relevance |
|---|---|---|
| Cloudflare Workers docs | https://developers.cloudflare.com/workers/ | Primary runtime for admin-api |
| Cloudflare Pages docs | https://developers.cloudflare.com/pages/ | Hosts admin-ui SPA |
| Cloudflare Access docs | https://developers.cloudflare.com/cloudflare-one/policies/access/ | Operator authentication at edge |
| Cloudflare Hyperdrive docs | https://developers.cloudflare.com/hyperdrive/ | MySQL connection pooling from Workers |
| Cloudflare R2 docs | https://developers.cloudflare.com/r2/ | Override file storage (replaces S3) |
| Workers Analytics Engine | https://developers.cloudflare.com/analytics/analytics-engine/ | Structured observability from Workers |
| Wrangler CLI docs | https://developers.cloudflare.com/workers/wrangler/ | Deploy, dev, secret management |
| Workers Cron Triggers | https://developers.cloudflare.com/workers/configuration/cron-triggers/ | Scheduled report delivery replacement |
| CF Access service tokens | https://developers.cloudflare.com/cloudflare-one/identity/service-tokens/ | Playwright E2E auth |
Framework and library documentation¶
| Package | URL | Purpose |
|---|---|---|
| Hono | https://hono.dev | TypeScript HTTP framework for Workers |
| @hono/zod-openapi | https://hono.dev/snippets/zod-openapi | OpenAPI spec generation from Zod schemas |
| Zod | https://zod.dev | Runtime schema validation |
| TanStack Router | https://tanstack.com/router | Type-safe SPA routing |
| TanStack Query | https://tanstack.com/query | Server-state management, caching |
| shadcn/ui | https://ui.shadcn.com | UI component primitives |
| Radix UI | https://www.radix-ui.com | Accessible headless component primitives |
| Tailwind CSS | https://tailwindcss.com | Utility-first CSS |
| Vitest | https://vitest.dev | Unit + integration testing |
| Playwright | https://playwright.dev | E2E testing |
| Stripe Node SDK | https://github.com/stripe/stripe-node | Stripe API (Workers-compatible) |
| openapi-typescript | https://openapi-ts.dev | UI type generation from OpenAPI spec |
Related internal projects¶
| Project | Path | Relationship |
|---|---|---|
| Public API Cloudflare Migration | ../Public API Cloudflare Migration/ |
Predecessor project — auth model, deployment pipeline, observability approach mirror this project |
| Stripe Billing Transition | ../Stripe Billing Transition/ |
Sibling project — billing surface area of this admin is co-designed with that project's decisions |
| Adventive Brand Guide | https://brandguide.adventive.com/dashboard | Visual and interaction language reference for admin-ui |
Inputs¶
Files analyzed during this planning engagement:
| File | Description | Source | Date |
|---|---|---|---|
application/controllers/Auth.php |
JumpCloud LDAP auth + Duo 2FA controller | adventive-admin repo | 2026-04-23 |
application/controllers/Dashboard.php |
Dashboard aggregation controller | adventive-admin repo | 2026-04-23 |
application/controllers/Account.php |
Account CRUD, user management, service levels | adventive-admin repo | 2026-04-23 |
application/controllers/Billing.php |
Invoice generation, payment, managed services | adventive-admin repo | 2026-04-23 |
application/controllers/Campaign.php |
Campaign and ad management | adventive-admin repo | 2026-04-23 |
application/controllers/Report.php |
On-demand reporting (22 methods) | adventive-admin repo | 2026-04-23 |
application/controllers/Reporting.php |
Scheduled report delivery (25 cron methods) | adventive-admin repo | 2026-04-23 |
application/controllers/Tools.php |
Admin tooling: lookup, Cognito sync, deploy | adventive-admin repo | 2026-04-23 |
application/controllers/Override.php |
Override file versioning (S3) | adventive-admin repo | 2026-04-23 |
application/controllers/Chart.php |
Chart JSON endpoints | adventive-admin repo | 2026-04-23 |
application/controllers/ManagedServiceJob.php |
Managed service job CRUD | adventive-admin repo | 2026-04-23 |
application/controllers/Utility.php |
CLI utilities | adventive-admin repo | 2026-04-23 |
application/models/Account_model.php |
Account queries (1,321 lines) | adventive-admin repo | 2026-04-23 |
application/models/Billing_model.php |
Billing queries (933 lines) | adventive-admin repo | 2026-04-23 |
application/models/Campaigns_model.php |
Campaign queries (665 lines) | adventive-admin repo | 2026-04-23 |
application/models/Report_model.php |
Partner report queries (5,333 lines, 24 functions) | adventive-admin repo | 2026-04-23 |
application/models/ManagedService_model.php |
Managed service job queries (505 lines) | adventive-admin repo | 2026-04-23 |
application/models/Stats_model.php |
Stats queries (1,286 lines) | adventive-admin repo | 2026-04-23 |
application/config/adventive.php |
Application config including hardcoded secrets | adventive-admin repo | 2026-04-23 |
application/config/config.php |
CI framework config (CSRF disabled at line 320) | adventive-admin repo | 2026-04-23 |
composer.json |
PHP dependency manifest | adventive-admin repo | 2026-04-23 |
application/views/ |
56 view files across all controller domains | adventive-admin repo | 2026-04-23 |
Open questions¶
The following items require a human decision before or during implementation. Items marked BLOCKING must be resolved before the indicated phase begins.
| # | Question | Blocking phase | Owner | Notes |
|---|---|---|---|---|
| OQ-1 | Identity provider for Cloudflare Access: JumpCloud vs. Google Workspace? | Phase 1 (before operators can authenticate) | Jeffrey | Deferred by ADR — but a decision must land before Phase 1 completes. Google Workspace is already in use for email; JumpCloud is the current LDAP provider. |
| OQ-2 | Secret rotation scope: which AWS keys are actively used, and by which processes? | Phase 0 (prerequisite) | Jeffrey + Patrick | Hardcoded keys include AWS S3 and IAM credentials. Need a full inventory before rotation to avoid breaking the legacy admin during the parallel-run period. |
| OQ-3 | Cloudflare account ID and API token provisioning: who owns this? | Phase 1 | Patrick | The GitHub Actions workflows need CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID as repository secrets. |
| OQ-4 | New GitHub repositories: where do they live? | Phase 1 | Jeffrey | The plan assumes adventive/adventive-admin-api and adventive/adventive-admin-ui on GitHub. Confirm organization name and visibility (private). |
| OQ-5 | Hyperdrive configuration: which DB host and credentials? | Phase 1 | Patrick | Hyperdrive needs a MySQL connection string pointing to the production/staging DB. Confirm the DB host is reachable from Cloudflare Workers (may require allowlisting Cloudflare IP ranges). |
| OQ-6 | Custom domain provisioning: admin.adventive.com and admin-api.adventive.com | Phase 1 (for staging) / Phase 3 (for production) | Jeffrey | Both domains must be added to Cloudflare Pages / Workers as custom domains. DNS must point to Cloudflare. |
| OQ-7 | Partner report replacement strategy: dedicated analytics Worker, Cloudflare Analytics, or third-party? | Phase 4 | Jeffrey + Patrick | Report_model.php is 5,333 lines with 24 bespoke SQL query functions. This is the largest single scope item and cannot be ported inline. Requires a separate architectural decision. |
| OQ-8 | Stripe Billing Transition timing: when is Phase B stable? | Phase 4 (Cohort 2 migration gate) | Jeffrey + Patrick | Cohort 2 (billing operators) should not migrate before Stripe Billing Transition Phase B is stable. Coordinate cutover timing. |
| OQ-9 | Invoice renderer: Cloudflare Browser Rendering vs. external container? | Phase 4 | Patrick | From Stripe Billing Transition: PDF rendering in Workers is constrained. Browser Rendering is the leading candidate but has cost and concurrency implications at invoice volume. |
| OQ-10 | Metering signal contract for Stripe Billing Transition: format, transport, idempotency guarantees | Phase 4 | Jeffrey + Patrick | The admin-api will surface billing data from Stripe, but the metering signal going into Stripe is owned by the Stripe Billing Transition project. The contract must be stable before billing surface is built in admin-api. |
| OQ-11 | Cognito sync tooling: retain or retire? | Phase 8 | Jeffrey | application/libraries/AwsCognito.php and the Cognito sync in Tools.php may be superseded by the Public API migration or another identity flow. Needs evaluation before tooling cohort is migrated. |
| OQ-12 | AppDeploy tooling: retain or retire? | Phase 8 | Jeffrey + Patrick | application/libraries/AppDeploy.php wraps AWS CodeDeploy. If the legacy EC2 deploy pipeline is retired before Phase 8, this tool becomes irrelevant. Track alongside the EC2 decommission timeline. |
Glossary¶
| Term | Definition |
|---|---|
| Access Group | A Cloudflare Zero Trust construct that defines a set of users (by email, IDP group, or other attribute) who can match a policy rule. The "Adventive Operators" Access Group contains all ~10 operator email addresses. |
| AUD tag | "Application Audience" — a unique identifier string attached to a Cloudflare Access Application. The admin-api Worker validates that incoming JWTs contain the correct AUD tag, preventing tokens issued for other Access Applications from being used against this API. |
| CF-Access-Jwt-Assertion | HTTP request header set by Cloudflare Access on every authenticated request. Contains a signed JWT with the operator's identity (email, identity provider, expiry). The admin-api reads this header to identify the operator without an application-managed session. |
| Cohort | A group of operators migrated together to the new admin in a single wave. Three cohorts are planned: (1) account management, (2) billing, (3) remaining workflows. |
| Cron Trigger Worker | A Cloudflare Workers feature that executes a Worker on a cron schedule. Used as the replacement for Reporting.php's 25 scheduled report delivery methods. |
| Hyperdrive | Cloudflare's MySQL (and PostgreSQL) connection pooling and caching layer for Workers. Workers cannot hold persistent TCP connections; Hyperdrive maintains a connection pool on Cloudflare's infrastructure and proxies queries. |
| RBAC | Role-Based Access Control. In this project: three tiers — super-admin (2 operators, all access), billing (billing domain read+write, account read), read-only (all surfaces, no mutations). Tier is derived at runtime from the operator's email address against Wrangler secret lists. |
| Schema-freeze policy | During the parallel-run period (Phases 1–9), no schema changes that break backward compatibility with the CodeIgniter admin are permitted. New nullable columns with defaults are allowed; column drops, renames, and type changes are blocked until the legacy admin is decommissioned. |
| Service token | A Cloudflare Access credential (client ID + client secret) that allows non-human callers (Playwright E2E tests, CI pipelines) to authenticate to an Access-protected application without a browser-based identity provider flow. |
| Smart placement | A Cloudflare Workers feature that routes Worker invocations to the data center geographically closest to the bound backend (in this case, the MySQL database). Reduces latency for database-heavy requests without manual region configuration. |
| Wrangler | Cloudflare's CLI tool for developing, deploying, and managing Workers and Pages projects. Used for deploys, secret management, tail logging, and local development. |
| Worker | A Cloudflare serverless function. The admin-api Worker handles all API requests; the invoice-renderer Worker (sibling project) handles PDF generation. |
| Stripe Billing Transition | The sibling project that migrates Adventive's billing pipeline from the custom admin-managed rollup to Stripe Billing as the system of record. The admin's billing surface is co-designed with this project's decisions. |
| Parallel run | The period during which both the legacy CodeIgniter admin and the new admin-api/admin-ui are live simultaneously, pointing at the same database. Operators migrate cohort-by-cohort; either admin can be used by any operator until their cohort is fully migrated. |
| R2 | Cloudflare's S3-compatible object storage. Used in this project as the replacement for AWS S3 for override file versioning. |
| Override file | An operator-managed configuration file (stored in S3/R2) that overrides platform defaults for specific accounts. Versioned; operators can view history and roll back. |
| Managed service job | A manually-created billing line item attached to a customer account for managed services (e.g., campaign management fees). Separate from subscription-based charges. |
Decisions log (cross-reference)¶
All formal decisions are in decisions/. Summary of locked-in decisions referenced throughout this document:
| Decision | Summary | File |
|---|---|---|
| ADR-1 | Operator auth = Cloudflare Access. Directory provider deferred. | decisions/2026-04-XX-cloudflare-access-auth.md |
| ADR-2 | UI stack = React + Vite + TypeScript SPA on Cloudflare Pages | decisions/2026-04-XX-ui-stack.md |
| ADR-3 | API stack = TypeScript + Hono on Cloudflare Workers, OpenAPI via @hono/zod-openapi | decisions/2026-04-XX-api-stack.md |
| ADR-4 | Deployment = parallel run, cohort-by-cohort operator migration | decisions/2026-04-XX-deployment-strategy.md |
| ADR-5 | No CodeIgniter retrofit — legacy app inventoried, not modified | decisions/2026-04-XX-no-retrofit.md |
| ADR-6 | Data store = existing DB, no migration in scope | decisions/2026-04-XX-data-store.md |
| ADR-7 | RBAC = super-admin (2), billing, read-only; ~10 operators | decisions/2026-04-XX-rbac.md |
Change log¶
| Version | Date | Author | Change |
|---|---|---|---|
| 1.0 | 2026-04-23 | Jeffrey Lambert | Initial planning deliverable — repo analysis complete; all chapters populated; PDF generated |