# Owner Control Plane — Implementation Checklist

Track implementation status. Check off items as they are completed and tested.

---

## Phase 0: Database Migration

- [ ] Write `supabase/migrations/supabase-migration-control-plane.sql`
  - [ ] `user_profiles` — add `is_platform_owner boolean DEFAULT false`
  - [ ] `cp_tenants` — tenant registry
  - [ ] `cp_tenant_environments` — per-tenant runtime config
  - [ ] `cp_plans` — plan catalog
  - [ ] `cp_features` — feature catalog (seed with all FeatureCodes)
  - [ ] `cp_plan_feature_entitlements` — plan × feature mapping
  - [ ] `cp_tenant_feature_overrides` — per-tenant exceptions
  - [ ] `cp_owner_users` — owner user registry with role
  - [ ] `cp_branding_profiles` — tenant branding config
  - [ ] `cp_provisioning_jobs` — provisioning job records
  - [ ] `cp_provisioning_job_steps` — per-step state
  - [ ] `cp_audit_events` — immutable audit log
  - [ ] `cp_release_rollouts` — kill switches and rollouts
  - [ ] `cp_support_access_sessions` — time-limited support sessions
  - [ ] RLS policies on all `cp_*` tables (service_role only)
  - [ ] Seed data: starter, professional, enterprise plans + features
  - [ ] Run migration and verify schema

---

## Phase 1: TypeScript Foundation

- [ ] `lib/control-plane/types.ts` — all CP domain types
- [ ] `lib/control-plane/client.ts` — Supabase client factory for CP
- [ ] `lib/entitlement/types.ts` — EntitlementResult, FeatureCode, etc.
- [ ] `lib/entitlement/engine.ts` — checkEntitlement(), requireEntitlement()
- [ ] `lib/entitlement/client-hook.ts` — useEntitlement() React hook
- [ ] `lib/branding/types.ts` — BrandingProfile type
- [ ] `lib/branding/engine.ts` — getActiveBranding(), requireBranding()
- [ ] `lib/provisioning/types.ts` — ProvisioningJob, Step types
- [ ] `lib/provisioning/workflow.ts` — runProvisioningStep() executor
- [ ] `lib/owner-audit/middleware.ts` — requireOwnerRole(), logAuditEvent()

---

## Phase 2: Middleware Guard

- [ ] Extend `lib/supabase/proxy.ts`
  - [ ] Intercept `/owner/` and `/api/owner/` paths
  - [ ] Call `checkIsPlatformOwner(supabase)`
  - [ ] Redirect to `/login?next=/owner/dashboard` if not authorized

---

## Phase 3: API Routes — Owner

- [ ] `app/api/owner/tenants/route.ts` — GET (list), POST (create)
- [ ] `app/api/owner/tenants/[tenantId]/route.ts` — GET, PATCH, DELETE
- [ ] `app/api/owner/tenants/[tenantId]/provision/route.ts` — POST
- [ ] `app/api/owner/tenants/[tenantId]/suspend/route.ts` — POST
- [ ] `app/api/owner/tenants/[tenantId]/archive/route.ts` — POST
- [ ] `app/api/owner/tenants/[tenantId]/modules/route.ts` — GET, PATCH
- [ ] `app/api/owner/tenants/[tenantId]/branding/route.ts` — GET, PATCH
- [ ] `app/api/owner/provisioning/route.ts` — GET (list jobs)
- [ ] `app/api/owner/provisioning/[jobId]/route.ts` — GET (job + steps)
- [ ] `app/api/owner/provisioning/[jobId]/retry/route.ts` — POST
- [ ] `app/api/owner/plans/route.ts` — GET, POST
- [ ] `app/api/owner/plans/[planId]/route.ts` — GET, PATCH, DELETE
- [ ] `app/api/owner/plans/[planId]/features/route.ts` — GET, PATCH
- [ ] `app/api/owner/audit/route.ts` — GET (paginated, filterable)
- [ ] `app/api/owner/settings/route.ts` — GET, PATCH

---

## Phase 4: Owner Portal Pages

