Skip to content

Commit 74ef139

Browse files
MaxwellCalkinclaude
andcommitted
fix: use leftJoin for workflow in V1 log API endpoints
The V1 public API log endpoints used innerJoin with the workflow table, which silently dropped logs for deleted workflows. The internal API endpoints already correctly use leftJoin. This aligns the V1 endpoints with that pattern. Changes: - v1/logs/route.ts: innerJoin -> leftJoin, handle null workflow fields - v1/logs/[id]/route.ts: innerJoin -> leftJoin, fix permissions join to use workflowExecutionLogs.workspaceId instead of workflow.workspaceId (which is null for deleted workflows), handle null workflow fields - v1/logs/executions/[executionId]/route.ts: same innerJoin -> leftJoin and permissions join fix Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 8c0a2e0 commit 74ef139

File tree

3 files changed

+30
-18
lines changed

3 files changed

+30
-18
lines changed

apps/sim/app/api/v1/logs/[id]/route.ts

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{
4747
workflowUpdatedAt: workflow.updatedAt,
4848
})
4949
.from(workflowExecutionLogs)
50-
.innerJoin(workflow, eq(workflowExecutionLogs.workflowId, workflow.id))
50+
.leftJoin(workflow, eq(workflowExecutionLogs.workflowId, workflow.id))
5151
.innerJoin(
5252
permissions,
5353
and(
5454
eq(permissions.entityType, 'workspace'),
55-
eq(permissions.entityId, workflow.workspaceId),
55+
eq(permissions.entityId, workflowExecutionLogs.workspaceId),
5656
eq(permissions.userId, userId)
5757
)
5858
)
@@ -64,17 +64,29 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{
6464
return NextResponse.json({ error: 'Log not found' }, { status: 404 })
6565
}
6666

67-
const workflowSummary = {
68-
id: log.workflowId,
69-
name: log.workflowName,
70-
description: log.workflowDescription,
71-
color: log.workflowColor,
72-
folderId: log.workflowFolderId,
73-
userId: log.workflowUserId,
74-
workspaceId: log.workflowWorkspaceId,
75-
createdAt: log.workflowCreatedAt,
76-
updatedAt: log.workflowUpdatedAt,
77-
}
67+
const workflowSummary = log.workflowName
68+
? {
69+
id: log.workflowId,
70+
name: log.workflowName,
71+
description: log.workflowDescription,
72+
color: log.workflowColor,
73+
folderId: log.workflowFolderId,
74+
userId: log.workflowUserId,
75+
workspaceId: log.workflowWorkspaceId,
76+
createdAt: log.workflowCreatedAt,
77+
updatedAt: log.workflowUpdatedAt,
78+
}
79+
: {
80+
id: log.workflowId,
81+
name: 'Deleted Workflow',
82+
description: null,
83+
color: null,
84+
folderId: null,
85+
userId: null,
86+
workspaceId: null,
87+
createdAt: null,
88+
updatedAt: null,
89+
}
7890

7991
const response = {
8092
id: log.id,

apps/sim/app/api/v1/logs/executions/[executionId]/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ export async function GET(
3434
workflow: workflow,
3535
})
3636
.from(workflowExecutionLogs)
37-
.innerJoin(workflow, eq(workflowExecutionLogs.workflowId, workflow.id))
37+
.leftJoin(workflow, eq(workflowExecutionLogs.workflowId, workflow.id))
3838
.innerJoin(
3939
permissions,
4040
and(
4141
eq(permissions.entityType, 'workspace'),
42-
eq(permissions.entityId, workflow.workspaceId),
42+
eq(permissions.entityId, workflowExecutionLogs.workspaceId),
4343
eq(permissions.userId, userId)
4444
)
4545
)

apps/sim/app/api/v1/logs/route.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ export async function GET(request: NextRequest) {
123123
workflowDescription: workflow.description,
124124
})
125125
.from(workflowExecutionLogs)
126-
.innerJoin(workflow, eq(workflowExecutionLogs.workflowId, workflow.id))
126+
.leftJoin(workflow, eq(workflowExecutionLogs.workflowId, workflow.id))
127127
.innerJoin(
128128
permissions,
129129
and(
@@ -168,8 +168,8 @@ export async function GET(request: NextRequest) {
168168
if (params.details === 'full') {
169169
result.workflow = {
170170
id: log.workflowId,
171-
name: log.workflowName,
172-
description: log.workflowDescription,
171+
name: log.workflowName ?? 'Deleted Workflow',
172+
description: log.workflowDescription ?? null,
173173
}
174174

175175
if (log.cost) {

0 commit comments

Comments
 (0)