5 phases — 1 calendar day each · 🚩 demo at end of each day · 🚀 production cutover Day 5
What's demoable at the end of each day · 23:59 UAE time
| Day | Phase | Demoable Outcome | Acceptance Gate | Story Set |
|---|---|---|---|---|
| DAY 1 · Fri May 8 | Foundation | Login as Super Admin → switch instance brand from HXIQ default to a custom one → create project → tag with category → author 9 PRD §5.4 question types in the library. CI green. 3-container compose healthy on staging. | run-phase-validation.sh 01 exits 0 (10 gates green: typecheck, lint, schema, vitest 80%+, containers healthy, health endpoint, e2e, axe, demo replay, acceptance verifier) |
FND-001..003 · INF-001 · OPS-001 · AUTH-001..006 · BRD-001..003 · PRJ-001 · CAT-001 · QL-001..002 |
| DAY 2 · Mon May 11 | Builder + Respondent | Build a 5-stage questionnaire (Pre-arrival → Arrival → During-stay → Workshop → Post-stay) with branching rules, publish first stage, scan QR on a phone, complete a stage as a respondent with PIN identity, request forgot-PIN 6-digit code, set new PIN, resume on second device. | run-phase-validation.sh 02 exits 0 · respondent flow E2E on 375×812 phone viewport with axe = 0 violations · forgot-PIN replay returns "already redeemed" |
BLD-001..004 · BRN-001..003 · LIF-001..003 · RSP-001..009 · PIN-001..005 |
| DAY 3 · Tue May 12 | Distribution + Identity | Bulk-import 50 ENVI Paje guests via CSV → assign 4-digit guest codes → custom fields populated (Stay type, Family type, Villa, Arrival date) → email Pre-arrival stage to all 50 with merge tags → watch Rule A/B/C/D/E reminders fire on schedule → Mailpit shows 50 deliveries. | run-phase-validation.sh 03 exits 0 · 50 SES sends with bounce/complaint webhook · Rule A frequency cap holds (1 per stage) · Rule E hour-bucket dedup verified |
DST-001..005 · CF-001..005 · GC-001..004 · IMP-001..004 · EML-001..009 · DLO-001 · REM-001..006 |
| DAY 4 · Wed May 13 | Reporting + AI | Open dashboard, filter by guest code + custom field + date range, see per-category aggregated score, time-series with 7-day rolling avg, NPS (% promoters − % detractors), export branded PDF, ask the conversational assistant "How did guests feel about food in the last 15 days?" → streamed answer with quoted excerpts and confidence indicator. | run-phase-validation.sh 04 exits 0 · all 8 chart components render · AI circuit breaker test passes · saved-report stale indicator + permalink share work · privacy export ZIP downloads with all required panels |
RPT-001..012 · EXP-001..004 · AI-001..012 · CAS-001..005 |
| DAY 5 · Thu May 14 | Hardening + Launch 🚀 | ENVI Paje instance live at surveys.envipaje.com · TLS green padlock (Let's Encrypt) · all security headers · Lighthouse perf ≥ 90, a11y = 100 · ENVI Paje brand applied · 50-guest roster imported · Pre-arrival emails sent · real test guest submits a real response on production · admin sees it on the dashboard with AI commentary · hand-off complete. |
run-phase-validation.sh 05 exits 0 · TLS verified end-to-end · backup-restore drill green · all retention crons scheduled · ENVI Paje contact receives credentials over secure channel · 48h hypercare window opens |
HRD-001..004 · INF-002..006 · OPS-002..010 · RET-001..004 · LCH-001..006 · TST-005 |
Third-party services, IAM access, API keys, and accounts the human needs to provide BEFORE each phase starts
| Phase | Service / Provider | What's Needed | Owner | Cost Model | Lead Time |
|---|---|---|---|---|---|
| DAY 0 (pre-flight) | AWS Account · me-central-1 | Root account or admin IAM user with EC2, VPC, IAM, Route 53, S3, SES, KMS, SNS, SSM Parameter Store, CloudWatch permissions. Generate access key + secret for `.env.deploy`. | Apptology CTO | Pay-per-use | Same day · 5 min |
| DAY 0 (pre-flight) | AWS SES Production Access | Submit production-access form on SES console with justification ("Per-instance transactional email for HXIQ survey platform"). Sandbox limits to verified-only addresses; production access lifts the cap. Sending domain (e.g. `surveys.envipaje.com`) verified with DKIM + SPF + DMARC via the `verify-ses-domain.sh` script. | Agent (script-driven; AWS approves) | Free signup | ~24h AWS approval — submit Day 0 morning |
| DAY 0 (pre-flight) | Cloudflare · DNS + Turnstile | Cloudflare account with the production domain added as a Zone. API token scoped to Zone:DNS:Edit + Account:Turnstile:Edit. Turnstile site key + secret key for the respondent landing's bot prevention. |
Apptology CTO | Free tier covers all v1 needs | Same day · 10 min |
| DAY 0 (pre-flight) | Anthropic API · Claude 3 Haiku | Anthropic API key (paid). Used for AI insights waves 1–4 and the conversational assistant. Default model: claude-3-haiku-20240307 at $0.25/M input + $1.25/M output. Pilot-volume cost: ~$3–$8/month. Billed to client (Rob). |
Client (Rob) | ~$3-$8/month · client-billed | Client provides key by Day 0 |
| DAY 0 (pre-flight) | Sentry · Error tracking | Sentry account + org auth token (used by CI to upload sourcemaps and to create the per-instance project hxiq-{instance-slug}). Billed to client (Rob). Either: (a) client signs up for a Sentry plan, or (b) the agent provisions a self-hosted Sentry on the same EC2 host (free, +~256MB RAM). |
Client (Rob) | Client-billed (or self-hosted free) | Client decides + provides token by Day 0 |
| DAY 0 (pre-flight) | GitHub · Apptologyteam/hxiq |
Repo at https://github.com/Apptologyteam/hxiq with default branch main. GitHub CLI (gh) authenticated on the agent's machine. CI runs on GitHub Actions free tier (2,000 min/month). |
Apptology CTO | Free tier | Same day · 5 min |
| DAY 0 (pre-flight) | Production Domain | Domain or subdomain for the instance (e.g. surveys.envipaje.com). Either Apptology's domain delegated to Cloudflare, or ENVI Paje's domain with a delegated CNAME. |
ENVI Paje team | $10–20/yr (separate) | Same day if delegated CNAME · up to 48h for full DNS |
| DAY 1 | Brand Assets · HXIQ + ENVI Paje | HXIQ default brand assets in `brand/` folder (logo SVG/PNG, mark, app icon, favicon — ~10 files per HXIQ Brand Guidelines §2.3). Agent falls back to a placeholder gradient if missing. ENVI Paje project-level brand can land any time before Day 5. | Apptology design / ENVI Paje | No external cost | Day 1 morning (HXIQ) · Day 5 morning (ENVI Paje) |
| DAY 3 | SES Sender Domain Verified | Day 0 SES production-access request must be approved by Day 3 morning. Sender domain `noreply@surveys.envipaje.com` verified in SES with DKIM/SPF/DMARC passing. Without this, Day 3 cannot send real emails — falls back to Mailpit only. | AWS SES | ~$0.10 per 1,000 emails | Day 3 morning hard cutoff |
| DAY 3 | ENVI Paje Guest Roster | 20–50-row CSV matching the sample format from PRD §5.10 (first_name, last_name, email, guest_code, Stay type, Guest profile, Interest profile, Nationality, Villa number, Arrival date, Departure date). Used for the import demo on Day 3 + the real launch on Day 5. | ENVI Paje team | N/A | Day 3 morning (latest) |
| DAY 4 | Anthropic API quota | Client's (Rob's) Anthropic key must be active on Day 4 morning. Daily $5 / monthly $100 budget caps configured per instance. Circuit breaker engages after 5 consecutive provider failures (graceful degrade — dashboard charts still work). | Client (Rob) | ~$3-8/mo · client-billed | Client provides key by Day 0 |
| DAY 5 | ENVI Paje Brand Assets | Logo SVG, primary + accent hex codes, hero/cover image, welcome copy, thank-you copy. Project brand applied via Super Admin's Project → Branding screen. Without this, the agent uses HXIQ default brand and ENVI Paje team can swap later (no code changes). | ENVI Paje team | N/A | Day 5 morning (latest) |
| DAY 5 | Question Bank — ENVI Paje | Per-stage questionnaire spec doc — questions to ask in Pre-arrival, Arrival, During-stay, Workshop, Post-stay stages. Format: free-text spec or filled-in CSV; agent transcribes into the Question Library. | Apptology operator | N/A | Day 5 morning (latest) |
| DAY 5 | DNS A Record · Cloudflare | A record for the production domain (e.g. `surveys.envipaje.com`) pointing to the EC2 elastic IP that Terraform provisions on Day 5 morning. Automated by the Cloudflare Terraform provider — no manual click needed if Cloudflare token has Zone:DNS:Edit. | Agent (Terraform-driven) | Cloudflare free tier | 5 min · TTL 300s · global propagation typically < 30 min |
| DAY 5 | Operator Admin Email | One email address that becomes the Super Admin user on the live instance. Credentials sent via secure channel (Signal / 1Password / SSE) — never email. Agent generates a temp password; Super Admin forced to change on first login. | Apptology operator | N/A | Day 5 evening (during hand-off) |
| DAY 5 | SES Email-Sending Approval · ENVI Paje | ENVI Paje must explicitly authorise transactional email from `noreply@surveys.envipaje.com` (or alt). Verified by sending the first real Pre-arrival email on Day 5 with bounce/complaint rates within SES policy. | ENVI Paje team | N/A | Confirmation by Day 5 morning |
20 production risks documented · all with concrete mitigations
| Risk | Phase | Severity | Mitigation |
|---|---|---|---|
| AWS SES production-access not approved by Day 3 | DAY 3 | Critical | Submit Day 0 morning. AWS approves within ~24h. Hard cutoff: Day 3 morning. If not approved, fall back to Mailpit-only Day 3 demo and escalate to AWS support. |
| Anthropic API outage (full provider down) | DAY 4 | High | Circuit breaker opens after 5 consecutive failures within 60s. Open for 5 min, then half-open. AI panels gracefully show "temporarily unavailable" pill; charts still render. |
| Cloudflare DNS propagation slow | DAY 5 | High | TTL 300s. Multi-geo `dig` test from cloud shells. If > 2h propagation, escalate to Cloudflare support. Ansible has "wait for DNS" gate before issuing certbot. |
| Let's Encrypt rate limits during testing | DAY 5 | Medium | Use `--staging` flag during all pre-launch testing. Production cert issued exactly once, with 5x retry + 60s back-off if first issuance fails. |
| SES bounce / spam complaint storm | DAY 3 | High | CloudWatch alarms at 0.05% complaint rate (warn) and 2% bounce rate (warn). Worker reads `email-paused` SSM flag to halt sends within 60s of alarm. |
| Disk full on EC2 t3.large (single host) | DAY 5 | High | Docker log driver capped at 50MB × 5 files per container. Beszel alerts at 75% disk. Export TTL deletes old artifacts. Runbook: `docker system prune -af --volumes`. |
| Worker container OOM during AI / PDF generation | DAY 4 | Medium | Worker `mem_limit: 1.5g` + `mem_reservation: 768m`. OOM-kill auto-restarts; BullMQ retries the job. Beszel alarm if > 3 worker restarts / 24h. |
| PII leak via AI prompts | DAY 4 | Critical | Every prompt passes `compromise` NER + regex redactor before reaching Anthropic. Identity fields (name, email) NEVER included; only respondent CUID. Redaction logged with original-text hash. |
| PIN brute-force | DAY 2 | Medium | Token-bucket rate limit (6 attempts / 15 min) + DB-persisted PinLockout (30 min) + 6-digit forgot-PIN code recovery (15-min TTL, 5-attempt cap, 3 codes / email / hour). |
| Backup restore drift after Day 5 | DAY 5 | Medium | Weekly cron `0 5 * * 0` runs `restore-drill.ts` — spins up temp Postgres, restores latest pg_dump, asserts row count > 0, tears down. Failures raise Sentry warning. |