GET /api/investors/me/referral-links/lookup — Пагинированный lookup своих ссылок
Назначение
Облегчённый постраничный список собственных реферальных ссылок для наполнения выпадающих списков
выбора реф-ссылки (SharePopover подборок, форма выбора ссылки при шаринге объекта,
/profile/partner). В отличие от get-my-referral-links.md — без дорогих
производных (registrationsCount не считается): только идентификатор, slug, описание и признак
default, достаточные, чтобы отрисовать пункт списка и подставить slug в cookie.
Metadata
| Поле | Значение |
|---|---|
| Сервис/контекст | referral |
| API area | public |
| Feature group | referral-links |
| Статус | draft |
Актор и доступ
| Проверка | Значение |
|---|---|
| Actor type | User (авторизованный пользователь) |
| Auth policy / Permissions | referral.links.view-self |
| Scope | self (роль не требуется) |
| Record-level | фильтр OwnerUserId = UserId актора — чужие ссылки в выборку не попадают (нет user enumeration) |
| Tenant isolation | не применяется (record-level по владельцу, ADR-0052) |
| Audit | none (несенситивное чтение собственных данных) |
HTTP-контракт
| Поле | Значение |
|---|---|
| Method | GET |
| Route | /api/investors/me/referral-links/lookup?Offset&Take |
| Success status | 200 |
| Idempotency | не применяется (safe GET) |
| Correlation | OpenTelemetry trace (traceparent) |
Маршрутизация: статический сегмент lookup имеет приоритет над route-параметром {id} того же
уровня — конфликта с lookup/{id}
(lookup-referral-link-by-id.md) нет.
Входные данные / параметры запроса
| Поле | Источник | Тип | Обязательность | Валидация / Ограничения | Безопасность |
|---|---|---|---|---|---|
UserId | identity claims (sub) | Guid | Да | валидный JWT (подпись, exp, notBefore) | 401 при отсутствии/просрочке |
Offset | query | int | Да | min 0, max 2147483647 | — |
Take | query | int | Да | min 1, max 1000 | ограничение размера выдачи |
Ограничения Offset/Take — единый дом paging-параметров README.md.
Модель ответа ReferralLinkLookupEntryPagingResult
Контейнер-страница с коллекцией и метаданными пагинации (дом paging-моделей — README.md).
| Поле | Тип | Обязательность | Источник | Masking | Описание |
|---|---|---|---|---|---|
items | ReferralLinkLookupEntry[] | Да | projection | — | Пункты страницы (может быть пустым). |
meta | PagingResultMeta | Да | computed | — | total/take/offset — README.md. |
Модель ReferralLinkLookupEntry (дом item-модели)
Первая операция-владелец lookup-семейства; переиспользуется
lookup-referral-link-by-id.md (одиночная выдача) и
get-or-create-default-referral-link.md (одиночная entry).
Поля — проекция агрегата referral-link.md.
| Поле | Тип | Обязательность | Источник | Masking | Описание |
|---|---|---|---|---|---|
id | string (Guid) | Да | ReferralLinkEntity.Id | — | Идентификатор ссылки (значение выпадающего пункта). |
url | string | Да | ReferralLinkEntity.Url | — | Slug (lowercase); полный URL собирает фронт. |
description | string? | Нет | ReferralLinkEntity.Description | — | Описание канала — подпись пункта списка. |
isDefault | bool | Да | ReferralLinkEntity.IsDefault | — | Ссылка «по умолчанию» (для преселекта пункта). |
channel | ReferralChannel | Нет | ReferralLinkEntity.Channel | — | Канал (enum строкой); additive optional. |
Предусловия и постусловия
- Предусловия. Пользователь авторизован. В выборку попадают только действующие (не удалённые) собственные ссылки.
- Постусловия. Состояние не меняется (чтение);
VisitsCountне растёт; события не публикуются.
Алгоритм
- Контекст и доступ. Операцию выполняет авторизованный пользователь;
UserId— из claimsub(иначе401); требуется правоreferral.links.view-self. - Проверка входа.
Offset >= 0,1 <= Take <= 1000— иначеValidationError. - Что читаем. Страницу собственных ссылок владельца (
OwnerUserId = UserId, не удалённых); без подсчёта регистраций. Порядок: default-ссылка сверху (IsDefault desc), далее свежие (CreatedAt desc), при равенстве — поId(детерминированный tie-break: устойчивая пагинация без пропусков/дублей на границах страниц) — удобный преселект в выпадающем списке.meta.total— общее число ссылок владельца по тому же условию. - Маппинг. Пункт страницы — поле-в-поле по таблице
ReferralLinkLookupEntry;meta={total, take, offset}(эхо запроса + подсчёт). - Результат.
ReferralLinkLookupEntryPagingResult→ HTTP200;itemsупорядочены (default → свежие). ИнкрементVisitsCountздесь не выполняется (перехода по ссылке нет — счётчик растит только validate-referral-link.md). Консистентность — read-your-writes.
Диаграмма
Ошибки и failure modes
| Код | HTTP status | Условие | Сообщение | Retry |
|---|---|---|---|---|
| — (auth) | 401 | Нет/просрочен/невалиден JWT | без тела схемы | re-login |
ValidationError | 400 | Offset/Take вне диапазона | список ошибок полей | исправить параметры |
Доменных REFERRAL_* ошибок нет: фильтрованное чтение собственных записей — пустая страница, не ошибка.
Критерии приёмки
- Given владелец с несколькими ссылками, одна из которых default, When запрос страницы,
Then
200, default-ссылка первой (IsDefault desc), далее свежие (CreatedAt desc);meta.total= число не удалённых ссылок владельца. - Given у владельца нет ссылок, When запрос, Then
200с пустымitemsиmeta.total = 0(не404). - Given
Offset >= meta.total, When запрос, Then200с пустымitemsи корректнымmeta.total. - Given несколько ссылок с одинаковым
IsDefault/createdAt, When последовательный обход страниц, Then каждая ссылка встречается ровно один раз (tie-break поId). - Given
Offset < 0илиTakeвне1..1000, When запрос, ThenValidationError(400). - Given soft-deleted собственная ссылка, When запрос, Then она в выборку не входит.
- Given отсутствует/просрочен токен, When запрос, Then
401.
Совместимость и наблюдаемость
- Контракт стабилен; additive:
channel(ReferralChannel, enum строкой) уReferralLinkLookupEntry— без breaking change. Unknown enum при чтении — fallbackOther+ warning (referral-link.md). Удаление/переименование/смена типа полей — breaking (migration + rollout). - Logs:
UserId, размер страницы (take/offset) — без PII; metrics:referral_links_lookup_requests_total, latency p95; traces — OpenTelemetry. Dashboard —referral-overview; алерт на p95 > 300 мс (SLO public API, README.md); операция дешевле get-my-referral-links.md — регистрации не считаются.
Обратные ссылки
Автоссылки: где используется этот документ.
- API (3): GET /api/investors/me/referral-links — Список моих реферальных ссылок (getMyReferralLinks), GET /api/investors/me/referral-links/lookup/{id} — Резолв реф-ссылки по id, Referral API — реестр операций и общие контрактные модели
- registries (1): Реестр API-методов PIN
Связанные документы
- Сущность (дом полей): referral-link.md.
- Соседние операции: lookup-referral-link-by-id.md (одиночный
lookup, тот же item), get-my-referral-links.md (полный список с
registrationsCount), get-or-create-default-referral-link.md (потребительReferralLinkLookupEntry). - Реестр, конверт и paging-модели: README.md.