14 KiB
Ревью schema drafts
Пошаговая инструкция: как смотреть драфт, какие проверки делать, как принимать решение.
Где найти драфты на ревью
В навигации — раздел «Согласования» (/reviews). Вкладка «Схемы» —
ожидающие schema drafts (отсортированы по дате создания, старые сверху).
Также: на странице справочника, если у него активный draft, появляется жёлтый банер «На согласовании: <автор>». Клик → откроется drawer с содержимым драфта.
Окно ревью (Schema Draft Drawer)
При открытии драфта видишь:
┌──────────────────────────────────────────────────────────────┐
│ Согласование draft [×] │
│ автор: zimin.an · отправлен: 2026-05-12 14:00 · v1.0.0→2.0.0│
├──────────────────────────────────────────────────────────────┤
│ Комментарий автора: │
│ «Добавляем поле frequency_band — будет FK на │
│ frequency_band.code, пока опциональное чтобы не ломать │
│ существующие записи.» │
├──────────────────────────────────────────────────────────────┤
│ Текущая (live) schema │ Предложено │
│ { │ { │
│ "code": ... │ "code": ..., │
│ "name": ... │ "name": ..., │
│ } │ "frequency_band": { │
│ │ "x-references": │
│ │ "frequency_band.code" │
│ │ } │
│ │ } │
├──────────────────────────────────────────────────────────────┤
│ ◯ Breaking change keys: нет │
│ ✓ Все существующие записи остаются валидными │
├──────────────────────────────────────────────────────────────┤
│ Комментарий ревьюера: │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ ... │ │
│ └──────────────────────────────────────────────────────────┘ │
├──────────────────────────────────────────────────────────────┤
│ [REJECT] [REQUEST CHANGES] [APPROVE] [PUBLISH] │
└──────────────────────────────────────────────────────────────┘
Что проверять — чек-лист
1. Понимаешь ли ты, ЧТО автор хочет сделать?
Прочти комментарий автора. Он должен объяснить:
- Зачем менять схему (новое требование? bug fix?)
- Что меняется (поле, тип, ограничение)
- Что с существующими записями (мигрируем? остаются как есть?)
Если непонятно — REQUEST CHANGES с вопросом. Не угадывай намерения.
2. Diff schema — что изменилось
В drawer'е — side-by-side сравнение. Смотри:
- Новые поля — выделены зелёным
- Удалённые поля — красным
- Изменённые поля — жёлтым (с подсветкой, что именно)
- Breaking change keys — система автоматически помечает:
type,format,required,x-references,*Of, удаления
3. Совместимость с существующими записями
Откладывается всё на server: при попытке publish сервер прогоняет все
существующие записи через новую схему и проверяет.
Но ревьюер должен проверить руками в простых случаях:
- Поле добавляется как обязательное (
required) без default? → существующие записи становятся невалидными - Поле удаляется и оно использовалось? → потеряется данные
- Меняется
enum(убирается значение)? → записи с этим значением станут невалидны
Если сомневаешься — запроси у автора: «прогони GET /records?validate=new-schema
и пришли результат». Эндпоинт покажет, сколько записей сломается.
4. Влияние на downstream
Schema change часто требует уведомления потребителей:
- Альтум — если меняем поле, которое они используют в карточках
- Геопортал — если меняем geo-поля
- BI — если меняем имена / типы полей, которые ушли в их витрины
Если не уверен — REQUEST CHANGES с просьбой согласовать с командами. Лучше потратить 2 дня на согласование, чем 2 дня на rollback.
5. Версионирование
Схема имеет schemaVersion (1.0.0, 2.0.0). Правила:
- Major bump — breaking change (удаление, изменение типа, обязательность). Все консьюмеры должны быть готовы.
- Minor bump — backward-compatible (добавление опциональных полей,
расширение
enum, новыеdescription). - Patch — косметика (документация, examples).
Если автор предлагает minor bump для breaking change — REQUEST CHANGES с просьбой обновить версию.
6. Тесты / валидация
Если справочник имеет sample data в bundle — после schema change нужно проверить, что sample data всё ещё валидна. Это проверяет CI автоматически после publish, но лучше catch'нуть раньше.
Действия
APPROVE
Изменение безопасное, можно публиковать. Кнопка переводит статус драфта в
APPROVED. Публикация ещё не произошла — нужен отдельный клик
«PUBLISH», который применяет схему к live справочнику.
Опциональный комментарий — почему approve. Появится в audit log.
REJECT
Изменение неприемлемо в принципе, обсуждать нечего. Например:
- Удаляется поле, которое critical для бизнеса
- Меняется тип так, что данные потеряются необратимо
Драфт переходит в REJECTED. Обязателен комментарий — почему отказ.
Автор увидит, может создать новый драфт с учётом feedback.
REQUEST CHANGES
Изменение в принципе ОК, но требует доработки. Например:
- Нужно изменить версию (major вместо minor)
- Нужно сделать поле опциональным с default
- Нужно добавить data migration script
Драфт переходит в CHANGES_REQUESTED. Автор увидит, отредактирует, отправит
заново (вернётся в REVIEW_PENDING). Обязателен комментарий — что
именно править.
WITHDRAW
Только автор может withdraw свой драфт (если передумал). Ревьюер этого не делает.
PUBLISH
Только после APPROVE. Применяет новую схему к live справочнику:
- Обновляется
schema_definitionв БД - Все будущие записи валидируются по новой схеме
- Существующие записи не модифицируются (их данные остаются как есть)
- Публикуется событие в Kafka — консьюмеры узнают о смене схемы
После publish откатить нельзя в один клик — нужен новый draft с inverse change.
Что произойдёт при APPROVE → PUBLISH
dictionary_definitions.schema_jsonобновляется до новой версииdictionary_definitions.schema_versionинкрементируется- В audit log пишется операция
SCHEMA_PUBLISHED - В Kafka топик публикуется
DictionarySchemaUpdatedevent с before/after - Redis projection (если включена) cascade-invalidates dependent projections
- Frontend admin-ui получает push notification (через next polling) → баннер «новая схема» появляется у активных операторов
Типичные паттерны
Добавление опционального поля
- frequency_band: {x-references: "frequency_band.code"} ← новое, опциональное
Обычно APPROVE. Существующие записи остаются валидными (поле просто
undefined).
Добавление обязательного поля без default
- mass_kg: {type: "number"} ← новое, в required
Обычно REQUEST CHANGES — либо default, либо nullable, либо
сначала миграция данных.
Изменение x-references
- type: {x-references: "satellite_type.code"}
+ type: {x-references: "satellite_type_v2.name"}
REQUEST CHANGES в подавляющем большинстве случаев. Если справочник переименован — нужно migration data, не просто schema swap.
Расширение enum
- status: {enum: ["ACTIVE", "INACTIVE"]}
+ status: {enum: ["ACTIVE", "INACTIVE", "MAINTENANCE"]}
APPROVE — обратно совместимо.
Сужение enum
- status: {enum: ["ACTIVE", "INACTIVE", "MAINTENANCE"]}
+ status: {enum: ["ACTIVE", "INACTIVE"]}
REJECT или REQUEST CHANGES — записи со значением MAINTENANCE
станут невалидны. Нужна data migration сначала.
Удаление поля
- legacy_id: {type: "string", x-unique: true}
Опасно. Спроси:
- Кто-то использует это поле в downstream?
- Что мы делаем с данными в нём?
- Не лучше ли его deprecate (оставить, не использовать)?
Обычно REQUEST CHANGES с обсуждением.
Если ошибся
Ревьюеры — люди. Если approve'нул и потом понял что зря:
- Если PUBLISH ещё не произошёл — попроси автора
WITHDRAW, потомREJECTили создать новый - Если PUBLISH произошёл — создай новый schema draft с inverse change (откати изменение), пройди ревью заново
- Документируй в audit — комментарий «откатываю, потому что X» — важная информация для будущих ревьюеров
Это не катастрофа, но и не норма. Если ошибаешься > 1 раза в квартал — стоит пересмотреть процедуру ревью (может, нужен mandatory peer-review).