11import type { ActionFunctionArgs } from "@remix-run/server-runtime" ;
22import { json } from "@remix-run/server-runtime" ;
33import { z } from "zod" ;
4- import { $replica , prisma } from "~/db.server" ;
5- import { env } from "~/env.server" ;
4+ import { $replica } from "~/db.server" ;
65import { authenticateApiRequest } from "~/services/apiAuth.server" ;
7- import { resolveSessionByIdOrExternalId } from "~/services/realtime/sessions.server" ;
6+ import {
7+ chatSnapshotStoragePathForSession ,
8+ resolveSessionByIdOrExternalId ,
9+ } from "~/services/realtime/sessions.server" ;
810import { createLoaderApiRoute } from "~/services/routeBuilders/apiBuilder.server" ;
911import { generatePresignedUrl } from "~/v3/objectStore.server" ;
1012
1113const ParamsSchema = z . object ( {
1214 sessionId : z . string ( ) ,
1315} ) ;
1416
15- // Canonical key for new sessions, prefixed with the default protocol so
16- // PUT/GET resolve to the same store on multi-provider deployments.
17- function defaultSnapshotKey ( sessionId : string ) : string {
18- const path = `sessions/ ${ sessionId } /snapshot.json` ;
19- const protocol = env . OBJECT_STORE_DEFAULT_PROTOCOL ;
20- return protocol ? ` ${ protocol } :// ${ path } ` : path ;
17+ // `chatSnapshotStoragePath` is stamped on every new Session at row creation
18+ // (see api.v1.sessions.ts). The fallback handles sessions created before
19+ // the column existed — read against the currently-configured default
20+ // protocol and compute the same path the SDK uploaded under.
21+ function snapshotKey ( session : { friendlyId : string ; chatSnapshotStoragePath : string | null } ) {
22+ return session . chatSnapshotStoragePath ?? chatSnapshotStoragePathForSession ( session . friendlyId ) ;
2123}
2224
2325export async function action ( { request, params } : ActionFunctionArgs ) {
2426 if ( request . method . toUpperCase ( ) !== "PUT" ) {
25- return { status : 405 , body : "Method Not Allowed" } ;
27+ return json ( { error : "Method Not Allowed" } , { status : 405 } ) ;
2628 }
2729
2830 const auth = await authenticateApiRequest ( request ) ;
@@ -40,31 +42,16 @@ export async function action({ request, params }: ActionFunctionArgs) {
4042 return json ( { error : "Session not found" } , { status : 404 } ) ;
4143 }
4244
43- // Reuse the stored path on subsequent writes; persist on first write so
44- // future default-protocol changes don't strand existing snapshots.
45- const key = session . chatSnapshotStoragePath ?? defaultSnapshotKey ( parsed . sessionId ) ;
46-
4745 const signed = await generatePresignedUrl (
4846 auth . environment . project . externalRef ,
4947 auth . environment . slug ,
50- key ,
48+ snapshotKey ( session ) ,
5149 "PUT"
5250 ) ;
5351 if ( ! signed . success ) {
5452 return json ( { error : `Failed to generate presigned URL: ${ signed . error } ` } , { status : 500 } ) ;
5553 }
5654
57- if ( session . chatSnapshotStoragePath === null ) {
58- await prisma . session
59- . updateMany ( {
60- where : { id : session . id , chatSnapshotStoragePath : null } ,
61- data : { chatSnapshotStoragePath : key } ,
62- } )
63- . catch ( ( ) => {
64- // Best-effort; concurrent writers may have already set it.
65- } ) ;
66- }
67-
6855 return json ( { presignedUrl : signed . url } ) ;
6956}
7057
@@ -76,18 +63,15 @@ export const loader = createLoaderApiRoute(
7663 findResource : async ( params , auth ) =>
7764 resolveSessionByIdOrExternalId ( $replica , auth . environment . id , params . sessionId ) ,
7865 } ,
79- async ( { params , authentication, resource : session } ) => {
66+ async ( { authentication, resource : session } ) => {
8067 if ( ! session ) {
8168 return json ( { error : "Session not found" } , { status : 404 } ) ;
8269 }
8370
84- // Stored path wins; fall back to computed default for pre-column sessions.
85- const key = session . chatSnapshotStoragePath ?? defaultSnapshotKey ( params . sessionId ) ;
86-
8771 const signed = await generatePresignedUrl (
8872 authentication . environment . project . externalRef ,
8973 authentication . environment . slug ,
90- key ,
74+ snapshotKey ( session ) ,
9175 "GET"
9276 ) ;
9377 if ( ! signed . success ) {
0 commit comments