Перейти к основному содержимому

Event Contract: pin.identity.company-upserted (CompanyUpsertedKafkaEvent)

Версионируемый контракт интеграционного события «компания создана/обновлена». Consumer-документы ссылаются сюда, не переописывая payload. Покрывает оба минимальных события — company-created и company-updated: создание отличается тем, что это первое событие агрегата (Version = 1, потребитель видит CompanyId впервые); отдельного «created»-контракта нет, чтобы не иметь два источника одинакового snapshot-а.

Назначение

Фиксирует создание CompanyEntity (через admin API PIN, SEED или синхронизацию из Talent) и каждое значимое обновление её публичных полей (Name/Status/Requisites/LogoFileId/Slug). Событие публичное: даёт downstream-контекстам snapshot компании без синхронного запроса в identity — карточка застройщика в каталоге, компании участников сделок в CRM, владельцы правил вознаграждений, авторы-компании постов.

Metadata

ПолеЗначение
Event typepin.identity.company-upserted
Topicpin.identity.companies.v1 — общий с company-suspended; порядок событий одной компании гарантирован общим ключом (CompanyId)
Partitions / key3 (компаний тысячи) / key = CompanyId
ContractVersion1
Produceridentity: операции компаний в admin API, синхронизация из Talent (talent-identity-sync)
Статусdraft
Атомарность публикации

Событие публикуется атомарно со сменой состояния компании: до фиксации изменения событие не отправляется, после фиксации — доставляется гарантированно (at-least-once).

Payload CompanyUpsertedKafkaEvent

Полный snapshot публичных display-полей. Дом полей — entity: CompanyEntity; здесь перечислено только то, что реально в событии.

ПолеТипОбязательностьИсточник (поле агрегата)CompatibilityОписание
CompanyIdGuidДаCompanyEntity.IdImmutableКлюч агрегата (= Kafka key). Для Talent-реплик равен TenantId Talent.
Typestring (enum CompanyType)ДаCompanyEntity.TypeImmutableDeveloper / Agency / Broker / Partner / Pin. Иммутабельно (INV-4, см. company.md).
Statusstring (enum CompanyStatus)ДаCompanyEntity.StatusAdditive only (новые значения enum)Pending / Active / Suspended / Archived.
NamestringДаCompanyEntity.NameAdditive onlyОтображаемое название (≤ 256).
SlugstringДаCompanyEntity.SlugAdditive onlyАдрес workspace (^[a-z0-9][a-z0-9-]{1,62}[a-z0-9]$).
LogoFileIdGuid?НетCompanyEntity.LogoFileIdAdditive onlyФайл логотипа во внешнем хранилище (пресайн — граница storage/CDN).
RequisitesCompanyRequisitesSnapshot?НетCompanyEntity.RequisitesAdditive onlyЮридические реквизиты (см. вложенную модель).
SyncSourcestring (enum CompanySyncSource)ДаCompanyEntity.SyncSourceImmutablePin / TalentIdentity — потребитель понимает, реплика это или локальная компания.
VersionlongДаCompanyEntity.VersionImmutable semanticsДоменная версия агрегата; монотонный guard у потребителей (событие с меньшей версией — skip). Version = 1 ⇔ создание компании.

Вложенная модель CompanyRequisitesSnapshot

ПолеТипОбязательностьОграниченияОписание
LegalNamestring?Нет≤ 512Юридическое наименование.
Innstring?Нет^\d{10}(\d{2})?$ИНН (10 — юрлицо, 12 — ИП).
Kppstring?Нет^\d{9}$КПП.
Ogrnstring?Нет^\d{13}(\d{2})?$ОГРН/ОГРНИП.
LegalAddressstring?Нет≤ 512Юридический адрес.

Когда публикуется

УсловиеПереход состоянияПубликация
Создание компании (admin API identity, SEED-миграция компании ПИН, синхронизация из Talent)[*] → Pending → Active (или сразу Suspended/Archived по snapshot Talent)атомарно со сменой состояния агрегата
Значимое обновление: Name / LogoFileId / Requisites / Slug и другие поля snapshot-абез переходата же
Возобновление (Suspended → Active) и архивация (→ Archived)Suspended → Active / `ActiveSuspended → Archived`

Потребители (consumers)

Сверено с service-boundaries.md («Владение данными»: catalog/crm/rewards/news читают identity).

Consumer-контекстЭффектИдемпотентностьЗадержка (SLA)
catalogПроекция «Застройщик» витрины: название/лого/статус; Suspended/Archived скрывает бренд-страницуMessageId + guard по Version< 1 мин
crmРеплика компании (стороны сделки/фиксации): название, тип, статусто же< 1 мин
rewardsСправочник компаний для правил вознаграждений и комиссионной политикито же< 5 мин
newsАвтор-компания постов: название/лого; доступные категории — по Typeто же< 5 мин

Порядок и согласованность

  • Полный snapshot — замещение, не слияние. Событие несёт полный набор публичных display-полей; потребитель замещает свою реплику целиком, а не мёржит дельты. Отсутствие optional-поля (LogoFileId, Requisites) в снапшоте означает «значение очищено», а не «оставить прежнее».
  • First-seen = создание. Upsert для ранее неизвестного CompanyId создаёт реплику, для известного — обновляет; поведение детерминировано CompanyId (idempotent upsert).
  • Порядок per-company. Ключ CompanyId в общем с company-suspended топике даёт строгий порядок; потребитель держит Version-guard, событие с меньшей версией — skip. Повтор доставки (at-least-once) — идемпотентный no-op.

Версионирование и совместимость

  • Версия — один ContractVersion = 1; consumer при несоответствии версии события логирует warning и продолжает (без upcasting/миграции схемы). Топик кодирует версию конвенцией суффикса .v1.
  • Additive-only для minor: новые поля добавляются как optional с безопасным default — без bump.
  • Breaking (удаление/переименование/смена типа/смысла поля) — новый ContractVersion = 2 + новый топик pin.identity.companies.v2 + dual-publish на период миграции + deadline миграции consumers + sunset .v1.
  • Unknown enum (Type/Status/SyncSource) на стороне потребителя — fallback: лог warning + сохранение строкового значения без изменений (не терять запись), поведение — как для наиболее ограничивающего статуса (Suspended).
  • Deprecated-версия — sunset через 2 релиза после миграции последнего потребителя.

Безопасность

ПолеКласс данныхПравило
CompanyId, Type, Status, Slug, Version, SyncSourcePublicinclude
Name, LogoFileIdPublicinclude
Requisites.*Internal (юрданные, не PII физлица)include; в публичные проекции каталога потребителями не отдаются (правило company.md)
Что не публикуется

Событие НЕ содержит secrets, tokens, PII физлиц, WorkspaceSettings (внутренние настройки workspace — не публикуются).

Обратные ссылки

Автоссылки: где используется этот документ.

Связанные документы

  • Источник: talent-identity-sync (синк) и admin API компаний (создание Agency/Broker/Partner — README identity, раздел API).
  • Сущность: company.md; соседнее событие того же топика: company-suspended.md.