53 lines
1.6 KiB
TypeScript
53 lines
1.6 KiB
TypeScript
import { and, desc, eq } from "drizzle-orm";
|
|
import { db } from "@/lib/db";
|
|
import { canvasProject } from "@/lib/db/schema";
|
|
import {
|
|
openApiErrorResponse,
|
|
requireOpenApiPrincipal,
|
|
} from "@/lib/access-keys/openapi-auth";
|
|
|
|
function normalizeWorkspaceType(value: string | null) {
|
|
return value === "agent" || value === "video" ? value : "canvas";
|
|
}
|
|
|
|
export async function GET(request: Request) {
|
|
try {
|
|
const principal = await requireOpenApiPrincipal(request, "canvas:read");
|
|
const url = new URL(request.url);
|
|
const workspaceType = normalizeWorkspaceType(
|
|
url.searchParams.get("workspaceType")
|
|
);
|
|
const requestedLimit = Number(url.searchParams.get("limit") || 24);
|
|
const limit = Number.isFinite(requestedLimit)
|
|
? Math.min(50, Math.max(1, Math.round(requestedLimit)))
|
|
: 24;
|
|
|
|
const projects = await db
|
|
.select({
|
|
id: canvasProject.id,
|
|
title: canvasProject.title,
|
|
description: canvasProject.description,
|
|
thumbnail: canvasProject.thumbnail,
|
|
workspaceType: canvasProject.workspaceType,
|
|
createdAt: canvasProject.createdAt,
|
|
updatedAt: canvasProject.updatedAt,
|
|
})
|
|
.from(canvasProject)
|
|
.where(
|
|
and(
|
|
eq(canvasProject.userId, principal.userId),
|
|
eq(canvasProject.workspaceType, workspaceType)
|
|
)
|
|
)
|
|
.orderBy(desc(canvasProject.updatedAt))
|
|
.limit(limit);
|
|
|
|
return Response.json(
|
|
{ success: true, data: projects },
|
|
{ headers: { "Cache-Control": "no-store" } }
|
|
);
|
|
} catch (error) {
|
|
return openApiErrorResponse(error);
|
|
}
|
|
}
|