# Sumali Zavv Platform Testing v1 Resolution

Date: 2026-05-08

This file records the implementation status for the numbered feedback in
`Sumali Zavv new platform testing v 1.docx`. It is intended for the human
architect handover and launch QA.

## 1. Home hero/banner should be animated

Done:
- Homepage hero image rotation is wired through `public/assets/js/home-page.js`.
- The animation respects reduced-motion settings.

Checked:
- `node --check public/assets/js/home-page.js`
- HTTP 200 for `http://localhost/zavvion-events/public/home.html`

## 2. Admin dashboard period selector should change data

Done:
- Admin dashboard period selector now calls `/api/v1/admin/console-data?period=...`.
- The backend returns `meta.period_days`.

Checked:
- Authenticated API smoke returned `admin_period = 7`.

## 3. Admin organiser search and manual approval

Done:
- Organiser applications table is backend-backed.
- Search/filter works client-side.
- Approve, reject, and suspend actions call the manual review endpoint.

Checked:
- Authenticated `/api/v1/admin/applications` returned clean JSON.

## 4. Fee and tax rule edit/delete/deactivate

Done:
- Fee and tax rules can be edited and deactivated.
- Safe delete was added. If a rule is referenced by historical records it is
  deactivated instead of hard-deleted.

Checked:
- Created and deleted a temporary platform fee rule through the protected API.

## 5. Customer-level settlement export

Done:
- Settlement details include customer-level rows ordered by organiser/event.
- CSV, Excel-compatible XLS, and PDF exports are available.
- Export responses now use no-store cache headers.

Checked:
- Authenticated settlement-detail CSV returned HTTP 200.
- Cache-Control header returned `no-store, no-cache, must-revalidate, max-age=0`.

## 6. Organiser featured placement purchase

Done:
- Admin can configure featured packages.
- Organiser marketing screen can start a featured placement purchase.
- Local MVP simulation can mark the purchase paid and feature the event.
- Stripe checkout failure branch was fixed to fail cleanly without undefined
  variables.

Checked:
- Organiser featured options returned three seeded packages.
- `public/mvp.php` syntax passed.

## 7. Audit/log exports and ticket-delivery route

Done:
- Audit exports work as CSV, XLS, and PDF.
- Export responses now use no-store cache headers.
- Ticket delivery send route remains protected and non-blocking.

Checked:
- Authenticated audit CSV returned HTTP 200.
- Cache-Control header returned `no-store, no-cache, must-revalidate, max-age=0`.

## 8. Organiser dashboard period selector

Done:
- Organiser dashboard period selector calls `/api/v1/organiser/summary?period=...`.
- Dashboard copy updates to show the selected period.

Checked:
- Authenticated organiser API smoke returned `period_days = 7`.

## 9. Organiser events search/filter

Done:
- Organiser event search and status filter now update the visible event table.

Checked:
- `node --check public/assets/js/organiser-page.js`

## 10. Event donation settings

Done:
- Event editor includes donation enable, cause, and suggested amount controls.
- Settings save through `/api/v1/organiser/donation-settings`.

Checked:
- Endpoint exists and organiser page JavaScript passed syntax checks.

## 11. Duplicate seat-map prevention

Done:
- Duplicate seat-map creation is rejected by venue, name, rows, seats per row,
  and seat type.
- MySQL advisory locking was added around seat-map creation to reduce concurrent
  duplicate race risk.

Checked:
- `public/mvp.php` syntax passed.
- Full PHPUnit suite passed after the change.

## 12. Attach map UI

Done:
- Attach-map UI was styled as a clear panel.
- Backend attach route remains wired to event/venue validation.

Checked:
- Organiser page returned HTTP 200.
- `node --check public/assets/js/organiser-page.js`

## 13. Ticket categories archive

Done:
- Ticket types can be archived from the organiser UI.
- Backend route is `/api/v1/organiser/ticket-types/{id}/archive`.

Checked:
- Endpoint exists in `public/mvp.php`.
- Organiser page JavaScript passed syntax checks.

## 14. Product edit

Done:
- Product edit uses the product upsert flow.
- SKU stays locked during edit for launch safety.

Checked:
- Existing product tests and full PHPUnit suite passed.

## 15. Preview

Done:
- Event preview saves a draft first if required, then opens the public event
  page.

Checked:
- Organiser page JavaScript passed syntax checks.

## 16. Staff creation and role structure

