docs(uat): SHIPPED annotations for PR6 (structured signatories + signers)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-21 17:35:32 +02:00
parent 301375a3c3
commit a673b6cec2

View File

@@ -345,6 +345,10 @@ _Component refactors, multi-file edits, single-service tweaks, new validators._
> - **(d-prereq) Create `document_signers` rows on external upload so "X / Y signed" badge works** — _src/components/documents/document-detail.tsx:278_ reads `signers.filter(s => s.status === 'signed').length / signers.length` from the `DetailSigner[]` array. For manually-uploaded external EOIs the array is empty (the upload writes only freetext `signerNames` metadata) → badge renders `0 / 0 signed` even with 3 signers entered in the dialog. Fix is downstream of (a): when migrating from freetext to the structured `signatories: Array<{name, email, role}>` shape, the service should also insert `document_signers` rows (one per signatory), all pre-stamped `status='signed'`, `signedAt=input.signedAt`, `signingOrder=index+1`, `invitedAt=null` (no invitation was sent — this is a backfill of an external signing event). Counter then renders `3/3 signed` correctly. ~15 min on top of (a)'s service work. Captured 2026-05-21 from UAT.
> - **(d) Default document title should reference client + berth(s), not just date** — _external-eoi-upload-dialog.tsx:103_ (current placeholder `'External EOI - <date>'`) — when the rep accepts the default, the document lands as `External EOI — 2026-05-21`, which is unscannable in any document list when a port has multiple deals closing on the same day. **Fix:** derive the default at dialog open time using the same `formatBerthRange()` helper that powers the locked folder-naming convention (Bucket 4 #5). Format: `External EOI — <Client name> — <berth range> — <YYYY-MM-DD>` (e.g. `External EOI — Matthew Ciaccio — A1-A3, B5-B7 — 2026-05-21`). When no client or berths are linked, gracefully fall back to the current minimal form. Apply the same idiom to the Reservation + Contract external-upload dialogs for consistency. ~15 min.
> - **Effort:** ~5-7h end-to-end. ~1.5h for (a) — structured recipient editor + service shape change + migration if a dedicated table is preferred. ~1h for (b) — auto-fill resolver + admin setting for developer defaults + UI wiring. ~3-4h for (c) — dialog + send service + branded email template + audit + attachment-vs-link logic. ~15min for (d). Captured 2026-05-21 from UAT. **Cross-ref:** the broader UploadForSigningDialog rework (item below) needs the same role-tagging UI — build the recipient-list editor once and reuse on both dialogs. The default-title derivation in (d) also belongs as a shared helper since Reservation/Contract uploads should match.
> - **SHIPPED (a) + (d-prereq) in 301375a:**
> - (a) Structured `signatories: Array<{name, email, role}>` lands on the service input, the API multipart payload, and the dialog UI. Role enum: `client/developer/rep/witness/cc`. Auto-seeds the client row from `interestData.clientName + clientPrimaryEmail` via a signatoriesOverride/null pattern (React-Compiler safe).
> - (d-prereq) `document_signers` rows inserted inside the transaction for every non-CC signatory, pre-stamped `status='signed'`, `signedAt=input.signedAt`. The document-detail "X / Y signed" badge now renders the right count.
> - **Remaining (b) + (c) + (d) deferred:** developer-default settings, "Email copy" multi-recipient dialog, send pipeline + branded template, role-based email auto-fill beyond the client row — bundles with the broader Documenso send-flow work in Wave 4.
> - **UploadForSigningDialog comprehensive rework — 4 linked issues** — _src/components/documents/upload-for-signing-dialog.tsx_ — surfaced together during UAT 2026-05-21 of the Reservation Agreement send flow. All four touch the same dialog and should ship as one coherent pass.
> - **(a) [bug] "Failed to load PDF file" on the place-fields step** — the place-fields step uses `URL.createObjectURL(file)` (line 265) as `fileUrl` and passes it to react-pdf inside `FieldPlacementStep`. `pdf-viewer.tsx:149` `onLoadError` fires when react-pdf can't parse the blob. Likely causes to check: (i) the uploaded file isn't a PDF (PNG, DOCX, etc. — select-file step likely doesn't enforce `application/pdf` mime check); (ii) PDF.js worker URL misconfigured (every PDF fails the same way); (iii) blob revoked too early (`useEffect` cleanup at line 266-270 — though the deps look right); (iv) react-pdf version-incompatible with the worker bundle. **First debug step:** check browser devtools console for the actual error message — currently it's collapsed into a generic "Failed to load PDF file." string. Surface the underlying error to the UI ("Couldn't parse PDF — check that you uploaded a `.pdf` file, not an image or Word doc.") so the rep can self-diagnose.
> - **(b) [ux] Dialog way too small for the place-fields step** — dialog is `max-w-5xl` (1024px, line 166) which is fine for the recipients step, but the place-fields step has a 176px-wide field palette + 200px-wide recipients list on the left and only ~650px for the PDF preview on the right. A US Letter page at fit-width in 650px is barely legible, and field placement requires precision. **Fix:** make the dialog adaptive per-step: `max-w-3xl` for select-file + configure-recipients steps (768px is plenty for forms), but expand to `max-w-[1400px]` or `max-w-[95vw]` on the place-fields step where horizontal PDF space matters most. Alternative: full-screen modal pattern for the place-fields step only (escape exits, top bar shows step indicator + Back/Send). Also shrink the field palette from `w-44` (176px) to `w-32` (128px) by using icon-only buttons with tooltips — recovers ~50px of PDF width.