Skip to content

Commit e800b18

Browse files
OAGrclaude
andcommitted
fix: rebase onto main + address CodeRabbit review feedback
- Resolve merge conflict with pagination changes (fetchAllPaginated) - Fix type mismatch: session_id column integer→bigint to match sessions.id - Fix dashboard fallback: don't fall back to branch heuristic when sessionId is set but not found (prevents attaching wrong session metadata) - Fix CLI: main() now uses syncSessionFile() to include FK linking - Add clobber guard: skip FK update if agent session already has sessionId - Add FK constraint error handling in PATCH endpoint (400 vs 500) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent aef12cf commit e800b18

File tree

5 files changed

+25
-14
lines changed

5 files changed

+25
-14
lines changed

apps/web/src/app/internal/agent-sessions/agent-sessions-content.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,10 @@ async function loadFromApi(): Promise<FetchResult<AgentSessionRow[]>> {
6464
}
6565

6666
const rows: AgentSessionRow[] = agentResult.data.sessions.map((s): AgentSessionRow => {
67-
// Prefer FK-linked session log; fall back to branch-name heuristic for older records
68-
const log = (s.sessionId != null ? logsById.get(s.sessionId) : undefined)
69-
?? logsByBranch.get(s.branch);
67+
// Prefer FK-linked session log; only fall back to branch heuristic when sessionId is absent
68+
const log = s.sessionId != null
69+
? logsById.get(s.sessionId)
70+
: logsByBranch.get(s.branch);
7071
return {
7172
id: s.id,
7273
branch: s.branch,

apps/wiki-server/drizzle/0063_add_session_id_to_agent_sessions.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@
1515
-- pattern impossible. agent_sessions is a small table (hundreds of rows), so the
1616
-- brief SHARE ROW EXCLUSIVE lock is acceptable.
1717

18-
ALTER TABLE "agent_sessions" ADD COLUMN IF NOT EXISTS "session_id" integer REFERENCES "sessions"("id") ON DELETE SET NULL;
18+
ALTER TABLE "agent_sessions" ADD COLUMN IF NOT EXISTS "session_id" bigint REFERENCES "sessions"("id") ON DELETE SET NULL;
1919

2020
CREATE INDEX IF NOT EXISTS "idx_as_session_id" ON "agent_sessions" ("session_id");

apps/wiki-server/src/routes/agent-sessions.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,21 @@ const agentSessionsApp = new Hono()
141141
if (sessionId !== undefined) updates.sessionId = sessionId;
142142

143143
const db = getDrizzleDb();
144-
const result = await db
145-
.update(agentSessions)
146-
.set(updates)
147-
.where(eq(agentSessions.id, id))
148-
.returning();
144+
let result;
145+
try {
146+
result = await db
147+
.update(agentSessions)
148+
.set(updates)
149+
.where(eq(agentSessions.id, id))
150+
.returning();
151+
} catch (e: unknown) {
152+
// Translate FK violation into a 400 response
153+
const msg = e instanceof Error ? e.message : String(e);
154+
if (msg.includes("foreign key") || msg.includes("violates foreign key")) {
155+
return c.json({ error: "invalid_reference", message: "sessionId references a non-existent session" }, 400);
156+
}
157+
throw e;
158+
}
149159

150160
if (result.length === 0) {
151161
return c.json({ error: "not_found", message: `No session with id: ${id}` }, 404);

apps/wiki-server/src/schema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -762,7 +762,7 @@ export const agentSessions = pgTable(
762762
prUrl: text("pr_url"), // PR URL recorded when crux issues done --pr=URL is called
763763
prOutcome: text("pr_outcome"), // Outcome: merged | merged_with_revisions | reverted | closed_without_merge
764764
fixesPrUrl: text("fixes_pr_url"), // URL of the PR this session is fixing (enables fix-chain tracking)
765-
sessionId: integer("session_id").references(() => sessions.id, { onDelete: "set null" }), // FK to session log — set when session completes and log is synced
765+
sessionId: bigint("session_id", { mode: "number" }).references(() => sessions.id, { onDelete: "set null" }), // FK to session log — set when session completes and log is synced
766766
status: text("status").notNull().default("active"),
767767
startedAt: timestamp("started_at", { withTimezone: true })
768768
.notNull()

crux/wiki-server/sync-session.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ export async function syncSessionFile(filePath: string): Promise<boolean> {
130130
if (entry.branch) {
131131
try {
132132
const agentSessionResult = await getAgentSessionByBranch(entry.branch);
133-
if (agentSessionResult.ok) {
133+
if (agentSessionResult.ok && agentSessionResult.data.sessionId == null) {
134134
await updateAgentSession(agentSessionResult.data.id, {
135135
sessionId: result.data.id,
136136
});
@@ -175,9 +175,9 @@ async function main() {
175175
console.log(` Branch: ${entry.branch || '(none)'}`);
176176
console.log(` Pages: ${entry.pages?.length || 0}`);
177177

178-
const result = await createSession(entry);
179-
if (result.ok) {
180-
console.log(`\u2713 Session synced to wiki-server (id: ${result.data.id})`);
178+
const ok = await syncSessionFile(resolved);
179+
if (ok) {
180+
console.log(`\u2713 Session synced to wiki-server`);
181181
} else {
182182
console.log('Warning: could not sync session to wiki-server (server unavailable or error)');
183183
// Not a hard failure — YAML is authoritative

0 commit comments

Comments
 (0)