Event Contract: pin.identity.company-suspended (CompanySuspendedKafkaEvent)
Версионируемый контракт интеграционного события «компания приостановлена». Consumer-документы ссылаются сюда, не переописывая payload.
Назначение
Сигнальное событие перехода CompanyEntity Active → Suspended: потребители должны немедленно
ограничить операции компании (скрыть витрину, заблокировать создание фиксаций/сделок со стороны
компании), не дожидаясь очередного snapshot-а. Выделено из
company-upserted, потому что несёт причину блокировки и требует более
жёсткого SLA реакции. Обратный переход (Suspended → Active) отдельного события не имеет —
публикуется обычный CompanyUpsertedKafkaEvent со Status = Active.
Metadata
| Поле | Значение |
|---|---|
| Event type | pin.identity.company-suspended |
| Topic | pin.identity.companies.v1 — общий с company-upserted; общий key (CompanyId) обеспечивает порядок per-company |
| Partitions / key | 3 / key = CompanyId |
| ContractVersion | 1 |
| Producer | identity: приостановка через admin API, синхронизация из Talent (блокировка tenant-а) |
| Статус | draft |
Событие публикуется атомарно с переходом статуса компании: до фиксации перехода событие не отправляется, после — доставляется гарантированно (at-least-once).
Payload CompanySuspendedKafkaEvent
Дом полей — entity: CompanyEntity (раздел «Доменные и интеграционные
события»: Id, SuspendedAt, причина).
| Поле | Тип | Обязательность | Источник (поле агрегата) | Compatibility | Описание |
|---|---|---|---|---|---|
CompanyId | Guid | Да | CompanyEntity.Id | Immutable | Ключ агрегата (= Kafka key). |
SuspendedAt | DateTimeOffset | Да | момент перехода в Suspended | Immutable | Когда компания приостановлена. |
Reason | string (enum CompanySuspendReason) | Да | причина, указанная при приостановке | Additive only (новые значения) | PinDecision (решение ПИН) / TalentBlocked (блокировка tenant-а в Talent) / Debt (задолженность). |
Version | long | Да | CompanyEntity.Version | Immutable semantics | Доменная версия после перехода; монотонный guard у потребителей. |
Вложенных моделей нет.
Когда публикуется
| Условие | Переход состояния | Публикация |
|---|---|---|
| Администратор платформы приостанавливает компанию (admin API, ADR-0053) | Active → Suspended (guard INV-8 company.md) | атомарно с переходом статуса |
| Блокировка tenant-а в Talent (talent-identity-sync, алгоритм B) | Active → Suspended, Reason = TalentBlocked | та же |
Потребители (consumers)
| Consumer-контекст | Эффект | Идемпотентность | Задержка (SLA) |
|---|---|---|---|
catalog | Скрытие бренд-страницы/пометка проектов застройщика | MessageId + Version-guard | < 1 мин |
crm | Блокировка новых фиксаций/сделок со стороны компании; действующие сделки — предупреждение менеджеру ПИН | то же | < 1 мин |
rewards | Заморозка начислений/выплат компании до возобновления | то же | < 5 мин |
Вход пользователей приостановленной компании enforce-ится самим identity (INV-9 user.md) —
отдельный consumer для этого не нужен.
Порядок и согласованность
- Общий топик и ключ с
company-upserted. Приостановка и последующее возобновление (Suspended → Active, публикуется как company-upserted) идут одним топиком с ключомCompanyId— строгий порядок per-company; потребитель применяет поVersion-guard, поздний дубликат приостановки — skip. - First-seen. Если приостановка — первое событие потребителя по этой компании (реплики ещё нет), он
создаёт запись в состоянии
Suspended(fail-closed: витрина скрыта, операции компании заблокированы) и досогласует остальные поля при ближайшемcompany-upserted. - Идемпотентность и приоритет реакции. Повтор доставки — no-op (компания уже
Suspended). Из-за более жёсткого SLA реакции (см. потребители) приостановка обрабатывается приоритетно относительно обычных snapshot-обновлений топика.
Версионирование и совместимость
ContractVersion = 1; несоответствие версии события — warn-and-proceed.- Additive-only: новые optional-поля — без bump; breaking —
ContractVersion = 2+ топикpin.identity.companies.v2+ dual-publish + sunset. - Unknown enum
Reason— fallback: трактовать какPinDecision(наиболее общий), лог warning. - Deprecation — sunset через 2 релиза после миграции потребителей.
Безопасность
| Поле | Класс данных | Правило |
|---|---|---|
CompanyId, SuspendedAt, Version | Public | include |
Reason | Internal | include; в UI конечных пользователей причина не показывается дословно (только «компания временно недоступна») |
Событие НЕ содержит secrets, PII, комментариев оператора (комментарий admin-операции остаётся в аудите identity).
Обратные ссылки
Автоссылки: где используется этот документ.
- События (2): События сервиса news: карта топиков и отклонённые события/консюмеры, Event Contract: pin.identity.company-upserted (CompanyUpsertedKafkaEvent)
- Консюмеры (3): Consumer: Identity Companies (pin-chessboard-identity-companies), Consumer: identity.companies.v1 → CompanyReplica, Consumer: Talent Identity Sync (pin-identity-talent-sync)
- index.md (1): Identity Service (Pin.Identity)
- registries (1): Реестр событий PIN
Связанные документы
- Сущность: company.md (stateDiagram, enum
CompanySuspendReason). - Источники: talent-identity-sync; admin API компаний (README identity).
- Соседний контракт топика: company-upserted.md.