SPB Git
2.5 KB · 27 lines typescript
1import { z } from "zod";2import { handler, parseBody } from "@/lib/api";3import { createPage } from "@/lib/pages/service";4import { db, schema } from "@/db";5import { and, desc, eq, isNull, isNotNull, sql as dsql } from "drizzle-orm";6import { audit } from "@/lib/audit";78/** GET ?view=recent|pinned|trash|section:<name>|children:<id> */9export const GET = handler(async ({ req, ws }) => {10  const u = new URL(req.url); const view = u.searchParams.get("view") ?? "recent"; const limit = Math.min(100, Number(u.searchParams.get("limit") ?? 20));11  const base = [eq(schema.pages.workspaceId, ws.id)];12  const cols = { id: schema.pages.id, title: schema.pages.title, icon: schema.pages.icon, section: schema.pages.section, type: schema.pages.type, parentId: schema.pages.parentId, updatedAt: schema.pages.updatedAt, lastOpenedAt: schema.pages.lastOpenedAt, deletedAt: schema.pages.deletedAt, wordCount: schema.pages.wordCount, pinned: schema.pages.pinned, properties: schema.pages.properties, databaseId: schema.pages.databaseId };13  if (view === "trash") return Response.json(await db.select(cols).from(schema.pages).where(and(...base, isNotNull(schema.pages.deletedAt))).orderBy(desc(schema.pages.deletedAt)).limit(limit));14  const where = [...base, isNull(schema.pages.deletedAt)];15  if (view === "pinned") where.push(eq(schema.pages.pinned, true));16  if (view.startsWith("section:")) where.push(eq(schema.pages.section, view.slice(8)), isNull(schema.pages.databaseId));17  if (view.startsWith("children:")) where.push(eq(schema.pages.parentId, view.slice(9)));18  const order = view === "recent" ? dsql`greatest(coalesce(last_opened_at, 'epoch'), updated_at) desc` : view.startsWith("children:") ? dsql`position asc` : desc(schema.pages.updatedAt);19  return Response.json(await db.select(cols).from(schema.pages).where(and(...where)).orderBy(order).limit(limit));20});21export const POST = handler(async ({ req, ws, user }) => {22  const b = await parseBody(req, z.object({ title: z.string().max(500).optional(), parentId: z.string().uuid().nullable().optional(), section: z.enum(["notes", "documents", "databases", "projects", "research"]).optional(), type: z.enum(["page", "database", "research"]).optional(), content: z.any().optional(), icon: z.string().max(16).nullable().optional(), properties: z.record(z.string(), z.unknown()).optional() }));23  const p = await createPage(ws.id, b);24  await audit(user.id, "page.create", { type: "page", id: p.id }, { title: p.title });25  return Response.json(p, { status: 201 });26});27
Files · main
Menu

Theme