# Implementation Plan

## Validation Checklist

- [x] File paths in Context Priming exist
- [x] MVP scope matches PRD Must-Haves (Features 1-8)
- [x] Each phase is testable (unit/integration)
- [x] All demo-only changes are behind demo routes/flags
- [x] External side effects are disabled in demo mode
- [x] Dependencies between phases are clear
- [x] Activity hints provided for specialist selection

---

## Context Priming

*Read before starting implementation.*

### Specifications
- `docs/specs/021-demo-dashboard/product-requirements.md` - Full PRD with 13 features
- `docs/specs/021-demo-dashboard/solution-design.md` - Architecture with 5 ADRs

### Reference Implementations
- `docs/specs/015-task-engine - done/solution-design.md` - TaskEngine patterns
- `docs/patterns/psr4-autoloading.md` - Namespace conventions

### Key Source Files
- `userfrosting/mock/MockDataGenerator.php` - Simulation engine (lines 177-181: Ably + WhenIWork init)
- `userfrosting/mock/SeasonalConfig.php` - Concept-specific parameters (pc/ou/se)
- `userfrosting/src/BuyerKiosk/Auth/Services/RememberMeService.php` - Token pattern for magic links
- `userfrosting/src/BuyerKiosk/TaskEngine/Services/PHPMailerAdapter.php` - Email sending pattern
- `userfrosting/src/BuyerKiosk/TaskEngine/Jobs/MockDataGeneratorJob.php` - Job scheduling pattern

---

## Phases

### P1: Demo Entry + Session (MVP Foundation)

**Goal:** QR → email capture → magic link → 24-hour session cookie + concept selection.

**PRD Coverage:** Features 1, 2, 3, 8 (partial)

#### P1.1 Prime Context
- [ ] T1.1.1 Read SDD Section: External Interfaces (lines 156-226) `[activity: research]`
- [ ] T1.1.2 Read SDD Section: Data Storage Changes (lines 424-507) `[activity: research]`
- [ ] T1.1.3 Review RememberMeService token pattern `[activity: research]`
- [ ] T1.1.4 Review PHPMailerAdapter email pattern `[activity: research]`

#### P1.2 Database Schema `[component: database]`
- [ ] T1.2.1 Create migration: `demo_sessions` table `[ref: SDD/Data Storage; lines: 427-445]` `[activity: database]`
- [ ] T1.2.2 Create migration: `demo_leads` table `[ref: SDD/Data Storage; lines: 447-457]` `[activity: database]`
- [ ] T1.2.3 Create migration: `demo_analytics_events` table `[ref: SDD/Data Storage; lines: 472-479]` `[activity: database]`
- [ ] T1.2.4 Create demo store databases: `kiosk_demo`, `kiosk_demo_pc`, `kiosk_demo_ou`, `kiosk_demo_se` `[activity: database]`

#### P1.3 Write Tests (TDD - Tests First) `[component: testing]`
- [ ] T1.3.1 Unit test: DemoSessionService::createMagicLink() `[ref: SDD/Example; lines: 743-792]` `[activity: unit-test]`
- [ ] T1.3.2 Unit test: DemoSessionService::validateAndActivate() - valid token `[activity: unit-test]`
- [ ] T1.3.3 Unit test: DemoSessionService::validateAndActivate() - expired token `[activity: unit-test]`
- [ ] T1.3.4 Unit test: DemoSessionService::validateAndActivate() - already-used token `[activity: unit-test]`
- [ ] T1.3.5 Unit test: DemoSession model methods (isExpired, remainingTime, etc.) `[activity: unit-test]`
- [ ] T1.3.6 Unit test: Rate limiter (5 requests per 5 minutes per IP) `[activity: unit-test]`
- [ ] T1.3.7 Integration test: Full magic link flow (request → email → validate) `[activity: integration-test]`

