feat(frontend): migrate dashboard projects flow off Supabase to V2 Studio

User-saved projects now read/write through the gateway /v1/saved-projects
(studio schema) using the Identity access-token cookie, replacing the
Supabase `projects` table. Adds src/lib/api/saved-projects.ts client that
maps studio snake_case DTOs into the existing DashboardProject shape.

- DashboardProjectsContent: lists via studio service, degrades gracefully
- /api/projects GET: studio list; POST: copy-from-template create
  (studio requires original_project_id; falls back to scene_data.templateId)
- /api/projects/[projectId] GET/PATCH: proxy to studio with JWT

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-05-30 05:56:25 +03:30
parent f366d73697
commit 14cdb772b4
4 changed files with 298 additions and 198 deletions
@@ -1,27 +1,11 @@
import { DashboardProjectsSection } from "@/components/dashboard/DashboardProjectsSection";
import { mapProjectRow, type ProjectRow } from "@/lib/projects";
import { isSupabaseConfigured } from "@/lib/supabase/config";
import { createClient } from "@/lib/supabase/server";
import { listSavedProjects } from "@/lib/api/saved-projects";
export async function DashboardProjectsContent() {
let projects: ReturnType<typeof mapProjectRow>[] = [];
if (isSupabaseConfigured()) {
const supabase = await createClient();
const {
data: { user },
} = await supabase.auth.getUser();
const { data } = user
? await supabase
.from("projects")
.select("*")
.eq("user_id", user.id)
.order("updated_at", { ascending: false })
: { data: [] };
projects = ((data ?? []) as ProjectRow[]).map(mapProjectRow);
}
// V2: user-saved projects come from the Studio service via the gateway,
// authenticated with the caller's access-token cookie. Degrades to an empty
// grid when signed out or the service is unreachable.
const projects = await listSavedProjects({ pageSize: 100 });
return <DashboardProjectsSection projects={projects} />;
}