chore(canary-phase1): database & repositories complete
Phase 1 deliverables (audited PASS by superpowers:code-reviewer + general-purpose):
Implementation (1 commit):
- b2558e2e Postgres schema + token & event repositories + testcontainers helper
Schema:
- 3 goose migrations under internal/core/migrations/ (tokens, events, indexes)
- All spec §7.1 columns + types + CHECK constraints present
- All 8 spec indexes present, including 2 partial indexes
- FK ON DELETE CASCADE on events.token_id (verified by TestRepository_FKCascade)
- chk_token_type enforces the 7-token locked enum exactly
Repositories:
- token: Insert / GetByID / GetByManageID / DeleteByManageID / IncrementTriggerCount /
SetEnabled / ListAll / CountAll
- event: Insert / GetByID / ListByToken (cursor pagination, LIMIT N+1 trick) /
CountByToken / AttachFingerprint (jsonb || merge into most-recent within
configurable window) / UpdateNotifyStatus / PruneToLimit (window function)
- Both: ErrNotFound on sql.ErrNoRows; all errors wrapped with %w; Repository struct
+ NewRepository(*sqlx.DB) constructor pattern matches template
Tests:
- 11 token integration tests + 9 event integration tests, all PASS
- testcontainers/postgres:18-alpine spins per test (~5-7s each)
- Tagged //go:build integration so plain `go test ./...` stays cheap
- Coverage: insert, get, not-found, delete with cascade, atomic increment,
enable toggle, list pagination across 3 pages, fingerprint merge preserving
existing extras, prune-keeps-newest, prune-rejects-zero, type CHECK rejection
Wired into main.go: core.RunMigrations(db.DB.DB) on startup; tokenRepo +
eventRepo blank-assigned (services consume them in Phase 9/10).
Audit findings (informational, non-blocking, deferred):
- Spec text says CHECK names 'chk_type'/'chk_channel'; implementation uses
'chk_token_type'/'chk_alert_channel' (audit prompt's expected names — both
agents endorse). Functionally identical; spec literal could be amended.
- main.go uses 'db.DB.DB' triple-chain to pass *sql.DB to goose. Visually
awkward; a Database.SQLDB() accessor would clean it up. Cleanup pass later.
- Default list limits (50, 20) are inline literals; hoisting to package consts
would satisfy MEMORY.md 'no magic numbers' rule. Minor.
- ptr[T any] helper duplicated across token + event test files. Could move to
testutil. Trivial.
- spec §12.4 ENVIRONMENT vs APP_ENVIRONMENT mismatch (logged in Phase 0
rollup) carries forward; not Phase 1's concern.
Verification at phase boundary:
- go build ./... clean
- go vet ./... clean
- go test -tags=integration ./internal/token/... 11/11 PASS
- go test -tags=integration ./internal/event/... 9/9 PASS
Phase 1 complete. Next: Phase 2 (generator interface + webbug + 1×1 GIF).
This commit is contained in:
parent
b2558e2e41
commit
7a98ef8d72