При сохранении vendor-spec строки с заполненным lot_mappings автоматически
отправляются на сервер и пишутся в новый столбец lot_suggestion. Столбец
хранит JSON-массив [{lot_name, qty}] — тот же формат, что qt_partnumber_book_items.lots_json.
Если миграция ещё не прошла (столбец отсутствует), приложение логирует WARN
и записывает строку без столбца; сбоя нет.
Контракт для инструмента создания partnumber-books описан в bible-local/11-lot-suggestions.md.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Паста BOM на странице конфигурирования теперь распознаёт текстовый и
Inspur-форматы: вместо дублирования парсера на JS добавлен stateless
эндпоинт POST /api/vendor-spec/parse-text, который использует те же
детекторы и парсеры, что и импорт файла (KISS — один парсер на оба
входа). JS-копии _parseInspurBOMText/_isInspurBOMText удалены.
Заголовок конфигурации определяется по маркеру ", в составе:" с любым
префиксом ("Сервер X3" и "Вычислительный GPU сервер X3" → модель X3);
строки тримятся, пробел в начале не попадает в P/N; запятые и дефисы
внутри описания сохраняются (RAID0,1,10; 8-GPU-2304GB).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- BOM paste: auto-detect columns by content (price, qty, PN, description);
handles $5,114.00 and European comma-decimal formats
- LOT input: HTML5 datalist rebuilt on each renderBOMTable from allComponents;
oninput updates data only (no re-render), onchange validates+resolves
- BOM persistence: PUT handler explicitly marshals VendorSpec to JSON string
(GORM Update does not reliably call driver.Valuer for custom types)
- BOM autosave after every resolveBOM() call
- Pricing tab: async renderPricingTab() calls /api/quote/price-levels for all
resolved LOTs directly — Estimate prices shown even before cart apply
- Unresolved PNs pushed to qt_vendor_partnumber_seen via POST
/api/sync/partnumber-seen (fire-and-forget from JS)
- sync.PushPartnumberSeen(): upsert with ON DUPLICATE KEY UPDATE last_seen_at
- partnumber_books: pull ALL books (not only is_active=1); re-pull items when
header exists but item count is 0; fallback for missing description column
- partnumber_books UI: collapsible snapshot section (collapsed by default),
pagination (10/page), sync button always visible in header
- vendorSpec handlers: use GetConfigurationByUUID + IsActive check (removed
original_username from WHERE — GetUsername returns "" without JWT)
- bible/09-vendor-spec.md: updated with all architectural decisions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>