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:
@@ -18,6 +18,7 @@ import type { ChangeSetRepository } from '../db/repositories/change-set-reposito
|
||||
import type { LogChunkRepository } from '../db/repositories/log-chunk-repository.js';
|
||||
import type { ConversationRepository } from '../db/repositories/conversation-repository.js';
|
||||
import type { ChatSessionRepository } from '../db/repositories/chat-session-repository.js';
|
||||
import type { ReviewCommentRepository } from '../db/repositories/review-comment-repository.js';
|
||||
import type { AccountCredentialManager } from '../agent/credentials/types.js';
|
||||
import type { DispatchManager, PhaseDispatchManager } from '../dispatch/types.js';
|
||||
import type { CoordinationManager } from '../coordination/types.js';
|
||||
@@ -76,6 +77,8 @@ export interface TRPCContext {
|
||||
conversationRepository?: ConversationRepository;
|
||||
/** Chat session repository for iterative phase/task chat */
|
||||
chatSessionRepository?: ChatSessionRepository;
|
||||
/** Review comment repository for inline review comments on phase diffs */
|
||||
reviewCommentRepository?: ReviewCommentRepository;
|
||||
/** Absolute path to the workspace root (.cwrc directory) */
|
||||
workspaceRoot?: string;
|
||||
}
|
||||
@@ -106,6 +109,7 @@ export interface CreateContextOptions {
|
||||
previewManager?: PreviewManager;
|
||||
conversationRepository?: ConversationRepository;
|
||||
chatSessionRepository?: ChatSessionRepository;
|
||||
reviewCommentRepository?: ReviewCommentRepository;
|
||||
workspaceRoot?: string;
|
||||
}
|
||||
|
||||
@@ -139,6 +143,7 @@ export function createContext(options: CreateContextOptions): TRPCContext {
|
||||
previewManager: options.previewManager,
|
||||
conversationRepository: options.conversationRepository,
|
||||
chatSessionRepository: options.chatSessionRepository,
|
||||
reviewCommentRepository: options.reviewCommentRepository,
|
||||
workspaceRoot: options.workspaceRoot,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import type { ChangeSetRepository } from '../../db/repositories/change-set-repos
|
||||
import type { LogChunkRepository } from '../../db/repositories/log-chunk-repository.js';
|
||||
import type { ConversationRepository } from '../../db/repositories/conversation-repository.js';
|
||||
import type { ChatSessionRepository } from '../../db/repositories/chat-session-repository.js';
|
||||
import type { ReviewCommentRepository } from '../../db/repositories/review-comment-repository.js';
|
||||
import type { DispatchManager, PhaseDispatchManager } from '../../dispatch/types.js';
|
||||
import type { CoordinationManager } from '../../coordination/types.js';
|
||||
import type { BranchManager } from '../../git/branch-manager.js';
|
||||
@@ -203,3 +204,13 @@ export function requireChatSessionRepository(ctx: TRPCContext): ChatSessionRepos
|
||||
}
|
||||
return ctx.chatSessionRepository;
|
||||
}
|
||||
|
||||
export function requireReviewCommentRepository(ctx: TRPCContext): ReviewCommentRepository {
|
||||
if (!ctx.reviewCommentRepository) {
|
||||
throw new TRPCError({
|
||||
code: 'INTERNAL_SERVER_ERROR',
|
||||
message: 'Review comment repository not available',
|
||||
});
|
||||
}
|
||||
return ctx.reviewCommentRepository;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { TRPCError } from '@trpc/server';
|
||||
import { z } from 'zod';
|
||||
import type { Phase } from '../../db/schema.js';
|
||||
import type { ProcedureBuilder } from '../trpc.js';
|
||||
import { requirePhaseRepository, requireTaskRepository, requireBranchManager, requireInitiativeRepository, requireProjectRepository, requireExecutionOrchestrator } from './_helpers.js';
|
||||
import { requirePhaseRepository, requireTaskRepository, requireBranchManager, requireInitiativeRepository, requireProjectRepository, requireExecutionOrchestrator, requireReviewCommentRepository } from './_helpers.js';
|
||||
import { phaseBranchName } from '../../git/branch-naming.js';
|
||||
import { ensureProjectClone } from '../../git/project-clones.js';
|
||||
|
||||
@@ -298,5 +298,48 @@ export function phaseProcedures(publicProcedure: ProcedureBuilder) {
|
||||
|
||||
return { rawDiff };
|
||||
}),
|
||||
|
||||
listReviewComments: publicProcedure
|
||||
.input(z.object({ phaseId: z.string().min(1) }))
|
||||
.query(async ({ ctx, input }) => {
|
||||
const repo = requireReviewCommentRepository(ctx);
|
||||
return repo.findByPhaseId(input.phaseId);
|
||||
}),
|
||||
|
||||
createReviewComment: publicProcedure
|
||||
.input(z.object({
|
||||
phaseId: z.string().min(1),
|
||||
filePath: z.string().min(1),
|
||||
lineNumber: z.number().int(),
|
||||
lineType: z.enum(['added', 'removed', 'context']),
|
||||
body: z.string().min(1),
|
||||
author: z.string().optional(),
|
||||
}))
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const repo = requireReviewCommentRepository(ctx);
|
||||
return repo.create(input);
|
||||
}),
|
||||
|
||||
resolveReviewComment: publicProcedure
|
||||
.input(z.object({ id: z.string().min(1) }))
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const repo = requireReviewCommentRepository(ctx);
|
||||
const comment = await repo.resolve(input.id);
|
||||
if (!comment) {
|
||||
throw new TRPCError({ code: 'NOT_FOUND', message: `Review comment '${input.id}' not found` });
|
||||
}
|
||||
return comment;
|
||||
}),
|
||||
|
||||
unresolveReviewComment: publicProcedure
|
||||
.input(z.object({ id: z.string().min(1) }))
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const repo = requireReviewCommentRepository(ctx);
|
||||
const comment = await repo.unresolve(input.id);
|
||||
if (!comment) {
|
||||
throw new TRPCError({ code: 'NOT_FOUND', message: `Review comment '${input.id}' not found` });
|
||||
}
|
||||
return comment;
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user