Identity Agent API — реестр методов и общие правила области
Реестр self-service методов агента (контекст identity, сервис Pin.Identity.Api, area agent):
пользователь c ролью agent управляет собственным членством в агентстве и переходом роли — выход из
агентства (остаётся независимым) и возврат к инвестору (ADR-0061). Общий дом правил области: модель
актора (User = сам агент, self-действие) и общий алгоритм развязки членства. Документы методов
ссылаются сюда и описывают дельту; общий конверт — в ../README.md; дома полей —
../../domain/.
Metadata
| Поле | Значение |
|---|---|
| Сервис/контекст | identity |
| API area | agent (self-действия агента над своим членством/ролью) |
| Тип документа | api (area-registry, не единичная операция) |
| Статус | draft (ADR-0061) |
| Owner | PIN Platform Core |
| Область действия | членство агента и переход роли агент→инвестор; приглашения (accept/decline/become-agent) — область investor/; приглашение/отзыв — company-user/; см. ../README.md |
| Assumptions | независимый агент = роль agent в scope Platform без активного AgentMembership (../../domain/agent-membership.md); метрики агента — user-centric (агрегация по AgentUserId), сохраняются при выходе |
Реестр методов
Route-префикс области — /api/v1/me/. Все методы — self-действия (UserId из claim sub).
| # | Метод | Route | Feature group | Permission | Документ |
|---|---|---|---|---|---|
| 1 | POST | /api/v1/me/agency-membership/leave | agent-membership | authenticated (self) | leave-agency.md |
| 2 | POST | /api/v1/me/become-investor | agent-membership | authenticated (self) | become-investor.md |
Модель актора и доступ (общий дом)
| Проверка | Значение |
|---|---|
| Actor type | User — сам агент (Bearer JWT, UserId из sub) |
| Auth | authenticated; операции self-scoped — актор меняет только своё членство и свою роль |
| Authz | не требует company-permission: агент распоряжается собственным членством. Исключение — исключение агента руководителем: тот же сценарий выхода, вызванный с правом identity.users.manage (документируется дельтой в leave-agency.md) |
| Record-level | активное AgentMembership выбирается по AgentUserId == sub |
| Tenant isolation | на входе не действует (агент/инвестор действует поверх своих кросс-компанийных membership); мутации membership/роли — в scope прежнего Organization |
Общий алгоритм развязки членства
Скелет, общий для методов области (метод описывает только дельту):
- Контекст и доступ. Операцию выполняет сам агент (
UserIdиз claimsub), self-действие. - Проверка входа и предусловий. Тело обычно пустое; учётка должна быть в статусе
Active(иначеIDENTITY_USER_BLOCKED). - Что читаем. Учётка агента; её активное членство
AgentMembershipпоAgentUserId(может отсутствовать у независимого агента); активное назначение ролиagent. - Бизнес-правила и переходы. Закрывается членство и/или снимается/перевыпускается роль
agent(детали — в документе метода); проставляется actor-stamping. Историческая привязка сделок/лидов/ фиксаций не пересчитывается (снапшоты crm иммутабельны, back-fill запрещён — ADR-0061 п.4). - Что меняется. Обновляются членство, учётка и назначение роли; история членства не удаляется (INV-AM2).
- События. Публикуются
AgentMembershipChangedKafkaEvent(pin.identity.agent-membership-changed.v1),UserUpsertedKafkaEvent(pin.identity.users.v1),UserAccessChangedKafkaEvent(pin.identity.access.v1). Мутации членства, учётки, назначения и публикация событий — в одном согласованном изменении. - Результат. Модель результата метода (
200); при отказе — код ошибки из таблицы ниже.
Интеграционная последовательность и окно согласованности (общий дом)
Что происходит у соседей после развязки членства/роли (эффекты асинхронны, лаг — секунды):
- crm по
AgentMembershipChangedKafkaEvent(Left) убирает агента из активного ростера агентства; историческая привязка сделок/лидов/фиксаций не пересчитывается (снапшоты иммутабельны, back-fill запрещён — ADR-0061 п.4). До применения события агент краткий промежуток ещё виден в прежнем ростере. - rewards продолжает начислять по user-centric метрикам (агрегация по
AgentUserId) — метрики и достижения переживают выход/смену роли. - gateway и потребители прав сбрасывают кэш эффективных прав по
UserAccessChangedKafkaEvent; реплики snapshot-полей учётки обновляются поUserUpsertedKafkaEvent(CompanyId = null,Type = Investorпри become-investor). - notifications уведомляет агента и руководителя по membership-событию.
Порядок гарантирован по ключу UserId (один агент). Все три события — из одного согласованного изменения
(либо все зафиксированы, либо ни одного).
Общие коды ошибок области
| Код | HTTP | Условие | Retry |
|---|---|---|---|
UNAUTHORIZED | 401 | Нет/просрочен JWT | no retry |
IDENTITY_USER_BLOCKED | 400 | user.Status != Active | no retry |
IDENTITY_MEMBERSHIP_NOT_ACTIVE | 404 | Нет активного членства (leave-agency) | no retry |
IDENTITY_NOT_AN_AGENT | 409 | user.Type != Agent (become-investor) | no retry |
CONCURRENCY_CONFLICT | 409 | Гонка версий с accept/leave вторым запросом | retry после перечитки |
Связанные документы
- Дома полей: ../../domain/agent-membership.md (INV-AM1..AM6),
../../domain/user.md (ослабленный INV-2, зеркало
CompanyId), ../../domain/role.md (рольagent:Organization ↔ Platform). - События: ../../events/agent-membership-changed.md, ../../events/user-upserted.md, ../../events/user-access-changed.md.
- Use cases: ../../use-cases/UC-IDN-010-agent-leaves-agency-keeps-metrics.md.
- Правила: api-method-template, command-query-template, algorithm-documentation-rules.
- Решения: ADR-0061 (независимый агент, приглашения), ADR-0052 (tenancy), ADR-0056 (simplicity-first).
- Соседние реестры: ../README.md (public/investor + конверт),
../company-user/(приглашение/отзыв агента),../admin/,../internal/.