Модель характеристик
NOTE
Статус: Target design. Документ описывает целевую доменную модель. Соответствующий код реализован частично (см.
backend/internal/core/) или пока не начат. Правила маркировки — в50-processes/documentation-standard.md.
Как описываются атрибуты товаров, как нормализуются значения, как сравниваются.
Классификация
Characteristic
Определение атрибута в классификаторе:
key— машинное имя, уникально (voltage,ip_rating,cable_section).display_name— локализованное ({"ru": "Напряжение", "en": "Voltage"}).value_type— см. ниже.default_unit_ref— ссылка на Unit (для числовых типов).validation— правила (min, max, regex, допустимые enum-значения).semantic_role— служебная роль:identity_key(резерв),object_type,none.
Одна и та же Characteristic может участвовать в разных Identity Profile, в некоторых как critical, в других как некритическая. Критичность не хранится на Characteristic, а на IdentityProfile.critical_attribute_keys.
Типы значений
number— одиночное число (voltage = 220).range— диапазон (operating_temp = [-40, +85]).tolerance— номинал с допуском (resistance = {nominal: 100, tolerance_percent: 1}).dimension— составной размер (size = {length: 100, width: 50, height: 25, unit: mm}).enum— значение из справочника значений характеристики.string— свободный текст; редко critical.boolean— признак.
Каждый тип имеет свой алгоритм:
- нормализации (парсинг из строки);
- сравнения на равенство;
- сравнения “не хуже” (для подбора аналогов);
- fuzzy-сравнения (для поиска).
Единицы измерения
Unit
├── key — "mm", "kg", "kPa"
├── symbol — "мм", "кг", "кПа"
├── aliases[] — ["mm", "миллиметр", "millimetre", "мм."]
├── dimension — "length", "mass", "pressure", ...
└── to_canonical — коэффициент (или функция) в каноническую единицу
Каждая dimension имеет одну каноническую единицу (length → m, mass → kg, pressure → Pa, …). При нормализации значение приводится к канонической, но оригинальная форма сохраняется для отображения.
Пример: поставщик прислал “50 мм”. Нормализуется в {value: 0.05, unit: "m", original_value: 50, original_unit: "mm"}.
Парсинг значений
Модуль парсинга — одно из самых важных мест в нормализации. Основные правила:
Числа и единицы
"50мм","50 mm","50.0 мм","50,0 mm"→ 50 mm."0,05 м","0.05 m","5 cm","50mm"→ 0.05 m (в канонике).- Десятичный разделитель — и
., и,, регион-нейтрально.
Диапазоны
"-40...+85","от -40 до 85","−40…+85 °C","-40..+85".
Допуски
"100 ± 1%","100 +/- 1%","100 ±1 Ом".
Размеры
"100x50x25 мм","100×50×25 мм","100*50*25".
Enum
- Алиасы значений как и у units: “IP54” = “ip 54” = “ИП54” = “IP-54”.
Отсутствующие значения (nullable / missing)
Если поставщик не предоставил значение характеристики:
- Сохраняется
nullв слое supplier offer. - При попадании в canonical product — заполняется из другого источника (другой поставщик, AI-enrichment, ручной ввод).
- Критичные характеристики не могут быть
nullу canonical product: если все источники молчат, canonical не создаётся, offer становится orphan.
Конфликты значений между поставщиками
Два поставщика сообщили разные значения одной критической характеристики у (по MPN) одного товара.
Правила разрешения (в порядке применения):
- Правило priority источников: производитель > дистрибьютор первого уровня > партнёр > маркетплейс.
- Если приоритеты равны — самое свежее.
- Если всё равно неоднозначно — помечаем конфликт, попадает в очередь модерации. Canonical получает значение
nullпо этой характеристике до разрешения.
Обогащение
Если характеристика отсутствует у всех поставщиков, но:
- её можно извлечь из описания через LLM — используется AI enrichment с флагом
source = ai,confidence. - её можно посчитать из других (например, объём из габаритов) — используется правило расчёта.
- AI-значения НЕ используются как critical в identity_signature без ручной верификации.
Версионирование
- Изменение
validationилиvalue_typeCharacteristic = breaking change, требует ADR и пересчёта затронутых canonical products. - Добавление нового alias unit — не breaking.
- Добавление новой Characteristic — не breaking.