fix: регистронезависимый поиск lot_name и удаление мёртвого кода

- SQLite-запросы по lot_name теперь используют UPPER(lot_name) IN/= для
  совместимости с легаси-данными, синхронизированными до нормализации регистра
- Удалена таблица local_components и весь связанный код синхронизации;
  источник данных для компонентов — local_pricelist_items
- Удалена функция getCategoryFromLotName из JS: категория берётся только
  из прайслиста, без инференса из имени лота
- Регистронезависимые сравнения lot_name в JS (warehouse stock set,
  addedLots, cartLots, allComponents.find, _bomLotValid)
- В support bundle добавлены: latest_pricelist_items.json, local.db,
  autocomplete_lots.json для диагностики

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-26 08:52:22 +03:00
parent 8b2dc6652a
commit 7d190cc7a8
19 changed files with 500 additions and 585 deletions
+2 -2
View File
@@ -4,9 +4,9 @@ import (
"errors"
"log/slog"
"net/http"
"strings"
"git.mchus.pro/mchus/quoteforge/internal/localdb"
"git.mchus.pro/mchus/quoteforge/internal/models"
"git.mchus.pro/mchus/quoteforge/internal/repository"
"git.mchus.pro/mchus/quoteforge/internal/services"
syncsvc "git.mchus.pro/mchus/quoteforge/internal/services/sync"
@@ -172,7 +172,7 @@ func normalizeLotMappings(in []localdb.VendorSpecLotMapping) []localdb.VendorSpe
merged := make(map[string]int, len(in))
order := make([]string, 0, len(in))
for _, m := range in {
lot := strings.TrimSpace(m.LotName)
lot := models.NormalizeLotName(m.LotName)
if lot == "" {
continue
}