Dev -> Local #14

Merged
cpfarhood merged 40 commits from dev into local 2026-05-16 14:16:30 +00:00
2 changed files with 70 additions and 2 deletions
Showing only changes of commit eb452fba30 - Show all commits
@@ -150,6 +150,7 @@ describeEmbeddedPostgres("issueService.list participantAgentId", () => {
await db.delete(projectWorkspaces);
await db.delete(projects);
await db.delete(goals);
await db.delete(heartbeatRuns);
await db.delete(agents);
await db.delete(instanceSettings);
await db.delete(companies);
@@ -1159,6 +1160,68 @@ describeEmbeddedPostgres("issueService.list participantAgentId", () => {
expect(comments.map((comment) => comment.id)).toEqual([firstCommentId]);
});
it("lists user comments when derived run attribution scans a timestamp window", async () => {
const companyId = randomUUID();
const agentId = randomUUID();
const issueId = randomUUID();
const commentId = randomUUID();
await db.insert(companies).values({
id: companyId,
name: "Paperclip",
issuePrefix: `T${companyId.replace(/-/g, "").slice(0, 6).toUpperCase()}`,
requireBoardApprovalForNewAgents: false,
});
await db.insert(agents).values({
id: agentId,
companyId,
name: "CodexCoder",
role: "engineer",
status: "active",
adapterType: "codex_local",
adapterConfig: {},
runtimeConfig: {},
permissions: {},
});
await db.insert(issues).values({
id: issueId,
companyId,
title: "Comments issue",
status: "todo",
priority: "medium",
});
await db.insert(heartbeatRuns).values({
id: randomUUID(),
companyId,
agentId,
contextSnapshot: { issueId },
createdAt: new Date("2026-05-12T22:58:00.000Z"),
startedAt: new Date("2026-05-12T22:58:00.000Z"),
finishedAt: new Date("2026-05-12T23:14:00.000Z"),
});
await db.insert(issueComments).values({
id: commentId,
companyId,
issueId,
authorUserId: "user-1",
body: "Comment should be visible",
createdAt: new Date("2026-05-12T23:00:00.000Z"),
updatedAt: new Date("2026-05-12T23:00:00.000Z"),
});
const comments = await svc.listComments(issueId, {
order: "desc",
limit: 50,
});
expect(comments.map((comment) => comment.id)).toEqual([commentId]);
expect(comments[0]?.body).toBe("Comment should be visible");
});
it("includes blockedBy summaries on list rows in one batched pass", async () => {
const companyId = randomUUID();
const blockerId = randomUUID();
+7 -2
View File
@@ -1943,6 +1943,11 @@ export function issueService(db: Db) {
}, null);
if (minCommentCreatedAtMs === null || maxCommentCreatedAtMs === null) return comments;
const minCommentCreatedAt = new Date(minCommentCreatedAtMs).toISOString();
const maxCommentCreatedAt = new Date(
maxCommentCreatedAtMs + ISSUE_COMMENT_RUN_LOG_DERIVATION_END_SLACK_MS,
).toISOString();
const runs = await db
.select({
runId: heartbeatRuns.id,
@@ -1969,8 +1974,8 @@ export function issueService(db: Db) {
and ${activityLog.runId} = ${heartbeatRuns.id}
)`,
),
sql`coalesce(${heartbeatRuns.finishedAt}, ${heartbeatRuns.createdAt}) >= ${new Date(minCommentCreatedAtMs)}`,
sql`coalesce(${heartbeatRuns.startedAt}, ${heartbeatRuns.createdAt}) <= ${new Date(maxCommentCreatedAtMs + ISSUE_COMMENT_RUN_LOG_DERIVATION_END_SLACK_MS)}`,
sql`coalesce(${heartbeatRuns.finishedAt}, ${heartbeatRuns.createdAt}) >= ${minCommentCreatedAt}::timestamptz`,
sql`coalesce(${heartbeatRuns.startedAt}, ${heartbeatRuns.createdAt}) <= ${maxCommentCreatedAt}::timestamptz`,
),
)
.orderBy(desc(heartbeatRuns.createdAt));