# Zavvion Events - Claude Code Audit Brief

Date: 2026-05-22

Purpose: provide Claude Code, or another senior reviewer, with enough project, workflow, and codebase context to critically audit Zavvion Events for logic integrity, workflow integrity, payment safety, privacy, permissions, and MVP launch readiness.

## 1. Codebase To Review

Primary local working copy:

```text
C:\Users\chama\Documents\ZavvionEvents\zavvion-events
```

Local XAMPP served copy:

```text
C:\xampp\htdocs\zavvion-events
```

Local base URL:

```text
http://localhost/zavvion-events/public/
```

GitHub repository:

```text
https://github.com/gayanck/ZavvionEvents
```

Current local branch observed during this pass:

```text
codex-mvp-audit-readiness-pass
```

Important: the local working copy may contain newer MVP changes than GitHub if not pushed. Claude should first check `git status`, current branch, and recent commits, then confirm whether it is auditing the local working copy or the GitHub branch.

## 2. Product Summary

Zavvion Events is an event ticketing and event operations platform. It supports:

- public event discovery;
- event details with posters, banners, merchandise, donations, promo codes, age rules, and reserved seating;
- public checkout through Stripe-ready online payment only;
- 15-minute server-enforced seat holds;
- QR ticket issuing only after trusted payment confirmation, safe local mock confirmation, free order confirmation, or recorded box-office payment;
- customer ticket wallet;
- organiser event, venue, ticket, product, staff, media, marketing, finance, and box-office operations;
- cashier counter sales for cash or external card terminal records;
- scanner validation for QR tickets;
- platform admin site builder, skins/themes, fees, taxes, reporting, audit, privacy, feature gates, and settings.

The project started as a Yii 3-oriented PHP application, but the current MVP uses a custom `public/index.php` router and a large `public/mvp.php` dispatch/handler layer. Full Yii 3 controller migration is intentionally post-MVP unless it can be done without risking the working MVP.

## 3. Stack And Runtime

- PHP 8+
- Yii 3-oriented packages and structure, but current API runtime is custom PHP routing
- MySQL via XAMPP
- Apache via XAMPP
- Vanilla JavaScript
- Bootstrap/CSS-style responsive UI
- Composer
- Local `.env` for DB and external settings

Default local database:

```text
Database: zavvion_events
Host: 127.0.0.1
Port: 3306
Username: root
Password: blank
```

Known local DSN:

```text
mysql:host=127.0.0.1;port=3306;dbname=zavvion_events;charset=utf8mb4
```

## 4. Demo Accounts

All seeded demo accounts use:

```text
ChangeMe123!
```

Accounts:

```text
admin@zavvion.test                 platform_super_admin
platform.admin@zavvion.test        platform_admin
organiser@zavvion.test             organiser_owner
organiser.admin@zavvion.test       organiser_admin
event.manager@zavvion.test         event_manager
cashier@zavvion.test               cashier
scanner@zavvion.test               ticket_scanner
customer@zavvion.test              customer
```

The role profile test page is:

```text
http://localhost/zavvion-events/public/mvp-profiles.html
```

## 5. Important Entry Points

### PHP

```text
public/index.php                         Main public/API entry point
public/mvp.php                           MVP API routes, runtime schema repair, auth, workflows
src/Application/PageController.php        Page routing helpers
src/Auth/*                                Auth, permissions, roles
src/Checkout/*                            Checkout calculation, drafts, rule resolution
src/Fee/*                                 Platform fee rule model/calculation/creation
src/Tax/*                                 Tax calculation/rules
src/SeatMap/*                             Seat map logic
src/Ticket/*                              Ticket types, ticket passes, QR/ticket handling
src/Payment/*                             Payment/webhook state transitions
src/Stripe/*                              Stripe readiness/adapters
src/BoxOffice/*                           Counter payment policy
src/Finance/*                            Reports and integrity helpers
src/Organiser/*                           Organiser staff/features
src/Event/*                               Event create/update/regional settings
src/Media/*                               Media metadata, scanning, retention
src/Security/*                            CSRF and related safety helpers
```

