# Production Deployment and Security Monitoring

## Current MVP readiness

The local MVP now includes an admin System Health screen with runtime, database, storage, Stripe readiness, webhook, delivery queue, upload execution guard, and deployment-readiness checks.

Open:

```text
http://localhost/zavvion-events/public/admin.html#health
```

## Before internet-facing deployment

- Set `APP_ENV=prod`.
- Set `APP_DEBUG=false`.
- Set `MVP_RUNTIME_SCHEMA_REPAIR=false` and run schema repair/migration commands explicitly during deployment.
- Replace `COOKIE_SECRET`, `QR_SIGNING_SECRET`, and `SMS_OTP_SIGNING_SECRET` with long random secrets outside Git.
- Keep `.env`, Composer archives, SQL files, backups, lock files, and timestamped backup artifacts such as `*.php.backup-before-*` blocked from public access.
- Serve over HTTPS only.
- Enable HSTS at the production reverse proxy or Apache vhost.
- Keep security headers enabled: CSP, `nosniff`, frame ancestor policy, referrer policy, permissions policy.
- Keep uploads under `public/uploads` protected by `.htaccess` so image files cannot execute as scripts.
- Configure alert notification delivery if operational alerts should leave the admin console:
  - `ALERT_NOTIFICATION_PROVIDER=log` for local/staging only.
  - `ALERT_NOTIFICATION_PROVIDER=http` with `ALERT_NOTIFICATION_HTTP_ENDPOINT` and `ALERT_NOTIFICATION_HTTP_BEARER_TOKEN` for a production email/SMS/on-call provider.
- Configure MFA email delivery separately from ticket delivery:
  - `MFA_MAIL_PROVIDER=log` for local/staging only.
  - `MFA_MAIL_PROVIDER=http` with `MFA_MAIL_HTTP_ENDPOINT` and `MFA_MAIL_HTTP_BEARER_TOKEN` for a production verification-email provider.
- Configure ticket delivery if customer email/SMS tickets should leave the local log:
  - `TICKET_DELIVERY_PROVIDER=log` for local/staging only.
  - `TICKET_DELIVERY_PROVIDER=http` with an HTTPS `TICKET_DELIVERY_HTTP_ENDPOINT` and a non-empty `TICKET_DELIVERY_HTTP_BEARER_TOKEN` for a production email/SMS delivery provider.
  - For the current production ticket email provider, set `TICKET_DELIVERY_HTTP_ENDPOINT=https://www.zavvionevents.com.techstak.co.uk/senMail/send` and place the bearer token in the deployed `.env` or host secret store, not in Git.
- Keep `CHECKOUT_GUEST_ENABLED=false` when customers must sign in before purchasing. Set it to `true` only if guest checkout is approved, and confirm buyer contact capture, fraud monitoring, ticket claiming, and support flows before launch.
- Configure finance export delivery if scheduled CSV exports should be sent outside the admin console:
  - `FINANCE_EXPORT_MAIL_PROVIDER=log` for local/staging only.
  - `FINANCE_EXPORT_MAIL_PROVIDER=http` with an HTTPS `FINANCE_EXPORT_MAIL_HTTP_ENDPOINT` and a non-empty `FINANCE_EXPORT_MAIL_HTTP_BEARER_TOKEN` for production export delivery.
- Move uploaded media to managed object storage/CDN after MVP validation. Set `MEDIA_STORAGE_DRIVER=cdn` or `object_storage` with an HTTPS `MEDIA_PUBLIC_BASE_URL`; production readiness warns if the app is still using local public uploads.
- Add daily database backups and restore drills.
- Add centralised application logs, web server logs, error alerts, and failed-login/rate-limit monitoring.

## Operational monitoring

Minimum production alerts:

- Checkout webhook failures or unprocessed webhooks.
- High login or checkout rate-limit failures.
- Delivery queue growth.
- Stale checkout drafts.
- Active public checkout seat holds past their 15-minute expiry and Box Office payment-link holds past the organiser-configured expiry.
- Database connection failures.
- Disk usage for uploads and runtime logs.
- Admin role/permission changes.

## Manual launch smoke checklist

1. Log in as platform admin.
2. Confirm System Health is not critical.
3. Upload a logo, homepage banner, event poster, and event hero image.
4. Confirm uploaded image metadata shows scan status and dimensions.
5. Create an organiser event, ticket type, and age policy.
6. Create a checkout draft.
7. Complete local mock payment or Stripe test payment.
8. Confirm order, ticket, QR, and scanner validation.
9. Export organiser orders and attendees.
10. Review audit logs for the actions above.

## Scheduled jobs

Run `php bin/expire-seat-holds` every minute on production and staging. This releases abandoned public reserved seats after the 15-minute hold window and cancels expired unpaid Box Office payment-link drafts, even when no customer is currently loading the event page.

Use `docs/schema.sql` or the Yii migration path only during controlled maintenance/deployment windows while the Yii 3 migration runner is still being completed. Runtime schema repair should stay disabled for internet-facing production traffic.

Run `php bin/send-system-alert-notifications` every minute in staging/production after the platform alert notification policy is enabled. The command processes the durable `system_alert_notifications` outbox and fails rather than pretending to send when the local `log` provider is used in production.

Run `php bin/send-ticket-deliveries --limit=100` every minute in staging/production after configuring a real ticket email/SMS provider. The command processes queued `email_sms_delivery_logs` for email and SMS ticket delivery and fails rather than pretending to send when the local `log` provider is used in production. The HTTP provider also refuses non-HTTPS endpoints or missing bearer tokens in production.

Run `php bin/send-finance-export-deliveries --limit=100` after scheduled export generation if finance CSVs should be delivered to admins by a provider. The HTTP provider refuses non-HTTPS endpoints or missing bearer tokens in production.
