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

Identity Service (Pin.Identity)

Назначение

identity владеет учётными записями пользователей, компаниями (workspace), ролевой моделью (Scoped-RBAC: роли + permissions + назначения в scope) и аутентификацией (СМС-вход, пароль, пин-код, 2FA, сессии). Сюда входят учётки инвесторов и сотрудников компаний, каталог permissions, роли и scope-назначения, а также синхронизация компаний-застройщиков и их менеджеров из внешнего talent.microservices.identity через Kafka-события.

Metadata

ПолеЗначение
Статусdraft
Owning teamPIN Platform Core
DomainIdentity & Access
Data classificationSensitive (PII: телефоны, email, ФИО; секреты — только хэши)
Runtime criticalitymission-critical (без identity не работает вход и авторизация всех контекстов)

Ownership

ArtifactOwner/Rule
PostgreSQL schemaidentity
API areas (папки api/ по актору)investor/ (public: СМС-вход, refresh, агент-онбординг accept/decline/become-agent), company-user/ (компании/роли/назначения + приглашение/отзыв агента), agent/ (self-действия членства: leave-agency/become-investor, ADR-0061), admin/ (m2m для администраторов платформы, ADR-0053), internal/ (permission-check/introspection для gateway)
Owned entitiesCompanyEntity, UserEntity, RoleDefinition (+RolePermission), RoleAssignment, PermissionDefinition (SEED), SignInConfirmationRequest, RefreshSession, TalentSyncState, CompanyInvitationEntity, AgentMembershipEntity (ADR-0061)
Produced eventspin.identity.companies.v1, pin.identity.users.v1, pin.identity.access.v1, pin.identity.sign-ins.v1, pin.identity.company-invitation-changed.v1, pin.identity.agent-membership-changed.v1 (ADR-0061)
Consumed eventstalent.identity.tenants.v1, talent.identity.users.v1 (реплика Talent)
Search indexesidentity-users (Elasticsearch-проекция UserSearchDocument — поиск пользователей компании по ФИО/телефону/email; ADR-0059) — search/users.md
Analytics factsnone (вход/активность — контекст user-activity)

Ответственность И Границы

  • Делает: регистрация/вход (СМС/пароль/пин/2FA), учётки 5 типов пользователей, компании 5 типов, каталог permissions (SEED, 139), роли компаний и системные, назначения ролей в scope (платформа/организация/группа проектов/проект) с наследованием, реплика компаний/менеджеров из Talent, сессии и их отзыв.
  • НЕ делает: администраторы платформы (живут в отдельной системе — ADR-0053); расширенный профиль, документы, реквизиты, KYC-верификация (контекст profile); enforcement record-level на записях (владеющие контексты, напр. crm-фиксации); реферальная привязка (referral); витрина сессий/трекинг (user-activity).
  • Source of truth: все owned-сущности; для Talent-компаний и их менеджеров реплика-поля — Talent (правила — domain/talent-replica.md).
  • Реплики/проекции у потребителей: UserId/CompanyId + snapshot-поля через pin.identity.* события; кэш эффективных прав — инвалидация pin.identity.access.v1.

Зависимости

ЗависимостьТипЗачем НужнаFailure mode
PostgreSQL (schema identity)dbВсе агрегаты + outboxПолный отказ сервиса (mission-critical)
KafkaqueueСинк Talent (in), события pin.identity.* (out, через outbox)Вход работает; реплики/кэши потребителей отстают (лаг-алерты)
СМС-verifier (внешний провайдер)external systemОтправка кодов подтвержденияВход по СМС недоступен; пароль/пин продолжают работать (realConfirmationCodeDispatched=false в тест-контуре)
RediscacheRate-limit кодов (INV-S4), кэш permissionsДеградация: rate-limit по БД, permissions без кэша (медленнее)
talent.microservices.identityexternal systemИсточник компаний-застройщиков и их менеджеровСинк отстаёт; локальные операции не затронуты
Администраторы платформыconsumer (m2m)Управление пользователями/ролями через admin-APIНедоступны admin-операции

Проекты

src/services/identity/
Pin.Identity.Api/ # public + admin + internal API areas
Pin.Identity.Application/ # прикладная логика (операции над агрегатами)
Pin.Identity.Domain/ # агрегаты domain/*.md
Pin.Identity.Infrastructure/ # EF (PostgreSQL), outbox, Redis, СМС-verifier adapter
Pin.Identity.Background/ # consumers Talent, jobs: expire-sessions, retention, access fan-out
Pin.Identity.Migrator/ # миграции + SEED (permissions, системные роли, компания ПИН)
Pin.Identity.Contracts/ # pin.identity.* event contracts

Основные Сущности