### Frontend

```text
public/home.html                         Public home
public/events.html                       Public listing
public/event.html                        Event detail and checkout basket
public/checkout.html                     Checkout page/panel
public/account.html                      Customer account/ticket wallet
public/login.html                        Session login/reset
public/organiser.html                    Organiser console
public/admin.html                        Platform admin console
public/scanner.html                      Scanner console
public/mvp-profiles.html                 No-login role showcase/test harness
public/theme-gallery.html                Skin/theme gallery
public/assets/js/zavvion-ui.js           Shared API client and UI helpers
public/assets/js/admin-page.js           Admin console behaviour
public/assets/js/organiser-page.js       Organiser console behaviour
public/assets/js/event-page.js           Event detail, basket, seats
public/assets/js/events-page.js          Event listing/search/filter
public/assets/js/mvp-profiles-page.js    Role profile test page
public/assets/css/zavvion-ui.css         Main design system CSS
public/assets/css/launch-skins.css       Skin catalogue styling
```

### Database And Scripts

```text
docs/schema.sql                          Main schema export
migrations/*.php                         Yii-style migration/seed files
bin/install-database                     Local DB installer
bin/check-mvp-smoke                      Smoke check script
bin/check-local-live-run                 Local live-run check script
bin/check-stripe-readiness               Stripe readiness check
bin/check-deployment-readiness           Deployment readiness check
bin/check-frontend-links                 Frontend link checker
```

## 6. Core Business Rules To Audit

### Public online checkout

- Public online customers must not be offered cash payment.
- Online public tickets must only be issued after trusted Stripe webhook success, explicit safe local mock success, free order confirmation, or equivalent trusted server-side confirmation.
- Browser redirect alone must never mark an order paid.
- Server calculates totals; frontend totals are display-only.
- Customer must accept terms and conditions.
- Customer email or phone is required where configured.
- Event currency comes from the server event record.

### Box office / cashier checkout

- Cash and external card terminal are counter-only methods.
- Cashier, organiser admin, organiser owner, and permitted event manager roles can record counter sales according to feature gates and permissions.
- Counter sales must record cashier user, event, ticket type, seats if reserved, amount, currency, customer contact if provided, payment method, timestamp, and audit entry.
- QR tickets may be issued after counter payment is recorded.
- Public customers must not see counter payment methods.

### Seat holds and double booking

- Reserved seats are held for 15 minutes from the latest server hold creation/update, not 15 minutes per ticket multiplied together.
- Expired or abandoned holds release seats.
- Server must prevent double booking with DB constraints/transactions and current status checks.
- Public UI must show the 15-minute hold message/countdown.
- Ticket quantity and selected reserved seats must match.

### Ticket model

- Reusable ticket catalogue defines ticket categories and defaults without event-specific prices.
- Event-specific ticket allocation sets price, quantity, age range, limits, terms, and active state.
- Supported categories include adult, child, infant, student, senior, family, carer, companion, VIP, general, and custom.
- Child tickets can require an adult ticket.
- Family bundles are deferred as structured bundles; currently they can be represented as a ticket type with description.

### Fees and taxes

- Platform fees are server-side.
- Current fee policy model after 2026-05-22 update:
  - one active global platform fee policy per country;
  - one active event-specific override per event;
  - no priority/winner logic;
  - no organiser/category fee overrides in the MVP UI;
  - conflicting active policies must be rejected by API and repaired/deactivated safely where legacy duplicates exist.
- Event-specific fee policies use the event country and currency.
- Global policies are country-based and store their currency for minor-unit amounts.
- Taxes remain configurable separately by country/component.
- Reports must not merge currencies without a real exchange-rate system.

### Privacy and customer data

