diff --git a/server/src/__tests__/external-objects-service.test.ts b/server/src/__tests__/external-objects-service.test.ts index 5f4e7a89785..967ea8ae42a 100644 --- a/server/src/__tests__/external-objects-service.test.ts +++ b/server/src/__tests__/external-objects-service.test.ts @@ -529,6 +529,28 @@ describeEmbeddedPostgres("externalObjectService", () => { expect(resolve).toHaveBeenCalledTimes(1); }); + it("removes comment mentions when a synced comment is hard-deleted", async () => { + const { companyId, issueId } = await createIssue(); + const commentId = randomUUID(); + await db.insert(issueComments).values({ + id: commentId, + companyId, + issueId, + authorType: "user", + authorUserId: "local-board", + body: "See https://github.com/acme/app/issues/88", + }); + const svc = externalObjectService(db, { github: false }); + + await svc.syncComment(commentId); + expect(await db.select().from(externalObjectMentions)).toHaveLength(1); + + await db.delete(issueComments).where(eq(issueComments.id, commentId)); + await svc.syncComment(commentId); + + expect(await db.select().from(externalObjectMentions)).toHaveLength(0); + }); + it("skips terminal objects when refreshing due objects", async () => { const { companyId, issueId } = await createIssue(); const resolve = vi.fn(async () => ({ diff --git a/server/src/services/external-objects.ts b/server/src/services/external-objects.ts index db34f3b476b..4823a80fe44 100644 --- a/server/src/services/external-objects.ts +++ b/server/src/services/external-objects.ts @@ -527,7 +527,12 @@ export function externalObjectService( .from(issueComments) .where(eq(issueComments.id, commentId)) .then((rows: Array<{ id: string; companyId: string; issueId: string; body: string }>) => rows[0] ?? null); - if (!comment) throw notFound("Issue comment not found"); + if (!comment) { + await tx + .delete(externalObjectMentions) + .where(and(eq(externalObjectMentions.sourceKind, "comment"), eq(externalObjectMentions.sourceRecordId, commentId))); + return; + } await replaceSourceMentions({ companyId: comment.companyId, sourceIssueId: comment.issueId,