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

UC-CTL-009. Просмотр шахматки и планировки этажа (переход в chessboard)

Назначение

Авторизованный пользователь просматривает объекты проекта по этажам и секциям (шахматка) с цветовым кодированием статусов и переходит в карточку объекта. Каталог — точка входа (полная карточка проекта, UC-CTL-006) и приёмник переходов (карточка объекта недвижимости, UC-CTL-008); source of truth и API самой матрицы — контекст chessboard (структура недвижимости и шахматка принадлежат chessboard, страница /hotels/[id]/chessboard).

Metadata

ПолеЗначение
IDUC-CTL-009
Контекстcatalog (вход/выход сценария) + chessboard (владелец матрицы — docs/06-services/chessboard/)
Типосновной
Статусdraft

Актор

ПолеЗначение
РольИнвестор / Агент / Девелопер / МенеджерПИН (авторизованные — шахматка входит в полную карточку проекта; для гостя шахматка скрывается)
Permissions / scopeвалидный JWT; permissions на чтение матрицы не требуются (правила выдачи — публичный API chessboard)
Tenantне применяется — просмотр платформенной витрины
Record-levelне применяется

Предусловие

  • Пользователь авторизован; открыта полная карточка проекта (UC-CTL-006).
  • Проект опубликован (CatalogProjectCard.Status = Published); в chessboard существует структура корпуса/этажей/объектов проекта.

Триггер

ПолеЗначение
ИсточникUI navigation
Триггерящий элементРаздел «Шахматка» внутри карточки проекта — /hotels/[id]/chessboard

Основной Поток

  1. Пользователь переходит к разделу «Шахматка» внутри карточки проекта; каталог передаёт projectId (= chessboard.Project.Id, единый Guid — поле Id карточки проекта) и список корпусов.

  2. Интерфейс запрашивает матрицу у public API chessboard (метод — ../../chessboard/api/public/get-project-chessboard.md; параметры: projectId, buildingId?, диапазон этажей для пагинации). На стороне chessboard: загрузка объектов проекта, группировка по этажам и секциям, присвоение ячейкам статуса; для большого числа объектов — пагинация по этажам, ответ порциями.

  3. Интерфейс рендерит интерактивную матрицу «этажи × секции» с цветовой индикацией. Маппинг цветов ↔ статусов (глоссарий «Статус объекта», отображение — enum PropertyObjectAvailabilityStatus в карточке объекта недвижимости):

    ЦветСтатусПоведение ячейки
    ЗелёныйFree (доступен)клик → карточка объекта; hover → подсказка
    ЖёлтыйReserved / Booked (резерв/бронь)клик → карточка (бронь недоступна)
    КрасныйSold (продан)клик → карточка (только просмотр)
    СерыйHidden (скрыт)ячейка неактивна, данные не раскрываются
  4. Наведение на ячейку показывает всплывающую подсказку с номером и ценой объекта — данные приходят в ответе матрицы chessboard; эффективная витринная цена объекта недвижимости при расхождении с источником — зона ответственности карточки объекта недвижимости (оверрайды применяются в каталоге, шахматка показывает цену источника).

  5. Пользователь переключает этаж или секцию — интерфейс догружает порцию матрицы (виртуализация/пагинация по этажам).

  6. Пользователь кликает по ячейке — интерфейс переходит на карточку объекта /lots/[propertyObjectId]/info: выполняется UC-CTL-008 (авторизован) — каталог отдаёт карточку по тому же propertyObjectId (= chessboard.PropertyObject.Id, единый Guid).

  7. Просмотр планировки этажа: из ячейки/карточки доступна визуализация планировки (VisualizationFileId карточки объекта недвижимости; пресайн-ссылка — граница storage/CDN).

  8. Интерфейс записывает действия в user-activity: ActionEvent { kind = ChessboardOpened, projectId } при открытии; открытие карточки объекта недвижимости из ячейки создаёт PropertyObjectView (UC-CTL-008) — статистика внимания к этажам/планировкам собирается в dev-stats (ADR-0057: иерархия Developer→Project→Building→LayoutGroup→Layout→PropertyObject).

Альтернативные Потоки

A1. Гость пытается открыть шахматку

  1. Шахматка — часть полной карточки; без JWT интерфейс показывает CTA «Войдите, чтобы увидеть шахматку» (шахматка скрыта для неавторизованных — UC-CTL-005).
  2. После входа (UC-IDN-001) — возврат к шагу 1.

A2. Клик по скрытой ячейке (Hidden)

  1. Серые ячейки неактивны; прямой запрос карточки скрытого объекта недвижимости вернёт CATALOG_PROPERTY_OBJECT_NOT_FOUND (404) — согласовано с INV-1 карточки объекта недвижимости. Возврат к шагу 3.

A3. Большой проект (тысячи объектов)

  1. Интерфейс рендерит только видимые этажи (виртуализация), догружая порции по скроллу/переключению. Поток не меняется.

