Dev -> Local #14
@@ -150,6 +150,7 @@ describeEmbeddedPostgres("issueService.list participantAgentId", () => {
|
|||||||
await db.delete(projectWorkspaces);
|
await db.delete(projectWorkspaces);
|
||||||
await db.delete(projects);
|
await db.delete(projects);
|
||||||
await db.delete(goals);
|
await db.delete(goals);
|
||||||
|
await db.delete(heartbeatRuns);
|
||||||
await db.delete(agents);
|
await db.delete(agents);
|
||||||
await db.delete(instanceSettings);
|
await db.delete(instanceSettings);
|
||||||
await db.delete(companies);
|
await db.delete(companies);
|
||||||
@@ -1159,6 +1160,68 @@ describeEmbeddedPostgres("issueService.list participantAgentId", () => {
|
|||||||
expect(comments.map((comment) => comment.id)).toEqual([firstCommentId]);
|
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 () => {
|
it("includes blockedBy summaries on list rows in one batched pass", async () => {
|
||||||
const companyId = randomUUID();
|
const companyId = randomUUID();
|
||||||
const blockerId = randomUUID();
|
const blockerId = randomUUID();
|
||||||
|
|||||||
@@ -1943,6 +1943,11 @@ export function issueService(db: Db) {
|
|||||||
}, null);
|
}, null);
|
||||||
if (minCommentCreatedAtMs === null || maxCommentCreatedAtMs === null) return comments;
|
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
|
const runs = await db
|
||||||
.select({
|
.select({
|
||||||
runId: heartbeatRuns.id,
|
runId: heartbeatRuns.id,
|
||||||
@@ -1969,8 +1974,8 @@ export function issueService(db: Db) {
|
|||||||
and ${activityLog.runId} = ${heartbeatRuns.id}
|
and ${activityLog.runId} = ${heartbeatRuns.id}
|
||||||
)`,
|
)`,
|
||||||
),
|
),
|
||||||
sql`coalesce(${heartbeatRuns.finishedAt}, ${heartbeatRuns.createdAt}) >= ${new Date(minCommentCreatedAtMs)}`,
|
sql`coalesce(${heartbeatRuns.finishedAt}, ${heartbeatRuns.createdAt}) >= ${minCommentCreatedAt}::timestamptz`,
|
||||||
sql`coalesce(${heartbeatRuns.startedAt}, ${heartbeatRuns.createdAt}) <= ${new Date(maxCommentCreatedAtMs + ISSUE_COMMENT_RUN_LOG_DERIVATION_END_SLACK_MS)}`,
|
sql`coalesce(${heartbeatRuns.startedAt}, ${heartbeatRuns.createdAt}) <= ${maxCommentCreatedAt}::timestamptz`,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.orderBy(desc(heartbeatRuns.createdAt));
|
.orderBy(desc(heartbeatRuns.createdAt));
|
||||||
|
|||||||
Reference in New Issue
Block a user