Contract Versioning Workflow¶
Обзор¶
Каждый контракт состоит из нескольких файлов для удобства версионирования и разделения ответственности.
Структура контракта¶
domains/{namespace}/{entity}/
├── contract.yaml # Метаданные, владелец (Data Owner)
├── schema.avsc # Avro схема (Application Developer)
├── quality_rules.yml # Правила качества (QA Engineer)
├── sla.yml # SLA, retention (Data Owner + SRE)
├── physical_layout.yml # Для Data Engineers (индексы, партиции)
└── runbook.md # Операционная документация (SRE)
Разделение ответственности¶
| Файл | Редактирует | Версия контракта | Git конфликты |
|---|---|---|---|
contract.yaml | Data Owner | Minor/Patch | Минимальные |
schema.avsc | Developer | Major/Minor | Редкие (только изменение схемы) |
quality_rules.yml | QA Engineer | Patch | Нет конфликтов с другими |
sla.yml | Data Owner + SRE | Patch | Нет конфликтов с другими |
physical_layout.yml | Data Engineer | НЕ меняет! | Нет конфликтов с другими |
runbook.md | SRE | НЕ меняет | Нет конфликтов с другими |
Сценарий 1: Добавление нового поля (MINOR)¶
Задача¶
Добавить опциональное поле customer_phone в контракт sales/orders.
Шаги¶
# 1. Создайте feature branch
git checkout -b feature/add-customer-phone
# 2. Редактируйте ТОЛЬКО schema.avsc
vim contracts/domains/sales/orders/schema.avsc
Изменение в schema.avsc:
{
"name": "customer_phone",
"type": ["null", "string"],
"default": null,
"doc": "Телефон клиента (опционально)"
}
# 3. Обновите версию в contract.yaml
vim contracts/domains/sales/orders/contract.yaml
# contract_version: "2.0.0" → "2.1.0" (MINOR bump)
# Добавьте в changelog:
# changelog:
# - version: "2.1.0"
# date: "2026-01-24"
# author: "developer@company.ru"
# changes:
# - type: "added"
# description: "Добавлено поле customer_phone (nullable)"
# breaking: false
# 4. Валидация
cd contracts
python ci/detect_breaking_changes.py --domain sales --entity orders
# ✅ No breaking changes detected
python ci/check_version_bump.py --domain sales --entity orders
# ✅ Version bump is correct: 2.0.0 → 2.1.0 (MINOR)
# 5. Commit (только 2 файла!)
git add domains/sales/orders/schema.avsc \
domains/sales/orders/contract.yaml
git commit -m "feat(sales): Add customer_phone field to orders
- Added nullable field customer_phone
- Non-breaking change
- Version: 2.0.0 → 2.1.0"
# 6. Push и создайте MR
git push origin feature/add-customer-phone
✅ Результат: - Git diff показывает только 2 файла - Другие изменения (SLA, quality rules) не конфликтуют - Code review фокусируется только на схеме
Сценарий 2: Изменение retention (PATCH)¶
Задача¶
Увеличить retention для prod данных с 30 до 60 дней.
Шаги¶
# 1. Feature branch
git checkout -b chore/increase-retention
# 2. Редактируйте ТОЛЬКО sla.yml
vim contracts/domains/sales/orders/sla.yml
Изменение в sla.yml:
# 3. Обновите версию в contract.yaml
vim contracts/domains/sales/orders/contract.yaml
# contract_version: "2.1.0" → "2.1.1" (PATCH bump)
# Добавьте в changelog:
# changelog:
# - version: "2.1.1"
# date: "2026-01-24"
# author: "sre@company.ru"
# changes:
# - type: "changed"
# description: "Retention для prod увеличено до 60 дней"
# breaking: false
# 4. Валидация
python ci/check_version_bump.py --domain sales --entity orders
# ✅ Version bump is correct: 2.1.0 → 2.1.1 (PATCH)
# 5. Commit (только 2 файла!)
git add domains/sales/orders/sla.yml \
domains/sales/orders/contract.yaml
git commit -m "chore(sales): Increase retention for orders.prod to 60 days
- Retention: 30d → 60d
- Reason: Monthly trend analysis
- Version: 2.1.0 → 2.1.1"
git push origin chore/increase-retention
✅ Результат: - Schema НЕ трогали → нет breaking changes - Git diff минимальный - Другие команды не затронуты
Сценарий 3: Оптимизация индексов (NO VERSION CHANGE)¶
Задача¶
Добавить композитный индекс для оптимизации запросов SLA мониторинга.
Шаги¶
# 1. Feature branch
git checkout -b perf/add-status-index
# 2. Редактируйте ТОЛЬКО physical_layout.yml
vim contracts/domains/sales/orders/physical_layout.yml
Изменение в physical_layout.yml:
indexes:
secondary:
# ... существующие индексы ...
# Новый индекс
- name: "idx_status_created"
fields: ["status", "created_at"]
type: "btree"
reason: "Запросы SLA мониторинга (заказы в статусе за период)"
cardinality: "medium"
# 3. Версию контракта НЕ МЕНЯЕМ!
# 4. Commit (только 1 файл!)
git add domains/sales/orders/physical_layout.yml
git commit -m "perf(sales): Add composite index on status + created_at
Improves SLA monitoring queries by 5x:
- Query: SELECT * FROM orders WHERE status = ? AND created_at >= ?
- Before: 2.5s
- After: 500ms
No contract version change (physical optimization only)"
git push origin perf/add-status-index
✅ Результат: - Версия контракта не изменилась - Consumers не затронуты - CI/CD пропустит deploy в Schema Registry
Сценарий 4: Breaking change (MAJOR)¶
Задача¶
Сделать поле status обязательным (было nullable).
Шаги¶
# 1. Feature branch
git checkout -b feat/require-status
# 2. Редактируйте schema.avsc
vim contracts/domains/sales/orders/schema.avsc
Изменение в schema.avsc:
{
"name": "status",
"type": {
"type": "enum",
"name": "OrderStatus",
"symbols": ["pending", "confirmed", "processing", "shipped", "delivered", "cancelled"]
},
"doc": "Статус заказа (ОБЯЗАТЕЛЬНОЕ ПОЛЕ)"
}
# 3. Обновите версию в contract.yaml
vim contracts/domains/sales/orders/contract.yaml
# contract_version: "2.1.1" → "3.0.0" (MAJOR bump!)
# Добавьте в changelog:
# changelog:
# - version: "3.0.0"
# date: "2026-01-24"
# author: "developer@company.ru"
# changes:
# - type: "changed"
# description: "Поле status теперь ОБЯЗАТЕЛЬНОЕ"
# breaking: true
# 4. Валидация
python ci/detect_breaking_changes.py --domain sales --entity orders
# ❌ BREAKING CHANGE DETECTED:
# - Field 'status' changed from optional to required
python ci/check_version_bump.py --domain sales --entity orders
# ✅ Version bump is correct: 2.1.1 → 3.0.0 (MAJOR)
# 5. Уведомите consumers!
# CI/CD автоматически отправит уведомления всем consumers из contract.yaml
# 6. Commit с BREAKING CHANGE в сообщении
git add domains/sales/orders/schema.avsc \
domains/sales/orders/contract.yaml
git commit -m "feat(sales)!: BREAKING CHANGE: status is now required
BREAKING CHANGE: Field 'status' is now required (was optional).
All producers MUST provide 'status' field.
Migration guide: https://docs.company.ru/contracts/sales/orders/v3-migration
Version: 2.1.1 → 3.0.0"
git push origin feat/require-status
✅ Результат: - CI/CD обнаружит breaking change - Consumers получат уведомления - MR потребует approval от всех consumers
Сценарий 5: Параллельные изменения (NO CONFLICTS!)¶
Ситуация¶
Три команды одновременно работают с контрактом sales/orders:
- Data Engineer добавляет materialized view
- QA Engineer добавляет новое правило качества
- SRE обновляет runbook
Без разделения на файлы (старый подход)¶
С разделением на файлы (новый подход)¶
Data Engineer:
git checkout -b perf/add-mv
vim domains/sales/orders/physical_layout.yml
# Добавил materialized view
git add domains/sales/orders/physical_layout.yml
git commit -m "perf: Add daily summary materialized view"
git push
QA Engineer:
git checkout -b feat/add-quality-rule
vim domains/sales/orders/quality_rules.yml
# Добавил правило валидации телефона
git add domains/sales/orders/quality_rules.yml
git commit -m "feat: Add phone validation rule"
git push
SRE:
git checkout -b docs/update-runbook
vim domains/sales/orders/runbook.md
# Обновил процедуру эскалации
git add domains/sales/orders/runbook.md
git commit -m "docs: Update escalation procedure"
git push
✅ Результат: - НЕТ конфликтов! Разные файлы - Все MR можно мерджить независимо - Code review простой и быстрый
Сценарий 6: Одновременное изменение схемы и качества¶
Ситуация¶
Два изменения в разных ветках: - Branch A: Добавление поля discount_amount - Branch B: Добавление правила качества для total_amount
Процесс¶
Branch A (schema):
git checkout -b feat/add-discount-field
# Изменения:
# - schema.avsc: добавлено поле
# - contract.yaml: версия 2.1.0 → 2.2.0
git push
Branch B (quality rule):
git checkout -b feat/add-amount-validation
# Изменения:
# - quality_rules.yml: новое правило
# - contract.yaml: версия 2.1.0 → 2.1.1
git push
Merge¶
# 1. Merge Branch A first
git checkout main
git merge feat/add-discount-field
# ✅ Merged: version now 2.2.0
# 2. Rebase Branch B
git checkout feat/add-amount-validation
git rebase main
# КОНФЛИКТ ТОЛЬКО в contract.yaml (версия):
# <<<<<<< HEAD
# contract_version: "2.2.0"
# =======
# contract_version: "2.1.1"
# >>>>>>> feat/add-amount-validation
# 3. Разрешить конфликт (просто!)
# contract_version: "2.2.1" # Patch bump поверх 2.2.0
# Обновить changelog:
# changelog:
# - version: "2.2.1"
# date: "2026-01-24"
# changes:
# - type: "added"
# description: "Добавлено правило валидации для total_amount"
# - version: "2.2.0" # Из Branch A
# ...
git add contract.yaml
git rebase --continue
git push -f
# 4. Merge Branch B
git checkout main
git merge feat/add-amount-validation
# ✅ Merged: version now 2.2.1
✅ Результат: - Конфликт только в одном месте (версия) - Легко разрешить - Логика изменений не смешалась
Best Practices¶
1. Atomic commits¶
Каждый commit трогает минимум файлов:
# ✅ Good
git add schema.avsc contract.yaml
git commit -m "feat: Add new field"
# ❌ Bad
git add schema.avsc quality_rules.yml sla.yml contract.yaml
git commit -m "feat: Multiple changes"
2. Clear commit messages¶
Используйте Conventional Commits:
feat(domain): Add new feature
fix(domain): Fix bug
chore(domain): Update configuration
perf(domain): Performance optimization
docs(domain): Update documentation
3. Migration guide для breaking changes¶
# Создайте migration guide
vim docs/migrations/sales-orders-v3.md
git add docs/migrations/sales-orders-v3.md
git commit -m "docs(sales): Add migration guide for orders v3.0.0"
4. Review checklist¶
Для reviewer'а: - [ ] Версия изменена согласно SemVer - [ ] Changelog обновлён - [ ] Breaking changes задокументированы - [ ] Consumers уведомлены (для breaking changes) - [ ] CI/CD checks прошли