chore(autonomous-session): consolidate uncommitted work from prior session

Bundles the prior autonomous-session output that was sitting unstaged:

- Em-dash sweep across src/ + tests/ (en-dash/em-dash to hyphen, ~2280 instances)
- country-flag-icons rollout (CountryFlag component, replaces emoji glyphs that
  never rendered on Windows; lazy-loads the 3x2 SVG index as a single chunk
  after the per-subpath dynamic-import approach silently failed in webpack)
- Admin IA Phase 1+2: 7-domain regroup, 41 to 38 pages, /admin/berths index,
  redirects (ocr to ai, reports to dashboard, invitations to users),
  docs/admin-ia-proposal.md
- Per-template email tester (registry + endpoint + UI on Email admin page)
- Cancel-document mode picker (delete-from-Documenso vs keep-for-audit)
- Dashboard PDF report: 25 widgets, SVG charts, date-range picker, 11 resolvers
- Customize-widgets per-region sortables at xl+ (charts/rails/feed); single
  flat sortable below xl when the layout stacks; per-viewport saved orders
- Audit doc updates capturing each shipped item
- Lint fixes: react-compiler immutability in DonutChart (reduce instead of
  let-reassign), set-state-in-effect disables in CountryFlag and
  UploadForSigning preview-bytes effect, unused 'confirm' destructures in
  interest contract + reservation tabs, unescaped apostrophe in test-template
  card copy
This commit is contained in:
2026-05-23 00:52:59 +02:00
parent 43719b49e9
commit 221ae5784e
749 changed files with 7440 additions and 3118 deletions

View File

@@ -32,7 +32,7 @@ function canonicalizeEvent(event: string): string {
// Discriminated union of every Documenso event we know how to react to.
// Adding a new event type forces a compile error in the `match(...)`
// below via `.exhaustive()` so we can't ship a Documenso 2.x bump
// below via `.exhaustive()` - so we can't ship a Documenso 2.x bump
// without consciously deciding how to handle each new event. Anything
// not in this list falls through to the structured-log catch-all below.
type KnownDocumensoEvent =
@@ -90,7 +90,7 @@ type DocumensoRecipient = {
readStatus?: string;
signedAt?: string | null;
/** Per-recipient signing token Documenso uses as the URL tail.
* Present on both v1.13 and v2 payloads under varied field names
* Present on both v1.13 and v2 payloads under varied field names -
* we coalesce them below. Phase 2: passed through to the handlers
* so they can match against `document_signers.signing_token`
* instead of email. */
@@ -162,8 +162,8 @@ async function handleDocumensoWebhook(req: NextRequest): Promise<NextResponse> {
source: 'webhook',
});
}
// Always return 200 (webhook best-practice don't leak signal). Body
// is intentionally empty/uniform error-ux-auditor H5 noted the
// Always return 200 (webhook best-practice - don't leak signal). Body
// is intentionally empty/uniform - error-ux-auditor H5 noted the
// literal "Invalid secret" string confirms the endpoint expects a
// secret, which is a free reconnaissance hint for enumeration.
return NextResponse.json({ ok: false }, { status: 200 });
@@ -206,14 +206,14 @@ async function handleDocumensoWebhook(req: NextRequest): Promise<NextResponse> {
// Every handler accepts an optional `portId` and refuses to mutate when
// the lookup is ambiguous across multiple ports without one. Forward
// the secret-resolved portId everywhere not just the expired path
// the secret-resolved portId everywhere - not just the expired path -
// so signed/completed/opened/rejected/cancelled events can't flip a
// foreign-tenant document via documensoId reuse.
const portScope = matchedPortId ? { portId: matchedPortId } : {};
try {
if (!isKnownEvent(event)) {
// New / unknown Documenso event structured log catches the
// New / unknown Documenso event - structured log catches the
// shape so we can add a handler before the next webhook lands.
logger.info({ event }, 'Unhandled Documenso webhook event type');
} else {
@@ -222,12 +222,12 @@ async function handleDocumensoWebhook(req: NextRequest): Promise<NextResponse> {
// v1.13 fires DOCUMENT_SIGNED per recipient sign;
// 2.x fires DOCUMENT_RECIPIENT_COMPLETED for the same semantics.
// Some 2.x deployments emit RECIPIENT_SIGNED as a v2-flavoured alias
// log when we see it (telemetry) and route to the same handler so
// - log when we see it (telemetry) and route to the same handler so
// v2 deployments don't silently drop per-recipient signs.
if (e === 'RECIPIENT_SIGNED') {
logger.info(
{ event: e, documensoId },
'Documenso v2 RECIPIENT_SIGNED received routing to recipient-signed handler',
'Documenso v2 RECIPIENT_SIGNED received - routing to recipient-signed handler',
);
}
const signedRecipients = recipients.filter(
@@ -253,7 +253,7 @@ async function handleDocumensoWebhook(req: NextRequest): Promise<NextResponse> {
if (e === 'RECIPIENT_VIEWED') {
logger.info(
{ event: e, documensoId },
'Documenso v2 RECIPIENT_VIEWED received routing to document-opened handler',
'Documenso v2 RECIPIENT_VIEWED received - routing to document-opened handler',
);
}
const openedRecipients = recipients.filter(
@@ -293,7 +293,7 @@ async function handleDocumensoWebhook(req: NextRequest): Promise<NextResponse> {
await handleDocumentExpired({ documentId: documensoId, ...portScope });
})
.with('DOCUMENT_REMINDER_SENT', async () => {
// Auto-reminder informational only, no state change.
// Auto-reminder - informational only, no state change.
logger.info(
{
documensoId,
@@ -313,7 +313,7 @@ async function handleDocumensoWebhook(req: NextRequest): Promise<NextResponse> {
} catch (err) {
logger.error({ err, event }, 'Error processing Documenso webhook');
// The audit caught that webhook handlers were the only API surface
// bypassing the platform-error pipeline admin/errors was silent on
// bypassing the platform-error pipeline - admin/errors was silent on
// Documenso webhook crashes. Pipe them in so they surface alongside
// every other 5xx.
void captureErrorEvent({
@@ -327,7 +327,7 @@ async function handleDocumensoWebhook(req: NextRequest): Promise<NextResponse> {
}
// Wrap with withPublicContext so the handler runs inside a
// runWithRequestContext ALS frame without it the inline
// runWithRequestContext ALS frame - without it the inline
// `captureErrorEvent` call in the catch block silently no-ops because
// getRequestContext() returns null for unauthenticated routes.
export const POST = withPublicContext(handleDocumensoWebhook);