Context
Follow-up to #1670 based on review feedback.
Currently, atepg.Connect dials and owns the primary PostgreSQL connection pool internally, and ateapi opens a separate dedicated *pgxpool.Pool (NewPool) for authz.NewServer because OpenFGA's postgres.Datastore.Close() closes the underlying pool. Additionally, authz.NewServer constructs stateful dependencies (datastore and fgaServer) inline rather than receiving them via dependency injection.
Goals
-
Share a single primary PostgreSQL connection pool between atepg and OpenFGA:
- Dial the
*pgxpool.Pool in cmd/ateapi/main.go and manage its lifecycle at the top level (defer pool.Close()).
- Inject the shared pool into both
atepg and OpenFGA to avoid extra connection pool pressure on PostgreSQL.
- Ensure shutdown ordering (
defer LIFO in main.go) cleanly stops fgaServer and atepg background loops before closing the shared pool.
-
Manage OpenFGA datastore and fgaServer lifecycles in main.go:
- Expose initialization helpers in
internal/authz (e.g., ApplyMigrations, store/model bootstrapping) rather than constructing and closing datastore and fgaServer inline inside authz.NewServer.
- Use unconditional
defer statements in cmd/ateapi/main.go for datastore.Close() and fgaServer.Close() so panics or startup errors cannot leak open resources.
-
Simplify internal/authz wrapper struct:
- Re-evaluate the
authz.Server wrapper alongside control-plane API authorization call sites (Check, Write, Read) so it only encapsulates what callers need (storeID, modelID, and domain helpers).
Acceptance Criteria
Context
Follow-up to #1670 based on review feedback.
Currently,
atepg.Connectdials and owns the primary PostgreSQL connection pool internally, andateapiopens a separate dedicated*pgxpool.Pool(NewPool) forauthz.NewServerbecause OpenFGA'spostgres.Datastore.Close()closes the underlying pool. Additionally,authz.NewServerconstructs stateful dependencies (datastoreandfgaServer) inline rather than receiving them via dependency injection.Goals
Share a single primary PostgreSQL connection pool between
atepgand OpenFGA:*pgxpool.Poolincmd/ateapi/main.goand manage its lifecycle at the top level (defer pool.Close()).atepgand OpenFGA to avoid extra connection pool pressure on PostgreSQL.deferLIFO inmain.go) cleanly stopsfgaServerandatepgbackground loops before closing the shared pool.Manage OpenFGA
datastoreandfgaServerlifecycles inmain.go:internal/authz(e.g.,ApplyMigrations, store/model bootstrapping) rather than constructing and closingdatastoreandfgaServerinline insideauthz.NewServer.deferstatements incmd/ateapi/main.gofordatastore.Close()andfgaServer.Close()so panics or startup errors cannot leak open resources.Simplify
internal/authzwrapper struct:authz.Serverwrapper alongside control-plane API authorization call sites (Check,Write,Read) so it only encapsulates what callers need (storeID,modelID, and domain helpers).Acceptance Criteria
cmd/ateapi/main.godials the shared*pgxpool.Pooland injects it intoatepgand OpenFGA.atepg.Persistence.NewPoolis removed in favor of the shared injected pool.datastoreandfgaServerlifecycles are managed viadeferinmain.go.