feat: Add errands persistence layer — repository port, Drizzle adapter, migration, and tests

- Add errand-repository.ts port with ErrandRepository, ErrandWithAlias, ErrandStatus types
- Add DrizzleErrandRepository adapter with create, findById (left-joins agents for alias),
  findAll (optional projectId/status filters, desc by createdAt), update, delete
- Wire exports into repositories/index.ts and repositories/drizzle/index.ts
- Add migration 0035_faulty_human_fly.sql (CREATE TABLE errands) and drizzle snapshot
- Add 13 tests covering CRUD, filtering, ordering, agentAlias join, cascade/set-null FK behaviour
- Update docs/database.md to document the errands table and ErrandRepository

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lukas May
2026-03-06 12:35:06 +01:00
parent 5d1292c7ad
commit 940b0f8ed2
8 changed files with 2456 additions and 4 deletions

View File

@@ -5,8 +5,8 @@
## Architecture
- **Schema**: `apps/server/db/schema.ts` — all tables, columns, relations
- **Ports** (interfaces): `apps/server/db/repositories/*.ts` — 13 repository interfaces
- **Adapters** (implementations): `apps/server/db/repositories/drizzle/*.ts` — 13 Drizzle adapters
- **Ports** (interfaces): `apps/server/db/repositories/*.ts` — 14 repository interfaces
- **Adapters** (implementations): `apps/server/db/repositories/drizzle/*.ts` — 14 Drizzle adapters
- **Barrel exports**: `apps/server/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.
@@ -196,6 +196,21 @@ Messages within a chat session.
Index: `(chatSessionId)`.
### errands
Tracks errand work items linked to a project branch, optionally assigned to an agent.
| Column | Type | Notes |
|--------|------|-------|
| id | text PK | caller-supplied |
| description | text NOT NULL | human-readable description |
| branch | text NOT NULL | working branch name |
| baseBranch | text NOT NULL | default 'main' |
| agentId | text FK → agents (set null) | assigned agent; null if unassigned |
| projectId | text FK → projects (cascade) | owning project |
| status | text enum | active, pending_review, conflict, merged, abandoned; default 'active' |
| createdAt, updatedAt | integer/timestamp | |
### review_comments
Inline review comments on phase diffs, persisted across page reloads.
@@ -216,7 +231,7 @@ Index: `(phaseId)`.
## Repository Interfaces
13 repositories, each with standard CRUD plus domain-specific methods:
14 repositories, each with standard CRUD plus domain-specific methods:
| Repository | Key Methods |
|-----------|-------------|
@@ -233,6 +248,7 @@ Index: `(phaseId)`.
| ConversationRepository | create, findById, findPendingForAgent, answer |
| ChatSessionRepository | createSession, findActiveSession, findActiveSessionByAgentId, updateSession, createMessage, findMessagesBySessionId |
| ReviewCommentRepository | create, findByPhaseId, resolve, unresolve, delete |
| ErrandRepository | create, findById, findAll (filter by projectId/status), update, delete |
## Migrations
@@ -244,4 +260,4 @@ Key rules:
- See [database-migrations.md](database-migrations.md) for full workflow
- Snapshots stale after 0008; migrations 0008+ are hand-written
Current migrations: 0000 through 0030 (31 total).
Current migrations: 0000 through 0035 (36 total).