заведён канон общих конвенций для личных проектов
- 13 конвенций по осям arch / lang / stack / common; репозитории берут оттуда копии в свой docs/conventions/ и коммитят их у себя - conv — синхронизация копий: add / status / diff / pull / push, локальные регионы исключены из сравнения, поэтому расхождение не даёт шума
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
---
|
||||
status: рекомендуемая
|
||||
extends: arch/db-identifiers.md
|
||||
---
|
||||
|
||||
# Идентификаторы: реализация на Go
|
||||
|
||||
Как `arch/db-identifiers.md` выглядит в Go-приложении, выбравшем ULID.
|
||||
|
||||
## Единая точка — `internal/ident`
|
||||
|
||||
- `ident.NewID()` — генерация. **PK сущности** генерируется в `Create`-методах
|
||||
слоя `store`. Прочие идентификаторы (батч, задание, корреляционный ключ)
|
||||
генерируются там, где начинается операция, — но тоже только через `ident`.
|
||||
- `ident.NewIDAt(t)` — генерация с заданным временем, для бэкфилла в
|
||||
Go-миграциях: сортировка id тогда сохраняет историческую хронологию, а не
|
||||
момент прогона миграции.
|
||||
- `ident.Parse()` — разбор и нормализация; зовётся на **входных границах**
|
||||
(HTTP-роут, форма, callback бота), до обращения к store.
|
||||
- Других генераторов и парсеров id в коде нет. Это то самое «единая точка»
|
||||
из базовой конвенции; без него нормализация регистра неизбежно
|
||||
где-нибудь пропускается.
|
||||
|
||||
## Типы
|
||||
|
||||
В структурах store и домена id — обычный `string`. Отдельный тип `ID`
|
||||
заводим, только если появится вторая семья идентификаторов, которую можно
|
||||
перепутать; до этого он даёт конверсии без выгоды. От перепутывания двух id
|
||||
одной семьи в сигнатуре он всё равно не спасает — там помогают имена
|
||||
параметров.
|
||||
|
||||
## Невалидный id на границе
|
||||
|
||||
Разбор не удался — дальше зависит от того, откуда id пришёл:
|
||||
|
||||
- **из пути или query URL** — сразу 404, без обращения к store и без
|
||||
фабрикации доменной ошибки: снаружи это неотличимо от несуществующей
|
||||
записи, и хорошо;
|
||||
- **из собственной формы или callback-данных кнопки** — 400 либо понятное
|
||||
сообщение («кнопка устарела»): это баг интерфейса или протухший экран, и
|
||||
под «не найдено» его маскировать нельзя.
|
||||
|
||||
Транспорт не создаёт доменные sentinel'ы, чтобы тут же их сматчить, — это
|
||||
инверсия правила «трансляция у источника» из `lang/go/errors.md`.
|
||||
|
||||
<!-- local:механизировано -->
|
||||
<!-- /local -->
|
||||
|
||||
<!-- local:отступления -->
|
||||
<!-- /local -->
|
||||
Reference in New Issue
Block a user