EntityНазначениеSource Of TruthДокумент
CompanyEntityКомпания/workspace (Застройщик/Агентство/Брокер/Партнёр/ПИН), граница tenantidentity (+реплика-поля Talent)domain/company.md
UserEntityУчётка (инвестор/менеджер застройщика/агент/сотрудник ПИН), секреты входа, контактыidentity (+реплика-поля Talent для DeveloperManager)domain/user.md
RoleDefinition + RolePermissionРоль компании/системная и её состав правidentitydomain/role.md
RoleAssignment (+ResourceScope)Назначение роли пользователю в scope с наследованиемidentitydomain/role.md
CompanyInvitationEntityПриглашение агента по телефону (Pending/Accepted/Declined/Expired/Revoked), ADR-0061identitydomain/company-invitation.md
AgentMembershipEntityЧленство агента в агентстве с историей join/leave; независимый агент — без активного членства, ADR-0061identitydomain/agent-membership.md
PermissionDefinitionSEED-каталог 139 permission (19 контекстов)identitydomain/permission.md
SignInConfirmationRequestОдноразовый запрос кода (вход/2FA/смена email/телефона)identitydomain/user-session.md
RefreshSessionRefresh-сессия входа, устройства, отзывidentitydomain/user-session.md
TalentSyncStateЧекпоинты/конфликты синка Talentidentitydomain/talent-replica.md

ER-обзор

API (карта областей; детали — api/ по api-method-template)

  • Public (18 операций, контракт стабилен): requestSignInCode, signUpOrSignIn, confirmSignIn, verifySignInPassword, signUp, getCurrentInvestor, updateInvestor, changePassword, setPinCode, clearPinCode, requestEnableTwoFactor, confirmEnableTwoFactor, requestDisableTwoFactor, confirmDisableTwoFactor, requestEmailChange, confirmEmailChange, requestPhoneChange, confirmPhoneChange.
  • Public (расширения): refreshToken, signOut, getMySessions/revokeSession, роли компании (CRUD RoleDefinition, grant/revoke RoleAssignment), просмотр каталога permissions.
  • Admin (m2m, ADR-0053): пользователи (список/блокировка/архив), компании (создание Agency/Broker/Partner, suspend), назначения платформенных ролей, resolution конфликтов синка.
  • Internal: интроспекция эффективных прав (effectivePermissions(userId, resource)) для gateway/сервисов.

Use Cases

IDСценарийДокумент
UC-IDN-001Вход/регистрация по СМС (signUpOrSignInconfirmSignIn, lazy-заполнение имени, referrerUrl)use-cases/UC-IDN-001-sms-sign-in-or-sign-up.md
UC-IDN-002Вход по паролю вместо СМС (verifySignInPassword, ветка 2FA)use-cases/UC-IDN-002-password-sign-in.md
UC-IDN-003Включение двухфакторной аутентификации (выключение — альтернативный поток)use-cases/UC-IDN-003-enable-two-factor.md
UC-IDN-004Смена телефона/email с подтверждением кодом (запрет self-service при TalentSync)use-cases/UC-IDN-004-change-phone-email.md
UC-IDN-005Создание роли компании и назначение агенту в scope проекта (Scoped-RBAC)use-cases/UC-IDN-005-company-role-create-and-assign.md
UC-IDN-006Приглашение менеджера (агента) в компанию, активация первым входомuse-cases/UC-IDN-006-invite-company-manager.md
UC-IDN-007Синхронизация компаний и менеджеров застройщиков из Talent Identity (system)use-cases/UC-IDN-007-talent-sync-company-users.md
UC-IDN-008Проверка доступа сервисом (internal check-permission, кэши и инвалидация)use-cases/UC-IDN-008-internal-permission-check.md
UC-IDN-009Приглашение агента по телефону и его принятие (CompanyInvitation → AgentMembership, ADR-0061)use-cases/UC-IDN-009-invite-agent-by-phone-and-accept.md
UC-IDN-010Выход агента из агентства с сохранением метрик (независимый агент, ADR-0061)use-cases/UC-IDN-010-agent-leaves-agency-keeps-metrics.md
UC-IDN-011Инвестор становится агентом (независимый / по приглашению, ADR-0061)use-cases/UC-IDN-011-investor-becomes-agent.md

Events И Consumers

TypeNameTopicНазначениеLink
ProducedCompanyUpsertedKafkaEventpin.identity.companies.v1Snapshot компаний для catalog/crm/rewards/newsevents/company-upserted.md · domain/company.md
ProducedCompanySuspendedKafkaEventpin.identity.companies.v1Приостановка компании: скрытие витрин, блокировка операцийevents/company-suspended.md · domain/company.md
ProducedUserUpsertedKafkaEventpin.identity.users.v1Snapshot пользователей для referral/crm/profile/messenger/user-activity/notificationsevents/user-upserted.md · domain/user.md
ProducedUserBlockedKafkaEventpin.identity.users.v1Блокировка пользователя у потребителейevents/user-blocked.md · domain/user.md
ProducedUserAccessChangedKafkaEventpin.identity.access.v1Инвалидация кэшей авторизацииevents/user-access-changed.md · domain/role.md
ProducedUserSignedInKafkaEventpin.identity.sign-ins.v1Связывание anonymous_id, алерты о новом устройствеevents/user-signed-in.md · domain/user-session.md
ProducedCompanyInvitationChangedKafkaEventpin.identity.company-invitation-changed.v1Приглашение агента по телефону (найм) для notifications/crm/rewardsevents/company-invitation-changed.md · domain/company-invitation.md
ProducedAgentMembershipChangedKafkaEventpin.identity.agent-membership-changed.v1Вступление/выход агента для crm/rewards/notifications (user-centric метрики)events/agent-membership-changed.md · domain/agent-membership.md
ConsumedTenantUpserted/Blocked/Unblocked/Deletedtalent.identity.tenants.v1Реплика компанийconsumers/talent-identity-sync.md · domain/talent-replica.md
ConsumedUserUpserted/Blocked/Unblocked/Deletedtalent.identity.users.v1Реплика менеджеров застройщиковconsumers/talent-identity-sync.md · domain/talent-replica.md

