feat(ux): P-4.5 inquiry linkage + docs N+1 parallelization

Step 4 (in progress) — first slice of UX features.

P-4.5: inquiry → client linkage now survives the triage conversion.

- inquiry-inbox.tsx adds `?create=1` to the redirect so the new-client
  sheet auto-opens (the existing prefill_* params were already being
  written but the form never opened).
- client-list.tsx reads prefill_name / prefill_email / prefill_phone /
  prefill_source / prefill_inquiry_id from useSearchParams and passes
  them to ClientForm via a typed `prefill` prop.
- ClientForm hydrates the create-flow initial values from the prefill
  AND threads `sourceInquiryId` through to the createClient mutation.
- createClientSchema accepts `sourceInquiryId`; the existing service
  spread already passes it to drizzle's insert.

Net effect: a website inquiry that gets converted now lands as a
client row with `clients.source_inquiry_id` populated. The conversion
funnel-by-source chart (Step 6) can attribute the win back to the
originating inquiry.

Documents tab N+1: `listInflightWorkflowsAggregatedByEntity` previously
walked direct + every company + every yacht + every related client
sequentially. On a busy client (~25 related entities) this was ~50
sequential round-trips with cumulative latency. Replaced with a single
`Promise.all` over the four lookup groups + nested Promise.all over
the per-entity queries within each group. Same query count, but wall-
clock collapses from "sum of every query" to "max single round-trip"
(typically <100ms now vs >1s before).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-14 15:37:23 +02:00
parent e933e32dbd
commit a77b3c670a
5 changed files with 124 additions and 26 deletions

View File

@@ -127,6 +127,9 @@ export function InquiryInbox() {
const phone = pickPhone(row.payload);
triageMutation.mutate({ id: row.id, state: 'converted' });
const qs = new URLSearchParams();
// create=1 auto-opens the new-client sheet; the client-list page
// reads the prefill_* params and hydrates the form (P-4.5).
qs.set('create', '1');
if (name) qs.set('prefill_name', name);
if (email) qs.set('prefill_email', email);
if (phone) qs.set('prefill_phone', phone);