11import { createLogger } from '@sim/logger'
22import type { NextRequest } from 'next/server'
3+ import { NextResponse } from 'next/server'
34import { getPublicFileContentContract } from '@/lib/api/contracts/public-shares'
45import { parseRequest } from '@/lib/api/server'
5- import { loadServableDocArtifact } from '@/lib/copilot/tools/server/files/doc-compile'
6+ import { resolveServableDoc } from '@/lib/copilot/tools/server/files/doc-compile'
67import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
78import { enforcePublicFileRateLimit } from '@/lib/public-shares/rate-limit'
89import { resolveActiveShareByToken } from '@/lib/public-shares/share-manager'
@@ -20,9 +21,10 @@ const logger = createLogger('PublicFileContentAPI')
2021 * shares. Disposition (inline vs attachment) is resolved from the file type by
2122 * {@link createFileResponse}; the public page's Download button uses `<a download>`.
2223 *
23- * Generated office docs are stored as source; {@link loadServableDocArtifact}
24- * swaps in their prebuilt compiled binary (read-only, never compiles). Uploaded
25- * binaries pass through untouched.
24+ * Generated office docs are stored as source; {@link resolveServableDoc} swaps in
25+ * their prebuilt compiled binary (read-only, never compiles). Uploaded binaries
26+ * pass through untouched. A generated doc whose compiled artifact isn't built yet
27+ * returns 409 rather than serving raw source under a binary content type.
2628 */
2729export const GET = withRouteHandler (
2830 async ( request : NextRequest , context : { params : Promise < { token : string } > } ) => {
@@ -42,11 +44,20 @@ export const GET = withRouteHandler(
4244 const { file } = resolved
4345 const raw = await downloadFile ( { key : file . key , context : 'workspace' } )
4446
45- const artifact = file . workspaceId
46- ? await loadServableDocArtifact ( file . workspaceId , raw , file . originalName )
47- : null
48- const buffer = artifact ?. buffer ?? raw
49- const contentType = artifact ?. contentType ?? file . contentType
47+ const servable = file . workspaceId
48+ ? await resolveServableDoc ( file . workspaceId , raw , file . originalName )
49+ : ( { kind : 'passthrough' } as const )
50+
51+ if ( servable . kind === 'unavailable' ) {
52+ logger . info ( 'Public shared doc not yet compiled' , { token, key : file . key } )
53+ return NextResponse . json (
54+ { error : 'This document is still being prepared. Please try again shortly.' } ,
55+ { status : 409 }
56+ )
57+ }
58+
59+ const buffer = servable . kind === 'artifact' ? servable . buffer : raw
60+ const contentType = servable . kind === 'artifact' ? servable . contentType : file . contentType
5061
5162 logger . info ( 'Public shared file served' , { token, key : file . key , size : buffer . length } )
5263
0 commit comments