Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/db/repositories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5094,7 +5094,7 @@ export async function getLatestPublishedAiReview(
): Promise<{ notes: string; reviewerCount: number; findings: AdvisoryFinding[]; headSha?: string | undefined; metadata?: Record<string, unknown> | undefined } | null> {
const row = await env.DB
.prepare(
"SELECT notes, reviewer_count AS reviewerCount, head_sha AS headSha, findings_json AS findingsJson, metadata_json AS metadataJson FROM ai_review_cache WHERE repo_full_name = ? AND pull_number = ? AND ai_review_mode = ? AND published_at IS NOT NULL ORDER BY published_at DESC LIMIT 1",
"SELECT notes, reviewer_count AS reviewerCount, head_sha AS headSha, findings_json AS findingsJson, metadata_json AS metadataJson FROM ai_review_cache WHERE repo_full_name = ? AND pull_number = ? AND ai_review_mode = ? AND published_at IS NOT NULL ORDER BY published_at DESC, rowid DESC LIMIT 1",
)
.bind(repoFullName, pullNumber, mode)
.first<{ notes: string; reviewerCount: number; headSha: string; findingsJson: string | null; metadataJson: string | null }>();
Expand Down
25 changes: 25 additions & 0 deletions test/unit/ai-review-cache.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,31 @@ describe("AI review cache (#1)", () => {
}
});

it("breaks ties on identical published_at via rowid DESC (#8894)", async () => {
const env = createTestEnv();
const publishedAt = "2026-07-09T12:00:00.000Z";
// Insert order ⇒ rising rowid; with equal published_at the higher rowid must win.
await env.DB.prepare(
`INSERT INTO ai_review_cache (repo_full_name, pull_number, head_sha, ai_review_mode, notes, reviewer_count, findings_json, metadata_json, cacheable, published_at, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
)
.bind("o/r", 56, "sha-earlier-rowid", "block", "earlier rowid", 1, "[]", "{}", 1, publishedAt, publishedAt)
.run();
await env.DB.prepare(
`INSERT INTO ai_review_cache (repo_full_name, pull_number, head_sha, ai_review_mode, notes, reviewer_count, findings_json, metadata_json, cacheable, published_at, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
)
.bind("o/r", 56, "sha-later-rowid", "block", "later rowid", 1, "[]", "{}", 1, publishedAt, publishedAt)
.run();

expect(await getLatestPublishedAiReview(env, "o/r", 56, "block")).toEqual({
notes: "later rowid",
reviewerCount: 1,
findings: [],
headSha: "sha-later-rowid",
});
});

it("omits headSha from the payload when the stored head_sha is empty", async () => {
const env = createTestEnv();
await env.DB.prepare(
Expand Down