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

GET /api/investors/me/referral-links/{id}/registrations — Обезличенный журнал одной ссылки (getLinkRegistrations)

Назначение

Постраничный обезличенный журнал регистраций по одной конкретной ссылке владельца: кто и когда пришёл по ней (Initial/Rebind), без ФИО/телефона. Владелец открывает журнал из карточки своей ссылки на /profile/partner (детализация одного канала). PII приглашённого раскрывается только в admin-выдаче (../admin/get-link-registrations.md, permission referral.registrations.view-all). Общий конверт и paging-модели — README.md.

Metadata

ПолеЗначение
Сервис/контекстreferral
API areapublic
Feature groupreferral-registrations
Статусapproved
Документdocs/06-services/referral/api/public/get-link-registrations.md

Актор и доступ

ПроверкаЗначение
Actor typeUser
Auth policy / Permissionsauthenticated; permission referral.registrations.view-self
Scope (RBAC)self
Record-levelownership guard: ссылка {id} должна принадлежать актору (OwnerUserId == UserId, INV-REF-L4); чужая/несуществующая неотличима → REFERRAL_LINK_NOT_FOUND (нет user enumeration)

HTTP-контракт

ПолеЗначение
MethodGET
Route/api/investors/me/referral-links/{id}/registrations
Success status200
Correlationсквозной trace через заголовок traceparent

Входные данные / параметры запроса

ПолеИсточникТипОбязательностьВалидация / ОграниченияБезопасность
UserIdidentity claims (sub)GuidДавалидный токен401 при отсутствии
idrouteGuidДанепустой; существующая ссылка владельцаrecord-level guard OwnerUserId == UserId
OffsetqueryintДаmin 0, max 2147483647
TakequeryintДаmin 1, max 1000ограничение размера выдачи

Модель ответа ReferralRegistrationItemPagingResult

Контейнер offset-paging (дом paging-моделей — README.md).

ПолеТипОбязательностьИсточникMaskingОписание
metaPagingResultMetaДаprojectiontotal/take/offsetREADME.md.
itemsReferralRegistrationItem[]ДаprojectionобезличеноСтраница записей журнала (дом item-модели ниже).

Модель ReferralRegistrationItem (дом item-модели)

Первая операция-владелец дома item-модели; переиспользуется get-all-registrations.md (журнал по всем ссылкам). Проекция полей — из referral-registration.md, только скалярные id (без PII).

ПолеТипОбязательностьИсточникMaskingОписание
registeredAtstring (ISO 8601)ДаReferralRegistrationEntity.RegisteredAtМомент регистрации/привязки (ключ сортировки).
referralLinkIdstring (Guid)ДаReferralRegistrationEntity.ReferralLinkIdСсылка, по которой пришёл пользователь (= {id} запроса).
linkUrlstringДаReferralRegistrationEntity.LinkUrl (денормализация)Историч. slug на момент записи: показывается даже после переименования/удаления ссылки.
referredInvestorIdstring (Guid)ДаReferralRegistrationEntity.ReferredUserIdПриглашённый пользователь — обезличенный идентификатор. ФИО/телефон реплики не присоединяются.
registrationTypestring (enum ReferralRegistrationType)ДаReferralRegistrationEntity.RegistrationTypeInitial / Rebind (referral-registration.md).

Исходы правил привязки (AppliedRule, LeadRequested) в public-выдачу не добавляются (владельцу не нужна механика привязки); PII (ФИО/телефон/email) — только admin.

Алгоритм

  1. Контекст и доступ. Пользователь авторизован; требуется permission referral.registrations.view-self (иначе FORBIDDEN).
  2. Проверка входа. id непустой, Offset >= 0, 1 <= Take <= 1000 — иначе ValidationError.
  3. Проверка владения. Ссылка {id} должна принадлежать актору (OwnerUserId == UserId, INV-REF-L4). Если ссылки нет или она принадлежит другому владельцу → REFERRAL_LINK_NOT_FOUND (чужая, несуществующая и удалённая ссылка неотличимы — нет раскрытия чужого id). Журнал читается и по soft-deleted ссылке (запись журнала переживает удаление ссылки, INV-REF-R2).
  4. Выдача. Возвращается страница записей журнала по ссылке (ReferralLinkId == id), упорядоченных по дате регистрации RegisteredAt desc, при равных значениях — по Id (стабильный tie-break; правило порядка/консистентности — README.md); журнал append-only — исторические страницы стабильны. ФИО/телефон не отдаются (обезличенная проекция, ReferralUserReplica не присоединяется). meta содержит полное число записей под фильтром, размер и смещение страницы.

Ошибки и failure modes

КодHTTP statusУсловиеСообщениеRetry
— (auth)401Нет/невалиден токен«Требуется авторизация»re-login
ValidationError400id пустой или Offset/Take вне диапазонаперечень полейисправить
REFERRAL_LINK_NOT_FOUND404Ссылка не найдена или принадлежит другому владельцу (INV-REF-L4, без раскрытия чужой ссылки)«Ссылка не найдена»no retry

Постусловие

Состояние не изменяется (обезличенное чтение): журнал, ссылка и реплика не трогаются, PII не отдаётся, события не публикуются.

Acceptance Criteria

  • Given авторизованный владелец и его ссылка с регистрациями, When GET …/referral-links/{id}/registrations, Then 200 со страницей ReferralRegistrationItem (registeredAt desc), обезличенной (только referredInvestorId); linkUrl — исторический slug на момент записи.
  • Given ссылка soft-deleted, но с историческими записями, When запрос, Then 200 — журнал переживает удаление ссылки (INV-REF-R2).
  • Given ссылка чужая, несуществующая или удалённая, When запрос, Then 404 REFERRAL_LINK_NOT_FOUND (все три случая неразличимы — нет раскрытия чужого id, INV-REF-L4).
  • Given ссылка принадлежит актору, но регистраций нет, When запрос, Then 200 с meta.total = 0, items = [].
  • Given актор без referral.registrations.view-self, When запрос, Then 403 FORBIDDEN; без токена — 401; id пустой / Offset/Take вне диапазона — 400 ValidationError.
  • Given записи с равным registeredAt, When постраничный обход, Then порядок стабилен по вторичному ключу Id (append-only журнал — исторические страницы не смещаются, README.md).

Совместимость и наблюдаемость

  • Контракт стабилен; ReferralRegistrationItem — обезличенная проекция. Новые optional поля — additive; удаление/переименование/смена типа полей item-а — breaking (migration + rollout). Unknown значение registrationType при чтении — по additive-политике enum (../README.md).
  • Logs: UserId, id ссылки, размер страницы (PII в лог не пишется); metrics: referral_link_registrations_requests_total; traces — сквозной trace через traceparent; dashboard referral-overview (../README.md).

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

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

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