A4. Расхождение статуса ячейки и карточки объекта недвижимости

  1. Шахматка (chessboard, source of truth) и витрина (catalog, реплика с лагом < 1 мин) могут на секунды расходиться после брони; при переходе в карточку пользователь видит статус реплики, критичная проверка — в crm (UC-CTL-008 A5). Ошибок не возникает.

A5. chessboard недоступен (деградация матрицы)

  1. Запрос матрицы (шаг 2) падает по таймауту/ошибке. Каталог-часть карточки проекта (UC-CTL-006) уже отображена; раздел «Шахматка» показывает skeleton и предлагает повтор. Каталог собственных ошибок не генерирует — это отказ соседнего контекста. Сценарий завершается частично успешно.
  2. Частичный отказ пагинации: если падает загрузка одной порции этажей (шаг 5), уже отрисованные этажи остаются; повтор загружает только недостающую порцию.

A6. Проект снят с публикации/делистнут во время просмотра

  1. Пока открыта шахматка, проект в каталоге переходит в Hidden/Delisted (скрыт оверрайдом или удалён в источнике). Повторный вход/refresh раздела → CATALOG_PROJECT_NOT_FOUND (404), интерфейс — страница «Проект недоступен». Уже открытая матрица не мутирует состояние каталога.

A7. Повторное открытие шахматки (идемпотентность аудита)

  1. Повторная доставка ActionEvent { kind = ChessboardOpened } не задваивает запись в user-activity (дедуп по ключу события); статистика dev-stats не искажается.

Инварианты, статусы и валидации

  • Гейт. Шахматка — часть полной карточки: требуется валидный JWT; гость → CTA «Войдите» (A1), согласовано с UC-CTL-005. Permissions на чтение матрицы не требуются (правила выдачи — публичный API chessboard).
  • Публикация проекта. Матрица доступна только для CatalogProjectCard.Status = Published; иначе — CATALOG_PROJECT_NOT_FOUND (404).
  • Владение матрицей. Source of truth структуры и статусов ячеек — chessboard; каталог матрицу не хранит и не проксирует (в схеме catalog нет таблиц матрицы, AC1). Единые Guid: projectId = chessboard.Project.Id, propertyObjectId = chessboard.PropertyObject.Id — тот же идентификатор ведёт из ячейки в карточку объекта (UC-CTL-008).
  • Цвет ↔ статус. Отображение по таблице шага 3 (enum PropertyObjectAvailabilityStatus): Free→зелёный (клик → карточка), Reserved/Booked→жёлтый (клик → карточка, бронь недоступна), Sold→красный (только просмотр), Hidden→серый (ячейка неактивна, данные не раскрываются).
  • Скрытые ячейки. По прямому id скрытого объекта каталог отдаёт CATALOG_PROPERTY_OBJECT_NOT_FOUND (404) — согласовано с INV-1 карточки (A2); данные Hidden-ячейки не раскрываются ни в матрице, ни по id.
  • Цена в подсказке. Всплывающая подсказка показывает цену источника (chessboard); эффективная витринная цена (после оверрайдов каталога) — зона ответственности карточки объекта (шаг 4); расхождение ожидаемо и не является ошибкой.
  • Пагинация. Параметры матрицы — projectId, buildingId?, диапазон этажей; для больших проектов — порции по этажам и виртуализация (A3).

Кросс-сервисные контракты и согласованность

  • Роль каталога. Вход сценария — полная карточка проекта (UC-CTL-006): каталог передаёт projectId и список корпусов. Выход — карточка объекта (UC-CTL-008) по propertyObjectId. Саму матрицу клиент запрашивает у public API chessboard напрямую (синхронно); каталог её не проксирует.
  • Расхождение источника и реплики. Статус ячейки авторитетен в chessboard; карточка объекта в каталоге — реплика с лагом < 1 мин (pin.chessboard.property-objects.v1). После брони ячейка и карточка на секунды могут расходиться (A4); критичная проверка — в crm на источнике. Ошибок не возникает.
  • Аудит (async). Открытие раздела → ActionEvent { kind = ChessboardOpened, projectId } в user-activitypin.user-activity.actions.v1crm (карточка лида). Просмотры объектов, открытых из ячеек, дают цепочку PropertyObjectViewpin.user-activity.property-object-view-ended.v1PopularityViews каталога и dev-stats; внимание к этажам/планировкам агрегируется в dev-stats (ADR-0057: иерархия Developer→Project→Building→LayoutGroup→Layout→PropertyObject).
  • Read-only. Сценарий не меняет состояние ни catalog, ни chessboard.

Постусловие

  • Пользователь просмотрел распределение объектов по этажам/секциям и, при клике, перешёл в карточку объекта (UC-CTL-008).
  • В user-activityActionEvent (ChessboardOpened) и PropertyObjectView открытых из матрицы объектов недвижимости; внимание к этажам/планировкам доступно застройщику в dev-stats.
  • Состояние catalog и chessboard не изменилось (read-only).

