import { type NextRequest } from "next/server"; import { prisma } from "@/lib/prisma"; import { ok, errorResponse, ApiError } from "@/lib/api"; import { getSessionUser } from "@/lib/session"; /** * Resolve a scanned QR token into enough context for the operator scan page. * * A scan can happen from: * - An admin still logged in on their laptop (shouldn't happen in the field * but we allow it for testing the print flow). * - An operator with a valid device session. * - An unauthenticated phone (the page redirects to /login/operator?next=... * before calling this route, so in practice we require a session here). * * We intentionally return only the operation fields the operator needs. Admin- * only stuff (audit logs, full file SHAs, etc.) is off-limits. */ export async function GET(_req: NextRequest, ctx: { params: Promise<{ token: string }> }) { try { const user = await getSessionUser(); if (!user) throw new ApiError(401, "unauthenticated", "Sign in required"); const { token } = await ctx.params; const op = await prisma.operation.findUnique({ where: { qrToken: token }, include: { machine: { select: { id: true, name: true, kind: true } }, part: { select: { id: true, code: true, name: true, material: true, qty: true, stepFileId: true, drawingFileId: true, cutFileId: true, assembly: { select: { id: true, code: true, name: true, project: { select: { id: true, code: true, name: true } }, }, }, }, }, claimedBy: { select: { id: true, name: true } }, }, }); if (!op) throw new ApiError(404, "unknown_token", "That QR code isn't recognised"); const claimedByMe = op.claimedByUserId === user.id; return ok({ operation: op, viewer: { id: user.id, role: user.role, claimedByMe } }); } catch (err) { return errorResponse(err); } }