- [ ] `app/owner/layout.tsx` — owner shell with sidebar nav
- [ ] `app/owner/dashboard/page.tsx` — summary: tenant count, recent activity
- [ ] `app/owner/tenants/page.tsx` — tenant list with status badges
- [ ] `app/owner/tenants/new/page.tsx` — create tenant form
- [ ] `app/owner/tenants/[tenantId]/page.tsx` — tenant detail
- [ ] `app/owner/tenants/[tenantId]/branding/page.tsx` — branding editor
- [ ] `app/owner/tenants/[tenantId]/modules/page.tsx` — module toggle grid
- [ ] `app/owner/provisioning/page.tsx` — provisioning job list
- [ ] `app/owner/provisioning/[jobId]/page.tsx` — job detail + step log
- [ ] `app/owner/plans/page.tsx` — plan list
- [ ] `app/owner/plans/[planId]/page.tsx` — plan detail + feature matrix
- [ ] `app/owner/audit/page.tsx` — audit log with filters

---

## Phase 5: Owner Portal Components

- [ ] `components/owner/tenant-table.tsx` — sortable tenant list
- [ ] `components/owner/tenant-form.tsx` — create/edit tenant
- [ ] `components/owner/tenant-status-badge.tsx` — lifecycle state badge
- [ ] `components/owner/provisioning-step-list.tsx` — step progress view
- [ ] `components/owner/module-toggle-grid.tsx` — feature override toggles
- [ ] `components/owner/branding-editor.tsx` — live preview branding form
- [ ] `components/owner/plan-feature-matrix.tsx` — plan × feature grid
- [ ] `components/owner/audit-log-table.tsx` — paginated audit view
- [ ] `components/owner/owner-sidebar.tsx` — owner nav sidebar

---

## Phase 6: Entitlement Integration (Tenant Side)

- [ ] Confirm `TENANT_ID` env var is set in all tenant deployments
- [ ] Wire `useEntitlement()` hook into navigation items
- [ ] Wire `requireEntitlement()` into all module API routes
- [ ] Add `CONTROL_PLANE_SUPABASE_URL` + `CONTROL_PLANE_READONLY_KEY` env vars

---

## Phase 7: Branding Integration (Tenant Side)

- [ ] Load branding at app startup (server component or layout)
- [ ] Apply `primary_color` to CSS variables
- [ ] Apply `company_name`, `logo_url` to AppHeader
- [ ] Apply `default_language` to i18n default
- [ ] Cache with 5-minute TTL, invalidate on owner change

---

## Phase 8: Support Access

- [ ] `cp_support_access_sessions` table (in migration)
- [ ] Owner API: POST `/api/owner/tenants/[tenantId]/support-access`
- [ ] Tenant API: middleware check for active support session
- [ ] Support access logged in both owner and tenant audit logs
- [ ] Expiry enforced on every request (not just at session creation)

---

## Phase 9: Tests

- [ ] `__tests__/entitlement-engine.test.ts` — all 4 layers, all denial reasons
- [ ] `__tests__/owner-auth.test.ts` — guard blocks non-owners, passes owners
- [ ] `__tests__/provisioning.test.ts` — idempotency, retry, step skip logic
- [ ] `__tests__/tenant-isolation.test.ts` — cross-tenant query rejection
- [ ] `__tests__/branding-engine.test.ts` — correct profile per tenant

---

## Phase 10: Local Development Seeds

- [ ] Seed script: create owner user in local Supabase
- [ ] Seed script: create 2-3 test tenants (ACTIVE, DRAFT, SUSPENDED)
- [ ] Seed script: create starter, professional, enterprise plans with features
- [ ] `.env.local.example` updated with all new env var names

---

## Definition of Done

All phases complete when:
- [ ] `npm run build` passes with zero type errors
- [ ] `npm run typecheck` passes
- [ ] All Phase 9 tests pass
- [ ] Owner portal renders at `/owner/dashboard`
- [ ] Tenant user redirected to login when visiting `/owner/`
- [ ] Entitlement check returns correct result for all 4 deny reasons
- [ ] Provisioning job runs and completes for a test tenant
- [ ] Audit log captures all owner mutations
