Files
Codewalkers/docs/database.md
Lukas May 342b490fe7 feat: Task decomposition for Tailwind/Radix/shadcn foundation setup
Decomposed "Foundation Setup - Install Dependencies & Configure Tailwind"
phase into 6 executable tasks:

1. Install Tailwind CSS, PostCSS & Autoprefixer
2. Map MUI theme to Tailwind design tokens
3. Setup CSS variables for dynamic theming
4. Install Radix UI primitives
5. Initialize shadcn/ui and setup component directory
6. Move MUI to devDependencies and verify setup

Tasks follow logical dependency chain with final human verification
checkpoint before proceeding with component migration.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-10 09:48:51 +01:00

6.9 KiB

Database Module

src/db/ — SQLite database via better-sqlite3 + Drizzle ORM with hexagonal architecture.

Architecture

  • Schema: src/db/schema.ts — all tables, columns, relations
  • Ports (interfaces): src/db/repositories/*.ts — 10 repository interfaces
  • Adapters (implementations): src/db/repositories/drizzle/*.ts — 10 Drizzle adapters
  • Barrel exports: src/db/index.ts re-exports everything

All adapters use nanoid() for IDs, auto-manage timestamps, and use Drizzle's .returning() for atomic reads after writes.

Tables

initiatives

Column Type Notes
id text PK nanoid
name text NOT NULL
status text enum 'active' | 'completed' | 'archived', default 'active'
mergeRequiresApproval integer/boolean default true
mergeTarget text nullable target branch for merges
createdAt, updatedAt integer/timestamp

phases

Column Type Notes
id text PK
initiativeId text FK → initiatives (cascade)
name text NOT NULL
content text nullable Tiptap JSON
status text enum 'pending' | 'approved' | 'in_progress' | 'completed' | 'blocked'
createdAt, updatedAt integer/timestamp

phase_dependencies

phaseId FK → phases, dependsOnPhaseId FK → phases. Both cascade delete.

tasks

Column Type Notes
id text PK
phaseId text nullable FK → phases (cascade)
initiativeId text nullable FK → initiatives (cascade)
parentTaskId text nullable self-ref FK (cascade) decomposition hierarchy
name text NOT NULL
description text nullable
type text enum 'auto' | 'checkpoint:human-verify' | 'checkpoint:decision' | 'checkpoint:human-action'
category text enum 'execute' | 'research' | 'discuss' | 'breakdown' | 'decompose' | 'refine' | 'verify' | 'merge' | 'review'
priority text enum 'low' | 'medium' | 'high'
status text enum 'pending_approval' | 'pending' | 'in_progress' | 'completed' | 'blocked'
requiresApproval integer/boolean nullable null = inherit from initiative
order integer default 0
createdAt, updatedAt integer/timestamp

task_dependencies

taskId FK → tasks, dependsOnTaskId FK → tasks. Both cascade delete.

agents

Column Type Notes
id text PK
name text NOT NULL UNIQUE human-readable alias (adjective-animal)
taskId text nullable FK → tasks (set null)
initiativeId text nullable FK → initiatives (set null)
sessionId text nullable CLI session ID for resume
worktreeId text NOT NULL path to agent's git worktree
provider text NOT NULL default 'claude'
accountId text nullable FK → accounts (set null)
status text enum 'idle' | 'running' | 'waiting_for_input' | 'stopped' | 'crashed'
mode text enum 'execute' | 'discuss' | 'breakdown' | 'decompose' | 'refine'
pid integer nullable OS process ID
exitCode integer nullable
outputFilePath text nullable
result text nullable JSON
pendingQuestions text nullable JSON
userDismissedAt integer/timestamp nullable
createdAt, updatedAt integer/timestamp

accounts

Column Type Notes
id text PK
email text NOT NULL
provider text NOT NULL default 'claude'
configJson text nullable serialized .claude.json
credentials text nullable serialized .credentials.json
isExhausted integer/boolean default false
exhaustedUntil integer/timestamp nullable
lastUsedAt integer/timestamp nullable round-robin scheduling
sortOrder integer
createdAt, updatedAt integer/timestamp

proposals

Column Type Notes
id text PK
agentId text FK → agents (cascade)
initiativeId text FK → initiatives (cascade)
targetType text enum 'page' | 'phase' | 'task'
targetId text nullable existing entity ID, null for creates
title, summary, content text markdown body
metadata text nullable JSON
status text enum 'pending' | 'accepted' | 'dismissed'
sortOrder integer
createdAt, updatedAt integer/timestamp

pages

Column Type Notes
id text PK
initiativeId text FK → initiatives (cascade)
parentPageId text nullable self-ref FK (cascade) root page has NULL
title text NOT NULL
content text nullable Tiptap JSON
sortOrder integer
createdAt, updatedAt integer/timestamp

projects

Column Type Notes
id text PK
name text NOT NULL UNIQUE
url text NOT NULL UNIQUE git repo URL
createdAt, updatedAt integer/timestamp

initiative_projects (junction)

initiativeId + projectId with unique index. Both FK cascade.

messages

Self-referencing (parentMessageId) for threading. Sender/recipient types: 'agent' | 'user'.

agent_log_chunks

Column Type Notes
id text PK
agentId text NOT NULL NO FK — survives agent deletion
agentName text NOT NULL snapshot for display
sessionNumber integer spawn=1, resume=prev+1
content text NOT NULL raw JSONL chunk
createdAt integer/timestamp

Index on agentId for fast queries.

Repository Interfaces

10 repositories, each with standard CRUD plus domain-specific methods:

Repository Key Methods
InitiativeRepository create, findById, findAll, findByStatus, update, delete
PhaseRepository + createDependency, getDependencies, getDependents, findByInitiativeId
TaskRepository + findByParentTaskId, findByPhaseId, findPendingApproval, createDependency
AgentRepository + findByName, findByTaskId, findBySessionId, findByStatus
MessageRepository + findPendingForUser, findRequiringResponse, findReplies
PageRepository + findRootPage, getOrCreateRootPage, findByParentPageId
ProjectRepository + junction ops: setInitiativeProjects (diff-based), findProjectsByInitiativeId
AccountRepository + findNextAvailable (round-robin), markExhausted, clearExpiredExhaustion
ProposalRepository + findByAgentIdAndStatus, updateManyByAgentId, countByAgentIdAndStatus
LogChunkRepository insertChunk, findByAgentId, deleteByAgentId, getSessionCount

Migrations

Located in drizzle/. Applied via ensureSchema() on startup using Drizzle's migrate().

Key rules:

  • Never use raw SQL for schema initialization
  • Run npx drizzle-kit generate to create migrations
  • See database-migrations.md for full workflow
  • Snapshots stale after 0008; migrations 0008+ are hand-written

Current migrations: 0000 through 0018 (19 total).