#### P1.4 Implement Services `[component: backend]`
- [ ] T1.4.1 Create `BuyerKiosk\Demo\Models\DemoSession` entity `[ref: SDD/Data Models; lines: 592-613]` `[activity: backend-model]`
- [ ] T1.4.2 Create `BuyerKiosk\Demo\Models\DemoLead` entity `[ref: SDD/Data Models; lines: 615-630]` `[activity: backend-model]`
- [ ] T1.4.3 Create `BuyerKiosk\Demo\Repositories\SessionRepository` `[activity: backend-repository]`
- [ ] T1.4.4 Create `BuyerKiosk\Demo\Services\DemoSessionService` `[ref: SDD/Example; lines: 743-792]` `[activity: backend-service]`
- [ ] T1.4.5 Create `BuyerKiosk\Demo\Services\DemoDbConnector` (routes to demo DBs) `[activity: backend-service]`
- [ ] T1.4.6 Implement rate limiting using Redis `[ref: SDD/Cross-Cutting; lines: 1001-1006]` `[activity: backend-service]`

#### P1.5 Implement Controllers + Routes `[component: backend]`
- [ ] T1.5.1 Create `BuyerKiosk\Demo\Controllers\DemoLandingController` (email capture) `[activity: backend-controller]`
- [ ] T1.5.2 Create `BuyerKiosk\Demo\Controllers\DemoAccessController` (magic link validation) `[activity: backend-controller]`
- [ ] T1.5.3 Create `BuyerKiosk\Demo\Controllers\DemoConceptController` (PC/OU/SE selection) `[activity: backend-controller]`
- [ ] T1.5.4 Create demo routes file: `routes/demo/landing.php` `[activity: backend-routing]`
- [ ] T1.5.5 Create demo routes file: `routes/demo/access.php` `[activity: backend-routing]`
- [ ] T1.5.6 Create `BuyerKiosk\Demo\Middleware\DemoMiddleware` (session validation) `[activity: backend-middleware]`

#### P1.6 Implement Templates `[component: frontend]`
- [ ] T1.6.1 Create `templates/themes/default/demo/landing.html` (email form) `[activity: frontend-template]`
- [ ] T1.6.2 Create `templates/themes/default/demo/concept-select.html` (PC/OU/SE cards) `[activity: frontend-template]`
- [ ] T1.6.3 Create `templates/themes/default/demo/error.html` (expired/invalid states) `[activity: frontend-template]`
- [ ] T1.6.4 Create `templates/themes/default/demo/check-email.html` (magic link sent) `[activity: frontend-template]`
- [ ] T1.6.5 Add demo-specific CSS: `public_html/css/admin/modules/demo.css` `[activity: frontend-css]`

#### P1.7 Email Integration `[component: email]`
- [ ] T1.7.1 Create magic link email template `[activity: frontend-template]`
- [ ] T1.7.2 Implement email sending in DemoSessionService using PHPMailerAdapter pattern `[activity: backend-service]`
- [ ] T1.7.3 Add email configuration for demo environment (DEMO_EMAIL_* vars) `[activity: config]`

#### P1.8 Validate Phase 1
- [ ] T1.8.1 Run unit tests: `./test.sh --testsuite unit --filter Demo` `[activity: run-tests]`
- [ ] T1.8.2 Run integration tests `[activity: run-tests]`
- [ ] T1.8.3 Manual E2E: Request link → receive email → click → select concept → session active `[activity: manual-test]`
- [ ] T1.8.4 Verify PRD acceptance criteria: Features 1, 2, 3 `[activity: business-acceptance]`

---

### P2: Simulation Safety + Data Setup

**Goal:** Run MockDataGenerator continuously without outbound side effects.

**PRD Coverage:** Feature 4 (Continuous Live Simulation)

**Dependency:** P1 complete (demo databases exist)

#### P2.1 Prime Context
- [ ] T2.1.1 Read MockDataGenerator (focus: initializeAbly, initializeScheduleManager) `[activity: research]`
- [ ] T2.1.2 Read SDD Section: Implementation Gotchas (lines 1125-1130) `[activity: research]`
- [ ] T2.1.3 Review MockDataGeneratorJob TaskEngine integration `[activity: research]`

