feat(studio B1): persist input edits to content elements (render-binding foundation)
Build backend images / build content-svc (push) Failing after 1m3s
Build backend images / build file-svc (push) Failing after 1m5s
Build backend images / build gateway (push) Failing after 1m0s
Build backend images / build identity-svc (push) Failing after 1m8s
Build backend images / build notification-svc (push) Failing after 57s
Build backend images / build render-svc (push) Failing after 1m6s
Build backend images / build studio-svc (push) Failing after 1m3s
Build backend images / build content-svc (push) Failing after 1m3s
Build backend images / build file-svc (push) Failing after 1m5s
Build backend images / build gateway (push) Failing after 1m0s
Build backend images / build identity-svc (push) Failing after 1m8s
Build backend images / build notification-svc (push) Failing after 57s
Build backend images / build render-svc (push) Failing after 1m6s
Build backend images / build studio-svc (push) Failing after 1m3s
Studio edits previously went only to edit_state; the render binds saved_scene_contents,
so edits never reached the MP4. Add studio-svc PATCH /v1/saved-projects/{id}/contents
(update saved_scene_contents.value/value_file_id by content key, ExecuteSqlInterpolated
for null-safe params) + Next /api/projects/[id]/contents route + persistence hook pushes
edited values (from bridged c-<key> layers) alongside the scene_data save. Verified
text persists incl. UTF-8 Persian (9 chars/17 bytes).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
import { gatewayFetch } from "@/lib/api/gateway";
|
||||
import { getAccessToken } from "@/lib/auth/session";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
/**
|
||||
* Persist the studio editor's per-input values to the saved project's content
|
||||
* elements (studio-svc PATCH /v1/saved-projects/{id}/contents). The render binder
|
||||
* reads saved_scene_contents.value, so this is what makes user edits reach the MP4.
|
||||
* Body: { items: [{ key, value, valueFileId? }] }
|
||||
*/
|
||||
export async function PATCH(
|
||||
req: Request,
|
||||
ctx: { params: Promise<{ projectId: string }> }
|
||||
) {
|
||||
const { projectId } = await ctx.params;
|
||||
const token = await getAccessToken();
|
||||
if (!token) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
|
||||
const body = (await req.json().catch(() => null)) as {
|
||||
items?: Array<{ key?: string; value?: string | null; valueFileId?: string | null }>;
|
||||
} | null;
|
||||
const items = Array.isArray(body?.items)
|
||||
? body!.items.filter((i) => typeof i?.key === "string" && i.key.length > 0)
|
||||
: [];
|
||||
if (items.length === 0) return NextResponse.json({ updated: 0 });
|
||||
|
||||
const res = await gatewayFetch(`/v1/saved-projects/${projectId}/contents`, {
|
||||
method: "PATCH",
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
body: JSON.stringify({ items }),
|
||||
});
|
||||
if (!res.ok) {
|
||||
const d = await res.json().catch(() => null);
|
||||
return NextResponse.json(
|
||||
{ error: d?.message ?? "Could not save inputs" },
|
||||
{ status: res.status }
|
||||
);
|
||||
}
|
||||
return NextResponse.json(await res.json().catch(() => ({ updated: items.length })));
|
||||
}
|
||||
Reference in New Issue
Block a user