refactor(db): set UTC timezone in pool config and add Querier docs

Set UTC timezone in pgxpool config to ensure consistent timestamp handling. Add detailed doc comment to Querier interface clarifying QueryRow vs Querier distinction.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-06-24 23:42:49 +01:00
co-authored by Sisyphus
parent 6ec2cf1d69
commit 08c8828bb0
3 changed files with 26 additions and 2 deletions
+6 -1
View File
@@ -23,7 +23,12 @@ func Connect() error {
getEnv("POSTGRES_DB"), getEnv("POSTGRES_DB"),
) )
pool, err := pgxpool.New(context.Background(), dsn) poolCfg, err := pgxpool.ParseConfig(dsn)
if err != nil {
return err
}
poolCfg.ConnConfig.RuntimeParams["timezone"] = "UTC"
pool, err := pgxpool.NewWithConfig(context.Background(), poolCfg)
if err != nil { if err != nil {
return err return err
} }
+6 -1
View File
@@ -22,7 +22,12 @@ func Connect() error {
getEnv("POSTGRES_DB"), getEnv("POSTGRES_DB"),
) )
pool, err := pgxpool.New(context.Background(), dsn) poolCfg, err := pgxpool.ParseConfig(dsn)
if err != nil {
return err
}
poolCfg.ConnConfig.RuntimeParams["timezone"] = "UTC"
pool, err := pgxpool.NewWithConfig(context.Background(), poolCfg)
if err != nil { if err != nil {
return err return err
} }
+14
View File
@@ -11,6 +11,20 @@ import (
// Querier is implemented by *pgxpool.Pool, pgx.Tx, and *PoolProxy. // Querier is implemented by *pgxpool.Pool, pgx.Tx, and *PoolProxy.
// Fixture functions and internal helpers that need to run queries should // Fixture functions and internal helpers that need to run queries should
// accept Querier to remain decoupled from transaction state. // accept Querier to remain decoupled from transaction state.
//
// DISTINCTION: QueryRow vs Querier
// - QueryRow() (lowercase 'r') is a METHOD on Querier. It returns pgx.Row.
// Call it like: row := q.QueryRow(ctx, sql, args...)
// - Querier (uppercase 'Q') is an INTERFACE. It declares the QueryRow method.
// Accept Querier when a helper must work with both pool + transactions.
// - pgx.Row (singular) is the RETURN TYPE of QueryRow(). It is NOT a Querier.
// pgx.Row only has Scan(). You cannot pass a pgx.Row where Querier is expected.
//
// Common mistake:
// // WRONG — pgx.Row does not implement Querier:
// func helper(ctx, row pgx.Row) { ... }
// // CORRECT — accept Querier, call QueryRow inside:
// func helper(ctx, q db.Querier) { row := q.QueryRow(ctx, sql, args...); ... }
type Querier interface { type Querier interface {
Exec(ctx context.Context, sql string, args ...any) (pgconn.CommandTag, error) Exec(ctx context.Context, sql string, args ...any) (pgconn.CommandTag, error)
Query(ctx context.Context, sql string, args ...any) (pgx.Rows, error) Query(ctx context.Context, sql string, args ...any) (pgx.Rows, error)