feat(server): tests API, contrats OpenAPI et vérification d'intégration (ticket #53)

Ajoute la spécification openapi.yaml documentant les 12 endpoints
réels du serveur (health, auth, sync, shares), les tests API auth
(test/auth_api_test.dart couvrant register/login/logout) et la
checklist de vérification d'intégration (docs/integration-checklist.md).
dart analyze clean, dart test 29/29 vert. Dernier ticket du chantier
serveur (#47 à #53), tous terminés.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-19 15:56:29 +02:00
parent 00c83921c9
commit c1dce3cae7
4 changed files with 993 additions and 0 deletions

View File

@ -0,0 +1,104 @@
# GameTime Server Integration Checklist
This checklist covers the checks that require a real Docker daemon, PostgreSQL
instance, or Gitea registry. They are intentionally not part of the sandbox test
suite.
## Docker Compose
- Copy `server/.env.example` to `server/.env`.
- Replace `POSTGRES_PASSWORD` and `DATABASE_PASSWORD` with a real secret.
- Set `API_BIND_ADDRESS` to the Docker host interface reachable by the external
reverse proxy.
- Set `API_PORT` to the host port consumed by the reverse proxy.
- Run:
```bash
cd server
docker compose config
docker compose up -d --build
docker compose ps
docker compose logs api
```
- Verify that the `api` service waits for the PostgreSQL healthcheck.
- Verify that migrations run automatically before the server starts.
- Verify that TLS is terminated by the external reverse proxy, not by the API
container.
## PostgreSQL Migrations
- Start a disposable PostgreSQL database or reuse the Compose database.
- Run the real migration integration test:
```bash
cd server
TEST_DATABASE_URL=postgres://gametime:change-me@localhost:5432/gametime dart test
```
- Confirm the test sees these tables:
- `users`
- `auth_sessions`
- `synced_resources`
- `shares`
- `share_recipients`
## Manual API Smoke Tests
Run the following checks against the real server URL. Use HTTP directly only on
the private LAN path between the reverse proxy and Docker host; external access
should be HTTPS through the reverse proxy.
```bash
curl http://localhost:8080/health
```
- Register a user with `POST /auth/register`.
- Login with `POST /auth/login` and store the returned bearer token.
- Call a protected endpoint without a token and confirm `401`.
- Logout with `POST /auth/logout` and confirm the token can no longer access
protected endpoints.
- Push a valid resource with `POST /sync/push`.
- Pull it with `GET /sync/pull`.
- Push an older version of the same resource and confirm `ignoredOlder`.
- Use `POST /sync/exchange` and confirm push results and pulled items are both
present.
- Create a second user, then create a share with `POST /shares`.
- Confirm unknown recipient emails are returned in `unresolvedEmails`.
- List shares with `GET /shares/inbox` as the recipient.
- Accept a share with `POST /shares/{id}/accept` and confirm a copied resource
appears in `GET /sync/pull` for the recipient.
- Decline a pending share with `POST /shares/{id}/decline`.
- Revoke a sent share with `POST /shares/{id}/revoke`.
- Confirm accepting a revoked or already answered share returns `409`.
## LWW Concurrency
- Run two concurrent `POST /sync/push` requests for the same
`(owner_user_id, resource_type, client_id)` with different `clientUpdatedAt`
values.
- Confirm the row with the strictly newer `clientUpdatedAt` wins.
- Confirm an equal timestamp is ignored by the later request.
- Inspect `server_updated_at` to confirm the update trigger advances it on
accepted updates.
## Gitea Container Registry
- Obtain the real Gitea registry host, owner/namespace, username and token.
- Run:
```bash
cd server
GITEA_REGISTRY=gitea.example.com \
GITEA_OWNER=my-org \
GITEA_IMAGE_NAME=gametime-server \
GITEA_IMAGE_TAG=latest \
GITEA_USERNAME=my-user \
GITEA_TOKEN='replace-with-token' \
./scripts/push-gitea-image.sh
```
- Confirm the image exists in the Gitea Container Registry.
- Pull the pushed image on the deployment host.
- Deploy the pushed image with the same environment variables as the local
Compose build.