#### P2.2 Write Tests (TDD - Tests First)
- [ ] T2.2.1 Unit test: MockDataGenerator demo mode disables Ably init `[activity: unit-test]`
- [ ] T2.2.2 Unit test: MockDataGenerator demo mode disables WhenIWork init `[activity: unit-test]`
- [ ] T2.2.3 Unit test: MockDataGenerator demo mode disables SMS notifications `[activity: unit-test]`
- [ ] T2.2.4 Integration test: Generator runs on kiosk_demo_pc without external calls `[activity: integration-test]`

#### P2.3 Implement Demo Mode Guards `[component: simulation]`
- [ ] T2.3.1 Add `DEMO_MODE` environment variable detection `[activity: backend-service]`
- [ ] T2.3.2 Modify MockDataGenerator::initializeAbly() to skip in demo mode `[activity: backend-service]`
- [ ] T2.3.3 Modify MockDataGenerator::initializeScheduleManager() to skip in demo mode `[activity: backend-service]`
- [ ] T2.3.4 Add demo mode check to any SMS notification paths `[activity: backend-service]`
- [ ] T2.3.5 Create `BuyerKiosk\Demo\DemoModeHelper` utility class `[activity: backend-service]`

#### P2.4 Demo Store Data Setup `[component: database]`
- [ ] T2.4.1 Create demo store records in kiosk_demo (typeNum: pc00, ou00, se00 mapped to demo DBs) `[activity: database]`
- [ ] T2.4.2 Copy store schema to kiosk_demo_pc, kiosk_demo_ou, kiosk_demo_se `[activity: database]`
- [ ] T2.4.3 Seed minimal baseline data (employees, categories, config) `[activity: database]`
- [ ] T2.4.4 Create demo-specific scheduler config for MockDataGeneratorJob `[activity: config]`

#### P2.5 TaskEngine Demo Configuration `[component: taskengine]`
- [ ] T2.5.1 Add demo queue configuration to TaskEngine `[activity: config]`
- [ ] T2.5.2 Create scheduled job definition for demo simulation (runs every 5 minutes) `[activity: config]`
- [ ] T2.5.3 Configure demo worker startup script `[activity: config]`

#### P2.6 Validate Phase 2
- [ ] T2.6.1 Run unit tests for demo mode guards `[activity: run-tests]`
- [ ] T2.6.2 Run MockDataGeneratorJob against demo database `[activity: integration-test]`
- [ ] T2.6.3 Verify: No Ably connection attempts in logs `[activity: manual-test]`
- [ ] T2.6.4 Verify: No WhenIWork API calls in logs `[activity: manual-test]`
- [ ] T2.6.5 Verify: Demo store data appears realistic (buys, customers, schedules) `[activity: manual-test]`

---

### P3: Shadow Table Overlay (MVP Interactive Actions)

**Goal:** Support session-scoped writes for a small, high-value subset of actions.

**PRD Coverage:** Feature 5 (Session-Scoped User Actions)

**Dependency:** P2 complete (simulation running, demo data exists)

#### P3.1 Prime Context
- [ ] T3.1.1 Read SDD Section: Shadow Table Pattern (lines 687-736) `[activity: research]`
- [ ] T3.1.2 Read SDD Section: ADR-1 Shadow Table Pattern (lines 1051-1059) `[activity: research]`
- [ ] T3.1.3 Read PRD: Session-Scoped User Actions spec (lines 236-260) `[activity: research]`

#### P3.2 Database Schema `[component: database]`
- [ ] T3.2.1 Create migration: `shadow_buys` table `[ref: SDD/Data Storage; lines: 481-490]` `[activity: database]`
- [ ] T3.2.2 Create migration: `shadow_customers` table `[activity: database]`
- [ ] T3.2.3 Create migration: `shadow_tasks` table `[activity: database]`
- [ ] T3.2.4 Create migration: `shadow_notes` table `[activity: database]`
- [ ] T3.2.5 Apply migrations to all demo store databases `[activity: database]`

