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>
6.6 KiB
6.6 KiB
| phase | plan | type | wave | depends_on | files_modified | autonomous | must_haves | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 01-core-infrastructure-security | 02 | execute | 1 |
|
true |
|
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_isreadybackend/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_dbasync 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 -dWait 5 seconds for postgres to start. Run:docker compose exec postgres pg_isready -U debateExpected: "accepting connections" PostgreSQL container running, async session factory configured with connection pooling.
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>