docs(uat): SHIPPED annotations for PR2 (external-EOI bundle)

Annotate B4 #5 with the 6cdb9af summary of what landed (a/b/c/d +
default title) and what's deferred (e — edit metadata UI bundles with
later signing-flow rework).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-21 17:02:12 +02:00
parent 6cdb9af6b2
commit 69444878ab

View File

@@ -694,6 +694,13 @@ _Functional defects. Tag each with `[critical|high|medium|low]` prefix._
- Side concern: the same edit affordance probably belongs on signed Reservations and signed Contracts too — but those are typically Documenso-bound (signedAt is webhook-attested), so editing should be more restricted there. For external EOIs the rep is the source of truth for signedAt anyway, so editing is safe.
- ~1-1.5h including dialog component + service PATCH + audit log + permission gate.
- **Effort:** ~3-4h total for all five sub-issues (was 1-1.5h before (d) + (e) landed). Captured 2026-05-21 from UAT.
- **SHIPPED (a) + (b) + (c) + (d) + default-title in 6cdb9af:**
- (a) `uploadExternallySignedEoi` returns `{ stageChanged, newStage }`; client toast branches on the flag.
- (b) `SignedPdfActions` now takes an `onView` callback; `InterestEoiTab` lifts a single `<FilePreviewDialog>` and forwards the callback to both call sites (active doc + history list).
- (c) S3 backend's `presignDownload` now sets `response-content-disposition: attachment; filename="<name>"; filename*=UTF-8''<encoded>` + `response-content-type`. `getDownloadUrl` threads `file.filename` through. Filesystem backend already honoured the param.
- (d) Service splits metadata write (always: `dateEoiSigned ?? signedAt ?? now()`, `eoiStatus='signed'`) from stage advance (gated on past-EOI). Also fires `evaluateRule('eoi_signed', …)` so berth rules stay in lockstep.
- **Default title** for the external-EOI dialog now derives `External EOI — <Client> — <berth range> — <date>` via the existing `formatBerthRange` helper; rep can override.
- **(e) Edit-metadata UI deferred** to a later wave so it can share infra with the broader signing-flow rework (queued as task #14).
7. **[high] Expense form: zod refine on `receiptFileIds` fires invisibly — Create button does nothing because the error renders nowhere** — _src/components/expenses/expense-form-dialog.tsx:64-77_ (form registers `useForm` + `zodResolver(createExpenseSchema)`) + _src/lib/validators/expenses.ts:40-47_ (schema-level `.refine()` requiring `receiptFileIds.length > 0 || noReceiptAcknowledged === true`, attached to `path: ['receiptFileIds']`). The form keeps `uploadedReceipt` + `noReceipt` in local React state, never injecting them into the form values via `setValue`. They're spliced into the payload INSIDE `onSubmit` (lines 188-189) — but `onSubmit` is never reached because validation fails first: zodResolver sees `receiptFileIds: undefined` in form values, the refine fails, `errors.receiptFileIds` is set. The form has NO `{errors.receiptFileIds && <p>...}` block, so the error is invisible. Browser scrolls to top of failed form. User reports "I filled everything in and uploaded a receipt — clicking Create does nothing."
- **Fix (recommended — single source of truth in react-hook-form):**
- When `handleFileChange` succeeds: `setValue('receiptFileIds', [uploadedReceipt.id], { shouldValidate: true })`.