mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 22:11:38 +00:00
8b6415035c
The coverage-gap audit flagged L-1 (P2): `HealthCheckRepository` (453 LOC,
11 methods) and `RenewalPolicyRepository` (289 LOC, 5 methods post-G-1 —
the audit's "92 lines, 2 methods" figure was stale) ship to production
with zero live-DB integration coverage. The existing `repo_test.go`
header self-documents the gap: "15 of 17 PostgreSQL repository files".
Operationally load-bearing piece: M48's scheduler calls
`HealthCheckRepository.ListDueForCheck` every tick to drive continuous
TLS health monitoring. A silent SQL regression there — wrong INTERVAL
math, NULL-handling slip, lost ORDER BY — would fail open: operator
adds endpoint → scheduler never picks it up → endpoint degrades in
production → no alert. The loop continues ticking and logs "processed
0 endpoints" normally, so the failure mode is operationally invisible.
Closure shape (test-only; no production code touched):
- internal/repository/postgres/health_check_test.go (new file, 7 tests)
· TestHealthCheckRepository_CRUD
· TestHealthCheckRepository_GetByEndpoint
· TestHealthCheckRepository_List_Filters
· TestHealthCheckRepository_ListDueForCheck (the load-bearing one —
seeds four rows with differing last_checked_at+interval
relationships to NOW() plus one NULL-last_checked_at row,
asserts the correct subset returns and ORDER BY last_checked_at
ASC NULLS FIRST holds)
· TestHealthCheckRepository_RecordHistory_GetHistory
· TestHealthCheckRepository_PurgeHistory
· TestHealthCheckRepository_GetSummary
- internal/repository/postgres/renewal_policy_test.go (new file, 3 tests)
· TestRenewalPolicyRepository_CRUD (exercises auto-generated
rp-<slug(name)> PK, JSONB round-trip of [30,14,7,0] thresholds,
UpdatedAt monotonic advance, ORDER BY name for List)
· TestRenewalPolicyRepository_DuplicateName (asserts
errors.Is(err, repository.ErrRenewalPolicyDuplicateName) on both
Create-name-unique and Update-name-unique collision paths, the pg
23505 sentinel mapping)
· TestRenewalPolicyRepository_DeleteInUse (raw-INSERTs a
managed_certificates row FK'ing the policy, asserts
errors.Is(err, repository.ErrRenewalPolicyInUse) from pg 23503
ON DELETE RESTRICT, cleans up, then asserts not-found surfaces
distinctly)
- internal/repository/postgres/repo_test.go (one-line header flip)
"covering 15 of 17 ... repository files" → "17 of 17"; added
cross-reference pointing readers at the two sibling files.
Both new files use the existing getTestDB(t) + schema-per-test-isolation
convention and skip via testing.Short() in CI, matching M26 TICKET-003
scaffolding byte-for-byte. Repository/postgres is not in the CI
coverage-gate path (grep -nE "internal/repository/postgres"
.github/workflows/ci.yml → no hits), so adding test-only files cannot
regress gated coverage elsewhere.
Verification gates run locally (sandbox without Docker, so the -short
skip gate itself is what's exercised; operator runs the testcontainer
path locally):
1. go vet ./... — clean
2. go build ./... — clean
3. go test -short -count=1 ./... — clean
4. go test -race -short ./internal/repository/postgres/... — clean
5. staticcheck — absent; CI checkset holds
6. govulncheck — skipped; test-only, no deps
7. per-layer coverage no-regression — N/A; repo/pg not gated
8. tsc --noEmit — N/A; no frontend change
9. vitest run — N/A; no frontend change
10. vite build — N/A; no frontend change
11. OpenAPI lint — N/A; no spec change
No migration, no interface change, no production code diff. The
RenewalPolicyRepository drift between audit ("92 lines, 2 methods")
and HEAD (289 lines, 5 methods post-G-1) is documented honestly in
the audit report's Resolution Log, not papered over.
Closes: coverage-gap-audit L-1 (P2)