aboutsummaryrefslogtreecommitdiffhomepage
path: root/backend/db/txmanager.go
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-02-15 22:13:50 +0900
committernsfisis <nsfisis@gmail.com>2026-02-15 22:16:22 +0900
commit5ed369a6c70707543fd5ec9a13c79851fdfc5d6c (patch)
treee5678d6d88fab3ac0ae8c05b85236f3e7d5eddfd /backend/db/txmanager.go
parent87e9f5ed48af3a8dca5f6373ae900336f285eef5 (diff)
downloadphperkaigi-2026-albatross-5ed369a6c70707543fd5ec9a13c79851fdfc5d6c.tar.gz
phperkaigi-2026-albatross-5ed369a6c70707543fd5ec9a13c79851fdfc5d6c.tar.zst
phperkaigi-2026-albatross-5ed369a6c70707543fd5ec9a13c79851fdfc5d6c.zip
refactor(backend): introduce DI interfaces for testability
Replace concrete *db.Queries and *pgxpool.Pool dependencies with db.Querier and db.TxManager interfaces across all handlers, game hub, and auth. This enables unit testing with mocks. - Enable sqlc emit_interface to generate Querier interface - Add TxManager abstraction to encapsulate transactions - Convert auth package-level functions to Authenticator struct - Add TaskQueueInterface/TaskWorkerInterface for game.Hub - Add initial unit tests for game logic and API handlers Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'backend/db/txmanager.go')
-rw-r--r--backend/db/txmanager.go40
1 files changed, 40 insertions, 0 deletions
diff --git a/backend/db/txmanager.go b/backend/db/txmanager.go
new file mode 100644
index 0000000..9495288
--- /dev/null
+++ b/backend/db/txmanager.go
@@ -0,0 +1,40 @@
+package db
+
+import (
+ "context"
+ "log/slog"
+
+ "github.com/jackc/pgx/v5"
+ "github.com/jackc/pgx/v5/pgxpool"
+)
+
+type TxManager interface {
+ RunInTx(ctx context.Context, fn func(q Querier) error) error
+}
+
+type PgxTxManager struct {
+ pool *pgxpool.Pool
+ queries *Queries
+}
+
+func NewTxManager(pool *pgxpool.Pool, queries *Queries) *PgxTxManager {
+ return &PgxTxManager{pool: pool, queries: queries}
+}
+
+func (m *PgxTxManager) RunInTx(ctx context.Context, fn func(q Querier) error) error {
+ tx, err := m.pool.Begin(ctx)
+ if err != nil {
+ return err
+ }
+ defer func() {
+ if err := tx.Rollback(ctx); err != nil && err != pgx.ErrTxClosed {
+ slog.Error("failed to rollback transaction", "error", err)
+ }
+ }()
+
+ qtx := m.queries.WithTx(tx)
+ if err := fn(qtx); err != nil {
+ return err
+ }
+ return tx.Commit(ctx)
+}