GET /api/v1/projects/{id} — Карточка проекта: ограниченная / полная
Назначение
Витринная карточка проекта для страниц /hotels/[id]/info и перехода из ленты. Ограниченная
версия (гость, без гейта): основная информация без точных цен, статусов объектов и шахматки.
Полная версия (User/RefGuest): точный диапазон цен, количество доступных объектов, метрики,
переходы к ассортименту (get-project-property-objects.md) и
шахматке. Каталог отдаёт витринную часть одной карточкой
catalog-project-card. Просмотр карточки фиксирует фронт
событием в user-activity (для гостя — с anonymous_id).
Контент вкладок (Информация/Локация/Финансирование/Юридическая информация/Ход строительства/Видео/Карта
— декларации, банки, медиа) и сама шахматка живут в контексте chessboard (дом —
chessboard/domain/project.md) — не этот метод: фронт запрашивает
их отдельно по id.
Metadata
| Поле | Значение |
|---|---|
| Сервис/контекст | catalog |
| API area | public |
| Feature group | cards |
| Статус | draft |
Актор и доступ
| Проверка | Значение |
|---|---|
| Actor type | Guest (ограниченная, без гейта) / RefGuest, User (полная) |
| Auth policy / Permissions | none (маскирование вместо отказа) |
| Scope | платформа |
| Tenant isolation | не применяется (платформенная витрина) |
| Audit | none в каталоге; просмотр (в т.ч. факт просмотра полной карточки) пишет фронт → user-activity |
HTTP-контракт
| Поле | Значение |
|---|---|
| Method | GET |
| Route | /api/v1/projects/{id} |
| Success status | 200 |
| Idempotency | не применяется (safe GET) |
| Correlation | OpenTelemetry trace (traceparent) |
Входные данные / параметры запроса
| Поле | Источник | Тип | Обязательность | Валидация / Ограничения | Безопасность |
|---|---|---|---|---|---|
Id | route | Guid | Да | валидный Guid | — |
ActorClass | identity middleware | Guest/RefGuest/User | Да | невалидный токен → 401; Guest допустим (ограниченный режим) | README.md |
Модель ответа ProjectCardModel
Состав = ProjectListItemModel (get-projects.md — дом модели, здесь только
дельта) + поля карточки ниже. Маскирование в ограниченном режиме (Guest): MASK-PRICE
(priceRange округлён), MASK-STATUS (propertyObjectsAvailable = null) — как в ленте.
Поле (дельта к ProjectListItemModel) | Тип | Обязательность | Источник | Masking | Описание |
|---|---|---|---|---|---|
assortmentAvailable | bool | Да | computed | — | true в полном режиме — фронт показывает список объектов/ассортимент (get-project-property-objects.md) и шахматку (chessboard); в ограниченном — false (шахматка гостю скрыта). |
isLimited | bool | Да | computed | — | true — ограниченный режим; фронт показывает предложение войти. |
publishedAt | string (ISO 8601)? | Нет | PublishedAt | — | Дата появления в каталоге («новинка» на фронте). |
Ссылки для переходов (девелопер, декларации) строит фронт из developerId и id проекта; контент —
chessboard, каталог URL-ы не генерирует.
Алгоритм
- Контекст и доступ. Актор определяется по токену (
User; невалидный → 401), затем по реф-cookiereferralUrl(RefGuest), иначеGuest— без отказа (ограниченный режим). - Проверка входа.
Id != Guid.Empty— иначеValidationError(400). Карточка проекта должна существовать и быть опубликованной (Status = Published); если карточки нет либо она в статусеHidden/Delisted→CATALOG_PROJECT_NOT_FOUND(404) — скрытое неотличимо от несуществующего. - Что читаем. Единственная карточка проекта по
id(owned VOGeoLocation,Payback— часть той же строки). Объекты недвижимости проекта, декларации, шахматка не читаются (ассортимент — отдельный метод; контент —chessboard). - Режим и маскирование.
isLimited = (ActorClass == Guest);assortmentAvailable = !isLimited. Маппинг базовых полей — таблицаProjectListItemModel(get-projects.md); в ограниченном режиме — MASK-PRICE/MASK-STATUS. - Результат.
ProjectCardModel→ 200 (оба режима). Консистентность — eventual (агрегаты цен/количеств пересчитываются по факту изменения объекта недвижимости, INV-2 project-card).
Диаграмма
Ошибки и failure modes
| Код | HTTP status | Условие | Сообщение | Retry |
|---|---|---|---|---|
| — (auth) | 401 | Невалидный/просроченный токен | без тела схемы | re-login |
ValidationError | 400 | Id = Guid.Empty | Список ошибок полей | no retry |
CATALOG_PROJECT_NOT_FOUND | 404 | Карточки нет либо Status ∈ {Hidden, Delisted} | «Проект не найден» | no retry |
Acceptance Criteria
- Полная карточка. Дано
User/RefGuestи опубликованный проект. Когда запрашивает карточку. Тогда200с точнымpriceRange, заполненнымpropertyObjectsAvailable,assortmentAvailable = true,isLimited = false. - Ограниченная карточка (гость). Дано
Guest. Когда запрашивает ту же карточку. Тогда200, ноpriceRangeокруглён (MASK-PRICE),propertyObjectsAvailable = null(MASK-STATUS),assortmentAvailable = false(шахматка скрыта),isLimited = true. - Скрытый/несуществующий проект. Дано проект в
Hidden/Delistedлибо отсутствует. Когда запрашивают. ТогдаCATALOG_PROJECT_NOT_FOUND(404) — скрытое неотличимо от несуществующего. - Невалидный токен vs гость. Дано просроченный JWT. Когда приходит запрос. Тогда
401; при полном отсутствии токена (гость) — ограниченный режим200, не401. - Свежесть агрегатов. Дано только что изменённый объект недвижимости проекта. Когда карточка читается. Тогда агрегаты цен/количеств могут отставать (eventual, INV-2 project-card) — расхождение сходится по мере пересчёта консюмерами.
Совместимость и наблюдаемость
- Модель — надмножество
ProjectListItemModel(совместная эволюция, дом — get-projects.md); новые optional-поля — additive; раскрытие маскированного гостю — breaking. - Logs: id, класс актора, режим; metrics —
catalog_project_card_requests_total{actor_class,result}, latency histogram (SLO p99 < 200 мс — ../README.md); traces/dashboard — общие правила area (README.md).
Обратные ссылки
Автоссылки: где используется этот документ.
- API (4): Catalog Public API — реестр методов и общие правила, GET /api/v1/lots/{id} — Карточка объекта недвижимости: ограниченная / полная, GET /api/v1/projects — Лента проектов, GET /api/v1/projects/{id}/lots — Ассортимент проекта/отеля
- registries (1): Реестр API-методов PIN
Связанные документы
- Дом модели ленты: get-projects.md; дом полей: ../domain/catalog-project-card.md.
- Ассортимент/список объектов: get-project-property-objects.md; шахматка и вкладки:
../../chessboard/(дом:chessboard/domain/project.md). - Трекинг просмотров:
../../user-activity/.