Done:
- Organiser staff can add an existing user or create a pending new user.
- Staff creation and role assignment now run inside one transaction.
- Role matrix is shown for owner/admin/event manager/cashier/scanner.

Checked:
- Full PHPUnit suite passed.

## 17. Organiser branding/white-label disabled

Done:
- Organiser branding no longer shows a large white-label upload box.
- It explains that site logo, skins, footer, disclaimers, and global banners
  are platform-admin controls.

Checked:
- Organiser page returned HTTP 200.

## 18. Organisers cannot control platform charges

Done:
- Organiser finance view shows Stripe connected-account metadata and read-only
  platform fee logic.
- Platform charges are controlled in the platform admin console.

Checked:
- Authenticated organiser Stripe account endpoint returned clean JSON.

## 19. Staff role rights

Done:
- Permissions are separated by role:
  owner/admin full organiser controls, event manager operations, cashier box
  office, scanner scan-only.

Checked:
- Role/permission tests in the existing suite passed.

## Additional Visual Fixes

Done:
- Seat-map stage bar is slim and horizontal.
- Promo code and donation controls are aligned in the ticket section.
- Retired skins are not exposed in the active theme catalogue, public
  fallback catalogue, or served CSS selectors.

Checked:
- Browser visual smoke on `event.html?slug=demo-gala#tickets`.
- Browser visual smoke on `event.html?slug=demo-gala#seats`.
- HTTP 200 for `theme-gallery.html`.
- `tests/SiteThemeCatalogTest.php` verifies retired skin selectors are not
  served by CSS.

## Browser Review Corrections - 2026-05-08

These items correspond to the numbered browser comments raised from
`admin.html`, `organiser.html`, and `mvp-profiles.html`.

### 1. Admin organiser applications need sample data

Done:
- Seed installer now creates sample organiser applications for Northstar Live,
  Lotus Arts Collective, and Harbour Comedy Rooms.
- The local database was reseeded and returned three organiser applications.

Checked:
- `bin/install-database --seed`
- Authenticated admin applications API returned seeded applications.

### 2. Admin categories need edit action

Done:
- Category table now includes an Edit action.
- Category form switches between create and edit modes and calls the protected
  category update API.

Checked:
- Authenticated category update API returned `ok`.
- `node --check public/assets/js/admin-page.js`

### 3. Admin finance settlement export needs sample data

Done:
- Seed installer now creates sample paid orders, order items, and tickets with
  ticket net, ticket tax, platform fee, VAT, organiser gross, donation, and
  merchandise components.

Checked:
- Local database count showed `orders: 19` and `tickets: 18`.
- Admin finance export endpoints returned HTTP 200.

### 4. Admin orders need CSV, Excel, and PDF downloads

Done:
- Admin orders panel now has CSV, Excel, and PDF export controls.
- Backend admin export routes now support `orders.csv`, `orders.xls`, and
  `orders.pdf`.

Checked:
- `GET /api/v1/admin/exports/orders.csv` returned HTTP 200.
- `GET /api/v1/admin/exports/orders.pdf` returned HTTP 200.

### 5. Audit integrity needs CSV, Excel, and PDF downloads

Done:
- Audit header and integrity view now expose CSV, Excel, and PDF export links.

Checked:
- Existing audit export routes were syntax-checked through `public/mvp.php`.
- Admin audit page returned HTTP 200.

### 6. Organiser applications need approve, freeze, and disable actions

Done:
- Manual KYC actions are labelled Approve, Freeze, and Disable.
- Freeze maps to suspended status; Disable maps to rejected/disabled review
  status for the MVP workflow.

Checked:
- Authenticated applications API returned seeded rows for action rendering.
- `node --check public/assets/js/admin-page.js`

### 7. Organiser dashboard tasks need links

Done:
- Dashboard tasks now link to Events, Event Editor, and Finance/Stripe setup.

Checked:
- `node --check public/assets/js/organiser-page.js`

### 8. New event page needs Save and Back

Done:
- New event header has Back.
- Launch editability panel has Save draft and back plus Back to events.

Checked:
- `node --check public/assets/js/organiser-page.js`
- Organiser page returned HTTP 200.

### 9. Venue Edit button needs working edit flow

Done:
- Venue edit populates the venue form.
- Venue form includes Back control.
- Venue save uses the existing protected venue update endpoint.

Checked:
- `node --check public/assets/js/organiser-page.js`

### 10. Ticketing button naming was unclear

