import { NextResponse } from "next/server"; import { z } from "zod"; import { apiError, parseBody } from "@/lib/api.ts"; import { assertSameOrigin, requireRole } from "@/lib/auth/session.ts"; import { all, run } from "@/lib/db/index.ts"; export async function GET() { try { await requireRole("instructor"); return NextResponse.json({ announcements: all("SELECT * FROM announcements ORDER BY id DESC LIMIT 100") }); } catch (e) { return apiError(e); } } const createSchema = z.object({ action: z.literal("create"), title: z.string().min(1).max(200), body: z.string().min(1).max(10_000), courseCode: z.enum(["IMM1003", "IMM1033"]).nullable(), pinned: z.boolean().default(false), }); const updateSchema = z.object({ action: z.literal("update"), id: z.number().int().positive(), active: z.boolean().optional(), pinned: z.boolean().optional(), }); const deleteSchema = z.object({ action: z.literal("delete"), id: z.number().int().positive() }); export async function POST(req: Request) { try { await assertSameOrigin(); const user = await requireRole("instructor"); const body = await parseBody(req, z.discriminatedUnion("action", [createSchema, updateSchema, deleteSchema])); if (body.action === "create") { run( "INSERT INTO announcements (title, body, course_code, pinned, created_by) VALUES (?, ?, ?, ?, ?)", body.title, body.body, body.courseCode, body.pinned ? 1 : 0, user.id ); } else if (body.action === "update") { if (body.active !== undefined) run("UPDATE announcements SET active = ? WHERE id = ?", body.active ? 1 : 0, body.id); if (body.pinned !== undefined) run("UPDATE announcements SET pinned = ? WHERE id = ?", body.pinned ? 1 : 0, body.id); } else { run("DELETE FROM announcements WHERE id = ?", body.id); } return NextResponse.json({ ok: true }); } catch (e) { return apiError(e); } }