Skip to content

Commit cb21c93

Browse files
committed
fix(files): resolve execution artifact workspace
1 parent f5ef0eb commit cb21c93

2 files changed

Lines changed: 53 additions & 5 deletions

File tree

apps/sim/lib/uploads/utils/file-utils.server.test.ts

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,51 @@
33
*/
44
import { beforeEach, describe, expect, it, vi } from 'vitest'
55

6-
const { mockDownloadFile } = vi.hoisted(() => ({
7-
mockDownloadFile: vi.fn(),
8-
}))
6+
const { mockDownloadFile, mockParseWorkspaceFileKey, mockResolveServableDocBytes } = vi.hoisted(
7+
() => ({
8+
mockDownloadFile: vi.fn(),
9+
mockParseWorkspaceFileKey: vi.fn(),
10+
mockResolveServableDocBytes: vi.fn(),
11+
})
12+
)
913

1014
vi.mock('@/lib/uploads/core/storage-service', () => ({
1115
downloadFile: mockDownloadFile,
1216
hasCloudStorage: vi.fn(() => true),
1317
}))
1418

19+
vi.mock('@/lib/uploads/contexts/execution/execution-file-manager', () => ({
20+
downloadExecutionFile: mockDownloadFile,
21+
}))
22+
23+
vi.mock('@/lib/uploads/contexts/workspace/workspace-file-manager', () => ({
24+
parseWorkspaceFileKey: mockParseWorkspaceFileKey,
25+
}))
26+
27+
vi.mock('@/lib/copilot/tools/server/files/doc-compile', () => ({
28+
resolveServableDocBytes: mockResolveServableDocBytes,
29+
}))
30+
1531
vi.mock('@/app/api/files/authorization', () => ({
1632
verifyFileAccess: vi.fn(),
1733
}))
1834

1935
import { createLogger } from '@sim/logger'
20-
import { downloadFileFromStorage } from '@/lib/uploads/utils/file-utils.server'
36+
import {
37+
downloadFileFromStorage,
38+
downloadServableFileFromStorage,
39+
} from '@/lib/uploads/utils/file-utils.server'
2140
import type { UserFile } from '@/executor/types'
2241

2342
describe('downloadFileFromStorage context derivation', () => {
2443
beforeEach(() => {
2544
vi.clearAllMocks()
2645
mockDownloadFile.mockResolvedValue(Buffer.from('bytes'))
46+
mockParseWorkspaceFileKey.mockReturnValue(null)
47+
mockResolveServableDocBytes.mockImplementation(async ({ rawBuffer }) => ({
48+
buffer: rawBuffer,
49+
contentType: 'application/pdf',
50+
}))
2751
})
2852

2953
it('downloads with the key-derived context, ignoring a caller-supplied public context', async () => {
@@ -44,4 +68,23 @@ describe('downloadFileFromStorage context derivation', () => {
4468
expect.objectContaining({ key: userFile.key, context: 'workspace' })
4569
)
4670
})
71+
72+
it('uses the workspace ID embedded in an execution key to resolve generated artifacts', async () => {
73+
const workspaceId = '2f1d8c3e-5b6a-4c7d-8e9f-0a1b2c3d4e5f'
74+
const userFile: UserFile = {
75+
id: 'f1',
76+
name: 'report.pdf',
77+
url: '',
78+
size: 5,
79+
type: 'text/x-python-pdf',
80+
key: `execution/${workspaceId}/3f2e9d4c-6a7b-4d8e-9f0a-1b2c3d4e5f6a/4a3b2c1d-7e8f-4a9b-8c0d-1e2f3a4b5c6d/report.pdf`,
81+
context: 'execution',
82+
}
83+
84+
await downloadServableFileFromStorage(userFile, 'req-1', createLogger('test'))
85+
86+
expect(mockResolveServableDocBytes).toHaveBeenCalledWith(
87+
expect.objectContaining({ workspaceId })
88+
)
89+
})
4790
})

apps/sim/lib/uploads/utils/file-utils.server.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { StorageService } from '@/lib/uploads'
1616
import { isExecutionFile } from '@/lib/uploads/contexts/execution/utils'
1717
import {
1818
extractStorageKey,
19+
extractWorkspaceIdFromExecutionKey,
1920
getFileExtension,
2021
getMimeTypeFromExtension,
2122
inferContextFromKey,
@@ -384,7 +385,11 @@ export async function downloadServableFileFromStorage(
384385
const { parseWorkspaceFileKey } = await import(
385386
'@/lib/uploads/contexts/workspace/workspace-file-manager'
386387
)
387-
const workspaceId = userFile.key ? (parseWorkspaceFileKey(userFile.key) ?? undefined) : undefined
388+
const workspaceId = userFile.key
389+
? (parseWorkspaceFileKey(userFile.key) ??
390+
extractWorkspaceIdFromExecutionKey(userFile.key) ??
391+
undefined)
392+
: undefined
388393

389394
const { resolveServableDocBytes } = await import('@/lib/copilot/tools/server/files/doc-compile')
390395
const resolved = await resolveServableDocBytes({

0 commit comments

Comments
 (0)