#### P3.3 Write Tests (TDD - Tests First) `[parallel: true]`
- [ ] T3.3.1 Unit test: ShadowTableService::recordWrite() for insert operation `[activity: unit-test]`
- [ ] T3.3.2 Unit test: ShadowTableService::recordWrite() for update operation `[activity: unit-test]`
- [ ] T3.3.3 Unit test: ShadowTableService::recordWrite() for delete operation `[activity: unit-test]`
- [ ] T3.3.4 Unit test: ShadowTableService::getMergedData() - baseline only `[activity: unit-test]`
- [ ] T3.3.5 Unit test: ShadowTableService::getMergedData() - with inserts `[activity: unit-test]`
- [ ] T3.3.6 Unit test: ShadowTableService::getMergedData() - with updates `[activity: unit-test]`
- [ ] T3.3.7 Unit test: ShadowTableService::getMergedData() - with deletes `[activity: unit-test]`
- [ ] T3.3.8 Unit test: ShadowTableService::getMergedData() - mixed operations `[activity: unit-test]`
- [ ] T3.3.9 Integration test: Two sessions don't see each other's writes `[activity: integration-test]`
- [ ] T3.3.10 Integration test: Session cleanup purges shadow data `[activity: integration-test]`

#### P3.4 Implement Shadow Table Service `[component: backend]`
- [ ] T3.4.1 Create `BuyerKiosk\Demo\Models\ShadowRecord` entity `[ref: SDD/Data Models; lines: 632-644]` `[activity: backend-model]`
- [ ] T3.4.2 Create `BuyerKiosk\Demo\Repositories\ShadowTableRepository` `[activity: backend-repository]`
- [ ] T3.4.3 Create `BuyerKiosk\Demo\Services\ShadowTableService` `[ref: SDD/Example; lines: 687-736]` `[activity: backend-service]`
- [ ] T3.4.4 Implement getMergedBuys() method `[activity: backend-service]`
- [ ] T3.4.5 Implement getMergedTasks() method `[activity: backend-service]`
- [ ] T3.4.6 Implement recordWrite() method `[activity: backend-service]`

#### P3.5 Integrate Shadow Tables with Demo Views `[component: backend]`
- [ ] T3.5.1 Create `BuyerKiosk\Demo\Controllers\DemoAdminController` (wraps admin pages) `[activity: backend-controller]`
- [ ] T3.5.2 Add demo admin routes: `routes/demo/admin.php` `[activity: backend-routing]`
- [ ] T3.5.3 Implement demo buy queue view with shadow merge `[activity: backend-controller]`
- [ ] T3.5.4 Implement demo workbook view with shadow merge `[activity: backend-controller]`
- [ ] T3.5.5 Add "Demo Environment" indicator banner to demo admin pages `[activity: frontend-template]`

#### P3.6 Session Cleanup Job `[component: taskengine]`
- [ ] T3.6.1 Create `BuyerKiosk\Demo\Jobs\DemoSessionCleanupJob` `[activity: backend-job]`
- [ ] T3.6.2 Implement expired session detection `[activity: backend-job]`
- [ ] T3.6.3 Implement shadow data purge for expired sessions `[activity: backend-job]`
- [ ] T3.6.4 Schedule cleanup job (runs hourly) `[activity: config]`

#### P3.7 Validate Phase 3
- [ ] T3.7.1 Run shadow table unit tests `[activity: run-tests]`
- [ ] T3.7.2 Run isolation integration tests `[activity: run-tests]`
- [ ] T3.7.3 Manual test: Complete a buy in demo → verify it appears `[activity: manual-test]`
- [ ] T3.7.4 Manual test: Second session doesn't see first session's buy `[activity: manual-test]`
- [ ] T3.7.5 Verify PRD acceptance criteria: Feature 5 `[activity: business-acceptance]`

---

### P4: Tour + Analytics + CTA

