First building block for parallel-safe BDD scenario isolation (T12 plan,
ADR-0025 follow-up). PR #28 had to revert BDD_SCHEMA_ISOLATION because
SetupScenarioSchema created an empty schema without migrations -- the
production server's repo never saw it. This PR adds the missing piece:
a factory that opens a *PostgresRepository connected via an arbitrary
DSN AND runs AutoMigrate against it, so a per-scenario schema actually
gets the users table.
Public API additions in pkg/user/postgres_repository.go:
- NewPostgresRepositoryFromDSN(cfg, dsn) (*PostgresRepository, error)
Opens the repo from an explicit DSN (overrides cfg's host/port/etc),
runs AutoMigrate -- creates tables in whatever schema the DSN's
search_path points to.
- BuildSchemaIsolatedDSN(cfg, schemaName) string
Builds a DSN with `search_path=<schemaName>` from a base config.
The existing NewPostgresRepository(cfg) is unchanged. Existing Close()
method is reused.
Integration test in postgres_repository_isolated_test.go proves:
- AutoMigrate creates `users` table in the per-scenario schema (not public)
- A CreateUser through the isolated repo writes into the per-scenario schema
- public.users sees ZERO rows for the test username
- The per-scenario schema users table sees exactly 1 row
Test skips gracefully when DLC_DATABASE_HOST is not set.
Out of scope (T12 stage 2/2 next):
- Wiring this factory into pkg/bdd/testserver/SetupScenarioSchema
- Spawning a fresh server.Server per scenario (requires NewServerWithUserRepo)
- Removing -p 1 from scripts/run-bdd-tests.sh after parallel safety is achieved
Per code-reviewer skill SOLID/DDD section :
- SRP : factory has single responsibility (open + migrate, no business logic)
- OCP : the new factory extends the package without changing existing callers
- Cognitive load : 1 file, 50 lines added, 1 dedicated test file
🤖 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>