- PostgresStore struct with *sql.DB field (no mutex needed for PostgreSQL)
- NewPostgresStore constructor with pool config: MaxOpenConns(25), MaxIdleConns(5), ConnMaxLifetime(5m)
- UpsertEvent with $1..$15 positional params and ON CONFLICT DO UPDATE
- GetUpdates identical SQL to SQLiteStore (TEXT timestamps, COALESCE)
- AcknowledgeUpdate uses NOW() instead of datetime('now')
- ListTags identical to SQLiteStore
- CreateTag uses RETURNING id (pgx does not support LastInsertId)
- DeleteTag, UnassignTag, TagExists use $1 positional param
- AssignTag uses ON CONFLICT (image) DO UPDATE SET tag_id = EXCLUDED.tag_id