Docs: sync booking expired (Back#60) + Front#31 UX polish. Fixes EventHub/EventHubSpec#13
This commit is contained in:
+28
-14
@@ -95,13 +95,19 @@ pending владельца, **не** меняет `calendar.type`. Legacy `downg
|
||||
- `POST /v1/events/:id/bookings` только если календарь события commercial, `booking_open=true`,
|
||||
событие `active`, есть свободная вместимость.
|
||||
- **Pending занимает capacity** наравне с confirmed (защита от overbook при auto/timeout).
|
||||
- Capacity: число booking со статусом `pending` | `confirmed`; `cancelled` не считаются.
|
||||
- Capacity: число booking со статусом `pending` | `confirmed`; `cancelled` и `expired` не считаются.
|
||||
- Политика `confirmation` календаря при создании booking:
|
||||
- `auto` → сразу `confirmed` + `confirmed_at`;
|
||||
- `manual` → `pending`; confirm/decline — владелец или specialist (см. ниже);
|
||||
- `{timeout, N}` → `pending`; через N секунд без решения: auto-confirm, если ещё есть
|
||||
capacity, иначе `cancelled` (`timeout_full`).
|
||||
- Участник: `DELETE /v1/bookings/:id` — отмена своей pending/confirmed.
|
||||
- **Past-pending → `expired`:** если событие уже началось (`now >= event.start_time`), а booking
|
||||
ещё `pending`, статус переводится в `expired` (lazy при чтении списков/`GET` booking и в
|
||||
`process_timeout_bookings`). `expired` не actionable: Confirm/Decline → `409` (`Booking expired`).
|
||||
- **Inbox:** `GET /v1/user/booking-requests` возвращает только ещё actionable pending
|
||||
(до старта события); past-pending помечает `expired` и **не** включает в ответ.
|
||||
- Участник: `DELETE /v1/bookings/:id` — отмена своей pending/confirmed; для уже `expired` —
|
||||
no-op успех (как для `cancelled`).
|
||||
- WS: `booking_update` участнику и владельцу (и specialist при confirm на «своём» событии).
|
||||
|
||||
#### Специалисты
|
||||
@@ -171,8 +177,9 @@ Legacy: прямой `POST /v1/calendars/:id/specialists` **не использ
|
||||
(иначе `400`).
|
||||
- **Confirm/decline booking:** владелец — любые booking календаря; `active` specialist — только
|
||||
booking на событиях, где `event.specialist_id` = его `user_id`.
|
||||
- **Inbox к подтверждению:** `GET /v1/user/booking-requests` агрегирует pending по тем же
|
||||
правилам (owner — все события своих календарей; specialist — только свои слоты).
|
||||
- **Inbox к подтверждению:** `GET /v1/user/booking-requests` агрегирует **actionable** pending
|
||||
по тем же правилам (owner — все события своих календарей; specialist — только свои слоты);
|
||||
past-pending → `expired` и из ответа исключается.
|
||||
|
||||
#### Фаза 2 (вне текущего контракта реализации)
|
||||
- `calendar_share` (`read` | `write` | `admin`): не путать с follow, specialist_invite и платной subscription.
|
||||
@@ -247,12 +254,17 @@ Legacy: прямой `POST /v1/calendars/:id/specialists` **не использ
|
||||
- Запись доступна только на событиях **commercial**-календаря с `booking_open=true` (§2.1.2).
|
||||
- На personal → `403` (`personal_calendar`); при restricted commercial → `403` (`subscription_inactive`).
|
||||
- В зависимости от `confirmation` календаря: auto / manual / timeout (§2.1.2).
|
||||
- Статусы: `pending`, `confirmed`, `cancelled`.
|
||||
- **Capacity:** лимит слотов считают `pending` + `confirmed` (pending резервирует место).
|
||||
- Участник может отменить свою запись (`DELETE`).
|
||||
- Статусы: `pending`, `confirmed`, `cancelled`, `expired`.
|
||||
- **Capacity:** лимит слотов считают `pending` + `confirmed` (pending резервирует место;
|
||||
`cancelled` / `expired` не занимают).
|
||||
- **Истечение:** past-pending (событие уже началось) → `expired` (lazy + timeout job); не
|
||||
путать с `specialist_invite.status=expired`.
|
||||
- Участник может отменить свою запись (`DELETE`) для pending/confirmed; `expired`/`cancelled` —
|
||||
идемпотентный успех.
|
||||
- Confirm/decline: владелец календаря — любые заявки; active specialist — только на событиях
|
||||
со своим `specialist_id` (§2.1.2).
|
||||
со своим `specialist_id` (§2.1.2). На `expired` (и после lazy-mark) → `409`.
|
||||
- При подтверждении фиксируется `confirmed_at`.
|
||||
- Inbox `GET /v1/user/booking-requests` — только pending до старта события (§2.1.2).
|
||||
|
||||
### 2.4. Отзывы и рейтинги
|
||||
- Пользователи могут оставлять отзывы (рейтинг 1–5 и комментарий) на события или календари.
|
||||
@@ -456,11 +468,11 @@ src/
|
||||
пара `current_password` + `password` (неверный текущий → `403`). Нельзя менять
|
||||
email/role/status; неизвестные поля → `400`. Ответ — полный профиль как GET.
|
||||
- `GET /v1/user/bookings` — бронирования пользователя **как участника**.
|
||||
- `GET /v1/user/booking-requests` — pending-заявки к подтверждению, где текущий
|
||||
пользователь — **owner** календаря события или **assigned specialist**
|
||||
(`event.specialist_id` = user и specialist active). Ответ — массив объектов
|
||||
booking + `role` (`owner`|`specialist`) + вложенный `event`
|
||||
(`id`, `calendar_id`, `calendar_title`, `title`, `start_time`, `duration`,
|
||||
- `GET /v1/user/booking-requests` — **actionable** pending-заявки к подтверждению, где
|
||||
текущий пользователь — **owner** календаря события или **assigned specialist**
|
||||
(`event.specialist_id` = user и specialist active). Past-pending помечается `expired` и
|
||||
**не** попадает в ответ. Ответ — массив объектов booking + `role` (`owner`|`specialist`) +
|
||||
вложенный `event` (`id`, `calendar_id`, `calendar_title`, `title`, `start_time`, `duration`,
|
||||
`specialist_id`). Confirm/decline — существующий `PUT /v1/bookings/:id`.
|
||||
- `GET /v1/user/reviews` — отзывы пользователя.
|
||||
- `GET /v1/user/following` — календари, которые пользователь отслеживает (follow).
|
||||
@@ -494,7 +506,9 @@ src/
|
||||
- `GET /v1/bookings/:id` — статус бронирования.
|
||||
- `PUT /v1/bookings/:id` — подтвердить/отклонить (`confirm`|`decline`); владелец —
|
||||
любые booking календаря; active specialist — только события со своим `specialist_id`.
|
||||
- `DELETE /v1/bookings/:id` — отменить бронирование (участник).
|
||||
На past-pending / уже `expired` → `409` (`Booking expired`); при полной вместимости на
|
||||
confirm → `409` (`Event is full`).
|
||||
- `DELETE /v1/bookings/:id` — отменить бронирование (участник; `expired`/`cancelled` — no-op `200`).
|
||||
- `POST /v1/reviews` — создать отзыв.
|
||||
- `GET /v1/reviews` — список отзывов (поле `my_vote` для текущего пользователя).
|
||||
- `GET /v1/reviews/:id` — отзыв по ID (`my_vote`).
|
||||
|
||||
Reference in New Issue
Block a user