# EscapePage — Online Escape Room

This repository contains a Symfony 7.3 (PHP >= 8.5.1) application for a collaborative online escape room experience.

- Start here: doc/FILES.md — quick file index.
- Development standards and workflows: doc/CONTRIBUTING.md
- All documentation is located under the doc/ directory.

## Getting Started (brief)
- Local machine (no Docker):
  1. Copy `.env` to `.env.local` and set database and `APP_SECRET`.
  2. Install PHP deps: `composer install`
  3. Create database and run migrations (when present): `php bin/console doctrine:database:create --if-not-exists && php bin/console doctrine:migrations:migrate -n`
  4. Install/import JS deps: `php bin/console importmap:install`
  5. Run the server: `symfony server:start -d` (or your preferred web server)
  6. Run tests: `vendor/bin/phpunit`

- With Docker:
  1. From `docker/`: `docker compose up -d`
  2. Install vendors inside the PHP container:
     - `docker compose exec php bash`
     - `composer install`
  3. Initialize DB:
     - `php bin/console doctrine:database:create --if-not-exists`
     - `php bin/console doctrine:migrations:migrate -n`
  4. App is at http://localhost:8080

## Email (Mailpit in dev, SendGrid for prod)
- Dev: a `mailer` service (Mailpit) runs in Docker.
  - SMTP DSN in `.env`: `MAILER_DSN=smtp://mailer:1025`
  - Mailpit UI: http://localhost:8025
  - Send a test mail: `php bin/console app:mail:test you@example.com`
- Staging/Prod: use SendGrid.
  - Require package (already in composer): `symfony/sendgrid-mailer`.
  - Set environment variables (do NOT commit secrets):
    - `MAILER_DSN=sendgrid+api://%env(SENDGRID_API_KEY)%`
    - `SENDGRID_API_KEY=YOUR_REAL_KEY`
    - Optional: `MAILER_FROM=no-reply@your-domain.tld`
  - Alternatively via SMTP (no extra package):
    - `MAILER_DSN="smtp://apikey:%env(SENDGRID_API_KEY)%@smtp.sendgrid.net:587?encryption=tls"`

Troubleshooting:
- If emails don’t appear in dev, open Mailpit at http://localhost:8025 and verify messages.
- In prod, check logs for HTTP 2xx responses from SendGrid and verify sender domain is verified in SendGrid.

## Frontend assets with Webpack Encore
We use Webpack Encore to build and minify JS/CSS from the `assets/` directory into `public/build/`.

Install Node dependencies (on your host machine):
```
npm install
```

Common commands:
```
# One-time dev build
npm run dev

# Watch & rebuild on changes
npm run watch

# Production build (minified, versioned filenames)
npm run build
```

How it’s wired:
- Entry file: `assets/app.js` (imports `assets/styles/app.css`).
- Webpack config: `webpack.config.js` outputs to `public/build/`.
- Twig template includes built assets via Encore:
  - In `templates/base.html.twig`:
    - `{{ encore_entry_link_tags('app') }}` (CSS)
    - `{{ encore_entry_script_tags('app') }}` (JS)

Notes:
- The PHP Docker image does not include Node. Run the build commands on your host, or ask to add a Node build container if you prefer fully containerized builds.
- Built files are ignored by git except for `public/build/.gitignore` to keep the directory.

See doc/CONTRIBUTING.md for code style and more details.

## Real‑time updates with Mercure
We use a Mercure hub (Docker service) to push server updates to browsers via Server‑Sent Events (SSE).

Quick start (dev):
1. Start Docker stack from `docker/`:
   ```
   docker compose up -d
   ```
   This starts `mercure` at http://localhost:8090 and the app at http://localhost:8080.
2. Install PHP deps inside the PHP container if you haven't yet:
   ```
   docker compose exec php bash
   composer install
   ```
3. Open the Game Hub page in your browser: http://localhost:8080/game
   - The page subscribes to a demo topic and logs messages in the console.
4. Publish a test update (in the PHP container):
   ```
   php bin/console app:mercure:publish
   ```
   You should see a console log like `[Mercure] Update received: { ... }` on the Game Hub page.

Configuration:
- Env vars (defined in `.env`, override in `.env.local` as needed):
  - `MERCURE_URL=http://mercure/.well-known/mercure` (internal URL from PHP to the hub)
  - `MERCURE_PUBLIC_URL=http://localhost:8090/.well-known/mercure` (browser URL)
  - `MERCURE_JWT_SECRET=!ChangeThisMercureJWT!` (dev secret; do not use in prod)
  - `MERCURE_TOPIC_BASE=https://escapepage.dev` (base topic URL)
- Docker service `mercure` is based on `dunglas/mercure` and allows anonymous subscribers in dev.

Topics:
- Topics must be URLs. We use `MERCURE_TOPIC_BASE` to control the domain per environment.
  - Dev: `.env` sets `https://escapepage.dev`
  - Prod: set `MERCURE_TOPIC_BASE=https://escapepage.com`
- The Game Hub demo topic is `${MERCURE_TOPIC_BASE}/game/hub`.

Production notes:
- Disable anonymous subscribers and require JWTs for subscriptions (configure the Mercure container accordingly).
- Use a strong, rotated `MERCURE_JWT_SECRET` and keep it out of VCS (use real env/secrets).
- Serve Mercure over HTTPS and set proper CORS/allowed origins for your production domain(s).