- Platform admin can see customer, visitor, checkout capture, and compliance details.
- Organisers receive operational/finance summaries only unless explicitly permitted.
- Organisers must not receive full customer mailing lists.
- Scanner/cashier should see only task-specific details.
- Sensitive actions should be audit logged.

### Roles and menus

- Menus should hide unavailable functionality for each role.
- API routes must enforce server-side permissions; hidden menu items alone are not security.
- Platform super admin must not be lockable out of critical permissions.
- Same staff email can have multiple additive roles, for example cashier and scanner.
- Organiser admin and event manager may have cashier/scanner operational abilities where policy permits, but finance/marketing/admin access should follow permissions and feature gates.

### International event settings

Each event may define:

- city;
- country code;
- currency code;
- timezone;
- locale;
- date style;
- time style;
- address display options;
- public online payment enabled;
- counter cash enabled;
- counter card/external terminal enabled.

Event-facing date/time and money display should use event settings.

## 7. Primary User Workflows To Audit

### Workflow A: Public visitor buys reserved-seat ticket

1. Visitor opens `home.html` or `events.html`.
2. Listing loads DB-backed events from `GET /api/v1/events`.
3. Visitor filters/searches events.
4. Visitor opens `event.html?slug=demo-gala`.
5. Detail loads from `GET /api/v1/events/demo-gala`.
6. Visitor accepts terms/privacy where required.
7. Visitor selects one or more seats.
8. Server creates/updates a 15-minute seat hold.
9. Visitor assigns adult/child/etc ticket type to each selected seat.
10. Basket validates seat count equals ticket quantity.
11. Visitor may add merchandise, promo code, and donation.
12. Checkout draft/session is posted to `POST /api/v1/checkout/session`.
13. Server recalculates total, currency, tax, fees, age rules, promo rules, and seat rules.
14. If Stripe is configured, server should return a Stripe checkout/payment response.
15. If Stripe is not configured locally, server returns safe mock/local checkout status.
16. Paid tickets are issued only after trusted confirmation/mock/free flow.
17. QR ticket appears in wallet/account.
18. Scanner can validate QR once and prevent duplicate check-in.

Audit risks:

- frontend total trust;
- cash option leaking to public checkout;
- browser redirect marking order paid;
- seat hold expiry or double booking race;
- child ticket without adult;
- stale seat availability after abandoned basket;
- currency mismatch between event and order/payment.

### Workflow B: Registered customer account

1. Customer logs in via `login.html`.
2. Customer opens `account.html`.
3. Account loads current user, ticket wallet, order history, support/privacy actions.
4. Customer can request export/delete/support actions according to policy.

Audit risks:

- customers seeing other customer tickets;
- stale or unverified QR tokens;
- unsafe account deletion/export handling;
- session handling and CSRF.

### Workflow C: Organiser onboarding and manual approval

1. Organiser submits application.
2. Platform admin sees applications in `admin.html#organisers`.
3. Admin manually approves, freezes, disables, or reviews KYC status.
4. Approved organiser gets organiser portal access.

Audit risks:

- auto-approval bypass;
- unapproved organiser access;
- missing audit entries for approval/freeze/disable;
- role assignment errors.

### Workflow D: Organiser creates event

1. Organiser logs in.
2. Opens `organiser.html#event-new`.
3. Sets event basics, schedule, venue, city, country, currency, timezone, payment methods, age rules, and publication status.
4. Chooses existing venue/seat plan or creates a new venue.
5. Allocates reusable ticket catalogue items to the event with event-specific price/quantity/rules.
6. Uploads/sets event media metadata for poster, hero, and gallery.
7. Adds merchandise assignments and promo codes.
8. Publishes once required setup checks pass.

Audit risks:

- event published without active ticket type or venue rules;
- wrong currency/timezone inherited globally;
- organiser edits another organiser event;
- media unsafe path/type;
- ticket catalogue price stored globally rather than event-specific.

### Workflow E: Venue and reserved seating setup

