# Implementation Plan

Source: `MASTER_SPEC.md` version 1.0, `DATABASE_SCHEMA.sql`, `OPENAPI.yaml`, `CODEX_PROMPTS.md`.
Status: living implementation plan. Phase 0, Phase 1, Phase 2, Phase 3, and Phase 4 skeleton work has been implemented; later phases remain planned. Backend runtime verification remains release-blocking until PHP/MySQL/Redis/Docker checks run.

## Repository Baseline

Current package root: `/Users/kerrydavisbiozen/Desktop/Airbridge/Made_in_Heaven_Wedding_Reels_Codex_Package`.

Current state:
- The repository now has `/apps`, `/packages`, `/server`, `/realtime`, `/infra`, `/tests`, and `/docs` trees.
- Phase 0 monorepo tooling, Docker Compose, PHP/Apache health skeleton, MySQL/Redis configuration, realtime health skeleton, and CI-equivalent checks exist.
- Phase 1 wedding setup/static reels/PWA/MV3/admin skeleton exists.
- Phase 2 server-authoritative spin engine skeleton exists.
- Automated Phase 0, Phase 1, and Phase 2 dependency-free tests pass locally through `npm run ci:local`.
- PHP runtime checks remain deferred in this Codex environment because local `php` is unavailable; Docker/CI with PHP 8.3 is the intended runtime validation path.

## Recommended Stack Decisions

The simplest maintainable stack compatible with PHP 8.3, MySQL 8, Redis, PWA, and Chrome MV3 is:

- Monorepo package manager: `pnpm` workspaces.
- Frontend build: native JavaScript modules during source development; Vite or another thin bundling step may package production PWA/MV3 artifacts when needed.
- Frontend UI: vanilla JavaScript modules, CSS3, and HTML5. No React/Vue/Lit unless explicitly approved in a later architectural decision.
- Shared frontend testing: dependency-free Node checks now; Vitest and Playwright remain planned for richer unit/browser/PWA/MV3 smoke tests once dependencies are installed.
- PHP backend: Slim 4 HTTP router, PHP-DI, PSR-7/PSR-15 middleware, Composer autoloading.
- Database access: Doctrine DBAL with explicit repositories and transactions; avoid a full ORM until domain pressure proves it useful.
- Migration tool: Phinx migrations under `server/database/migrations`.
- Backend tests: PHPUnit for unit/integration tests.
- Redis client: Predis or phpredis adapter hidden behind a small interface.
- WebSocket gateway: Node.js `ws` service in `server/realtime` or `apps/realtime`, using Redis pub/sub/streams for fan-out. REST remains PHP. This keeps long-running socket concerns out of Apache/PHP request workers.
- Image processing: PHP Imagick when available with GD fallback, hidden behind `ImageProcessor`.
- API docs: keep OpenAPI as the source contract and validate key responses in tests.
- CI: GitHub Actions or equivalent running the current dependency-free checks now, then Composer install, pnpm install, PHP checks, unit tests, and selected browser smoke tests once lockfiles/dependencies are introduced.

## Proposed Monorepo Structure

```text
wedding-reels/
  apps/
    web/                    # PWA/browser shell using vanilla JavaScript modules
    extension/              # Chrome MV3 wrapper using shared browser modules
    admin/                  # Admin console shell using shared UI modules; desktop is history/review only for image updates
  packages/
    protocol/               # Shared TypeScript API/event/domain contracts
    core/                   # Game client services: bootstrap, spins, realtime, capture orchestration
    ui/                     # Vanilla UI helpers, CSS tokens, admin setup behavior, and shared browser modules
    platform/               # Browser/PWA/extension adapters, storage, notifications, AirBridge adapter interface
  server/
    public/                 # Apache document root, index.php, static media gateway if needed
    src/
      Controllers/
      Middleware/
      Services/
      Domain/
      Repositories/
      Realtime/
      Jobs/
      Support/
    database/
      migrations/
      seeds/
    tests/
      Unit/
      Integration/
  realtime/
    src/                    # Node ws gateway, Redis subscriber, auth validator client
    tests/
  infra/
    apache/
    docker/
    mysql/
    redis/
  tests/
    e2e/
    load/
    fixtures/
  docs/
```

## Phase Plan

