test(managementapi): DB-backed composition floor for the read handlers
Follow-up to !788 (merged) (was stacked on its branch; retargeted to main when it merged).
!788 (merged)'s unit tests drive the read handlers through fakeRepositoryReader, which mirrors the store's keyset contract in parallel code. That leaves one documented hole (called out in !788 (merged)'s description): a symmetric misreading of the contract, the same bug in the fake's bound and the store's SQL, passes both test tiers separately. This MR adds the composition authority that closes it.
One integration-tagged file (//go:build integration), following the OCI package's handler-integration precedent and the datastore package's TestMain convention (own isolated database per package):
managementapi.NewHandlerwired exactly as production: realNamespaceStoreresolves the slug, realRepositoryStoreserves the reads, repository rows seeded through the realCreatewrite path (namespace + default collection seeded directly; they have no write surface yet).TestReadHandlersIntegration_KeysetWalkRoundTrip: the full forward-and-backwardLinkwalk against the real keyset SQL, including backward-page link emission, prev-then-next symmetry, and a savedrel="next"replayed after its boundary row is soft-deleted (the bound is a row-value comparison, not a boundary-row lookup; only this tier can catch a store rewrite that changes that).TestReadHandlersIntegration_FilteredWalkAndSortedUnion: aformatfilter surviving followed pages against the realWHEREclause, and alast_updated_atwalk asserting exact page order across bothCOALESCE(last_updated_at, created_at)arms, so an updated row'stimestamptzrides the wire cursor's JSON round trip and never-updated rows take thecreated_atfallback. (Index usage is pinned by the schema tier, not here.)TestReadHandlersIntegration_Detail: detail hit with real-column-state body assertions, and the existence-hiding 404 through the store's wrappedErrNotFound.
The fake stays authoritative for what a live database cannot do: deterministic error injection, the zero-store-calls-on-400 assertion, and param-mapping seam checks.
Runs in the test:integration CI job (-tags=integration); locally via testcontainers. This MR adds the missing CI wiring for internal/managementapi (the job's go list set and its changes: anchor) plus a drift guard, scripts/ci/check-integration-test-wiring.sh (pre-commit hook and lint:integration-test-wiring job), which fails whenever a package has //go:build integration tests but is missing from either place.
Related to #171 (closed)