# 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 ``` - For an Android emulator client, confirm the APK was built with the default `http://10.0.2.2:8090` URL or with an explicit server URL: ```bash flutter build apk --debug --dart-define=GAMETIME_API_BASE_URL=http://192.168.1.75:8090 ``` - 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.