fix(b4-bugs): external-EOI cache collision + stage-gate regression test + search popover opacity
Three B4 bug fixes shipped together:
- **#4 Upload-signed-copy blank body** — ExternalEoiUploadDialog used
queryKey=['interests', interestId] but didn't unwrap the {data} envelope
while the parent InterestDetail (same key) does, so opening the dialog
clobbered the cache with a wrapped shape and blanked the detail page
("Unknown Client" + empty tab body). Dialog now unwraps to match.
- **#2 Legacy-stage canonicalization regression test** — new integration
test locks in the external-EOI advance gate: canonical pre-EOI stages
(enquiry/qualified/nurturing) advance to 'eoi' on upload; at-or-past-EOI
stages stay put while metadata still writes. 7/7 passing. Backfill
script intentionally not shipped — dev DB is test data, prod cutover
is manual.
- **#3 Global-search dropdown translucent rows** — defensive opaque
background on the popover wrapper (bg-white dark:bg-popover) guards
against the subtle transparency UAT captured on the Berths page.
Live-browser repro still needed to identify the exact bleeding row;
this defense makes the surface unambiguously solid in light mode
regardless of which class wins tailwind-merge.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -81,14 +81,21 @@ export function ExternalEoiUploadDialog({
|
||||
// unscannable in any list when a port has multiple deals closing on
|
||||
// the same day. Also drives auto-fill on signatory rows tagged
|
||||
// role=client.
|
||||
// Cache shape MUST match the parent <InterestDetail> consumer of the same
|
||||
// ['interests', interestId] key, which unwraps the envelope and caches the
|
||||
// inner row. Caching the wrapped { data: ... } here would clobber the
|
||||
// parent's cache and blank the detail page (the rep would see "Unknown
|
||||
// Client" + an empty tab body the moment this dialog opened — UAT
|
||||
// 2026-05-24).
|
||||
const { data: interestData } = useQuery<{
|
||||
data: { clientName: string | null; clientPrimaryEmail: string | null };
|
||||
clientName: string | null;
|
||||
clientPrimaryEmail: string | null;
|
||||
}>({
|
||||
queryKey: ['interests', interestId],
|
||||
queryFn: () =>
|
||||
apiFetch<{ data: { clientName: string | null; clientPrimaryEmail: string | null } }>(
|
||||
`/api/v1/interests/${interestId}`,
|
||||
),
|
||||
).then((r) => r.data),
|
||||
enabled: open,
|
||||
staleTime: 60_000,
|
||||
});
|
||||
@@ -99,11 +106,11 @@ export function ExternalEoiUploadDialog({
|
||||
const signatories: SignatoryRow[] = useMemo(() => {
|
||||
if (signatoriesOverride !== null) return signatoriesOverride;
|
||||
if (prefillSignatories && prefillSignatories.length > 0) return prefillSignatories;
|
||||
if (!interestData?.data) return [];
|
||||
if (!interestData) return [];
|
||||
return [
|
||||
{
|
||||
name: interestData.data.clientName ?? '',
|
||||
email: interestData.data.clientPrimaryEmail ?? '',
|
||||
name: interestData.clientName ?? '',
|
||||
email: interestData.clientPrimaryEmail ?? '',
|
||||
role: 'client' as const,
|
||||
},
|
||||
];
|
||||
@@ -124,7 +131,7 @@ export function ExternalEoiUploadDialog({
|
||||
.map((b) => b.mooringNumber)
|
||||
.filter((m): m is string => !!m);
|
||||
const berthLabel = moorings.length > 0 ? formatBerthRange(moorings) : null;
|
||||
const clientName = interestData?.data?.clientName ?? null;
|
||||
const clientName = interestData?.clientName ?? null;
|
||||
const parts = ['External EOI'];
|
||||
if (clientName) parts.push(clientName);
|
||||
if (berthLabel) parts.push(berthLabel);
|
||||
|
||||
Reference in New Issue
Block a user