# Zavvion Events MVP Launch Handoff

Launch target: Monday 11 May 2026.

This handoff is for the senior developer or launch owner taking the MVP through final integration, QA, deployment, and rollback planning. It is documentation only; it does not claim that production Stripe, SMS, email, CDN, malware scanning, or live traffic have been tested.

For the concise handover evidence pack, see `docs/human-architect-handoff.md`.

## Current MVP Scope

The MVP currently includes:

- Auth, sessions, RBAC, organiser staff roles, CSRF protection, rate limits, password reset, email verification-ready flows, MFA APIs, and phone OTP policy controls.
- Public event discovery, event details, organiser event/venue/ticket setup, age policies, reusable seat maps, and event publishing readiness checks.
- Reserved seats with 15-minute holds, checkout drafts, adult/child ticket validation, ticket quantity and reserved-seat matching, promo codes, donations, merchandise, fee/tax calculation, and inventory checks.
- Stripe Checkout/Connect adapter path with direct-charge/application-fee configuration, webhook handling, and fail-closed payment mode selection. Real Stripe test credentials and webhook delivery still need final validation.
- Free checkout confirmation for zero-total orders and local mock completion only when explicitly enabled in local/dev/test.
- QR tickets, customer wallet, pass-ready JSON, printable ticket page, scanner device registration, online validation, offline manifest, and offline sync conflict handling.
- Customer-facing pages require platform Terms and Conditions acceptance before continuing, and checkout/legal copy states that organisers are responsible for refund decisions and approved refund processing when organisers collect payment.
- Admin themes/skins, public branding, media upload metadata, media scan/rescan, feature gates, finance/tax, settlements, compliance, privacy requests, system health, alerts, and deployment readiness checks.

## Server Setup Checklist

- Use PHP 8.2 or newer.
- Install Composer dependencies with the lock file.
- Configure MySQL and create the production/staging database.
- For local/staging handover installs, run `php bin/install-database --fresh --yes`; see `docs/database-install.md`.
- Point the web server document root to `public/` or route requests to `public/index.php` while preserving static file serving for HTML, CSS, JS, images, and uploads.
- Serve only over HTTPS for staging/production.
- Keep `.env`, backups, SQL dumps, Composer archives, lock files where required by policy, and runtime files out of public web access.
- Ensure `public/uploads` cannot execute scripts.
- Set filesystem permissions so the app can write only the required runtime/upload locations.
- Configure backups before launch and complete at least one restore drill.
- Configure central application, PHP, database, and web server logs.
- Confirm the server timezone and scheduled task timezone match the launch team's operating plan.

## `.env` Checklist

Production or launch-staging values must be reviewed explicitly:

- `APP_ENV=prod` for production; use a separate staging value for rehearsals.
- `APP_DEBUG=false`.
- `APP_LAUNCH_PROFILE=ticket-selling-v1` for the first commercial light package.
- `APP_URL` set to the public HTTPS base URL.
- `APP_FORCE_HTTPS=true` or equivalent reverse-proxy HTTPS enforcement.
- `SESSION_NAME`, `SESSION_SAME_SITE`, `SESSION_COOKIE_PATH`, and `SESSION_COOKIE_DOMAIN` reviewed for the deployed hostname.
- `MVP_RUNTIME_SCHEMA_REPAIR=false`; use controlled schema maintenance instead of request-time repair.
- `DB_DSN`, `DB_USERNAME`, and `DB_PASSWORD` set to least-privilege database credentials.
- `COOKIE_SECRET`, `QR_SIGNING_SECRET`, `MFA_OTP_SECRET`, and `SMS_OTP_SIGNING_SECRET` replaced with long random production secrets.
- `PAYMENT_MOCK_ENABLED=false` outside local/dev/test.
- `STRIPE_MODE=test` until real Stripe test checkout, webhook, and reconciliation are signed off.
- `STRIPE_SECRET_KEY`, `STRIPE_PUBLISHABLE_KEY`, `STRIPE_WEBHOOK_SECRET`, `STRIPE_PLATFORM_ACCOUNT_ID`, and `STRIPE_CONNECT_CHARGE_MODEL=direct_charge` reviewed by the payment owner.
- `SMS_OTP_PROVIDER`, `TICKET_DELIVERY_PROVIDER`, `FINANCE_EXPORT_MAIL_PROVIDER`, and `ALERT_NOTIFICATION_PROVIDER` set to production-safe providers before claiming outbound delivery is live.
- `MEDIA_MALWARE_SCAN_REQUIRED=true` and `CLAMAV_CLAMSCAN_PATH` configured before internet-facing media uploads.
- `MEDIA_STORAGE_DRIVER` and `MEDIA_PUBLIC_BASE_URL` reviewed; local public uploads are an MVP fallback, not the preferred commercial production storage model.
- `PRIVACY_CONTACT_EMAIL` set to a monitored address.