### Phase 0 - Repository and contracts

Goal: create the buildable monorepo skeleton and shared contracts without gameplay features.

Modules:
- Repo tooling, CI, Docker, PHP REST skeleton, WebSocket skeleton health endpoint, shared protocol package.

Expected files:
- `package.json`, `pnpm-workspace.yaml`, `tsconfig.base.json`, `.editorconfig`, `.gitignore`.
- `composer.json`, `phpunit.xml`, `server/public/index.php`, `server/src/*` skeleton.
- `docker-compose.yml`, `infra/apache/*`, `infra/docker/*`.
- `packages/protocol/src/*.ts`, `packages/core/src/index.ts`, `packages/platform/src/index.ts`.
- `.env.example`, `.github/workflows/ci.yml`.
- `docs/DEVELOPER_SETUP.md`.

Tests:
- Composer autoload and PHPUnit smoke test.
- Vitest protocol serialization tests.
- Health checks for REST, DB, Redis, and realtime service.
- CI-equivalent local command documented.

### Phase 1 - Wedding setup and static reels

Goal: admin setup, wedding assets, bootstrap, static themed reels, PWA and MV3 shell.

Modules:
- Admin auth foundation, wedding CRUD, asset validation/upload, bootstrap API, reel strip generator, frontend shell, mobile-first admin setup, PWA manifest/service worker, extension wrapper.

Expected files:
- `server/src/Controllers/WeddingController.php`, `AssetController.php`, `BootstrapController.php`.
- `server/src/Services/WeddingService.php`, `AssetService.php`, `ReelStripService.php`.
- `server/database/migrations/*weddings*.php`, `*assets*.php`, `*symbols*.php`, `*reel_strips*.php`.
- `apps/web/src/*`, `apps/web/public/manifest.webmanifest`, `apps/web/src/service-worker.ts`.
- `apps/extension/manifest.json`, `apps/extension/src/*`.
- `apps/admin/src/*` and shared admin browser logic in `packages/ui/src/*`.

Tests:
- CRUD authorization tests.
- Asset type/size/content validation tests.
- Bootstrap contract tests.
- Strip construction tests for exactly 3 reels x 40 stops and exactly two copies of 20 identities per reel.
- PWA manifest validation.
- MV3 no remote executable code check.
- Responsive smoke tests.

### Phase 2 - Server-authoritative spins

Goal: outcome engine, signed spin authorizations, stop mapping, rates, protected events, and completion ack.

Modules:
- Spin authorization service, random decision engine, commitment/hash, rate limits, idempotency, client spin controller and reel animation consumer.

Expected files:
- `server/src/Services/SpinAuthorizationService.php`, `OutcomeEngine.php`, `StopMappingService.php`, `TokenSigner.php`.
- `server/src/Controllers/SpinController.php`.
- `packages/core/src/spin-controller.ts`, `packages/core/src/reel-engine.ts`.
- `server/database/migrations/*spins*.php`.

Tests:
- One-million-decision deterministic statistical harness.
- Win-rate bounds and protected-rate tests.
- Uniform conditional target distribution across 17 replaceable symbols.
- Non-win accidental match prevention.
- Protected combination semantics.
- Stop mapping tests.
- Expired/forged/duplicate token tests.
- Paused/closed/rate-limited wedding tests.

### Phase 3 - Real-time operation

Goal: ordered realtime events, presence, pause state, fallback polling, sequence gap recovery.

Modules:
- WebSocket gateway, Redis fan-out, event envelope, realtime client, polling fallback, live announcements.

Expected files:
- `realtime/src/server.ts`, `realtime/src/redis-subscription.ts`, `realtime/src/auth.ts`.
- `server/src/Services/EventPublisher.php`, `PresenceService.php`, `WeddingStateService.php`.
- `packages/core/src/realtime-client.ts`, `packages/ui/src/announcement-overlay.ts`.
- `server/database/migrations/*event_log*.php`.

Tests:
- Ordered fan-out, duplicate delivery, sequence-gap recovery.
- Reconnect and polling fallback.
- 500 simulated subscribers.
- p95 broadcast measurement.
- Accessibility live-region tests.

### Phase 4 - Camera and atomic replacement

Goal: winner capture, image processing, entitlement lifecycle, atomic replacement, public/private notifications.

