import { NextResponse } from "next/server"; import { z } from "zod"; import { LocationKind } from "@prisma/client"; import { db } from "@/lib/db"; import { requireAuth } from "@/lib/auth"; import { recomputeAllPaths } from "@/lib/locations/db"; const createSchema = z.object({ name: z.string().min(1), kind: z.nativeEnum(LocationKind).optional(), parentId: z.string().optional(), notes: z.string().optional(), }); // GET /api/locations — flat list of active locations (client builds the tree). export async function GET() { try { await requireAuth(); const locations = await db.location.findMany({ where: { active: true }, orderBy: { name: "asc" }, include: { _count: { select: { plants: { where: { active: true } } } } }, }); return NextResponse.json(locations); } catch (err) { if (err instanceof Error && err.message === "Unauthorized") return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); console.error(err); return NextResponse.json({ error: "Server error" }, { status: 500 }); } } // POST /api/locations — create a location node. export async function POST(req: Request) { try { const session = await requireAuth(); const data = createSchema.parse(await req.json()); const name = data.name.trim(); if (!name) return NextResponse.json({ error: "Name is required" }, { status: 400 }); // Validate parent exists (if given). if (data.parentId) { const parent = await db.location.findUnique({ where: { id: data.parentId } }); if (!parent) return NextResponse.json({ error: "Parent location not found" }, { status: 400 }); } const location = await db.$transaction(async (tx) => { const created = await tx.location.create({ data: { name, kind: data.kind ?? LocationKind.AREA, parentId: data.parentId || null, notes: data.notes?.trim() || null, }, }); await recomputeAllPaths(tx as unknown as typeof db); await tx.auditEvent.create({ data: { action: "location.create", entityId: created.id, actorId: session.user.id, payload: { name: created.name, kind: created.kind, parentId: created.parentId }, }, }); return created; }); return NextResponse.json(location, { status: 201 }); } catch (err) { if (err instanceof z.ZodError) return NextResponse.json({ error: err.issues[0]?.message ?? "Invalid data" }, { status: 400 }); if (err instanceof Error && err.message === "Unauthorized") return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); console.error(err); return NextResponse.json({ error: "Server error" }, { status: 500 }); } }