## Stripe Checklist

Stripe is code-ready, not launch-proven until these are completed:

- Use Stripe test mode first.
- Confirm `stripe/stripe-php` is installed from Composer.
- Configure valid test secret and publishable keys.
- Configure webhook endpoint for `POST /api/v1/webhooks/stripe`.
- Configure `STRIPE_WEBHOOK_SECRET` from the exact endpoint used by the environment.
- Confirm `STRIPE_CONNECT_CHARGE_MODEL=direct_charge` unless the payment owner signs off a reviewed merchant-of-record migration to another charge model.
- Create or connect an organiser Stripe connected account that is onboarding-complete, charges-enabled, and transfer-ready.
- Complete one paid test checkout from event page to hosted Stripe Checkout.
- Confirm the Stripe webhook, not the browser redirect alone, marks checkout paid and issues tickets.
- Confirm expired or failed checkout sessions release reserved seats.
- Confirm platform fee, organiser gross, tax, payment record, ledger, and settlement views reconcile for the test order.
- Confirm no live keys are used before written go-live approval.

## Scheduler Commands

Use the full PHP path on Windows/XAMPP if `php` is not on `PATH`.

Run every minute in staging/production:

```powershell
php bin/expire-seat-holds
php bin/send-system-alert-notifications
php bin/send-ticket-deliveries --limit=100
```

Run on the finance export schedule agreed by the business:

```powershell
php bin/run-finance-exports
php bin/send-finance-export-deliveries --limit=100
```

Run periodically or during launch readiness windows:

```powershell
php bin/sync-ticket-inventory
php bin/rescan-media-assets --force --limit=100
php bin/apply-media-retention --limit=100
```

Readiness commands:

```powershell
php bin/check-deployment-readiness
php bin/check-production-launch --allow-warnings
php bin/check-stripe-readiness
php bin/check-local-live-run
php bin/check-mvp-smoke --base-url=http://localhost/zavvion-events/public
```

For the real production go/no-go, prefer `php bin/check-production-launch` without `--allow-warnings` unless the launch owner has accepted every warning in writing.

## Launch Rooms

Assign named owners before launch:

- Launch lead: final go/no-go authority.
- Backend lead: PHP/API/database/schema/scheduler readiness.
- Frontend lead: mobile, browser, and checkout UI walkthrough.
- Payments owner: Stripe account, webhook, Connect, reconciliation, and keys.
- Operations owner: server, DNS, TLS, logs, backups, and rollback.
- Compliance owner: privacy contact, consent text, ticket terms, age policies, and refund disclaimers.
- Support owner: customer support inbox, organiser contact path, incident notes, and launch FAQ.

## Rollback and Fallback

Before launch:

- Keep the old site deployable and DNS-ready.
- Snapshot the database before final launch rehearsal and again before production cutover.
- Preserve the previous web root or release artifact.
- Record DNS TTLs and deployment switch steps.
- Confirm who can revert DNS, web server config, or application release.

Fallback options:

- If the new site fails before orders are taken, route traffic back to the old site.
- If checkout is unsafe, disable paid checkout and leave discovery/event information live only if the launch owner accepts that reduced mode.
- If Stripe webhook validation fails, do not issue production paid tickets manually without a reconciliation process.
- If scanner validation fails on event day, use the exported attendee/order list as a manual fallback and reconcile scan logs later.
- If media processing fails, use pre-approved static images and disable further uploads until scanning/storage is fixed.

## Production Hardening Warnings

Do not describe the MVP as fully production-hardened until these are done:

- Real Stripe test account, connected account, webhook, fee, refund policy, and reconciliation validation.
- Real outbound delivery provider for email/SMS ticket delivery, finance exports, alerts, and OTP if those are part of launch scope.
- Managed malware scanning and production media storage/CDN.
- Real-device mobile and scanner QA.
- Database backup and restore drill.
- Load/performance checks for event detail, checkout, seat holds, scanner validation, and admin finance views.
- Review of public legal copy: privacy, consent, refund, cancellation, age policy, ticket terms, and organiser responsibilities.
- Monitoring and alert routing for payment, webhook, delivery, scan, media, and database failures.

## Known Deferrals

- Full Yii 3 controller/repository migration from the MVP router.
- Live Stripe disputes/refunds and deeper payout reconciliation beyond current MVP settlement review.
- Production SMTP/SMS/on-call providers unless configured during launch.
- CDN/object-storage migration if launch uses local public uploads.
- Broader browser QR library for scanner devices that lack native `BarcodeDetector`.
- Structured family-ticket bundle rules beyond current MVP validation.
- Full i18n.
- Season passes and advanced organiser commercial workflows.
