docs: записать решения по итогам ценообразования и индексу decisions

Смысл красной подсветки итогов сменился с «цены есть не для всех
позиций» на «часть суммы посчитана по ценам-заглушкам world» —
оформлено отдельной записью в decision log. Журнал решений добавлен
в оглавление bible-local.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Mikhail Chusavitin
2026-07-24 17:16:36 +03:00
co-authored by Claude Opus 4.8
parent 97629a1441
commit bc17c18943
3 changed files with 52 additions and 0 deletions
@@ -43,3 +43,7 @@ is missing or ≤ 0:
"latest active `world` pricelist," not a per-configuration pin.
- If no `world` pricelist exists locally, behavior is unchanged (missing prices stay "—",
no error).
- How the footer totals surface this fallback is decided separately in
[2026-07-24-pricing-total-world-share.md](2026-07-24-pricing-total-world-share.md);
membership of world LOTs in the configurator's LOT set is decided in
[2026-07-24-component-universe-world-union.md](2026-07-24-component-universe-world-union.md).
@@ -0,0 +1,47 @@
# Decision: pricing totals signal the world-fallback share, not row coverage
**Date:** 2026-07-24
**Status:** active
## Context
The footer totals of both "Ценообразование" tables used to mean one thing: a red number
with a trailing `*` said "prices are missing for some positions (N of M)". Two problems:
- the asterisk was a separate `<span>` after the number and wrapped onto its own line,
pushing the footer layout around;
- coverage was the wrong thing to warn about. Since
[2026-07-10-world-pricelist-fallback.md](2026-07-10-world-pricelist-fallback.md) a
missing price is silently filled from the `world` pricelist, so the total is rarely
incomplete — it is *contaminated*. A sum resting on world stand-in prices looked exactly
like a sum of real ones.
## Decision
`_setPricingTotal` in `web/templates/index.html` renders every footer total for Estimate,
Склад and Конкуренты in both tables (buy and sale):
- No asterisk, ever. The number stands alone.
- The total is red **if and only if** part of it was computed from `world` prices — that
is, `worldTotal > 0`. A clean sum is not coloured. Red is a contamination signal, not a
coverage signal.
- The world share per column is accumulated from the same per-row flags that tint the
cells amber (`estWorld` / `whWorld` / `compWorld`), summed over line totals, not unit
prices.
- Hovering the total opens a styled popup (`.pricing-total-tip` in `web/static/app.css`),
not a `title=` tooltip — the native one appears too late to notice on a number the user
is meant to distrust. It states the exact percentage and, when prices are genuinely
missing for some rows, adds the coverage line that the asterisk used to carry.
- "Ручная цена" is not part of this: it is user input, never world-derived.
## Consequences
- Red in the pricing footer means "part of this sum is a stand-in price", nothing else.
Do not reuse it for coverage, staleness or any other condition.
- The colour and popup classes are re-applied on every render and stripped first, so they
never accumulate across re-renders.
- The totals are written with `innerHTML` (number plus popup element). Nothing may read
`textContent` off `#pricing-total-*-estimate|warehouse|competitor`; the vendor-price
column and row `data-` attributes remain the read path for `applyCustomPrice` and
`_getPricingEstimateTotal`.
- The old `_setPartialTotal` helper is gone; do not reintroduce a coverage-only signal.