The bundled frontend gets a token with API_PASSWORD from config.js. The server now
generates config.js from its own config, so setting API_PASSWORD on the server
container is enough.
The spec is now built from the same calls that register the routes, so it
can't drift from the router like the swag comments did (all /api/v1
routes were missing).
- /api/v1 endpoints are typed Huma operations; the spec is OpenAPI 3.1 at
/openapi.json (3.0 at /openapi-3.0.json, YAML too), docs at /docs.
/openapi and /swagger/* redirect there
- Bearer token security is declared per operation; token creation and
the new GET /api/v1/health are public
- Legacy routes use the same handlers, are hidden from the spec and keep
the Deprecation header
- /sync/reset is hidden (debug only); the /sync/new, /sync/quick and
/sync/new/full aliases are removed (use /sync and /sync/full)
- Invalid parameters return 422 (validation); every error is
{"error": "..."}; empty lists are [] instead of null
- /sync/progress is documented as progress or result (oneOf)
- Tests validate the spec and check real responses of every documented
operation against it (kin-openapi)
- Removed swag annotations, cmd/docs, echo-swagger and the swag tool
- Unit tests use an in-memory fake database (internal/testutil/fakedb),
temp folders and httptest; `go test ./...` needs no Docker or env vars
- Integration tests (build tag "integration") start PostgreSQL with
testcontainers: migrations step by step, SQL dumps (skipped if
missing) and a full sync against a real database
- Removed tests that only checked copies of the logic or had empty
bodies, the broken root integration_test.go, compose.test.yaml and
.env.test with hardcoded paths
- testMusic MP3s replaced with tiny placeholders (sync never decodes
audio), 194 MB -> 168 KB