Modules:
- Capture entitlement service, image processing pipeline, upload controller, replacement workflow, distributed lock, frontend camera capture/uploader.

Expected files:
- `server/src/Controllers/EntitlementController.php`, `ImageController.php`.
- `server/src/Services/CaptureEntitlementService.php`, `ImageProcessor.php`, `ReplacementWorkflowService.php`, `LockService.php`.
- `packages/core/src/camera-capture.ts`, `image-uploader.ts`.
- `packages/ui/src/capture-flow.ts`, `replacement-announcement.ts`.
- Migrations for `capture_entitlements`, `symbol_occupants`, `occupant_images`, `replacement_events`.

Tests:
- Replace default art, replace guest, removed guest history preserved, removed guest wins back.
- Duplicate commit idempotency.
- Concurrent commit lock/transaction safety.
- Timeout/cancel behavior.
- Malformed image rejection and MIME sniffing.
- Camera denied fallback.
- Protected replacement rejected.

### Phase 5 - History and administration

Goal: timelines, moderation, restore, close, final snapshot, ZIP/static gallery export.

Modules:
- History/audit service, admin dashboard, moderation queue, restore flow, snapshot/export jobs.

Expected files:
- `server/src/Controllers/Admin/*`, `HistoryController.php`, `ExportController.php`.
- `server/src/Services/HistoryService.php`, `ModerationService.php`, `SnapshotService.php`, `ExportService.php`.
- `apps/admin/src/pages/*`.
- Migrations for `final_snapshots`, `moderation_actions`, `admin_users`, any missing audit tables.

Tests:
- Complete replace/remove/re-enter timeline.
- Restore through new occupant version.
- Close race with pending entitlement.
- Snapshot immutability.
- Export manifest integrity.
- Authorization and audit tests.

### Phase 6 - AirBridge discovery

Goal: optional AirBridge join discovery only, with normalized browser/extension/no-op adapters.

Modules:
- AirBridge adapter interface, browser/extension/no-op implementations, payload validator, join route builder.

Expected files:
- `packages/platform/src/airbridge/browser-adapter.ts`.
- `packages/platform/src/airbridge/extension-adapter.ts`.
- `packages/platform/src/airbridge/noop-adapter.ts`.
- `packages/core/src/airbridge-join.ts`.
- Server token validation endpoint/service additions.

Tests:
- Valid join, expired token, wrong wedding/environment, duplicate pulse, unsupported browser, extension adapter, no microphone permission, tampered payload.

### Phase 7 - Hardening and release candidate

Goal: security, accessibility, load, deployment, observability, backup/restore, release evidence.

Modules:
- Security headers/CSP, admin MFA integration point, logs/metrics, load tests, backup/export/delete tools, release readiness docs.

Expected files:
- `docs/RELEASE_READINESS.md`, `docs/DEPLOYMENT.md`, `docs/RUNBOOK.md`.
- `infra/apache/production.conf`, `infra/docker/production*`.
- `tests/load/*`, `tests/e2e/*`.

Tests:
- Full suite plus device/browser matrix.
- 500 concurrent clients and 50 spin requests/second burst.
- Reconnect storm and fallback tests.
- Accessibility audit evidence.
- Vulnerability scan evidence.

## Acceptance Criteria Mapping

