Adds internal/keycloak/client_test.go: a minimal stubKC built on
httptest.Server that responds to /token + /admin/serverinfo + the
Admin API paths the adapter actually calls. Coverage on the keycloak
package jumps from ~5% → ~50%; total project line coverage from 60% →
71.6%, back above the 70% gate.
Workflow updated to include internal/keycloak/... in the test
command (was missing — only server + config were enumerated).
Tests added:
Health success GET /admin/serverinfo with bearer
CreateOrgAndInvite full flow POST org + user + member + email,
assert call counts and ID parsing
from the Location header
Conflict surfacing POST /organizations → 409 →
ErrOrgConflict
Empty admin email rejected before any HTTP call
Token unavailable connection refused →
errors.Is(err, ErrUnavailable)
Token unauthorized 401 on /token → ErrUnauthorized
SyncClaims PUT /users/:id with attributes
Token caching 3 Health() calls produce ONE
/token fetch — the lock + expiry
check works as designed
Refs: M4.3
Full M4.2 deliverable: 16 endpoints (tenants CRUD + lifecycle, catalog, entitlements, API keys with argon2 hashing, audit append + filter), Store interface with pgx-backed Postgres + in-memory parallel implementations exercised by the same eachStore harness, openapi.yaml at 3.1 with kin-openapi contract test. M4.3 adds auth.
Refs: M4.2
Minimal Go service: /healthz + /v1/tenants/by-slug/:slug + /v1/tenants/:id with an in-memory store seeded with the acme tenant. Stdlib-only; pgx + JWT validation land in M4.1 follow-up.