// PLAN-DOCVER.md §1 — GET /api/documents/versions/{versionId}/download-link?format=docx|pdf // คืน presigned URL อายุสั้น (env DOCVER_LINK_TTL_SECONDS) ให้ UI เปิดในเบราว์เซอร์จริง // ของผู้ใช้ — เช็ค docId (จาก fid ใน token) กับ versionId คู่กันกันโยน id ข้ามเอกสาร // auth: Authorization: Bearer (access_token จาก POST /api/documents/token — ทุก endpoint ของกลุ่ม) import { docverError, parseDownloadFormat, parseVersionIdParam, } from "@/lib/document-versioning"; import { requireDocverBearer } from "@/lib/docver-token"; import { findVersionForDoc, presignVersionUrl } from "@/lib/docver-store"; export const runtime = "nodejs"; export const dynamic = "force-dynamic"; export async function GET( request: Request, { params }: { params: { versionId: string } }, ) { const auth = requireDocverBearer(request); if (!auth.ok) return auth.response; // docId มาจาก fid ใน token — claim ถูกบังคับเป็น string ไม่ว่างตั้งแต่ขอ token + verify const docId = auth.claims.fid; const versionId = parseVersionIdParam(params.versionId); if (!versionId.ok) return docverError(versionId.error, 400); let format: string | null = null; try { format = new URL(request.url).searchParams.get("format"); } catch { return docverError("URL ของ request ไม่ถูกต้อง", 400); } const parsedFormat = parseDownloadFormat(format); if (!parsedFormat.ok) return docverError(parsedFormat.error, 400); try { const row = await findVersionForDoc(docId, versionId.versionId); if (!row) { return docverError("ไม่พบ version นี้ของเอกสาร", 404); } if (parsedFormat.format === "pdf" && row.pdfObjectKey === null) { return docverError("version นี้ไม่มีสำเนา PDF", 404); } const link = await presignVersionUrl(row.id, parsedFormat.format); return new Response(JSON.stringify(link), { headers: { "content-type": "application/json; charset=utf-8" }, }); } catch (err) { console.error("docver: สร้าง download link ล้ม", err); return docverError("เกิดข้อผิดพลาดของระบบ โปรดลองใหม่อีกครั้ง", 500); } }