Architecture Spine: PostgreSQL Database Migration & Provider Abstraction¶
Status: Final
Altitude: Feature / Platform Component
Date: 2026-08-24
1. Architectural Paradigms & Invariants¶
This architecture establishes a Provider-Agnostic Relational Database Layer utilizing the Repository Pattern, Abstract Driver Factories, and Dual-Mode Connection Management (Local Postgres vs Supabase Transaction Pooler).
Invariant Decisions (ADs)¶
[AD-1] Async-Native Database Driver & Query Engine¶
- Binds:
backend/app/db/,backend/app/services/, all repository modules. - Prevents: Synchronous blocking database calls, driver fragmentation, and dialect lock-in.
- Rule: All database operations must use SQLAlchemy 2.0 (
AsyncEngine,AsyncSession) withasyncpgorpsycopg(v3). Direct database driver imports (sqlite3,psycopg2) in domain or route layers are strictly forbidden.
[AD-2] Dual-Mode Environment & Provider Abstraction¶
- Binds:
backend/app/config.py, database connection factory. - Prevents: Vendor lock-in to Supabase or Cloud Run / local environment coupling.
- Rule: The system MUST connect via a single environment-driven connection interface:
- Local: Direct Postgres instance (
postgresql+asyncpg://postgres:postgres@localhost:5432/app_db). - Production (Supabase): Connection pooling via PgBouncer (
postgresql+asyncpg://postgres.xxxx:[PASSWORD]@aws-0-region.pooler.supabase.com:6543/postgres?ssl=require). - Provider Swappability: Changing from Supabase to AWS RDS, GCP Cloud SQL, CockroachDB, or Neon requires ONLY updating
DATABASE_URL/ environment variables.
[AD-3] Repository Pattern with Strict Interface Segregation¶
- Binds:
backend/app/repositories/(IOrganizationRepository,IWorkItemRepository,IInterruptRepository,IThreadMetadataRepository). - Prevents: Leakage of SQL/ORM details into FastAPI routes or domain services.
- Rule: Domain services and API endpoints MUST depend exclusively on Abstract Base Classes (interfaces). Concrete repository implementations execute queries via AsyncSession injected through FastAPI dependency injection (
Depends(get_db_session)).
[AD-4] LangGraph Checkpointer Migration (AsyncPostgresSaver)¶
- Binds:
backend/app/services/thread_manager.py,backend/app/orchestrator/supervisor.py. - Prevents: File system dependencies (
storage/*.sqlite), thread concurrency bottlenecks, and single-instance locks. - Rule: LangGraph agent state persistence is backed by
langgraph-checkpoint-postgres(AsyncPostgresSaver). Initialization occurs during FastAPI lifespan startup (app.py), reusing the shared async connection pool.
[AD-5] Schema Versioning & DDL Management (Alembic)¶
- Binds:
backend/alembic/, database schema definitions. - Prevents: Embedded
CREATE TABLElogic in python repository files and schema drift between local and production. - Rule: Schema migrations are managed strictly through Alembic. Raw DDL execution in Python app code is replaced by Alembic migration scripts.
[AD-6] PostgreSQL Test Isolation Strategy¶
- Binds:
backend/tests/,conftest.py. - Prevents: Flaky tests, test pollution, or fallback to in-memory SQLite.
- Rule: All automated unit/integration tests run against a dedicated Postgres database/schema or isolated nested transactions (
savepoint).
[AD-7] Zero SQLite Policy & Cleanup¶
- Binds: Entire repository (backend code, tests, scripts,
.gitignore, documentation). - Prevents: Residual SQLite files, dead code, dangling
langgraph-checkpoint-sqlitepackages, and documentation confusion. - Rule: Every instance of SQLite,
SqliteSaver,sqlite3, andstorage/*.sqliteis replaced or removed. Zero references to SQLite remain in the codebase.
2. Structural Component Diagram¶
graph TD
subgraph FastAPI Application
API[API Routes / Controllers] --> |Depends| Service[Domain Services]
Service --> |Depends| IRepo[Abstract Repositories]
Supervisor[LangGraph Supervisor] --> |State Checkpoint| PGCheckpointer[AsyncPostgresSaver]
end
subgraph Persistence Layer
IRepo --> |Impl| PostgresRepo[Postgres Repositories]
PostgresRepo --> |AsyncSession| Engine[SQLAlchemy AsyncEngine / Pool]
PGCheckpointer --> |Pool| Engine
end
subgraph Environment Configuration
Engine --> Config[Pydantic DatabaseConfig]
Config --> |Local Env| LocalPG[(Local PostgreSQL 5432)]
Config --> |Prod Env| SupabasePG[(Supabase PgBouncer 6543)]
Config --> |Future Env| AWS_RDS[(AWS RDS / Neon / GCP Cloud SQL)]
end 3. Non-Functional Requirements (NFR Matrix)¶
| Category | Requirement | Implementation Design |
|---|---|---|
| Scalability | High concurrent read/write support | PgBouncer transaction pooling in production; async non-blocking IO (asyncpg) |
| Testability | Fast, isolated test suite | Pytest AsyncSession fixtures with nested transaction savepoints / rollback |
| Flexibility | Provider-agnostic architecture | Environment-driven DATABASE_URL + SQLAlchemy abstraction + Repository pattern |
| Maintainability | Clean schema version control | Alembic migration scripts tracking DDL history |
| Security | Encrypted production transport | SSL Mode (sslmode=require) enforced for cloud Postgres (Supabase) |
4. Deferred Invariants¶
- Database read-replica routing (Deferred until read volume requires replica splitting).
- Multi-region DB failover routing (Deferred until multi-region deployment is scoped).