**Goal:** Flows.sh tour wiring + track events + capture sales intent.

**PRD Coverage:** Features 6, 7, 8, 9

**Dependency:** P3 complete (demo admin pages working)

#### P4.1 Prime Context
- [ ] T4.1.1 Read SDD Section: Flows.sh Integration (lines 675-682) `[activity: research]`
- [ ] T4.1.2 Read PRD: Interactive Guided Tour spec (lines 261-284) `[activity: research]`
- [ ] T4.1.3 Review Flows.sh SDK documentation `[activity: research]`

#### P4.2 Write Tests (TDD - Tests First)
- [ ] T4.2.1 Unit test: TourService::getProgress() `[activity: unit-test]`
- [ ] T4.2.2 Unit test: TourService::updateProgress() `[activity: unit-test]`
- [ ] T4.2.3 Unit test: AnalyticsService::track() `[activity: unit-test]`
- [ ] T4.2.4 Unit test: LeadRepository::createFromSession() `[activity: unit-test]`
- [ ] T4.2.5 Integration test: Analytics events persisted correctly `[activity: integration-test]`

#### P4.3 Implement Tour Integration `[component: frontend]`
- [ ] T4.3.1 Create `templates/themes/default/demo/partials/flows-init.html` `[activity: frontend-template]`
- [ ] T4.3.2 Create tour configuration JS: `public_html/js/demo/tour-config.js` `[activity: frontend-js]`
- [ ] T4.3.3 Define tour steps for Workbook section `[activity: frontend-js]`
- [ ] T4.3.4 Define tour steps for Buy Queue section `[activity: frontend-js]`
- [ ] T4.3.5 Define tour steps for Admin Dashboard section `[activity: frontend-js]`
- [ ] T4.3.6 Define tour steps for Events section `[activity: frontend-js]`
- [ ] T4.3.7 Define tour steps for Backstock section `[activity: frontend-js]`
- [ ] T4.3.8 Define tour steps for Scheduling section `[activity: frontend-js]`

#### P4.4 Implement Backend Tour Support `[component: backend]`
- [ ] T4.4.1 Create `BuyerKiosk\Demo\Services\TourService` `[activity: backend-service]`
- [ ] T4.4.2 Add tour progress to DemoSession model `[activity: backend-model]`
- [ ] T4.4.3 Create API endpoint: `POST /api/demo/tour/progress` `[ref: SDD/API; lines: 566-574]` `[activity: backend-api]`
- [ ] T4.4.4 Implement tour completion CTA trigger `[activity: backend-service]`

#### P4.5 Implement Analytics `[component: backend]`
- [ ] T4.5.1 Create `BuyerKiosk\Demo\Services\AnalyticsService` `[activity: backend-service]`
- [ ] T4.5.2 Create `BuyerKiosk\Demo\Repositories\LeadRepository` `[activity: backend-repository]`
- [ ] T4.5.3 Create API endpoint: `POST /api/demo/track` `[ref: SDD/API; lines: 552-561]` `[activity: backend-api]`
- [ ] T4.5.4 Implement tracking events from PRD (lines 300-311) `[activity: backend-service]`
- [ ] T4.5.5 Create analytics JS: `public_html/js/demo/analytics.js` `[activity: frontend-js]`

#### P4.6 Implement CTA + Lead Capture `[component: frontend]`
- [ ] T4.6.1 Create `templates/themes/default/demo/partials/cta-banner.html` `[activity: frontend-template]`
- [ ] T4.6.2 Create contact form template `[activity: frontend-template]`
- [ ] T4.6.3 Create API endpoint: `POST /api/demo/contact` `[ref: SDD/API; lines: 576-586]` `[activity: backend-api]`
- [ ] T4.6.4 Integrate CTA placement across demo admin pages `[activity: frontend-template]`

#### P4.7 QR Code Generation `[component: backend]`
- [ ] T4.7.1 Create static QR code asset (demo.buyerkiosk.com) `[activity: design]`
- [ ] T4.7.2 Implement event-specific QR code with source_qr_id tracking `[activity: backend-service]`
- [ ] T4.7.3 Create QR code generation utility (if internal) `[activity: backend-service]`

