diff --git a/docs/superpowers/audits/alpha-uat-master.md b/docs/superpowers/audits/alpha-uat-master.md index 2ae83a41..e3724068 100644 --- a/docs/superpowers/audits/alpha-uat-master.md +++ b/docs/superpowers/audits/alpha-uat-master.md @@ -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 `` and forwards the callback to both call sites (active doc + history list). + - (c) S3 backend's `presignDownload` now sets `response-content-disposition: attachment; filename=""; filename*=UTF-8''` + `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 — ` 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 &&

...}` 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 })`.