# GoodPlay Website Architecture

## Request Flow

1. The browser uses GET routes for read-only discovery and POST routes for state changes.
2. CI4 validates session-backed CSRF on state-changing requests and, for protected pages, the local login session.
3. `GoodPlayApi` calls `https://app.goodplay.my/api/` server-side.
4. The customer's API `user_token` remains in the PHP session and is sent as `X-Token`.
5. Views receive decoded arrays and render responsive HTML.

The website is a server-rendered API client, not a replacement API or database application.

## Security Decisions

- Session-backed CSRF applies to browser-side state changes only and therefore does not affect Flutter.
- The CSRF token remains stable for the local session so valid forms survive browser history and multiple tabs; it is never required for read-only search or date URLs.
- Basic API authentication is loaded from `.env` and is never rendered into HTML or JavaScript.
- External absolute API URLs are rejected unless their host is explicitly allowed by configuration.
- Every upstream request gets a cryptographically random idempotency key.
- Session IDs regenerate after login and are destroyed on logout.
- All application routes are explicit; automatic routing remains disabled.
- Output is escaped by default in views.

## UI Strategy

- Mobile-first, matching the app's Montserrat typography, purple `#3d36c0`, and yellow `#ffba00` identity.
- A desktop header/sidebar enhancement replaces the app-only bottom-navigation constraint.
- Standard URLs and forms replace Flutter navigation and local widget state.
- Venue and booking pages use canonical slugs generated from `venue_name`; CI4 resolves them to API IDs, while legacy numeric URLs permanently redirect to the slug URL.
- A random, session-bound completion URL presents the provider payment link without exposing sequential booking IDs. The customer continues through a single “Pay now” action; the payment provider's return remains API-owned and does not require an API change.
