From 08cedad1bf0eb0dba0610a0b0b2c82d4c3cb3ec9 Mon Sep 17 00:00:00 2001 From: bot-backend Date: Sat, 4 Jul 2026 10:32:43 +0300 Subject: [PATCH] =?UTF-8?q?fix(tradein/v2):=20audit=20#2081=20residual=20?= =?UTF-8?q?=E2=80=94=20404=20short-circuit,=20disabled-tab=20tooltips,=20s?= =?UTF-8?q?tale=20hex=20token,=20=D0=94=D0=9A=D0=9F=20decode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit L3: sibling dashboard hooks (analytics/location-coef/placement-history/ sell-time) now short-circuit once restore-by-id confirms 404, instead of each firing their own doomed request against the same dead estimate id. L5: dimmed non-interactive user-menu items (Профиль/Настройки/Помощь) get a hover title explaining why they're disabled. L7: TopNav logo subtitle used a stale literal #6f8195 predating the C1 contrast sweep; now references tokens.muted. M12: HistoryView's "ДКП-сделки" card gets the same one-time ДКП decode convention ObjectSummary already uses. H2/M8/M9/M10/M11 re-verified live/by-code — already correct, no changes needed (see issue comment). L4 (HistoryView outlier clamp) and L6 (blueprint-grid background-image) left as follow-ups (mapper-level change / no contrast payoff respectively). Refs #2081 --- tradein-mvp/frontend/src/app/v2/page.tsx | 23 +++++++++++------ .../components/trade-in/v2/HistoryView.tsx | 13 ++++++++++ .../src/components/trade-in/v2/TopNav.tsx | 25 ++++++++++++++++--- 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/tradein-mvp/frontend/src/app/v2/page.tsx b/tradein-mvp/frontend/src/app/v2/page.tsx index c6c8659b..7b9160d5 100644 --- a/tradein-mvp/frontend/src/app/v2/page.tsx +++ b/tradein-mvp/frontend/src/app/v2/page.tsx @@ -439,9 +439,24 @@ export default function TradeInV2Page() { // Skip the restore fetch once we already hold a fresh result. const restored = useEstimate(freshResult === null ? urlId : null); + // L3 — once the restore-by-id fetch has confirmed the estimate does not + // exist (404), `currentEstimateId` below drops to null so the sibling + // dashboard hooks (analytics/location-coef/placement-history/sell-time, + // all `enabled: estimate_id !== null`) don't each fire their own doomed + // request against the same dead id. Hoisted above the sub-hooks (was + // computed further down, after they'd already fired on the stale id). + const restoreActive = urlId !== null && freshResult === null; + const restoreError = restoreActive && restored.isError; + const restoreNotFound = + restoreError && + restored.error instanceof HTTPError && + restored.error.status === 404; + const estimate: AggregatedEstimate | null = freshResult ?? restored.data ?? null; - const currentEstimateId = freshResult?.estimate_id ?? urlId; + const currentEstimateId = restoreNotFound + ? null + : (freshResult?.estimate_id ?? urlId); // Per-user side data, independent of the current estimate. Both fail-soft // (retry:false): history feeds the «Предыдущие оценки» overlay (04), quota @@ -486,13 +501,7 @@ export default function TradeInV2Page() { const sellTimeData = sellTime.data ?? null; // ── Derived state flags ─────────────────────────────────────────────────── - const restoreActive = urlId !== null && freshResult === null; const restoreLoading = restoreActive && restored.isPending; - const restoreError = restoreActive && restored.isError; - const restoreNotFound = - restoreError && - restored.error instanceof HTTPError && - restored.error.status === 404; const loading = mutation.isPending || restoreLoading; const insufficient = diff --git a/tradein-mvp/frontend/src/components/trade-in/v2/HistoryView.tsx b/tradein-mvp/frontend/src/components/trade-in/v2/HistoryView.tsx index 2c590e3c..afda51c2 100644 --- a/tradein-mvp/frontend/src/components/trade-in/v2/HistoryView.tsx +++ b/tradein-mvp/frontend/src/components/trade-in/v2/HistoryView.tsx @@ -175,6 +175,19 @@ export default function HistoryView({ > {data.dkpHeader.title} + {/* M12 — расшифровка «ДКП» один раз на секцию, тем же lowercase + hint-стилем что ObjectSummary.rowHint() (fontSize 8/letterSpacing + 0.2/muted3), а не uppercase ResultPanel §M8 стилем. */} +
+ ДКП · договор купли-продажи +
ОЦЕНКА НЕДВИЖИМОСТИ @@ -370,7 +372,14 @@ export default function TopNav({
-
+ {/* L5 — `title` gives the dimmed/non-interactive item a hover + tooltip explaining WHY it's disabled, instead of a silent dead + row (mirrored on Настройки/Помощь below). */} +
-
+
+