#### P4.8 Validate Phase 4
- [ ] T4.8.1 Run tour and analytics unit tests `[activity: run-tests]`
- [ ] T4.8.2 E2E test: Tour launches on first visit `[activity: manual-test]`
- [ ] T4.8.3 E2E test: Tour progress saves and resumes `[activity: manual-test]`
- [ ] T4.8.4 E2E test: Analytics events appear in database `[activity: manual-test]`
- [ ] T4.8.5 E2E test: Contact form creates lead with attribution `[activity: manual-test]`
- [ ] T4.8.6 Verify PRD acceptance criteria: Features 6, 7, 8, 9 `[activity: business-acceptance]`

---

### P5: Hardening + Ops (Post-MVP)

**Goal:** Production readiness, monitoring, and operational tooling.

**PRD Coverage:** Feature 10 (Demo Environment Dashboard)

**Dependency:** P4 complete (MVP functional)

#### P5.1 Demo Health Dashboard `[component: frontend]`
- [ ] T5.1.1 Create demo admin dashboard page `[activity: frontend-template]`
- [ ] T5.1.2 Implement active sessions count widget `[activity: backend-api]`
- [ ] T5.1.3 Implement simulation status widget `[activity: backend-api]`
- [ ] T5.1.4 Implement recent leads widget `[activity: backend-api]`
- [ ] T5.1.5 Add manual simulation reset button `[activity: backend-api]`

#### P5.2 Alerting + Monitoring `[component: ops]`
- [ ] T5.2.1 Add simulation failure alerts (via TaskEngine FailureNotifier) `[activity: config]`
- [ ] T5.2.2 Add email delivery failure alerts `[activity: config]`
- [ ] T5.2.3 Add session count monitoring `[activity: config]`
- [ ] T5.2.4 Add demo database size monitoring `[activity: config]`

#### P5.3 Data Retention `[component: database]`
- [ ] T5.3.1 Define analytics retention policy (90 days) `[activity: config]`
- [ ] T5.3.2 Define leads retention policy (indefinite for sales follow-up) `[activity: config]`
- [ ] T5.3.3 Create data cleanup job for old analytics `[activity: backend-job]`

#### P5.4 Documentation `[component: docs]`
- [ ] T5.4.1 Create demo deployment guide `[activity: documentation]`
- [ ] T5.4.2 Create demo operations runbook `[activity: documentation]`
- [ ] T5.4.3 Document QR code generation process `[activity: documentation]`

#### P5.5 Final Validation
- [ ] T5.5.1 Full E2E test: Conference attendee journey `[activity: manual-test]`
- [ ] T5.5.2 Load test: 50 concurrent demo sessions `[activity: performance-test]`
- [ ] T5.5.3 Security review: Token handling, session isolation `[activity: security-review]`
- [ ] T5.5.4 Verify all PRD acceptance criteria `[activity: business-acceptance]`

---

## Summary

| Phase | Tasks | PRD Features | Key Deliverables |
|-------|-------|--------------|------------------|
| P1 | 33 | 1, 2, 3, 8 | Magic link auth, concept selection, demo routes |
| P2 | 17 | 4 | Safe simulation, demo databases, TaskEngine config |
| P3 | 25 | 5 | Shadow tables, session isolation, cleanup jobs |
| P4 | 29 | 6, 7, 8, 9 | Flows.sh tour, analytics, CTAs, lead capture |
| P5 | 17 | 10 | Dashboard, monitoring, documentation |

**Total Tasks:** 121

**Parallel Opportunities:**
- P1.3 tests can run in parallel
- P3.3 tests can run in parallel
- P4.3 and P4.4 (frontend/backend tour) can run in parallel
- P4.5 and P4.6 (analytics/CTA) can run in parallel

**Critical Path:** P1 → P2 → P3 → P4 (sequential dependencies)
