# Zavvion Events MVP Implementation Notes

Last updated: 2026-05-03

## Runtime Strategy

The working local MVP keeps the custom `public/index.php` router because it already serves the DB-backed API and prototype safely. Full Yii 3 runtime conversion remains a planned migration, not a blocker.

Current router additions:

- `public/mvp.php` contains dependency-light MVP API workflows.
- `public/index.php` includes `public/mvp.php` and dispatches MVP endpoints before legacy event/checkout endpoints.
- Existing public event APIs remain stable.
- Runtime schema repair is enabled by default for local development and can be disabled with `MVP_RUNTIME_SCHEMA_REPAIR=false`; use `docs/schema.sql` or the Yii migration path for controlled maintenance/deployment changes.

## Backend-Backed MVP Workflows

- Session auth: login, logout, current user.
- Hardened session cookie policy, inactive-user session invalidation, and CSRF protection for checkout, seat holds, account, admin, organiser, media, and scanner device writes.
- RBAC: role checks from `users`, `roles`, and `user_roles`; demo role repair is idempotent when `user_roles` is empty.
- Admin summary: database counts and audit activity.
- Organiser summary: organiser-scoped event list.
- Site settings/theme draft save and read.
- Media upload metadata with safe local file storage under `public/uploads`.
- Privacy request creation.
- Checkout draft creation with Stripe-aware, fail-closed payment-mode response.
- Fifteen-minute reserved-seat holds with customer-facing countdown, automatic expiry release, a scheduler-safe expiry script, and server-side double-booking guards.
- Local mock checkout success simulation only when explicitly enabled in local/dev/test mode.
- Free/complimentary checkout confirmation through `checkout/confirm-free` for server-calculated zero-total drafts.
- Order and ticket creation after Stripe webhook, explicitly-enabled local mock success, or zero-total free confirmation.
- Signed QR token generation.
- Scanner validation and check-in.
- Basic product and promo-code creation endpoints.

## Stripe Status

`POST /api/v1/checkout/session` now returns:

- `payment_mode: payment_unavailable` when Stripe credentials are missing and local mock payment is not explicitly enabled.
- `payment_mode: local_mock` only when `PAYMENT_MOCK_ENABLED=true` in a local/dev/test environment.
- `payment_mode: free_checkout` when the server-calculated total is zero.
- `payment_mode: stripe_checkout` when a real `sk_test_...` key is configured and Stripe session creation succeeds.

Real Stripe testing still requires:

- Valid `STRIPE_SECRET_KEY`.
- Valid `STRIPE_WEBHOOK_SECRET`.
- Webhook forwarding to `/api/v1/webhooks/stripe`.
- Connect account decisions for production organiser-gross transfers, platform service fees, and organiser settlement.

## Media Upload Status

Local MVP supports JPEG, PNG, and WebP uploads up to 5MB.

Implemented:

- Site logo upload endpoint.
- Homepage banner upload endpoint.
- Event poster/hero/gallery upload endpoint shape.
- Safe random filenames.
- Metadata in `media_assets`.
- Event media link records in `event_media` when owner is an event.
- Alt text capture.

Production TODO:

- Malware scanning.
- Image resizing and cropping persistence.
- CDN/object storage.
- Private staging area before publication.
- Stronger moderation and image policy controls.

## Yii 3 Migration Path

Next migration step should move the current router functions into:

- Controllers under `src/Api` and interface modules.
- Services under `src/Auth`, `src/Checkout`, `src/Payment`, `src/Scanner`, `src/Compliance`, and `src/Admin`.
- Middleware for sessions, CSRF, auth, permissions, and rate limiting.
- Console commands for schema repair, seeding, seat-hold expiry, checkout expiry, and media cleanup.

Do not break the currently working local endpoints during the migration.
