## Objectif

Builder et lancer le serveur GameTime (`server/`, package Dart `gametime_server`) avec sa
base PostgreSQL, pour :
- valider fonctionnellement les routes API (health, auth, sync, shares) sur HTTP ;
- fournir une cible vivante aux tests fonctionnels de routes de QA ;
- développer/débugger côté serveur.

Skill de pilotage — exécutable par **Main**, support pour **QA** (tests fonctionnels de
routes). Le contrat des routes est dans `server/openapi.yaml`.

## Mode 1 — Docker Compose (recommandé, stack complète)

Depuis `server/`, créer/éditer `.env` (modèle `server/.env.example`) :
```
API_BIND_ADDRESS=0.0.0.0     # interface hôte publiée par Docker. 0.0.0.0 = LAN + loopback ; une IP précise restreint
API_PORT=8080                # port hôte publié
MIGRATE_ON_STARTUP=true      # applique les migrations SQL au démarrage du conteneur api
DATABASE_HOST=postgres       # nom du service Compose (interne au réseau Docker)
DATABASE_PORT=5432
DATABASE_NAME=gametime
DATABASE_USER=gametime
DATABASE_PASSWORD=change-me
POSTGRES_DB=gametime
POSTGRES_USER=gametime
POSTGRES_PASSWORD=change-me
```

Lancer :
```bash
cd server
docker compose up -d --build
```

Le service `api` attend le healthcheck Postgres, exécute `/app/bin/migrate`, puis
`/app/bin/server`. Le conteneur écoute en interne sur `0.0.0.0:8080` (log trompeur) ;
l'adresse réellement joignable côté hôte est **`${API_BIND_ADDRESS}:${API_PORT}`**.

Vérifier :
```bash
curl http://${API_BIND_ADDRESS}:${API_PORT}/health      # attendu : {"status":"ok"}
```

Commandes utiles :
```bash
docker compose logs -f api          # logs serveur temps réel
docker compose config               # config Compose interpolée (vérifier les ports publiés)
docker compose restart api          # relancer l'API sans toucher Postgres
docker compose down                 # arrêter la stack (volume Postgres conservé)
```

### Piège LAN (accès depuis le téléphone)
- L'adresse publiée doit être l'IP LAN de l'hôte (ex. `192.168.1.75`), pas `localhost`.
- Ouvrir le firewall hôte sur `API_PORT`.
- L'app mobile pointe par défaut sur `http://localhost:8080` (codé au build via
  `GAMETIME_API_BASE_URL`) → surcharger au build de l'APK avec
  `--dart-define=GAMETIME_API_BASE_URL=http://<ip-lan>:<port>` et autoriser le HTTP en
  clair côté Android (`usesCleartextTraffic` dans `AndroidManifest.xml`).

## Mode 2 — Local Dart (sans Docker)

Nécessite un PostgreSQL joignable (hors Compose, ou le conteneur `postgres` exposé).
```bash
cd server
dart pub get
DATABASE_HOST=localhost DATABASE_PORT=5432 DATABASE_NAME=gametime \
DATABASE_USER=gametime DATABASE_PASSWORD=gametime \
dart run bin/migrate.dart              # migrations lues depuis server/migrations/
DATABASE_HOST=localhost DATABASE_PORT=5432 DATABASE_NAME=gametime \
DATABASE_USER=gametime DATABASE_PASSWORD=gametime \
PORT=8080 dart run bin/server.dart     # écoute sur 0.0.0.0:$PORT
```

## Lancer les tests (support QA)

Depuis `server/` :
```bash
dart test                                                                  # unitaires + handlers en isolation
TEST_DATABASE_URL=postgres://gametime:gametime@localhost:5432/gametime dart test   # + intégration Postgres (sinon skippées)
```
Limite : les sandbox agents n'ont pas d'accès réseau à pub.dev → si `dart pub get` est
requis, Main le passe avant ; `dart test` sur deps résolus reste jouable par QA.

## État courant connu (machine projet, 2026-07-25)

- Stack Docker validée : `GET /health` → 200, `POST /auth/register` → 201.
- IP LAN hôte : `192.168.1.75` (interface `enp4s0`).
- `.env` courant publie sur `192.168.1.75:8090`.
