Two changes in one diff because they share the same surface (JWTConfig
plumbing):
1. **Bug fix** : pkg/server/server.go was hardcoding ExpirationTime to
24h, ignoring the auth.jwt.ttl config value entirely (default 1h).
Production has been signing tokens with 24h TTL regardless of config
since the config field was added.
2. **Hot-reload (ADR-0023 Phase 2)** : extends JWTConfig with a GetTTL
func() time.Duration callback. effectiveTTL() prefers GetTTL when
set, falls back to ExpirationTime otherwise (test-friendly). server.go
wires GetTTL = cfg.GetJWTTTL — a method value that captures the
*Config, so when WatchAndApply re-unmarshals, the next token
generation reads the new TTL automatically. Tokens already issued
keep their original expiry.
WatchAndApply now also logs the new jwt_ttl on every reload event.
Tests:
- New TestWatchAndApply_JWTTTL in pkg/config/config_hot_reload_test.go
rewrites the config file and asserts the in-memory ttl flips within
2s. Polling (no fixed sleep), race-clean.
- Existing pkg/user tests (including JWT manager + cleanup loop) all
pass with -race.
- Full BDD suite (auth/config/greet/health/info/jwt) green.
ADR-0023 status: Phase 1+2 Implemented. Phase 3 (telemetry sampler)
and Phase 4 (api.v2_enabled — needs router refactor) remain Proposed.
Per-package isolated Postgres schema with migrations. Local benchmark: 12.87s sequential → 4.51s parallel = 2.85x. ADR-0025 status to Implemented. CI uses BDD_SCHEMA_ISOLATION=true.
Co-authored-by: Gabriel Radureau <arcodange@gmail.com>
Co-committed-by: Gabriel Radureau <arcodange@gmail.com>
NewPostgresRepositoryFromDSN factory + BuildSchemaIsolatedDSN helper + integration test proving per-schema isolation works at repo level. Foundation for T12. Wiring into testserver is stage 2/2.
Co-authored-by: Gabriel Radureau <arcodange@gmail.com>
Co-committed-by: Gabriel Radureau <arcodange@gmail.com>