| AC | Acceptance criterion | Phase | Primary module | Test case | Expected files |
|---|---|---:|---|---|---|
| AC-01 | Admin can create a wedding and upload all required images and sounds. | 1 | Admin, Wedding, Asset | `WeddingCrudTest`, `AssetUploadValidationTest`, admin setup Playwright smoke | `server/src/Controllers/WeddingController.php`, `AssetController.php`, `apps/admin/src/pages/setup/*` |
| AC-02 | A QR link opens the correct themed game. | 1 | Join/bootstrap, frontend shell | `JoinResolveTest`, `BootstrapContractTest`, PWA route smoke | `server/src/Controllers/JoinController.php`, `BootstrapController.php`, `apps/web/src/routes/join.ts` |
| AC-03 | AirBridge adapter can resolve a valid compact join payload. | 6 | AirBridge adapters | `AirbridgeJoinAdapterTest`, extension adapter test | `packages/platform/src/airbridge/*`, `packages/core/src/airbridge-join.ts` |
| AC-04 | Three reels display 40 stops and 20 identities. | 1 | Reel strip generator/UI | `ReelStripServiceTest`, `reel-engine.test.ts`, visual smoke | `server/src/Services/ReelStripService.php`, `packages/core/src/reel-engine.ts` |
| AC-05 | Server controls every outcome. | 2 | Spin authorization | `ClientCannotAuthorizeWinTest`, forged completion test | `server/src/Services/SpinAuthorizationService.php`, `packages/core/src/spin-controller.ts` |
| AC-06 | Celebration rate is configurable and statistically verified. | 2 | Outcome engine | `OutcomeEngineStatisticalTest` | `server/src/Services/OutcomeEngine.php` |
| AC-07 | Every replaceable identity is equally selectable on wins. | 2 | Outcome engine | chi-square/uniform target test over 17 identities | `server/src/Services/OutcomeEngine.php` |
| AC-08 | Protected-image combinations trigger Made in Heaven and cannot open camera capture. | 2,4 | Outcome engine, capture entitlement | protected combinations unit test, claim rejection test | `OutcomeEngine.php`, `CaptureEntitlementService.php` |
| AC-09 | A normal winner can submit one to three photos. | 4 | Capture/uploader/images | capture flow E2E, upload validation tests | `packages/core/src/camera-capture.ts`, `server/src/Controllers/EntitlementController.php` |
| AC-10 | Photos replace the matched identity across all clients. | 4 | Replacement workflow/realtime | replacement integration, realtime fan-out test | `ReplacementWorkflowService.php`, `EventPublisher.php` |
| AC-11 | Added and removed guests are publicly announced. | 4 | Announcement overlay/events | announcement wording/unit and E2E | `packages/ui/src/replacement-announcement.ts` |
| AC-12 | Removed guest receives private encouragement when enabled. | 4 | Realtime/private session notifications | private removed guest notification test | `ReplacementWorkflowService.php`, `realtime/src/server.ts` |
| AC-13 | Removed media remains in history. | 4,5 | History/assets | occupant timeline integration test | `HistoryService.php`, `occupant_images` migration |
| AC-14 | Removed guest can later win back onto any replaceable identity. | 4,5 | Replacement/history | re-entry E2E and timeline test | `ReplacementWorkflowService.php`, `HistoryService.php` |
| AC-15 | Concurrent replacement attempts cannot corrupt state. | 4 | Lock/transaction | concurrent commit test, idempotent retry test | `LockService.php`, `ReplacementWorkflowService.php` |
| AC-16 | Admin can pause, moderate, restore, close, and export. | 5 | Admin/history/export | admin workflow integration tests | `apps/admin/src/pages/*`, `ModerationService.php`, `ExportService.php` |
| AC-17 | Event close produces immutable final snapshot and chronological gallery. | 5 | Snapshot/export | snapshot immutability and ZIP manifest tests | `SnapshotService.php`, `ExportService.php`, `final_snapshots` migration |
| AC-18 | PWA and extension use the same core code. | 1 | Build/platform packages | dependency graph/build artifact test | `apps/web`, `apps/extension`, `packages/core`, `packages/ui` |
| AC-19 | Core flows pass on iPhone, Android, desktop Chrome, and MV3 extension. | 7 | E2E/device matrix | Playwright plus manual device checklist | `tests/e2e/*`, `docs/RELEASE_READINESS.md` |
| AC-20 | No wager, payment, or cash-prize functionality exists. | 1-7 | Product/security review | static route/schema scan, final audit | all app/server routes and schema |

## Baseline Commands and Results

- `find ... -name package.json -o -name composer.json -o -name phpunit.xml* -o -name vite.config.* -o -name docker-compose*`: no results.
- `wc -l MASTER_SPEC.md DATABASE_SCHEMA.sql OPENAPI.yaml CODEX_PROMPTS.md`: 1520 total lines.
- No existing tests could be run because no test framework or source tree exists yet.

## Recommended First Implementation Phase

Proceed with Phase 0 only: bootstrap the monorepo, contracts, local Docker environment, health checks, CI, and shared protocol types. Do not start wedding setup, spins, camera, or realtime product behavior until Phase 0 has a clean local and CI-equivalent baseline.
