Documentation
¶
Overview ¶
Package postgres provides a Postgres-backed implementation of service.Repository for the identity service.
This is an alternative to the EntDB-backed repository. The two are interchangeable from the AuthService's point of view: both implement the same service.Repository interface.
Why Postgres ¶
Postgres is well understood, ubiquitous in production environments, and ships with a mature ops toolkit (pg_dump, pg_basebackup, replicas, PITR via WAL archiving). It is the right default for teams that want to run identity without taking a dependency on the tenant-shard-db stack.
Driver choice ¶
The implementation uses pgx/v5 directly (not via database/sql). pgxpool.Pool gives us a tuneable connection pool; pgx is also faster than database/sql and exposes Postgres-specific features (LISTEN / NOTIFY, COPY, JSONB native typing) that we may want later.
Migrations ¶
Schema DDL lives under migrations/ and is applied via golang-migrate/migrate using the embed.FS source. By default New() does NOT run pending migrations on connect — production deploys run migrations out-of-band as a separate Job, so a rolling rollout never races two replicas to apply the same change. Set Config.AutoMigrate to true (or GATEWAY_POSTGRES_AUTO_MIGRATE=true) only for local dev and single-replica environments.
Multi-tenancy ¶
Every table carries a tenant_id text not null column and uniqueness constraints are scoped to (tenant_id, ...). A pgRepository instance is constructed with a single tenant_id and writes/reads only that tenant's rows.
Error mapping ¶
Postgres unique-violation errors (SQLSTATE 23505) are mapped to service.ErrAlreadyExists by errors.go::wrapPgErr. ErrNoRows is surfaced as a nil result (not an error), matching the existing in-memory and EntDB drivers.
Index ¶
Constants ¶
const DefaultConnTimeout = 5 * time.Second
DefaultConnTimeout is used when Config.ConnTimeout is zero.
const DefaultMaxConns int32 = 25
DefaultMaxConns is used when Config.MaxConns is zero.
Variables ¶
This section is empty.
Functions ¶
func New ¶
New constructs a Postgres-backed repository:
- Parse / validate cfg.
- Open a pgxpool with cfg.MaxConns, cfg.ConnTimeout.
- Optionally run pending migrations (cfg.AutoMigrate=true).
- Ping to fail fast on a misconfigured DSN.
The returned store implements both service.Repository and service.DB. The caller is responsible for keeping the *pgRepository alive for the lifetime of the service; pool resources are released by Close().
Types ¶
type Config ¶
type Config struct {
DSN string
MaxConns int32
ConnTimeout time.Duration
AutoMigrate bool
TenantID string
}
Config controls how the postgres repository connects to its database.
DSN is the libpq-style connection string, e.g.
postgres://user:pass@host:5432/dbname?sslmode=disable
MaxConns caps the underlying pgxpool. A zero value means "use the pgxpool default" (currently 4 + GOMAXPROCS-ish). 25 is the suggested default for an identity service node (see DefaultMaxConns).
ConnTimeout is the per-acquire timeout used when checking a connection out of the pool. It does NOT bound the total query time — callers are still responsible for passing a context with the appropriate deadline.
AutoMigrate controls whether New() applies pending schema migrations on first connect. In CI / dev / test we want true (the default); in strict production deploys teams may flip it to false and run `migrate ... up` from a deploy pipeline instead.
TenantID is the tenant whose rows this repository instance writes and reads. Multi-tenant deployments construct one repository per tenant; the most common single-tenant config plumbs cfg.DefaultTenantID straight through.
func ConfigFromEnv ¶
ConfigFromEnv reads Config values from GATEWAY_POSTGRES_* env vars. It is a convenience for callers that don't want to plumb each field through their own config struct. tenantID is passed in (rather than read from env) because identity already plumbs cfg.DefaultTenantID.
Source Files
¶
- config.go
- db.go
- doc.go
- email_change.go
- email_verification.go
- errors.go
- identity_verification.go
- invitation.go
- login_challenge.go
- migrations.go
- oauth_identity.go
- oauth_one_time_code.go
- organization.go
- passkey.go
- password_reset.go
- qr_login.go
- recovery_code.go
- refresh_token.go
- repo.go
- session.go
- sweeper.go
- totp.go
- tracepool.go
- user.go