From 419b784f9cf757852c310dedfdb291229a54dc36 Mon Sep 17 00:00:00 2001 From: Fluory Date: Mon, 28 Sep 2026 18:21:11 +0200 Subject: [PATCH 1/4] build(deps): add pdfjs-dist to show the original PDF page in review (#74) The review screen shall show the cited PDF page with the stored bounding box highlighted. pdf.js renders the original in the browser from the existing tenant-checked document route: no new route, no public URL, no third-party request, no extra load on the stateless AI service. Apache-2.0, pinned; loaded lazily only when a PDF source is shown. Decision and rejected options: ADR-0002. Co-Authored-By: Claude Opus 5.5 (1M context) --- docs/decisions/ADR-0002-pdf-page-view.md | 51 +++++++++ docs/decisions/INDEX.md | 1 + package.json | 1 + pnpm-lock.yaml | 129 +++++++++++++++++++++++ 4 files changed, 182 insertions(+) create mode 100644 docs/decisions/ADR-0002-pdf-page-view.md diff --git a/docs/decisions/ADR-0002-pdf-page-view.md b/docs/decisions/ADR-0002-pdf-page-view.md new file mode 100644 index 0000000..3a1d7aa --- /dev/null +++ b/docs/decisions/ADR-0002-pdf-page-view.md @@ -0,0 +1,51 @@ +# ADR-0002 · Original PDF page in the review screen: pdf.js in the browser + +- **Status:** Accepted – decided by the orchestrator on 2026-09-28 in #74 +- **Date:** 2026-09-28 +- **Context issue:** #74 (showcase review 2026-09-27, P1 item 2; epic #19) +- **Relates to:** ADR-0001 D5 (originals only through the tenant-checked route), D8 (grounding, stored bounding boxes) + +## Context + +The review screen shows a value's source as text in reading order with the cited segment marked +(#8, #25). For PDFs the AI service already stores the cited segment's page and bounding box +(`PdfLocator.bbox`, PDF points, origin top-left); #8 left the rendered view as "decision needed". +The showcase review asked for the original page beside the values so a visitor sees within a minute +that every value can be checked against the original. + +Constraints: originals are read only through `GET /api/documents/:id` (tenant-checked, private +bucket, no public URLs); no third-party requests from the review screen; the AI service stays +stateless and never gets storage credentials (D8); the web app runs on Vercel Hobby (D11). + +## Options + +| Option | + | − | +|---|---|---| +| **A · pdf.js (`pdfjs-dist`) in the browser** | renders the exact original from the existing route; bbox → overlay is a percentage of the page; no server cost; Apache-2.0; widely used, maintained by Mozilla | new dependency (~35 MB unpacked in `node_modules`, the page loads it lazily); a worker file must be served by the app | +| B · server-side page image (pdfium in the AI service or a Node renderer) | no PDF code in the browser | the AI service would need the original bytes again per view or storage access (breaks D8 statelessness) or the web runtime needs a native renderer; extra CPU per page view; images must be cached and tenant-scoped | +| C · the browser's own PDF viewer (`