GET /api/investors/me/referral-links/registrations — Обезличенный журнал по всем моим ссылкам (getAllRegistrations)
Назначение
Сводный постраничный журнал регистраций по всем реферальным ссылкам текущего пользователя — единая
лента «кто и когда пришёл по моим ссылкам», обезличенная (без ФИО/телефона приглашённого). Питает блок
истории регистраций на партнёрской странице /profile/partner (в отличие от
get-link-registrations.md — журнала одной конкретной ссылки). Общий конверт
и paging-модели — README.md.
Metadata
| Поле | Значение |
|---|---|
| Сервис/контекст | referral |
| API area | public |
| Feature group | referral-registrations |
| Статус | approved |
| Документ | docs/06-services/referral/api/public/get-all-registrations.md |
Актор и доступ
| Проверка | Значение |
|---|---|
| Actor type | User |
| Auth policy / Permissions | authenticated; permission referral.registrations.view-self (каталог — permission.md) |
| Scope (RBAC) | self-service |
| Record-level | фильтр ReferrerUserId == actor.UserId по денормализованному владельцу журнала — чужие записи в выборку не попадают (нет user enumeration) |
HTTP-контракт
| Поле | Значение |
|---|---|
| Method | GET |
| Route | /api/investors/me/referral-links/registrations?Offset&Take |
| Success status | 200 |
| Correlation | сквозной trace через заголовок traceparent |
Маршрутизация: статический сегмент registrations имеет приоритет над route-параметром {id} того же
уровня (правило маршрутизации) — конфликта нет (README.md, раздел «Реестр операций»).
Входные данные / параметры запроса
| Поле | Источник | Тип | Обязательность | Валидация / Ограничения | Безопасность |
|---|---|---|---|---|---|
UserId | identity claims (sub) | Guid | Да | валидный токен | record-level фильтр ReferrerUserId; 401 при отсутствии |
Offset | query | int | Да | min 0, max 2147483647 | — |
Take | query | int | Да | min 1, max 1000 | ограничение размера выдачи |
Body и route-параметры отсутствуют. Paging-ограничения — единый дом README.md («Query-параметры paging»).
Модель ответа ReferralRegistrationItemPagingResult
Контейнер offset-paging; тот же результат, что у get-link-registrations.md.
| Поле | Тип | Обязательность | Источник | Masking | Описание |
|---|---|---|---|---|---|
meta | PagingResultMeta | Да | computed | — | total / take / offset — README.md. |
items | ReferralRegistrationItem[] | Да | projection | обезличено | Записи журнала, registeredAt desc. |
Модель ReferralRegistrationItem (дом — get-link-registrations.md)
Item-модель принадлежит операции-владельцу getLinkRegistrations; здесь приведена как выход сводного
журнала. Поля — проекция сущности referral-registration.md,
обезличенная (только referredInvestorId, без ФИО/телефона).
| Поле | Тип | Обязательность | Источник (ReferralRegistrationEntity) | Masking | Описание |
|---|---|---|---|---|---|
registeredAt | string (ISO 8601) | Да | RegisteredAt | — | Момент регистрации/привязки; ключ сортировки (desc). |
referralLinkId | string (Guid) | Да | ReferralLinkId | — | По какой из ссылок владельца пришёл пользователь. |
linkUrl | string | Да | LinkUrl (денормализация на момент записи) | — | Исторический slug ссылки — показывается даже после её переименования/удаления. |
referredInvestorId | string (Guid) | Да | ReferredUserId | PII-минимизация: только id | Приглашённый пользователь. ФИО/телефон — только admin-выдача (referral.registrations.view-all). |
registrationType | string (enum ReferralRegistrationType: Initial | Rebind) | Да | RegistrationType | — | Тип записи журнала (дом enum — referral-registration.md). |
ReferrerUserId в выдачу не включается — он тождественно равен актору (сводный журнал именно его ссылок).
Алгоритм
Обезличенное фильтрованное чтение. Пользователь авторизован, требуется permission
referral.registrations.view-self (иначе FORBIDDEN); paging-параметры проверяются на диапазон
(иначе ValidationError). Возвращается страница записей журнала, отобранных по денормализованному
владельцу (ReferrerUserId == UserId) и упорядоченных по дате регистрации RegisteredAt desc, при
равных значениях — по Id (стабильный tie-break; правило порядка/консистентности —
README.md); в выборку попадают записи обоих типов — Initial и Rebind. Журнал
append-only: исторические страницы стабильны, новые записи появляются только в «голове» ленты.
Обезличивание — на уровне проекции: ФИО/телефон приглашённого не отдаются (ReferralUserReplica не
присоединяется). meta содержит полное число записей под фильтром, размер и смещение страницы.
Ошибки и failure modes
| Код | HTTP status | Условие | Сообщение | Retry |
|---|---|---|---|---|
ValidationError | 400 | Offset/Take вне диапазона | перечень полей | исправить параметры |
UNAUTHORIZED | 401 | Нет/просрочен access-токен | «Требуется авторизация» | retry после refresh-token |
FORBIDDEN | 403 | Нет permission referral.registrations.view-self | «Недостаточно прав» | no retry |
Доменных REFERRAL_*-ошибок нет: операция не резолвит сущности по id (нет 404) и не меняет состояние.
Постусловие
Состояние не изменяется (обезличенное чтение): журнал, ссылки и реплика не трогаются, PII не отдаётся, события не публикуются.
Acceptance Criteria
- Given авторизованный пользователь с записями журнала по его ссылкам, When
GET …/referral-links/registrations, Then200со страницейReferralRegistrationItem(registeredAtdesc), обезличенной (толькоreferredInvestorId, без ФИО/телефона), включающей записи обоих типовInitialиRebind. - Given у пользователя нет ни одной регистрации, When запрос, Then
200сmeta.total = 0,items = []. - Given в выборку теоретически попадают чужие записи, When запрос, Then они отфильтрованы по
ReferrerUserId == actor.UserId(нет user enumeration);ReferrerUserIdв выдачу не включается. - Given актор без
referral.registrations.view-self, When запрос, Then403 FORBIDDEN; без токена —401;Offset/Takeвне диапазона —400 ValidationError. - Given записи с равным
registeredAt, When постраничный обход, Then порядок стабилен по вторичному ключуId(append-only журнал — исторические страницы не смещаются, README.md).
Совместимость и наблюдаемость
- Контракт стабилен. Новые optional поля item-а — additive; удаление/переименование/смена типа
registeredAt/referralLinkId/linkUrl/referredInvestorId/registrationType— breaking (migration + rollout). Раскрытие ФИО/телефона в этой public-выдаче запрещено (обезличенность — инвариант безопасности, README.md, «Общие правила безопасности»). - Unknown
registrationTypeпри чтении — не возникает (значения пишетreferral); внешние потребители трактуют неизвестное строковое значение как проигнорированное (unknown-enum handling). - Logs:
UserId, размер страницы, длительность запроса (без PII); metrics:referral_all_registrations_get_total{result}, histogram длительности; traces — сквозной trace черезtraceparent. Dashboard —referral-overview; алерт на p95 > 300 мс (SLO public API, README.md).
Обратные ссылки
Автоссылки: где используется этот документ.
- API (4): GET /api/investors/me/referral-links — Список моих реферальных ссылок (getMyReferralLinks), GET /api/investors/me/referral-links/{id}/registrations — Обезличенный журнал одной ссылки (getLinkRegistrations), GET /api/v1/partner/stats — Партнёрская сводка по каналам, Referral API — реестр операций и общие контрактные модели
- registries (1): Реестр API-методов PIN
Связанные документы
- Дом сущности и enum: referral-registration.md
(
ReferrerUserId,LinkUrl,ReferralRegistrationType, индексы). - Журнал одной ссылки (дом item-модели): get-link-registrations.md; список ссылок: get-my-referral-links.md; статистика: get-link-stats.md, get-partner-stats.md.
- Реестр, конверт и paging: README.md; permissions: permission.md.