- Add 03-01-SUMMARY.md with full execution record - Update STATE.md: advance to plan 2, record metrics and decisions - Update ROADMAP.md: phase 03 in progress (1/2 plans complete) - Update REQUIREMENTS.md: mark DB-01 and DB-03 complete
4.7 KiB
4.7 KiB
phase, plan, subsystem, tags, dependency_graph, tech_stack, key_files, decisions, metrics
| phase | plan | subsystem | tags | dependency_graph | tech_stack | key_files | decisions | metrics | |||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 03-postgresql-support | 01 | persistence |
|
|
|
|
|
|
Phase 03 Plan 01: PostgreSQL Store and Migration Infrastructure Summary
PostgresStore implementing all 9 Store interface methods using pgx/v5 stdlib adapter, plus PostgreSQL migration infrastructure with RunPostgresMigrations and renamed RunSQLiteMigrations.
What Was Built
PostgresStore (pkg/diunwebhook/postgres_store.go)
Full implementation of the Store interface for PostgreSQL:
NewPostgresStoreconstructor with connection pool:MaxOpenConns(25),MaxIdleConns(5),ConnMaxLifetime(5m)- All 9 methods:
UpsertEvent,GetUpdates,AcknowledgeUpdate,ListTags,CreateTag,DeleteTag,AssignTag,UnassignTag,TagExists - PostgreSQL-native SQL:
$1..$15positional params,NOW(),RETURNING id,ON CONFLICT DO UPDATE - No
sync.Mutex— PostgreSQL handles concurrent writes natively
PostgreSQL Migrations (pkg/diunwebhook/migrations/postgres/)
0001_initial_schema.up.sql: Creates same 3 tables as SQLite (updates,tags,tag_assignments); usesSERIAL PRIMARY KEYfortags.id; timestamps remainTEXTto match scan logic0001_initial_schema.down.sql: Drops all 3 tables in dependency order
Updated migrate.go
RunMigrationsrenamed toRunSQLiteMigrationsRunPostgresMigrationsadded usingpgxmigratedriver with"pgx5"database name- Second
//go:embed migrations/postgresdirective added forpostgresMigrations
Decisions Made
| Decision | Rationale |
|---|---|
| TEXT timestamps in PostgreSQL schema | Avoids scan divergence with SQLiteStore; both stores parse RFC3339 strings identically |
| RETURNING id in CreateTag | pgx driver does not implement LastInsertId; RETURNING is the PostgreSQL-idiomatic approach |
| ON CONFLICT (image) DO UPDATE in AssignTag | Replaces SQLite's INSERT OR REPLACE; functionally equivalent upsert in standard SQL |
| No mutex in PostgresStore | PostgreSQL connection pool + MVCC handles concurrency; mutex would serialize unnecessarily |
| Both drivers compiled into binary | Simpler than build tags; binary size cost acceptable for a server binary |
Deviations from Plan
Auto-fixed Issues
1. [Rule 1 - Bug] Updated export_test.go to use renamed function
- Found during: Task 1 verification
- Issue:
go vet ./pkg/diunwebhook/failed becauseexport_test.gostill referencedRunMigrations(renamed toRunSQLiteMigrations). The plan's acceptance criteria requiresgo vetto exit 0, which takes precedence over the instruction to defer export_test.go changes to Plan 02. - Fix: Updated both
NewTestServerandNewTestServerWithSecretinexport_test.goto callRunSQLiteMigrations - Files modified:
pkg/diunwebhook/export_test.go - Commit:
95b64b4
Verification Results
go build ./pkg/diunwebhook/exits 0go vet ./pkg/diunwebhook/exits 0- PostgreSQL migration UP contains
SERIAL PRIMARY KEY, all 3 tables - PostgreSQL migration DOWN contains
DROP TABLE IF EXISTSfor all 3 tables go.modcontainsgithub.com/jackc/pgx/v5 v5.9.1migrate.goexports bothRunSQLiteMigrationsandRunPostgresMigrations
Known Stubs
None — this plan creates implementation code, not UI stubs.