Done:
- `New ticket type` was renamed to `Clear for new ticket type` to clarify
  that it resets the editor.
- `Create ticket type` remains the actual save/create action.

Checked:
- `node --check public/assets/js/organiser-page.js`

### 11. Ticket allocation to events was unclear

Done:
- Ticketing copy now explains that the event dropdown is the allocation point.
- Existing ticket type edit flow can change the assigned event.

Checked:
- `node --check public/assets/js/organiser-page.js`

### 12. Organiser Orders menu should not be visible

Done:
- Organiser Orders side menu is hidden.
- Orders panel route was renamed so it is not reachable through normal route
  navigation.

Checked:
- Organiser page returned HTTP 200.
- No organiser orders link remains in the MVP profile walkthrough.

### 13. Organiser Orders section should be removed

Done:
- Organiser route handling no longer exposes the Orders section.
- Role-aware navigation excludes Orders for organiser, event manager, cashier,
  and scanner roles.

Checked:
- `node --check public/assets/js/organiser-page.js`

### 14. Organiser downloadable customer/order reports should be removed

Done:
- Organiser finance no longer renders the detailed download reports section.
- Organiser-facing exports and reports were scrubbed of individual customer and
  visitor fields.

Checked:
- Organiser order API first row returned without customer fields.
- Organiser orders CSV header returned without customer fields.

### 15. Email campaigns should be admin-requested

Done:
- Organiser marketing email campaign card now says campaigns are handled by
  platform admin request.
- Added request textarea and `mailto:` action for contacting admin.

Checked:
- `node --check public/assets/js/organiser-page.js`

### 16. Trackable links table needs explanation

Done:
- Marketing screen now explains that UTM links are privacy-safe campaign links
  for click attribution and do not expose customer details to organisers.

Checked:
- `node --check public/assets/js/organiser-page.js`

### 17. Current staff need edit action

Done:
- Staff table includes Edit actions.
- Edit action populates the staff form and changes the submit button into save
  mode.

Checked:
- `node --check public/assets/js/organiser-page.js`

### 18. Organiser Branding menu should be removed

Done:
- Branding side menu is hidden for organiser users.
- The old branding route is no longer shown by normal navigation.

Checked:
- Organiser page returned HTTP 200.

### 19. Box Office must load for cashier login

Done:
- Cashier role can now load organiser events and ticket types required by the
  box-office screen.
- Role-aware organiser navigation limits cashier view to dashboard, box office,
  and check-in.

Checked:
- Logged in as `cashier@zavvion.test`.
- Organiser events API returned four events.
- Organiser ticket types API returned five ticket types.

### Profile walkthrough access cleanup

Done:
- `mvp-profiles.html` now shows only visible menu items/routes for each role.
- Removed the old Restricted card from the role walkthrough.
- Removed stale organiser Orders link from the box-office journey.
- Data visibility copy now states that individual customer/visitor data is
  platform-admin only.

Checked:
- `node --check public/assets/js/mvp-profiles-page.js`
- `http://localhost/zavvion-events/public/mvp-profiles.html` returned HTTP 200.
- Served HTML check found no stale `Restricted` text or organiser Orders link.

## Validation Summary

Passed:
- `C:\xampp\php\php.exe -l public\mvp.php`
- `C:\xampp\php\php.exe -l public\index.php`
- `node --check` for changed JavaScript files
- `composer validate --strict`
- `composer audit`
- `vendor\bin\phpunit`: 486 tests, 1611 assertions, 2 skipped
- `bin\check-mvp-smoke --base-url=http://localhost/zavvion-events/public`: ok, 0 warnings
- `bin\check-local-live-run --base-url=http://localhost/zavvion-events/public`: 0 critical, 1 expected payment-completion warning
- `bin\check-deployment-readiness`: 0 critical, 6 expected environment warnings
- `bin\check-production-launch --allow-warnings`: ready with 6 accepted environment warnings
- `bin\check-stripe-readiness`: not ready until Stripe test keys, webhook secret, and a transfer-ready connected organiser account are configured
- `theme-gallery.html`: HTTP 200 from the XAMPP local URL
- Backup/source files such as `index.php.broken-line-56-backup` and
  `mvp.php.backup-before-*`: HTTP 403 from the XAMPP local URL

Remaining environment sign-off:
- Real Stripe test credentials and signed webhook run
- Production secrets and server configuration
- Final mobile/device/payment QA
