debate/.planning/phases/01-core-infrastructure-security/01-02-PLAN.md
Mikkel Georgsen 262a32673b docs(01): create phase plan
Phase 01: Core Infrastructure & Security
- 5 plans in 3 waves
- 3 parallel (Wave 1-2), 1 sequential (Wave 3)
- Ready for execution

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 19:59:49 +00:00

6.6 KiB

phase plan type wave depends_on files_modified autonomous must_haves
01-core-infrastructure-security 02 execute 1
backend/app/db/__init__.py
backend/app/db/base.py
backend/app/db/session.py
backend/app/db/models/__init__.py
backend/app/db/models/build.py
backend/alembic.ini
backend/alembic/env.py
backend/alembic/script.py.mako
backend/alembic/versions/.gitkeep
docker-compose.yml
true
truths artifacts key_links
PostgreSQL container starts and accepts connections
Alembic migrations run without errors
Database session factory creates async sessions
Build model persists to database
path provides contains
backend/app/db/session.py Async database session factory async_sessionmaker
path provides contains
backend/app/db/base.py SQLAlchemy declarative base DeclarativeBase
path provides contains
backend/app/db/models/build.py Build tracking model class Build
path provides contains
backend/alembic/env.py Alembic migration environment run_migrations_online
path provides contains
docker-compose.yml PostgreSQL container configuration postgres
from to via pattern
backend/app/db/session.py backend/app/core/config.py settings.database_url settings.database_url
from to via pattern
backend/alembic/env.py backend/app/db/base.py target_metadata target_metadata.*Base.metadata
Set up PostgreSQL database with async SQLAlchemy, Alembic migrations, and initial build tracking model.

Purpose: Establish the data persistence layer that tracks builds, users, and configurations. Output: Running PostgreSQL instance, async session factory, and migration infrastructure with initial Build model.

<execution_context> @/home/mikkel/.claude/get-shit-done/workflows/execute-plan.md @/home/mikkel/.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/phases/01-core-infrastructure-security/01-RESEARCH.md (Pattern 1: Async Database Session Management, Code Examples: Database Migrations with Alembic) Task 1: Set up PostgreSQL with Docker and async session factory docker-compose.yml backend/app/db/__init__.py backend/app/db/base.py backend/app/db/session.py Create docker-compose.yml: - PostgreSQL 18 service (postgres:18-alpine image if available, or postgres:16-alpine) - Container name: debate-postgres - Environment: POSTGRES_USER=debate, POSTGRES_PASSWORD=debate_dev, POSTGRES_DB=debate - Port: 5432:5432 - Volume: postgres_data for persistence - Health check on pg_isready

backend/app/db/init.py:

  • Empty or re-export key items

backend/app/db/base.py:

  • Create SQLAlchemy 2.0 DeclarativeBase
  • Import all models (for Alembic autogenerate)
  • Pattern: class Base(DeclarativeBase): pass

backend/app/db/session.py:

  • Import settings from core.config
  • Create async engine with connection pooling (from research):
    • pool_size=10
    • max_overflow=20
    • pool_timeout=30
    • pool_recycle=1800
    • pool_pre_ping=True
  • Create async_sessionmaker factory
  • Create get_db async generator dependency for FastAPI

Update .env.example (if not already done):

  • DATABASE_URL=postgresql+asyncpg://debate:debate_dev@localhost:5432/debate Run: cd /home/mikkel/repos/debate && docker compose up -d Wait 5 seconds for postgres to start. Run: docker compose exec postgres pg_isready -U debate Expected: "accepting connections" PostgreSQL container running, async session factory configured with connection pooling.
Task 2: Configure Alembic and create Build model backend/alembic.ini backend/alembic/env.py backend/alembic/script.py.mako backend/alembic/versions/.gitkeep backend/app/db/models/__init__.py backend/app/db/models/build.py Initialize Alembic in backend directory: ```bash cd backend && alembic init alembic ```

Modify backend/alembic.ini:

  • Set script_location = alembic
  • Remove sqlalchemy.url (we'll set it from config)

Modify backend/alembic/env.py:

  • Import asyncio, async_engine_from_config
  • Import settings from app.core.config
  • Import Base from app.db.base (this imports all models)
  • Set sqlalchemy.url from settings.database_url
  • Implement run_migrations_online() as async function (from research)
  • Use asyncio.run() for async migrations

Create backend/app/db/models/init.py:

  • Import all models for Alembic discovery

Create backend/app/db/models/build.py:

  • Build model with fields:
    • id: UUID primary key (use uuid.uuid4)
    • config_hash: String(64), unique, indexed (SHA-256 of configuration)
    • status: Enum (pending, building, completed, failed, cached)
    • iso_path: Optional String (path to generated ISO)
    • error_message: Optional Text (for failed builds)
    • build_log: Optional Text (full build output)
    • started_at: DateTime (nullable, set when build starts)
    • completed_at: DateTime (nullable, set when build finishes)
    • created_at: DateTime with server default now()
    • updated_at: DateTime with onupdate
  • Add index on status for queue queries
  • Add index on config_hash for cache lookups

Update backend/app/db/base.py to import Build model.

Generate and run initial migration:

cd backend && alembic revision --autogenerate -m "Create build table"
cd backend && alembic upgrade head
Run: `cd /home/mikkel/repos/debate/backend && alembic current` Expected: Shows current migration head. Run: `docker compose exec postgres psql -U debate -d debate -c "\\dt"` Expected: Shows "builds" table. Alembic configured for async, Build model created with migration applied. 1. `docker compose ps` shows postgres container running and healthy 2. `cd backend && alembic current` shows migration applied 3. `docker compose exec postgres psql -U debate -d debate -c "SELECT * FROM builds LIMIT 1;"` succeeds (empty result OK) 4. `ruff check backend/app/db/` passes 5. Database has builds table with correct columns

<success_criteria>

  • PostgreSQL 18 running in Docker with health checks
  • Async session factory with proper connection pooling
  • Alembic configured for async migrations
  • Build model exists with config_hash, status, timestamps
  • Initial migration applied successfully </success_criteria>
After completion, create `.planning/phases/01-core-infrastructure-security/01-02-SUMMARY.md`