1. Organiser creates venue.
2. Organiser either generates a seat grid or works from an uploaded layout/image metadata flow.
3. Seat map stores sections/rows/seats.
4. Event selects venue/seat plan.
5. Public seat map allows seat selection.

Audit risks:

- event-seat records not generated from venue seats;
- changing seat map after sales breaks sold tickets;
- inaccessible or sold seats selectable;
- floor-plan upload treated as trusted.

### Workflow F: Organiser box office/counter sale

1. Cashier or permitted staff opens `organiser.html#box-office`.
2. Selects event and ticket type.
3. For reserved event, opens seat map and selects available seats.
4. Enters customer contact if provided.
5. Records payment method as cash or external card terminal.
6. Server calculates total, currency, tax, platform fee, and ticket issuance.
7. Counter sale appears in organiser/admin finance reports.
8. Audit log records staff action.

Audit risks:

- cashier sees finance/customer data beyond task;
- cash option exposed online;
- no audit/cash reconciliation trail;
- issuing ticket without payment record;
- same seat sold online and at counter.

### Workflow G: Ticket scanner

1. Scanner logs in or pairs device.
2. Selects assigned event.
3. Uses mobile camera or external scanner/manual QR input.
4. Validation endpoint checks token, event, status, expiry, and duplicate use.
5. First valid scan marks checked-in.
6. Repeated or invalid scan returns warning/refused state.
7. Offline sync records conflicts and later reconciliation.

Audit risks:

- scanner can scan wrong organiser/event;
- duplicate check-in race;
- scanner sees customer data not required;
- offline sync conflict not logged.

### Workflow H: Admin site builder, themes, and skins

1. Admin opens `admin.html#site-builder` and `#theme-studio`.
2. Admin updates logo, hero/banner, footer/disclaimer, CTAs, notices, theme/skin.
3. Admin can preview, save draft, publish, rollback, and configure rotation.
4. Public pages use published settings.

Audit risks:

- draft settings leak publicly;
- image paths unsafe;
- theme switch not persisted;
- rotation creates inaccessible contrast;
- footer/disclaimer missing on public pages.

### Workflow I: Admin finance, fees, taxes, and reports

1. Admin configures global country fee policies and event overrides.
2. Admin configures tax rules.
3. Orders/ledger/reports show customer gross, platform fee, platform fee VAT/tax, organiser gross, merchandise, donations, and payment method.
4. Admin exports CSV/Excel/PDF where offered.
5. Reports group by currency and do not invent exchange rates.

Audit risks:

- conflicting fee policies;
- event-specific override not used;
- platform fee counted twice or omitted;
- tax applied to wrong component;
- organiser can see customer detail;
- export includes hidden data or omits filtered/all data unexpectedly.

### Workflow J: Admin compliance/privacy/audit

1. Admin views audit logs, integrity summary, privacy requests, consents, visitor/checkout capture.
2. Admin exports reports.
3. Sensitive actions create audit entries.
4. Hash chain/integrity issues are visible.

Audit risks:

- audit logs editable without record;
- privacy exports leak too much;
- checkout abandoned capture lacks lawful basis display;
- integrity mismatch not actionable.

## 8. API Areas To Inspect

Primary public/API routes are dispatched through `mvp_dispatch()` in `public/mvp.php`.

Representative API areas:

```text
GET  /api/v1/events
GET  /api/v1/events/{slug}
POST /api/v1/checkout/session
GET  /api/v1/checkout/drafts
POST /api/v1/auth/login
POST /api/v1/auth/logout
GET  /api/v1/auth/me
GET  /api/v1/csrf
GET/POST admin site settings/theme/branding endpoints
GET/POST admin role/permission endpoints
GET/POST admin organiser application review endpoints
GET/POST admin platform fee and tax rule endpoints
GET admin finance/reconciliation/report/export endpoints
GET/POST organiser event/venue/ticket/product/promo/media/staff endpoints
POST organiser box-office sale endpoints
GET/POST scanner validation and sync endpoints
GET/POST customer account/privacy/ticket endpoints
POST payment/webhook or simulation endpoints where configured
```