Возможные Ошибки

КодHTTPУсловиеПоведение клиента
Unauthorized401Нет JWT (шахматка — полная карточка)CTA входа (A1)
CATALOG_PROJECT_NOT_FOUND404Проект каталога отсутствует/не PublishedСтраница «Проект недоступен»
Ошибки матрицы (chessboard)по контракту chessboardskeleton + повтор запроса
CATALOG_PROPERTY_OBJECT_NOT_FOUND404Переход в скрытый/делистнутый объект недвижимости (A2)Сообщение «Объект недоступен»

Kafka Интеграционные События

СобытиеTopicКогда публикуетсяConsumers
ActionEventRecorded (производит user-activity)pin.user-activity.actions.v1приём ChessboardOpened (шаг 8)crm (карточка лида)
PropertyObjectViewEnded (производит user-activity)pin.user-activity.property-object-view-ended.v1закрытие просмотров объектов недвижимости, открытых из матрицыcatalog (популярность), dev-stats

Наблюдаемость и НФТ

  • Логи (без PII): chessboard-opened { projectId }, cell-click-to-card { projectId, propertyObjectId }, matrix-degraded { projectId, reason } при отказе chessboard.
  • Метрики: catalog_chessboard_open_total, catalog_cell_click_to_card_total, счётчик деградации матрицы (отказ соседнего контекста), доля гостевых CTA (без JWT).
  • НФТ: матрицу обслуживает chessboard (её бюджет латентности); большие проекты (тысячи объектов) — виртуализация и пагинация по этажам, полной перезагрузки нет; нагрузка — до 10k одновременных (ADR-0056).
  • Безопасность: JWT-гейт (шахматка — часть полной карточки); гость шахматку не видит (A1/UC-CTL-005); данные Hidden-ячеек не раскрываются ни в матрице, ни по прямому id.

Acceptance Criteria

#Given (контекст)When (действие)Then (результат)Проверка
AC1Опубликованный проект со структурой в chessboardОткрыт раздел «Шахматка»Матрица группирует объекты по этажам и секциям; данные — из chessboard (каталог матрицу не хранит и не проксирует)контракт-тест: в схеме catalog нет таблиц матрицы; интерфейс ходит в chessboard напрямую
AC2Объекты во всех статусах доступностиОтрисована матрицаЦвет ↔ статус по таблице шага 3 (зелёный/жёлтый/красный/серый)тест ячеек во всех статусах
AC3Активная (не Hidden) ячейкаHover, затем кликHover показывает номер и цену; клик открывает карточку объекта с тем же propertyObjectIde2e-тест перехода
AC4Скрытый объект (Hidden)Просмотр ячейки / прямой запрос по idСерая неактивная ячейка; данные не раскрываются ни в матрице, ни по id (404)A2-тест
AC5Большой проект (тысячи объектов)Переключение этажа/секцииДогрузка порции без полной перезагрузки матрицы (виртуализация)e2e больших проектов
AC6Авторизованный пользовательОткрыта шахматка и просмотрены объекты из ячеекВ user-activityActionEvent (ChessboardOpened) и PropertyObjectView (вход статистики dev-stats)проверка записей
AC7Пользователь без JWTПопытка открыть шахматкуШахматка не видна, показан CTA входа — согласовано с UC-CTL-005запрос без JWT
AC8chessboard недоступенОткрыт раздел «Шахматка»Раздел показывает skeleton + повтор; каталог собственных ошибок не генерирует (A5)отказ chessboard
AC9Проект снят с публикации/делистнутПовторный вход/refresh разделаCATALOG_PROJECT_NOT_FOUND (404), «Проект недоступен» (A6)смена статуса проекта
AC10Объект забронирован конкурентноПереход из ячейки в карточкуЯчейка (chessboard) и карточка (реплика каталога) расходятся в пределах лага < 1 мин; ошибок нет (A4)гонка статуса
AC11Повторная доставка ChessboardOpenedСобытие пришло дваждыЗапись в user-activity не задваивается (идемпотентность, A7)повторное событие

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

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

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

  • Дом матрицы: ../../chessboard/domain/property-object.md (статусы/переходы), api/public/get-project-chessboard.md (контракт матрицы).
  • Domain entity (вход/выход): карточка проекта, карточка объекта недвижимости (единые Guid проектов/объектов недвижимости, PropertyObjectAvailabilityStatus, INV-1).
  • Просмотры/статистика: ../../user-activity/ (ADR-0054), ../../dev-stats/ (ADR-0057 — иерархия фильтров до планировки/группы).
  • Связанные UC: UC-CTL-006 (вход — полная карточка проекта), UC-CTL-008 (выход — карточка объекта недвижимости), UC-CTL-005 (гостевое ограничение).