# Repository Guidelines
- You act as a lead senior web developer.
## Project Structure & Module Organization
- `src/` holds the PHP application code, following a simple MVC-style layout.
  - `Controller/` contains admin and API controllers.
  - `Model/` defines domain models.
  - `Repository/` handles data access.
  - `views/` contains PHP templates and partials.
  - `Config/`, `Security/`, and `Interfaces/` store configuration, CSRF helpers, and shared contracts.
- `public/` is the web root (entry points like `index.php` and `api.php`). Static assets live in `public/assets/`, and runtime uploads go to `public/uploads/`.
- `src/table.sql` provides the database schema reference.

## Build, Test, and Development Commands
- `composer install` installs dependencies and sets up the PSR-4 autoloader.
- `composer dump-autoload` refreshes the autoloader after adding or moving classes.
- `php -S localhost:8000 -t public` runs a local PHP server pointing at the `public/` directory. (If using XAMPP/Apache, configure the document root to `public/`.)

## Coding Style & Naming Conventions
- Indentation uses 4 spaces with braces on the same line as declarations.
- Class names use `PascalCase`, method/variable names use `camelCase`, and constants use `UPPER_SNAKE_CASE`.
- Keep namespaces aligned with PSR-4 (`App\\...` maps to `src/`).
- Views in `src/views/` should keep logic minimal and focus on rendering.

## Testing Guidelines
- No automated test suite is present in this checkout. If adding tests, place them under a top-level `tests/` directory and document the runner (e.g., PHPUnit) in this file.

## Browser Validation with Playwright MCP
- Use the official `@playwright/mcp` server for interactive browser checks. It lets Codex and the developer share a visible Firefox window, inspect the accessibility tree and computed DOM state, use the console/network tools, and take screenshots.
- Node is installed through Linuxbrew. Codex must use absolute executable paths because the Homebrew directory may not be present in its `PATH`:
  - Node: `/home/linuxbrew/.linuxbrew/bin/node`
  - npx: `/home/linuxbrew/.linuxbrew/bin/npx`
- Install the Firefox build required by the MCP package once (and repeat after an MCP upgrade if it requests a different browser revision):

```bash
/home/linuxbrew/.linuxbrew/bin/npx -y @playwright/mcp@latest install-browser firefox
```

- The workstation's local desktop runs on XWayland display `:0`. An SSH-launched process can display a window on the physically connected screen by using the desktop session's Xauthority file. Find the current file and verify access with:

```bash
ls /run/user/$(id -u)/xauth_*
DISPLAY=:0 XAUTHORITY=/run/user/$(id -u)/xauth_CURRENT xdpyinfo -display :0
```

  Replace `xauth_CURRENT` with the filename returned by the first command. The filename may change after the graphical session logs out or the machine reboots.
- Register Playwright MCP globally in Codex using `stdio`, not an HTTP URL. Codex uses a separate network namespace, so an MCP server bound to the host's `127.0.0.1:8931` is not reachable as `http://127.0.0.1:8931/mcp`. The working configuration is:

```bash
codex mcp remove playwright 2>/dev/null || true
codex mcp add \
  --env DISPLAY=:0 \
  --env XAUTHORITY=/run/user/1000/xauth_CURRENT \
  --env XDG_RUNTIME_DIR=/run/user/1000 \
  --env DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus \
  --env PATH=/home/linuxbrew/.linuxbrew/bin:/usr/local/bin:/usr/bin \
  playwright -- \
  /home/linuxbrew/.linuxbrew/bin/npx -y @playwright/mcp@latest --browser=firefox
```

- Restart Codex after adding or changing the MCP entry. Confirm it with `codex mcp get playwright`, then ask Codex to navigate to `http://127.0.0.1:8070/contact`. The Playwright Firefox process should appear on the local monitor and must not contain the `-headless` argument.
- If Codex reports that Firefox is missing, run the `install-browser firefox` command above. If navigation succeeds but no window is visible, check the configured `DISPLAY` and `XAUTHORITY`, validate them with `xdpyinfo`, update the MCP entry, and restart Codex.
- The Playwright-managed Firefox profile is separate from the user's regular Firefox/Flatpak profile and is stored beneath `~/.cache/ms-playwright-mcp/`. Browser binaries are cached beneath `~/.cache/ms-playwright/`.

## Commit & Pull Request Guidelines
- No `.git` history is available here, so commit conventions cannot be inferred. Use short, imperative summaries (e.g., “Add artist upload validation”) and include context in the body when changes are non-trivial.
- For pull requests, include a clear description, list of affected areas (e.g., `Controller/`, `views/`, `public/assets/`), and screenshots for UI changes.

## Security & Configuration Tips
- Update database settings in `src/Config/Database.php` for local environments and avoid committing secrets.
- Treat `public/uploads/` as generated content; do not edit or version control files there manually.
- Music embeds are sanitized on save and rendered client-side in the SPA (no server-rendered embed partials).

## Accepted Risks (for now)
- Rate limiting remains session-based for contact/admin flows; no shared store or IP throttling yet.
- Uploads are stored under `public/uploads/` without extra web-server hardening or re-encoding.
- No 2FA or IP allowlisting on admin accounts at this stage.