Claude should extract the exact route list from `public/mvp.php` near the `mvp_dispatch()` function and compare it with the JavaScript API client methods in `public/assets/js/zavvion-ui.js`.

## 9. Database Areas To Inspect

Primary schema file:

```text
docs/schema.sql
```

Important tables or domains:

```text
users
roles
permissions
role_permissions
user_roles
organiser_staff
organisers
organiser_applications
organiser_features
organiser_feature_overrides
events
event_categories
venues
venue_seat_maps
venue_sections
seats
event_seats
ticket_type_catalog
ticket_types
ticket_inventory
seat_holds
checkout_drafts
orders
order_items
payments
payment_transactions
tickets
ticket_qr_tokens
ledger_entries
tax_rules
platform_fee_rules
tax_breakdowns
products
promo_codes
media_assets
audit_logs
privacy_requests
consents
settings
stripe_connected_accounts
```

Review schema for:

- missing unique constraints;
- missing indexes;
- foreign key mismatches;
- nullable fields that should be required;
- status values not enforced consistently;
- money/currency fields that can drift;
- event currency/timezone fields;
- seat hold expiry and uniqueness;
- ticket/order/payment state transitions;
- audit log integrity.

## 10. Current Strict Fee Policy Design

The platform fee model was changed because overlapping priority-based fee rules were confusing.

Expected model now:

```text
Global policy:
  Scope: country
  Constraint: one active global policy per country
  Applies: all events in that country unless event override exists

Event override:
  Scope: event
  Constraint: one active event-specific policy per event
  Applies: that event only

Forbidden in MVP:
  organiser-scoped fee overrides
  category-scoped fee overrides
  priority/winner conflict resolution
  multiple active policies for same country or same event
```

Files changed for this:

```text
src/Fee/PlatformFeeRuleCreationService.php
src/Checkout/CheckoutRuleResolver.php
public/mvp.php
public/admin.html
public/assets/js/admin-page.js
docs/schema.sql
migrations/M260502175000SeedDevelopmentData.php
tests/PlatformFeeRuleCreationServiceTest.php
tests/CheckoutRuleResolverTest.php
```

Claude should verify:

- create API rejects duplicate active global country policies;
- create API rejects duplicate active event policies;
- update API rejects conflicts;
- event-specific policy overrides global country policy;
- global policy is selected by event country;
- old priority UI is not present;
- legacy duplicate active rules are deactivated, not silently selected as winners;
- existing historical orders keep their `fee_rule_id`.

## 11. Testing Commands

Run from:

```text
C:\xampp\htdocs\zavvion-events
```

Recommended checks:

```powershell
C:\xampp\php\php.exe -l public\index.php
C:\xampp\php\php.exe -l public\mvp.php
node --check public\assets\js\zavvion-ui.js
node --check public\assets\js\admin-page.js
node --check public\assets\js\organiser-page.js
node --check public\assets\js\event-page.js
C:\xampp\php\php.exe composer.phar validate --strict
C:\xampp\php\php.exe composer.phar audit
C:\xampp\php\php.exe vendor\bin\phpunit
C:\xampp\php\php.exe bin\check-mvp-smoke --base-url=http://localhost/zavvion-events/public
C:\xampp\php\php.exe bin\check-local-live-run --base-url=http://localhost/zavvion-events/public
C:\xampp\php\php.exe bin\check-stripe-readiness
C:\xampp\php\php.exe bin\check-deployment-readiness
C:\xampp\php\php.exe bin\check-frontend-links --base-url=http://localhost/zavvion-events/public
```

If `vendor/bin/phpunit` is missing in the Documents copy, use the XAMPP served copy where Composer dependencies are installed, or run Composer install after approval.

Manual browser workflows to run:

