88 lines
3.5 KiB
Markdown
88 lines
3.5 KiB
Markdown
# Phase 3: PostgreSQL Support - Discussion Log
|
|
|
|
> **Audit trail only.** Do not use as input to planning, research, or execution agents.
|
|
> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.
|
|
|
|
**Date:** 2026-03-24
|
|
**Phase:** 03-postgresql-support
|
|
**Areas discussed:** PostgreSQL driver interface, SQL dialect handling, Connection pooling, Docker Compose integration, Testing strategy
|
|
**Mode:** Auto (all selections made by Claude using recommended defaults)
|
|
|
|
---
|
|
|
|
## PostgreSQL Driver Interface
|
|
|
|
| Option | Description | Selected |
|
|
|--------|-------------|----------|
|
|
| pgx/v5/stdlib (database/sql adapter) | Matches SQLiteStore's *sql.DB pattern, Store interface unchanged | ✓ |
|
|
| pgx native interface | More features (COPY, batch), but different API from SQLiteStore | |
|
|
| lib/pq | Legacy driver, less maintained | |
|
|
|
|
**User's choice:** [auto] pgx/v5/stdlib — recommended for consistency with existing database/sql pattern
|
|
**Notes:** Keeping both stores on database/sql means identical constructor signatures and no Store interface changes.
|
|
|
|
---
|
|
|
|
## SQL Dialect Handling
|
|
|
|
| Option | Description | Selected |
|
|
|--------|-------------|----------|
|
|
| Separate SQL per store | Each store has its own raw SQL, no shared templates | ✓ |
|
|
| Runtime dialect switching | Single store with if/else for dialect differences | |
|
|
| Query builder (squirrel/goqu) | Abstract SQL differences behind builder API | |
|
|
|
|
**User's choice:** [auto] Separate SQL per store — recommended per project constraint (no ORM/query builder)
|
|
**Notes:** PROJECT.md explicitly states "No ORM or query builder — raw SQL per store implementation."
|
|
|
|
---
|
|
|
|
## Connection Pooling
|
|
|
|
| Option | Description | Selected |
|
|
|--------|-------------|----------|
|
|
| Standard pool defaults | MaxOpenConns(25), MaxIdleConns(5), ConnMaxLifetime(5m) | ✓ |
|
|
| Minimal single-connection | Match SQLite's MaxOpenConns(1) | |
|
|
| Configurable via env vars | Let users tune pool settings | |
|
|
|
|
**User's choice:** [auto] Standard pool defaults — appropriate for low-traffic self-hosted dashboard
|
|
**Notes:** PostgreSQL handles concurrent writes natively, so no mutex needed unlike SQLiteStore.
|
|
|
|
---
|
|
|
|
## Docker Compose Integration
|
|
|
|
| Option | Description | Selected |
|
|
|--------|-------------|----------|
|
|
| Docker Compose profiles | `--profile postgres` activates postgres service | ✓ |
|
|
| Separate compose file | compose.postgres.yml alongside compose.yml | |
|
|
| Always include postgres | Postgres service always defined, user enables via DATABASE_URL | |
|
|
|
|
**User's choice:** [auto] Docker Compose profiles — keeps simple deploys unchanged, opt-in for postgres
|
|
**Notes:** ROADMAP success criterion #4 states "optional postgres service profile."
|
|
|
|
---
|
|
|
|
## Testing Strategy
|
|
|
|
| Option | Description | Selected |
|
|
|--------|-------------|----------|
|
|
| Build tag `//go:build postgres` | Tests only run when postgres available | ✓ |
|
|
| Testcontainers (auto-start postgres) | No external dependency needed | |
|
|
| Mock store for postgres tests | No real postgres needed, but less confidence | |
|
|
|
|
**User's choice:** [auto] Build tag — simplest approach, CI optionally runs with `-tags postgres`
|
|
**Notes:** Matches existing test pattern where SQLite tests always run. PostgreSQL tests are additive.
|
|
|
|
---
|
|
|
|
## Claude's Discretion
|
|
|
|
- Exact PostgreSQL connection pool tuning beyond defaults
|
|
- RunMigrations split strategy (two functions vs dialect parameter)
|
|
- Error message formatting for connection failures
|
|
- Health check endpoint (optional)
|
|
|
|
## Deferred Ideas
|
|
|
|
None — discussion stayed within phase scope.
|