US-реестр контекста calendar (US-CAL)
Назначение
Реестр user stories контекста calendar — рабочий календарь агента/консультанта ПИН, слоты доступности,
самозапись инвестора, жизненный цикл записи (подтверждение, отмена, перенос, исход), напоминания и
командный обзор для руководителя агентства. Каждая story — самостоятельная формулировка «кто → что хочет →
зачем» со ссылками на покрывающие документы: домены (../domain/), API-методы, use cases
(UC-CAL-001 … UC-CAL-009)
и интеграционные события (../events/). Границы контекста и вне-scope — README
(../README.md) и ADR-0064.
Metadata
| Поле | Значение |
|---|---|
| ID-диапазон | US-CAL-01..20 |
| Контекст | calendar (лиды/сделки — crm; доставка напоминаний — notifications; видеосвязь — messenger) |
| Статус | draft |
| Правило покрытия | Каждая story обязана иметь ≥ 1 покрывающий домен-документ и ≥ 1 операционный документ (api / UC / событие); отсутствие покрытия = дыра traceability |
Карта покрытия (обзор)
Роль: Агент / консультант ПИН (US-CAL-01..12)
Владелец календаря ведёт события и слоты в tenant своей компании (агентство / ПИН, ADR-0052); управляющие операции — record-level по владельцу. Тот же набор доступен инвест-консультанту ПИН в платформенном scope.
| № | User Story | Покрытие: домен | Покрытие: API / UC / события |
|---|---|---|---|
| US-CAL-01 | Как Агент, я хочу видеть свой календарь за выбранный период (диапазон дат, все виды событий — показы, консультации, встречи, задачи, дедлайны броней), чтобы планировать день. | ../domain/calendar-event.md — Kind, StartAt/EndAt/TimeZone, индекс ix_calendar_events_owner_start | ../api/agent/list-events.md; UC-CAL-001 |
| US-CAL-02 | Как Агент, я хочу создавать событие вручную (показ/консультация/встреча/задача) с интервалом, местом и, для онлайн-консультации, ссылкой на встречу, чтобы фиксировать договорённости. | ../domain/calendar-event.md — Origin = Manual, матрица kind-обязательностей (INV-CAL-1/5), MeetingLink | ../api/agent/create-event.md; UC-CAL-001; событие pin.calendar.event-created.v1 (../events/event-created.md) |
| US-CAL-03 | Как Агент, я хочу редактировать своё событие (заголовок, описание, место, офсеты напоминаний), чтобы держать календарь актуальным. | ../domain/calendar-event.md — поля события, ReminderOffsetsMinutes | ../api/agent/update-event.md |
| US-CAL-04 | Как Агент, я хочу переносить событие на другое время с сохранением длительности, чтобы не пересоздавать его при изменении планов. | ../domain/calendar-event.md — reschedule (не переход статуса), пересоздание напоминаний; ../domain/event-reminder.md — правило 2 | ../api/agent/reschedule-event.md; pin.calendar.event-rescheduled.v1 (../events/event-rescheduled.md) |
| US-CAL-05 | Как Агент, я хочу отмечать событие начатым и завершённым (Planned → InProgress → Completed), чтобы отражать реальный ход дня. | ../domain/calendar-event.md — EventStatus, INV-CAL-2 (start → InProgress) | ../api/agent/start-event.md, ../api/agent/complete-event.md; pin.calendar.event-status-changed.v1 (../events/event-status-changed.md) |
| US-CAL-06 | Как Агент, я хочу отменять своё событие с указанием причины, чтобы участники понимали, что встреча не состоится. | ../domain/calendar-event.md — Cancelled + CancelReason (INV-CAL-7), каскад напоминаний → Skipped | ../api/agent/cancel-event.md; pin.calendar.event-status-changed.v1 |
| US-CAL-07 | Как Агент, я хочу видеть пометку о пересечении событий в моём календаре (soft-conflict), чтобы замечать двойные брони времени, но не быть заблокированным. | ../domain/calendar-event.md — HasConflicts (INV-CAL-6, soft-conflict, не ошибка) | ../api/agent/list-events.md; UC-CAL-001 A-конфликты |
| US-CAL-08 | Как Агент, я хочу публиковать слоты доступности пакетом (окна по дням недели × длительность × горизонт, с таймзоной), чтобы инвесторы записывались ко мне без переписки. | ../domain/availability-slot.md — batch-генерация (DST-корректно, INV-SLT-1/2), лимит ≤ 500 | ../api/agent/publish-slots.md; UC-CAL-002 |
| US-CAL-09 | Как Агент, я хочу получать отчёт публикации (сколько создано, что пропущено и почему — пересечение / lead-time / несуществующее локальное время), чтобы понимать результат. | ../domain/availability-slot.md — отчёт публикации (Overlap/LeadTime/NonExistentLocalTime) | ../api/agent/publish-slots.md; UC-CAL-002 |
| US-CAL-10 | Как Агент, я хочу видеть свои слоты и архивировать неактуальные свободные слоты, чтобы убирать лишнее время из витрины. | ../domain/availability-slot.md — SlotStatus, archive-slot (занятый слот → CAL_SLOT_BOOKED, INV-SLT-4) | ../api/agent/list-slots.md, ../api/agent/archive-slot.md |
| US-CAL-11 | Как Агент, я хочу подтверждать или отклонять входящие записи на слот (AutoConfirm = false) с причиной отклонения, чтобы решать, кого принять. | ../domain/appointment.md — Pending → Confirmed/Declined, PendingExpiresAt | ../api/agent/confirm-appointment.md, ../api/agent/decline-appointment.md; UC-CAL-004; pin.calendar.appointment-confirmed.v1 / -cancelled.v1 (../events/appointment-confirmed.md, ../events/appointment-cancelled.md) |
| US-CAL-12 | Как Агент, я хочу фиксировать исход встречи (Completed — состоялась / NoShow — клиент не пришёл), чтобы CRM видела результат в ленте лида. | ../domain/appointment.md — Confirmed → Completed/NoShow (INV-APT-4, только после StartAt) | ../api/agent/complete-appointment.md; UC-CAL-006; pin.calendar.appointment-completed.v1 (../events/appointment-completed.md) → crm/notifications |
Роль: Инвестор / аноним витрины (US-CAL-13..17)
Инвестор действует record-level по InvestorUserId вне tenant (ADR-0052); аноним видит публичную
витрину слотов и записывается через lazy-регистрацию по телефону (identity, как в
create-consultation-request).
| № | User Story | Покрытие: домен | Покрытие: API / UC / события |
|---|---|---|---|
| US-CAL-13 | Как Инвестор/аноним, я хочу видеть свободные слоты агента/консультанта (фильтры: агент, проект, объект, вид, диапазон дат), чтобы выбрать удобное время показа/консультации. | ../domain/availability-slot.md — витрина Available (payload без PII, INV-SLT-5 lead-time) | ../api/public/list-available-slots.md |
| US-CAL-14 | Как Инвестор/аноним, я хочу записаться на конкретный свободный слот (при необходимости — с комментарием «интересует 2-комнатная…»), чтобы забронировать встречу. | ../domain/appointment.md — создание записи (Pending/Confirmed по AutoConfirm), атомарная связка слот+запись+событие (INV-APT-1) | ../api/public/book-slot.md; UC-CAL-003; pin.calendar.appointment-created.v1 (../events/appointment-created.md) → crm (get-or-create клиента/лида) |
| US-CAL-15 | Как Инвестор, я хочу видеть свои записи и их статусы (ожидает подтверждения, подтверждена, отклонена, отменена), чтобы понимать, состоится ли встреча. | ../domain/appointment.md — AppointmentStatus, record-level по InvestorUserId | ../api/investor/list-my-appointments.md, ../api/investor/get-my-appointment.md |
| US-CAL-16 | Как Инвестор, я хочу отменить свою запись, пока не прошёл cutoff, чтобы освободить время, если планы изменились. | ../domain/appointment.md — cutoff инвестора (INV-APT-3, APPOINTMENT_CUTOFF_PASSED), каскад освобождения слота | ../api/investor/cancel-my-appointment.md; UC-CAL-005; pin.calendar.appointment-cancelled.v1 |
| US-CAL-17 | Как Инвестор, я хочу перенести свою запись на другой свободный слот того же агента одной операцией, чтобы не терять договорённость при смене времени. | ../domain/appointment.md — перенос как атомарная пара (отмена старой + новая запись, RescheduledFrom/To, INV-APT-5); при занятости нового слота — SLOT_ALREADY_BOOKED | ../api/investor/reschedule-my-appointment.md; UC-CAL-005 |
Роль: Руководитель агентства / менеджер ПИН (US-CAL-18..20)
Руководитель агентства — read-only обзор команды в своём tenant (calendar.team.view); менеджер ПИН — та же
семантика в платформенном scope над календарями инвест-консультантов.
| № | User Story | Покрытие: домен | Покрытие: API / UC / события |
|---|---|---|---|
| US-CAL-18 | Как Руководитель агентства, я хочу видеть события всех агентов моей компании за период (кто чем занят, где пересечения расписаний), чтобы распределять нагрузку. | ../domain/calendar-event.md — tenant isolation, HasConflicts в командной выборке (внутри календаря каждого владельца) | ../api/agency/list-team-events.md; UC-CAL-009 |
| US-CAL-19 | Как Руководитель агентства, я хочу видеть записи агентов команды со статусами (зависшие Pending, подтверждённые встречи без исхода после начала), чтобы замечать необработанные обращения. | ../domain/appointment.md — статусы записей, read-only команда (calendar.team.view) | ../api/agency/list-team-appointments.md; UC-CAL-009 |
| US-CAL-20 | Как Менеджер ПИН, я хочу смотреть календари и записи инвест-консультантов ПИН в платформенном scope, чтобы контролировать поток консультаций. | ../domain/calendar-event.md, ../domain/appointment.md — платформенный scope | ../api/pin-manager/list-events.md, ../api/pin-manager/list-appointments.md; UC-OVR-002 |
Кросс-story: напоминания (сквозная механика US-CAL-02..05, US-CAL-11/14)
Напоминания не имеют собственной пользовательской операции — они материализуются из офсетов события и
доставляются notifications. Механика единая для всех событий календаря (ручных, порождённых записью,
дедлайнов броней).
| Аспект | Покрытие: домен | Покрытие: событие / UC |
|---|---|---|
«Напомнить за N минут до встречи» (default {1440, 60}) | ../domain/event-reminder.md — материализация (правило 1), пересоздание при переносе | UC-CAL-008; pin.calendar.reminder-due.v1 (../events/reminder-due.md) → notifications |
| Дедлайны броней в календаре агента сделки | ../domain/calendar-event.md — Kind = BookingDeadline, Origin = CrmBooking (INV-CAL-4) | UC-CAL-007; консюмер ../consumers/crm-booking-events.md |
Интеграционные ожидания US-блока calendar
Строгая согласованность гарантируется внутри одной операции calendar (агрегат записи/события + слот +
напоминания + запись outbox — атомарно); между контекстами — eventual (окно обычно < 1 мин,
ADR-0064).
| US-кластер | Синхронно (в ответе операции) | Асинхронно (событие → консюмер) | Что видит пользователь до доставки |
|---|---|---|---|
| US-CAL-14 (самозапись) | Слот Booked, запись Pending/Confirmed, событие Planned в календаре агента | pin.calendar.appointment-created.v1 → crm (get-or-create клиента/лида + лента), notifications (агенту/инвестору) | Запись видна в календаре сразу; лид в CRM — после обработки события |
| US-CAL-11/12/16/17 (решения по записи) | Новый статус записи + каскад слота/события | pin.calendar.appointment-confirmed/-cancelled/-completed.v1 → crm (лента лида), notifications | Статус актуален сразу; лента лида и уведомления — с задержкой |
| US-CAL-12 (исход + дедлайны броней) — see US-CAL кросс | Completed/NoShow записи | downstream crm/notifications идемпотентны по AppointmentId (at-least-once) | Исход зафиксирован; последствия в CRM — асинхронно |
Ключи партиционирования (AppointmentId/EventId/ReminderId), версии и гарантии доставки — в контрактах
событий (../events/); downstream-консюмеры идемпотентны, доставка at-least-once.
Обратные ссылки
Автоссылки: где используется этот документ.
- registries (1): Реестр use cases и user stories PIN
Связанные документы
- Домены: ../domain/calendar-event.md, ../domain/availability-slot.md, ../domain/appointment.md, ../domain/event-reminder.md.
- Use cases: UC-CAL-001 … UC-CAL-009.
- Сквозные сценарии: UC-OVR-001, UC-OVR-002, UC-OVR-003.
- README контекста: ../README.md; ADR-0064 (границы, слоты, запись, напоминания, вне-scope).