Files
bible/rules/patterns/identifier-normalization/contract.md
2026-03-01 22:07:19 +03:00

2.7 KiB
Raw Blame History

Contract: Identifier Normalization

Version: 1.0

Purpose

Правила хранения и сравнения идентификаторов оборудования: серийные номера, вендоры, версии прошивок, партномера, артикулы.


Правило

Оригинальное значение сохраняется как пришло — регистр не меняется. Все сравнения, поиск и дедупликация выполняются без учёта регистра.

Пришло: "SN-001-ABC"  → хранится: "SN-001-ABC"
Пришло: "sn-001-abc"  → это тот же объект, не дубликат
Пришло: "Sn-001-Abc"  → то же самое

Применяется к полям

  • Серийный номер (serial_number, serial)
  • Вендор / производитель (vendor, manufacturer)
  • Версия прошивки (firmware_version, fw_version)
  • Партномер (part_number, part_no)
  • Артикул (article, sku)

Реализация

Go — сравнение

import "strings"

func SameIdentifier(a, b string) bool {
    return strings.EqualFold(a, b)
}

Go — дедупликация

func deduplicateBySerial(items []Device) []Device {
    seen := make(map[string]struct{})
    result := items[:0]
    for _, item := range items {
        key := strings.ToLower(item.SerialNumber)
        if _, exists := seen[key]; !exists {
            seen[key] = struct{}{}
            result = append(result, item)
        }
    }
    return result
}

Ключ в map — всегда strings.ToLower(value). Сам объект сохраняется с оригинальным значением.

SQL — поиск и уникальность

Поиск:

SELECT * FROM devices WHERE LOWER(serial_number) = LOWER(?);

Уникальный индекс (MySQL / MariaDB):

-- Collation ci обеспечивает case-insensitive уникальность
ALTER TABLE devices MODIFY serial_number VARCHAR(255)
    CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

ALTER TABLE devices ADD UNIQUE INDEX uniq_serial (serial_number);

SQLite:

CREATE UNIQUE INDEX uniq_serial ON devices (LOWER(serial_number));

Что не делать

  • Не приводить значение к нижнему или верхнему регистру перед сохранением.
  • Не считать "SN-001" и "sn-001" разными объектами.
  • Не использовать == для сравнения идентификаторов в Go — только strings.EqualFold.