```text
http://localhost/zavvion-events/public/home.html
http://localhost/zavvion-events/public/events.html
http://localhost/zavvion-events/public/event.html?slug=demo-gala
http://localhost/zavvion-events/public/login.html
http://localhost/zavvion-events/public/account.html
http://localhost/zavvion-events/public/organiser.html
http://localhost/zavvion-events/public/admin.html
http://localhost/zavvion-events/public/scanner.html
http://localhost/zavvion-events/public/mvp-profiles.html
```

## 12. Claude Audit Checklist

Ask Claude to produce severity-ranked findings with file/line evidence, reproduction steps, impact, and recommended fix.

Audit these dimensions:

1. Auth and sessions
   - password verification;
   - session fixation/regeneration;
   - CSRF on state-changing APIs;
   - password reset safety;
   - MFA/phone verification policy toggles.

2. RBAC and tenant isolation
   - platform admin vs organiser vs cashier vs scanner;
   - hidden menu vs server-side route checks;
   - organiser scoping;
   - event-specific permissions;
   - same staff with multiple roles.

3. Public checkout safety
   - totals from server;
   - public no-cash rule;
   - Stripe webhook/mock-only ticket issuance;
   - abandoned basket capture and privacy basis;
   - promo windows and age rules.

4. Seat holds and double booking
   - 15-minute expiry;
   - transaction boundaries;
   - release path;
   - reserved seat status;
   - counter sale interaction.

5. Payments and Stripe readiness
   - no secret exposure;
   - webhook signature verification when configured;
   - safe local fallback;
   - connected account/platform fee split design;
   - organiser Stripe setup visibility vs platform-owned secret handling.

6. Finance and ledger
   - fee/tax/organiser split;
   - multi-currency grouping;
   - counter cash/external card reports;
   - downloadable exports include complete intended datasets;
   - no reconciliation gaps hidden.

7. Privacy and compliance
   - organiser cannot access customer mailing lists;
   - scanner/cashier least data;
   - audit logs for sensitive changes;
   - privacy requests and data export/delete.

8. Media and uploads
   - file type/size/MIME validation;
   - safe filenames and paths;
   - public upload serving rules;
   - malware scan status and retention;
   - alt text.

9. Frontend integrity
   - broken links and buttons;
   - role profile login buttons;
   - admin/organiser/customer/scanner screens;
   - mobile/tablet responsive layout;
   - theme/skin application and rotation;
   - accessibility labels/focus/contrast.

10. Architecture and maintainability
   - logic currently in `public/mvp.php`;
   - services that should own domain rules;
   - future Yii 3 migration path;
   - duplicate/dead code;
   - fragile runtime schema repair.

## 13. Known Deferred Items

These should not be treated as launch blockers unless code falsely claims production completion:

- Real Stripe credential testing and live webhook setup.
- Production DNS/SSL/hosting setup.
- Final legal/privacy/refund policy copy.
- Real SMS/email provider setup beyond local/log adapters.
- Full Yii 3 controller migration.
- Structured family bundles beyond ticket-type description.
- Automated disputes/refunds.
- Full real-device mobile/scanner QA.

These remain important before true production operation:

- final payment gateway test with real Stripe test credentials;
- server secrets and environment configuration;
- production malware scanning/CDN/storage hardening;
- real mobile/tablet/browser QA;
- backup/restore and monitoring setup.

## 14. Expected Audit Output From Claude

Claude should return:

1. Executive summary and go/no-go recommendation.
2. Workflow integrity table.
3. Security/privacy findings ranked critical/high/medium/low.
4. Payment/finance findings.
5. RBAC/tenant-isolation findings.
6. Frontend broken-link/button findings.
7. Database integrity findings.
8. Tests run and evidence.
9. Patches or recommended patches.
10. Specific human decisions needed before launch.

Claude should not:

- reintroduce `firebase/php-jwt`;
- mark Stripe payments successful from browser redirect alone;
- expose cash payment to public online customers;
- remove MVP routes/pages without a verified replacement;
- weaken Composer audit/TLS;
- expose `.env` secrets;
- assume GBP globally.