Гарантии доставки и порядок событий (контракт потребителя)

Общие правила для всех pin.identity.* — что потребители могут на них закладывать:

  • Доставка — at-least-once через transactional outbox (событие уходит в том же согласованном изменении, что и мутация агрегата). Потребитель обязан быть идемпотентным.
  • Ключ партиционирования и порядокUserId для users/access/sign-ins/ agent-membership-changed, CompanyId для companies, invitationId/адресат для company-invitation-changed. Порядок событий гарантирован в пределах одной сущности (один ключ), между разными сущностями — нет.
  • Дедуп и устаревание — каждое событие несёт монотонную Version агрегата; потребитель применяет событие, только если его Version больше уже применённой (last-writer-wins по версии), более старые/ повторные игнорирует. Это защищает реплики при переупорядочивании и повторной доставке.
  • Эволюция контрактаContractVersion растёт только additive (новые optional-поля, новые enum- значения); неизвестные потребителю поля и enum-значения игнорируются (forward-compatible). Breaking- изменение — новый major топика с параллельным периодом.
  • Окна согласованности — инвалидация кэшей прав по pin.identity.access.v1 и обновление snapshot- реплик у потребителей — секунды при штатном лаге (алерт при > 5 мин, см. SLO). До применения события потребитель может краткий промежуток видеть прежний snapshot; критичные проверки статуса на привилегированных операциях идут через internal permission-check (не через реплику).

Runtime И Эксплуатация

ОбластьТребование
Health checks/health/live, /health/ready (PostgreSQL, Kafka, Redis), /health/startup (миграции/SEED применены)
SLO/SLAconfirm-операции p99 < 300 мс; интроспекция прав p99 < 50 мс (кэш); лаг синка Talent < 5 мин
Dashboardidentity-overview (входы, ошибки кодов, лаг синка, DLQ)
Alertsлаг синка > 5 мин; DLQ > 0; всплеск IDENTITY_CONFIRMATION_RATE_LIMITED; ошибки СМС-verifier
Runbooksreplay DLQ синка; merge учёток (конфликт телефона R6); массовый отзыв сессий
Feature flagsidentity.refresh-flow.enabled (поэтапный ввод refresh-flow)

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

  • Actor types: guest (только request/confirm входа), user (self-операции), company-admin (роли/пользователи в scope), platform (роли ПИН), m2m (администраторы платформы, gateway), system (consumers/jobs).
  • Permission model: domain/permission.md (каталог) + domain/role.md (scope-назначения, INV-R8).
  • Sensitive data: телефоны/email/ФИО (PII, маскирование в логах); PasswordHash/PinCodeHash/CodeHash/ RefreshTokenHash — только хэши (Argon2id / HMAC/SHA-256), не покидают домен.
  • Audit: actor-stamping + Version на агрегатах; полная история RoleAssignment (не удаляются); security-изменения — события.
  • Tenant isolation: ADR-0052 — TenantId = CompanyId; инвестор — вне tenant, record-level по UserId; кросс-tenant — только платформенные permissions.

Известные Ограничения И Assumptions

  • Имена топиков/контракты Talent (talent.identity.{tenants,users}.v1) — assumption до подтверждения schema registry Talent (domain/talent-replica.md).
  • Группы проектов (ResourceScope.ProjectGroupId) ссылаются на chessboard без FK; консистентность — eventual (событие удаления проекта → отзыв назначений).
  • Merge учёток при конфликте телефона Talent-менеджера и инвестора — ручной процесс заботы (R6).
  • Admin-identity (хранение админов, их MFA) — вне scope (ADR-0053), проектируется отдельно.
  • «СуперАгент» из матриц не роль — дубль agent (technical-assignment.md).

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

  • Домены: company · user · role · permission · user-session · talent-replica · company-invitation · agent-membership.
  • Решения: ADR-0052 (tenancy), ADR-0053 (админы), ADR-0061 (независимый агент, приглашения, переходы ролей), technical-assignment.md (решения №1, №2, №8), glossary.md, service-boundaries.md.
  • Шаблоны/правила: service-readme-template, entity-template, algorithm-documentation-rules, cross-cutting-document-requirements; SDK — docs/11-backend-sdk/.