feat: Persist review comments to database

Review comments on phase diffs now survive page reloads and phase
switches. Adds review_comments table (migration 0028), repository
port/adapter (13th repo), tRPC procedures (listReviewComments,
createReviewComment, resolveReviewComment, unresolveReviewComment),
and replaces useState-based comments in ReviewTab with tRPC queries
and mutations.
This commit is contained in:
Lukas May
2026-03-05 11:16:54 +01:00
parent 69d2543995
commit 173c7f7916
14 changed files with 293 additions and 27 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` — 12 repository interfaces
- **Adapters** (implementations): `apps/server/db/repositories/drizzle/*.ts` — 12 Drizzle adapters
- **Ports** (interfaces): `apps/server/db/repositories/*.ts` — 13 repository interfaces
- **Adapters** (implementations): `apps/server/db/repositories/drizzle/*.ts` — 13 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.
@@ -195,9 +195,27 @@ Messages within a chat session.
Index: `(chatSessionId)`.
### review_comments
Inline review comments on phase diffs, persisted across page reloads.
| Column | Type | Notes |
|--------|------|-------|
| id | text PK | nanoid |
| phaseId | text FK → phases (cascade) | scopes comment to phase |
| filePath | text NOT NULL | file in diff |
| lineNumber | integer NOT NULL | line number (new-side or old-side for deletions) |
| lineType | text enum | 'added' \| 'removed' \| 'context' |
| body | text NOT NULL | comment text |
| author | text NOT NULL | default 'you' |
| resolved | integer/boolean | default false |
| createdAt, updatedAt | integer/timestamp | |
Index: `(phaseId)`.
## Repository Interfaces
12 repositories, each with standard CRUD plus domain-specific methods:
13 repositories, each with standard CRUD plus domain-specific methods:
| Repository | Key Methods |
|-----------|-------------|
@@ -213,6 +231,7 @@ Index: `(chatSessionId)`.
| LogChunkRepository | insertChunk, findByAgentId, deleteByAgentId, getSessionCount |
| ConversationRepository | create, findById, findPendingForAgent, answer |
| ChatSessionRepository | createSession, findActiveSession, findActiveSessionByAgentId, updateSession, createMessage, findMessagesBySessionId |
| ReviewCommentRepository | create, findByPhaseId, resolve, unresolve, delete |
## Migrations
@@ -224,4 +243,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 0027 (28 total).
Current migrations: 0000 through 0028 (29 total).

View File

@@ -113,6 +113,10 @@ Each procedure uses `require*Repository(ctx)` helpers that throw `TRPCError(INTE
| getPhaseReviewCommits | query | List commits between initiative and phase branch |
| getCommitDiff | query | Diff for a single commit (by hash) in a phase |
| approvePhaseReview | mutation | Approve and merge phase branch |
| listReviewComments | query | List review comments by phaseId |
| createReviewComment | mutation | Create inline review comment on diff |
| resolveReviewComment | mutation | Mark review comment as resolved |
| unresolveReviewComment | mutation | Mark review comment as unresolved |
### Phase Dispatch
| Procedure | Type | Description |