"use server"; import { auth } from "@/auth"; import { createForgejoIssue } from "@/lib/forgejo"; import { z } from "zod"; const PRIORITIES = ["P0 — Critical (broken / blocking)", "P1 — High", "P2 — Medium", "P3 — Low"] as const; const reportSchema = z.object({ title: z.string().min(5, "Please give the issue a short title (min 5 characters)").max(150), description: z.string().min(10, "Please describe the issue (min 10 characters)").max(5000), priority: z.enum(PRIORITIES), page: z.string().max(500).optional(), }); type Result = { ok: true; issueNumber: number; issueUrl: string } | { error: string }; export async function reportIssue(formData: FormData): Promise { const session = await auth(); if (!session?.user) return { error: "Unauthorized" }; const parsed = reportSchema.safeParse(Object.fromEntries(formData)); if (!parsed.success) return { error: parsed.error.errors[0].message }; const { title, description, priority, page } = parsed.data; const body = [ "### Raised by", `${session.user.name} (${session.user.email}, ${session.user.role}) — via portal Report Issue button`, "", "### Description", description, "", "### Priority", priority, "", "### Context", `- Page: \`${page || "unknown"}\``, `- Reported at: ${new Date().toISOString()}`, ].join("\n"); try { const issue = await createForgejoIssue({ title: `[Issue]: ${title}`, body, labels: ["portal", "claude-queue"], }); return { ok: true, issueNumber: issue.number, issueUrl: issue.html_url }; } catch (err) { console.error("reportIssue failed:", err); return { error: "Could not file the issue. Please try again or contact the administrator." }; } }