# PRIME · полный каталог действий

TASK-PRIME-006 · 2026-09-27 · контракт, интеграции не подключены.

186 состояний · 377 переходов · 28 путей.

Граф описывает разные сессии участников. Межролевая стрелка передаёт работу, а не полномочия. Условия guard проверяет будущий backend; просмотр здесь не исполняет платежи или регистрацию.

## Пути

### J01 · Владелец: от найма до открытия

Создать действующую команду и опубликовать запись только после проверки готовности.

O00 Подтвердить владение → O01 Создать организацию → O02 Настроить филиал → O03 Услуги и длительность → O04 Правила сервиса → O05 Подключить ЮKassa → O06 Открыть набор барберов → O07 Рассмотреть кандидата → O08 Пробная смена → O09 Предложить условия → O10 Пригласить в команду → B00 Получить приглашение → B02 Войти как приглашённый → B03 Принять приглашение → B04 Пройти вводный этап → B05 Готов к записи → O12 Опубликовать запись

### J02 · Гость → первый оплаченный визит

Три входа маркетолога сходятся в подтверждённой записи; платёж отделён от места.

O12 Опубликовать запись → G00 Открыть PRIME → G01 Выбрать образ → G02 Выбрать мастера → G03 Найти время → G05 Собрать черновик → G06 Продолжить с аккаунтом → A00 Выбрать способ входа → A01 Войти через Telegram → A04 Проверить ответ провайдера → A06 Завершить профиль → A07 Аккаунт готов → C00 Главная клиента → C03 Собрать услуги → C02 Выбрать барбера → C04 Выбрать окно → S01 Проверить свободный ресурс → C06 Получить расчёт → C07 Временно удержать слот → C09 Проверить визит → P00 Выбрать оплату → P01 Ввести карту у провайдера → P06 Создать платёж → P07 Подтвердить в банке → P08 Ожидать статус оплаты → P10 Платёж успешен → C10 Подтвердить запись → S00 Зафиксировать запись → C12 Визит подтверждён

### J03 · Визит → паспорт → повтор

Замкнуть память о результате в новую, добровольную запись.

C12 Визит подтверждён → C21 Управлять визитом → C17 Подготовиться к визиту → C29 Прибыть в филиал → B11 Отметить прибытие → B10 Карточка клиента → B12 Согласовать результат → B13 Начать работу → C32 Получить услугу → B16 Показать результат → B17 Записать Cut Passport → B18 Закончить услугу → C34 Завершить визит → S07 Закрыть визит в учёте → C38 Открыть Cut Passport → C39 Выбрать следующий образ → C40 Записаться снова → C05 Повторить прошлый образ → C03 Собрать услуги

### J04 · Барбер заболел — замена

Не потерять визиты и не менять мастера без согласия клиента.

B06 Открыть свой день → B08 Сообщить о болезни → O15 Мастер недоступен → O16 Согласовать замену → C22 Перенести визит → C23 Подтвердить перенос → C12 Визит подтверждён

### J05 · Клиент заболел — возврат

Отменить визит и отдельно довести денежную компенсацию до результата.

C21 Управлять визитом → C26 Клиент заболел → C24 Проверить отмену → C25 Визит отменён → P16 Запросить возврат → P17 Возврат выполняется → P18 Возврат завершён → C40 Записаться снова

### J06 · Клиент опаздывает

Успеть обслужить только в согласованном scope без ущерба следующему клиенту.

C21 Управлять визитом → C27 Клиент опаздывает → B12 Согласовать результат → B13 Начать работу → C32 Получить услугу → B16 Показать результат → B17 Записать Cut Passport → B18 Закончить услугу → C34 Завершить визит

### J07 · Забыл, не пришёл, восстановился

No-show после проверки факта; человеческий разбор и ясный выход.

N00 Запланировать напоминания → N02 Доставить уведомление → N05 Забыть или пропустить → C28 Клиент не пришёл → C43 Помощь человеку → S05 Операционная очередь → O13 Операционный день → S06 Закрыть обращение → C21 Управлять визитом

### J08 · Напоминание не доставлено

Fallback только с согласием; доставка не равна прочтению.

N00 Запланировать напоминания → N02 Доставить уведомление → N03 Не доставлено → N08 Разрешённый запасной канал → N04 Прочитать напоминание → N06 Напомнить позже → N00 Запланировать напоминания

### J09 · Оплата прошла, ответ потерян

Сверить одну операцию без повторного списания.

P06 Создать платёж → P12 Оплата неизвестна → P13 Сверить платёж → P10 Платёж успешен → C10 Подтвердить запись → S00 Зафиксировать запись → C12 Визит подтверждён

### J10 · Оплачено, но слот утрачен

Компенсация paid-unallocated вместо двойного бронирования.

P08 Ожидать статус оплаты → P10 Платёж успешен → P25 Деньги пришли после потери слота → P16 Запросить возврат → P17 Возврат выполняется → P18 Возврат завершён → C40 Записаться снова

### J11 · Сохранить и отвязать карту

Consent, provider token, затем запрет будущих списаний без разрушения истории.

P00 Выбрать оплату → P02 Разрешить сохранение карты → P01 Ввести карту у провайдера → P06 Создать платёж → P07 Подтвердить в банке → P08 Ожидать статус оплаты → P10 Платёж успешен → P03 Сохранённый способ оплаты → P05 Отвязать карту → R00 Приватность и аккаунт

### J12 · Наличные / терминал после услуги

Учесть оплату на месте без фиктивного банковского callback.

C34 Завершить визит → P14 Оплатить на месте → P15 Подтвердить оплату на месте → P20 Выдать чек → S07 Закрыть визит в учёте → C38 Открыть Cut Passport

### J13 · PRIME CLUB и гостевой визит

Плательщик и получатель раздельны; одноразовая привилегия.

L00 Посмотреть PRIME CLUB → L01 Принять условия клуба → P00 Выбрать оплату → P01 Ввести карту у провайдера → P06 Создать платёж → P07 Подтвердить в банке → P08 Ожидать статус оплаты → P10 Платёж успешен → L02 Членство активно → L08 Подарить гостевой визит → G10 Получить приглашение в клуб → A00 Выбрать способ входа → A02 Войти через Яндекс → A04 Проверить ответ провайдера → A06 Завершить профиль → A07 Аккаунт готов → L09 Принять гостевой визит → C03 Собрать услуги

### J14 · Продление клуба не прошло

Ограничить повторы и сохранить историю без принудительного членства.

L02 Членство активно → L04 Продлить членство → L05 Продление не прошло → L07 Период завершён → C00 Главная клиента

### J15 · Недовольство → исправление

Дать человеку выбор исправления; не принуждать к хорошему отзыву.

B16 Показать результат → C33 Попросить изменить результат → C36 Подать претензию → O20 Разобрать претензию → C22 Перенести визит → C23 Подтвердить перенос → C12 Визит подтверждён

### J16 · Потеря телефона и доступа

Восстановление с доказательством владения без слияния по совпавшему email.

R00 Приватность и аккаунт → R07 Потерян телефон → A10 Восстановить доступ → A00 Выбрать способ входа → A02 Войти через Яндекс → A04 Проверить ответ провайдера → A06 Завершить профиль → A07 Аккаунт готов → C00 Главная клиента

### J17 · Удаление профиля и обязательства

Отозвать доступ, удалить допустимые данные, явно отделить ограниченные финансовые записи.

R00 Приватность и аккаунт → R04 Удалить аккаунт → R05 Завершить обязательства → R06 Профиль удалён

### J18 · Мастер уходит из команды

Отозвать права, сверить расчёт, не потерять будущие визиты и клиентские паспорта.

B06 Открыть свой день → B22 Уйти из команды → O17 Уволить или приостановить → O18 Доступ сотрудника отозван → O21 Расчёт с барбером → B20 Проверить начисление → O23 Отчёт и новые решения → O06 Открыть набор барберов

### J19 · Пауза в визитах и возвращение

Поездка, усталость или болезнь не повод для бесконечных напоминаний.

C38 Открыть Cut Passport → C39 Выбрать следующий образ → C41 Взять паузу → C00 Главная клиента → C05 Повторить прошлый образ → C03 Собрать услуги

### J20 · MAX недоступен — другой вход

MAX условен до проверенной интеграции; нет тупика регистрации.

A00 Выбрать способ входа → A03 Подтвердиться через MAX → A05 Вход отменён или недоступен → A00 Выбрать способ входа → A02 Войти через Яндекс → A04 Проверить ответ провайдера → A06 Завершить профиль → A07 Аккаунт готов → C00 Главная клиента

### J21 · Перенос вместо отмены

Исходный визит сохраняется до атомарной замены.

C21 Управлять визитом → C22 Перенести визит → C23 Подтвердить перенос → C12 Визит подтверждён → C21 Управлять визитом

### J22 · Лист ожидания

Место становится визитом только после явного принятия и final commit.

C04 Выбрать окно → C13 Лист ожидания → C14 Предложено окно → C15 Предложение истекло → C13 Лист ожидания → C14 Предложено окно → C06 Получить расчёт → C07 Временно удержать слот → C09 Проверить визит

### J23 · Авария в филиале

Каждый затронутый клиент получает понятное решение и компенсацию.

O13 Операционный день → O19 Закрытие филиала / авария → O15 Мастер недоступен → C24 Проверить отмену → C25 Визит отменён → P16 Запросить возврат → P17 Возврат выполняется → P18 Возврат завершён

### J24 · Положительный опыт → рекомендация

Рекомендация добровольна, ссылка не раскрывает личные данные.

S07 Закрыть визит в учёте → C35 Оставить отзыв → C37 Поблагодарить барбера → C38 Открыть Cut Passport → L10 Пригласить друга → G11 Вернуться по ссылке → G00 Открыть PRIME

### J25 · Чек задержался

Не списывать повторно из-за сбоя фискализации; видимый владелец проблемы.

P10 Платёж успешен → P20 Выдать чек → P21 Чек ещё не готов → S05 Операционная очередь → O13 Операционный день → S06 Закрыть обращение → O23 Отчёт и новые решения

### J26 · Перерыв сети во время услуги

Восстановить серверное состояние и разрешённый рабочий контекст.

B13 Начать работу → S02 Нет сети / приложение закрыто → S03 Восстановить состояние → B06 Открыть свой день → B10 Карточка клиента

### J27 · Согласие и отказ от фотографий

Обслужить без фото; черновик и orphan upload не превращаются в публичное медиа.

C17 Подготовиться к визиту → C18 Добавить фото → C20 Фото не загрузилось → C19 Отказать в фото → C21 Управлять визитом

### J28 · Отбор кандидата и отказ

Отказ закрывает временный доступ и возвращает владельца к поиску.

O06 Открыть набор барберов → O07 Рассмотреть кандидата → O08 Пробная смена → O11 Отказ в найме → O06 Открыть набор барберов

## Действия и все исходящие переходы

### O00 · Подтвердить владение

Роль: owner · Слой: front · Фаза: Настройка · contract

Фронт: Войти и подтвердить право управлять PRIME.

Бэкенд: Проверить предварительно выданное право создания организации или существующий owner grant и step-up. Публичный OAuth не выдаёт роль owner.

API: CMD-ORG · Политики: POL-01

- **Создать организацию → O01** (happy, actor=owner). Проверить актуальное состояние, полномочия и версию объекта.
- **Подтвердить личность → A00** (recovery, actor=owner, межролевая передача). Continuation owner_setup; grant владельца уже существует вне публичной регистрации.

### O01 · Создать организацию

Роль: owner · Слой: back · Фаза: Настройка · contract

Фронт: Показать черновик организации и ответственного.

Бэкенд: Создать organization с owner membership в транзакции; аудит, unique legal identity после проверки.

API: CMD-ORG · Политики: POL-01

- **Настроить филиал → O02** (happy, actor=system). Проверить актуальное состояние, полномочия и версию объекта.

### O02 · Настроить филиал

Роль: owner · Слой: front · Фаза: Настройка · contract

Фронт: Адрес, часовой пояс, часы, кресла и контакты.

Бэкенд: Версионировать Branch и Resource; проверить зоны и интервалы, не переносить hosts МАУ.

API: CMD-BRANCH · Политики: общие инварианты

- **Услуги и длительность → O03** (happy, actor=owner). Проверить актуальное состояние, полномочия и версию объекта.

### O03 · Услуги и длительность

Роль: owner · Слой: front · Фаза: Настройка · contract

Фронт: Услуги, навыки, длительность, перерывы, цена.

Бэкенд: ServiceVersion: integer minor units/RUB, skill requirements, equipment, duration и buffer.

API: CMD-CATALOG · Политики: общие инварианты

- **Правила сервиса → O04** (happy, actor=owner). Проверить актуальное состояние, полномочия и версию объекта.

### O04 · Правила сервиса

Роль: owner · Слой: front · Фаза: Настройка · contract

Фронт: Предоплата, отмена, опоздание, возврат, клуб — с явным статусом решения.

Бэкенд: PolicyVersion; ничего не удерживать по неутверждённым правилам. Снимок условий в каждом заказе.

API: CMD-POLICY · Политики: POL-03

- **Подключить ЮKassa → O05** (happy, actor=owner). Проверить актуальное состояние, полномочия и версию объекта.

### O05 · Подключить ЮKassa

Роль: owner · Слой: back · Фаза: Настройка · contract

Фронт: Статус тестового/боевого магазина и фискализации.

Бэкенд: Секреты только серверу; shopId, webhook, сверка, способ выдачи чека. Sandbox smoke до включения продаж.

API: CMD-MERCHANT · Политики: POL-11

- **Открыть набор барберов → O06** (happy, actor=system). Проверить актуальное состояние, полномочия и версию объекта.

### O06 · Открыть набор барберов

Роль: owner · Слой: front · Фаза: Команда · contract

Фронт: Описать навыки, загрузку, условия и этапы отбора.

Бэкенд: Vacancy/candidate consent; не публиковать персональные данные кандидата в клиентский каталог.

API: CMD-HIRING · Политики: общие инварианты

- **Рассмотреть кандидата → O07** (happy, actor=owner). Проверить актуальное состояние, полномочия и версию объекта.

### O07 · Рассмотреть кандидата

Роль: owner · Слой: front · Фаза: Команда · contract

Фронт: Портфолио, интервью, доступность; согласовать пробную смену.

Бэкенд: RecruitmentCase с ограниченным доступом; отклонение и retention отдельно от клиентского аккаунта.

API: CMD-CANDIDATE · Политики: общие инварианты

- **Пробная смена → O08** (happy, actor=owner). Проверить актуальное состояние, полномочия и версию объекта.
- **Кандидат не подошёл → O11** (exception, actor=owner). Решение владельца с reason и ограниченным retention.

### O08 · Пробная смена

Роль: owner · Слой: front · Фаза: Команда · contract

Фронт: Оценить навыки и дать обратную связь.

Бэкенд: Trial shift не даёт доступа к всей базе; отметка результата и решение владельца.

API: CMD-CANDIDATE · Политики: общие инварианты

- **Предложить условия → O09** (happy, actor=owner). Проверить актуальное состояние, полномочия и версию объекта.
- **Пробная смена не пройдена → O11** (exception, actor=owner). Нет активного membership.

### O09 · Предложить условия

Роль: owner · Слой: front · Фаза: Команда · contract

Фронт: Ставка/процент, услуги, филиал, права и дата старта.

Бэкенд: Versioned offer; модель занятости и расчётов требует утверждения, принятие фиксируется отдельно.

API: CMD-CANDIDATE · Политики: POL-02

- **Пригласить в команду → O10** (happy, actor=owner). Проверить актуальное состояние, полномочия и версию объекта.

### O10 · Пригласить в команду

Роль: owner · Слой: back · Фаза: Команда · contract

Фронт: Показать одноразовое приглашение и его срок.

Бэкенд: Хеш invite-token, expiry, intended scope; доставка после согласия получателя, повтор инвалидирует старый token.

API: CMD-INVITE · Политики: общие инварианты

- **Получить приглашение → B00** (happy, actor=system, межролевая передача). Доставка согласованного приглашения; это межролевой handoff, не переключение owner session в barber.

### O11 · Отказ в найме

Роль: owner · Слой: front · Фаза: Команда · contract

Фронт: Закрыть кандидатуру с корректной обратной связью.

Бэкенд: Закрыть case, отозвать trial-доступ, применить retention; не создавать membership.

API: CMD-CANDIDATE · Политики: общие инварианты

- **Продолжить поиск → O06** (recovery, actor=owner). Новое vacancy/candidate действие, без восстановления старого доступа.

### O12 · Опубликовать запись

Роль: owner · Слой: back · Фаза: Выбор · contract

Фронт: Проверить готовность мастеров, цен и расписания.

Бэкенд: Открыть каталог только при active staff, shifts, policies и выбранном режиме оплаты; outbox catalog.published.

API: CMD-PUBLISH · Политики: общие инварианты

- **Открыть PRIME → G00** (happy, actor=system, межролевая передача). Проверить актуальное состояние, полномочия и версию объекта.
- **Открыть операционный день → O13** (happy, actor=system). Владельцу свой branch scope.

### O13 · Операционный день

Роль: owner · Слой: front · Фаза: Визит · contract

Фронт: Нагрузка, исключения, обращения, незакрытые оплаты.

Бэкенд: Read model по филиалу; только разрешённые персональные данные. Нет подмены банковского статуса.

API: CMD-OPERATIONS · Политики: общие инварианты

- **Изменить смены → O14** (happy, actor=owner). Version check; существующие визиты не исчезают.
- **В филиале авария → O19** (exception, actor=owner). Пауза новых бронирований, известный период недоступности.
- **Завершить работу с мастером → O17** (happy, actor=owner). Owner step-up, scope и план будущих визитов.
- **Сверить деньги → O22** (happy, actor=owner). Owner finance capability.
- **Передать владение → O24** (happy, actor=owner). Двойное подтверждение identity и прав, MFA.
- **Поступил банковский спор → P22** (exception, actor=owner). Есть реальное уведомление/acquirer case, сверить объект.
- **Зафиксировать решение обращения → S06** (happy, actor=owner). Resolved downstream operations verified, audit и notice.

### O14 · Смены и отпуска

Роль: owner · Слой: front · Фаза: Выбор · contract

Фронт: Одобрить график, отпуск, замену, блокировку кресла.

Бэкенд: Revision + resource constraints; изменение смены не удаляет существующие записи.

API: CMD-SHIFT · Политики: общие инварианты

- **Опубликовать согласованный график → B06** (happy, actor=owner, межролевая передача). Нет конфликтов с визитами и ресурсами.
- **Кто-то изменил график раньше → S04** (exception, actor=owner). Revision mismatch, никакого silent overwrite.

### O15 · Мастер недоступен

Роль: owner · Слой: back · Фаза: До визита · contract

Фронт: Показать затронутые визиты и варианты замены.

Бэкенд: Freeze affected slots; incident batch с индивидуальным решением по каждому booking, дедупликация сообщений.

API: CMD-REASSIGN · Политики: общие инварианты

- **Предложить замену → O16** (recovery, actor=system). Есть подходящий барбер и ресурс.
- **Нет замены — предложить отмену → C24** (recovery, actor=system, межролевая передача). Инициатор салон; refund по опубликованной политике, клиент информирован.

### O16 · Согласовать замену

Роль: owner · Слой: front · Фаза: До визита · contract

Фронт: Предложить другого барбера/время или отмену.

Бэкенд: Никакой тихой замены: consent клиента, новая quote при изменении цены, transfer booking атомарно.

API: CMD-REASSIGN · Политики: общие инварианты

- **Клиент выбирает перенос → C22** (handoff, actor=owner, межролевая передача). Согласие клиента, подходящий навык/ресурс; новое ценовое предложение при разнице.
- **Клиент отказался → C24** (recovery, actor=owner, межролевая передача). Нельзя заменить барбера без согласия.

### O17 · Уволить или приостановить

Роль: owner · Слой: front · Фаза: Управление · contract

Фронт: Дата окончания, будущие визиты, расчёт и отзыв прав.

Бэкенд: Membership.revoking; закрыть новые слоты, подготовить перенос, revoke sessions, сохранить audit.

API: CMD-OFFBOARD · Политики: POL-16

- **Передать будущие визиты → O15** (async, actor=owner). Все неоказанные визиты включены в batch.
- **Отозвать доступ → O18** (happy, actor=owner). Немедленно при риске, иначе по дате; обязательства остаются в incident queue.

### O18 · Доступ сотрудника отозван

Роль: owner · Слой: back · Фаза: Управление · contract

Фронт: Показать завершённую процедуру и оставшиеся обязательства.

Бэкенд: Отмена membership немедленно на API; общие паспорта остаются у клиента, staff media cache истекает.

API: CMD-OFFBOARD · Политики: общие инварианты

- **Сверить окончательный расчёт → O21** (happy, actor=system). Нет потери ledger и возвратов.
- **Нанять замену → O06** (happy, actor=system). Новая вакансия, не перенос credentials старого мастера.

### O19 · Закрытие филиала / авария

Роль: owner · Слой: front · Фаза: До визита · contract

Фронт: Отключение воды, света, оборудования, погода: приостановить запись.

Бэкенд: Branch incident; затронутые визиты → предложение/возврат, запрет новых hold, владельцу список незавершённых компенсаций.

API: CMD-BRANCH · Политики: POL-16

- **Разобрать затронутые визиты → O15** (async, actor=owner). Каждый booking получает отдельное решение/компенсацию.

### O20 · Разобрать претензию

Роль: owner · Слой: front · Фаза: После визита · contract

Фронт: Услышать клиента, предложить исправление/возврат/объяснение.

Бэкенд: Case, факты и сроки; не стирать отзыв за компенсацию, решение с audit и независимым возвратом.

API: CMD-CASE-RESOLVE · Политики: общие инварианты

- **Одобрить возврат → P16** (happy, actor=owner, межролевая передача). Refund entitlement/amount подтверждены и записаны.
- **Предложить исправление в другой день → C22** (recovery, actor=owner, межролевая передача). Клиент согласен, стоимость и scope ясны.
- **Объяснить решение → S06** (happy, actor=owner). Все обещанные действия имеют authoritative результат; можно обжаловать.

### O21 · Расчёт с барбером

Роль: owner · Слой: front · Фаза: Управление · contract

Фронт: Выручка, возвраты, чаевые отдельно, начисление по версии договора.

Бэкенд: Payroll ledger и период; ЮKassa merchant settlement не является зарплатой. Выплата отдельным подтверждённым каналом.

API: CMD-PAYROLL · Политики: POL-02

- **Проверить свой расчёт → B20** (handoff, actor=owner, межролевая передача). Только свой statement, без чужих персональных данных.

### O22 · Сверка выручки

Роль: owner · Слой: back · Фаза: Управление · contract

Фронт: Платежи, касса, возвраты, чеки и банковские поступления раздельно.

Бэкенд: Reconciliation job; сумма заказа ≠ выручка после возвратов ≠ merchant settlement; расхождение → case.

API: CMD-RECONCILE · Политики: POL-11

- **Подготовить начисления → O21** (happy, actor=system). Учтены settled/refunded операции, правила договора имеют версию.

### O23 · Отчёт и новые решения

Роль: owner · Слой: front · Фаза: Повтор · contract

Фронт: Конверсия, загрузка, повторы, отмены, качество без рейтинговой гонки.

Бэкенд: Агрегаты из событий, исключить технические дубли, cohort attribution; новые правила только следующей версией.

API: CMD-OPERATIONS · Политики: общие инварианты

- **Улучшить услуги → O03** (happy, actor=owner). Новая версия не меняет старые quote/заказы.
- **Расширить команду → O06** (happy, actor=owner). Новая потребность в найме.

### O24 · Передача владения

Роль: owner · Слой: front · Фаза: Управление · contract

Фронт: Усиленная проверка обеих сторон и подтверждение передачи.

Бэкенд: Не оставлять организацию без владельца; атомарная замена grant, аудит, отзыв старых полномочий.

API: CMD-TRANSFER · Политики: POL-01, POL-16

- **Завершить передачу → O13** (happy, actor=owner). Новый owner grant записан атомарно, старые сессии отозваны.
- **Вернуться к удалению аккаунта → R04** (recovery, actor=owner, межролевая передача). Новый владелец принял управление, транзакция завершена. Вернуться к исходному deletion intent той же identity с повторной проверкой полномочий.

### B00 · Получить приглашение

Роль: barber · Слой: front · Фаза: Команда · contract

Фронт: Увидеть PRIME, филиал, автора и условия.

Бэкенд: GET invite проверяет hash/expiry/revoked; не раскрывать чужие данные до аутентификации.

API: CMD-INVITE-ACCEPT · Политики: общие инварианты

- **Войти как приглашённый → B02** (happy, actor=barber). Проверить актуальное состояние, полномочия и версию объекта.
- **Ссылка просрочена или отозвана → B01** (exception, actor=barber). expiry/revoked/consumed проверяет сервер.
- **Отказаться от предложения → B21** (exit, actor=barber). Отказ не активирует доступ.

### B01 · Приглашение истекло

Роль: barber · Слой: front · Фаза: Команда · contract

Фронт: Запросить новое или отказаться.

Бэкенд: Не восстанавливать старый token; только владелец выдаёт новую версию.

API: CMD-INVITE-ACCEPT · Политики: общие инварианты

- **Попросить новое приглашение → O10** (recovery, actor=barber, межролевая передача). Владелец подтверждает, новый token инвалидирует старый.

### B02 · Войти как приглашённый

Роль: barber · Слой: front · Фаза: Команда · contract

Фронт: Подтвердить свою идентичность, затем прочитать условия.

Бэкенд: Связать invitation с verified identity; membership ещё pending, claim не принимает role из клиента.

API: CMD-INVITE-ACCEPT · Политики: общие инварианты

- **Принять приглашение → B03** (happy, actor=barber). Проверить актуальное состояние, полномочия и версию объекта.
- **Выбрать провайдера → A00** (happy, actor=barber, межролевая передача). Сохранить invite continuation с expiry, роль не берётся из клиента.

### B03 · Принять приглашение

Роль: barber · Слой: back · Фаза: Команда · contract

Фронт: Подтвердить конкретную версию условий.

Бэкенд: Одноразовый claim в транзакции, membership onboarding, аудит и уведомление владельцу.

API: CMD-INVITE-ACCEPT · Политики: общие инварианты

- **Пройти вводный этап → B04** (happy, actor=system). Проверить актуальное состояние, полномочия и версию объекта.

### B04 · Пройти вводный этап

Роль: barber · Слой: front · Фаза: Команда · contract

Фронт: Профиль, навыки, правила фото, расписание и подтверждение готовности.

Бэкенд: Минимальные права; owner подтверждает навыки и старт, клиентский профиль скрыт до публикации.

API: CMD-ONBOARD · Политики: общие инварианты

- **Готов к записи → B05** (happy, actor=barber). Проверить актуальное состояние, полномочия и версию объекта.

### B05 · Готов к записи

Роль: barber · Слой: back · Фаза: Выбор · contract

Фронт: Проверить публичный профиль и смену.

Бэкенд: Active membership + approved skills + published shift; availability пересчитывается.

API: CMD-ONBOARD · Политики: общие инварианты

- **Опубликовать запись → O12** (happy, actor=system, межролевая передача). Проверить актуальное состояние, полномочия и версию объекта.
- **Начать смену → B06** (happy, actor=system). Membership и shift active.

### B06 · Открыть свой день

Роль: barber · Слой: front · Фаза: Визит · contract

Фронт: Предстоящие визиты, перерывы, свободные окна, незакрытые задачи.

Бэкенд: Scoped read model; server now и timezone филиала, запрет чужого расписания вне scope.

API: CMD-DAY · Политики: общие инварианты

- **Запросить отпуск → B07** (happy, actor=barber). Своя membership, корректные даты.
- **Я заболел → B08** (exception, actor=barber). Не требовать диагноз; быстро заморозить новые слоты.
- **Я опаздываю → B09** (exception, actor=barber). ETA и затронутые визиты, без тихого сдвига.
- **Сообщить об уходе → B22** (happy, actor=barber). Свой membership, дата и handover.
- **Открыть следующий визит → B10** (happy, actor=barber). Своя назначенная запись.

### B07 · Попросить отпуск

Роль: barber · Слой: front · Фаза: Выбор · contract

Фронт: Выбрать даты и предложить смену.

Бэкенд: LeaveRequest; до решения владельца существующие записи сохранены, новые временно ограничиваются политикой.

API: CMD-SHIFT-REQUEST · Политики: общие инварианты

- **Рассмотреть отпуск → O14** (async, actor=barber, межролевая передача). Владелец решает и уведомляет сотрудника.

### B08 · Сообщить о болезни

Роль: barber · Слой: front · Фаза: До визита · contract

Фронт: Одним действием сообщить недоступность без диагноза.

Бэкенд: Absence incident + blocked availability; минимизация данных о здоровье, owner получает очередь замен.

API: CMD-ABSENCE · Политики: общие инварианты

- **Разобрать смену → O15** (async, actor=barber, межролевая передача). Incident с дедупликацией затронутых booking.

### B09 · Сообщить об опоздании

Роль: barber · Слой: front · Фаза: До визита · contract

Фронт: Ожидаемое прибытие и затронутые визиты.

Бэкенд: Recompute delay impact; клиенты получают выбор, никаких молчаливых сдвигов всего дня.

API: CMD-ABSENCE · Политики: POL-06

- **Рассчитать задержку → O15** (async, actor=barber, межролевая передача). Не сокращать услугу клиента без согласия.

### B10 · Карточка клиента

Роль: barber · Слой: front · Фаза: Визит · contract

Фронт: Пожелания, разрешённый паспорт, ограничения и время.

Бэкенд: Проверить assignment и consent на каждый media URL; audit доступа, signed URL ограничен временем.

API: CMD-DAY · Политики: общие инварианты

- **Согласовать результат → B12** (happy, actor=barber). Проверить актуальное состояние, полномочия и версию объекта.
- **Доступ к визиту отозван → A13** (exception, actor=barber, межролевая передача). Membership/assignment/consent больше не позволяет чтение.

### B11 · Отметить прибытие

Роль: barber · Слой: back · Фаза: Визит · contract

Фронт: Сверить клиента и услугу, отметить check-in.

Бэкенд: Booking confirmed → arrived; серверная отметка, повтор check-in идемпотентен.

API: CMD-ARRIVE · Политики: общие инварианты

- **Карточка клиента → B10** (happy, actor=system). Проверить актуальное состояние, полномочия и версию объекта.

### B12 · Согласовать результат

Роль: barber · Слой: front · Фаза: Визит · contract

Фронт: Обсудить форму, тишину, чувствительность и цену до начала.

Бэкенд: Consultation snapshot; consent на изменение состава и цены, фото отдельным согласием.

API: CMD-SCOPE · Политики: общие инварианты

- **Начать работу → B13** (happy, actor=barber). Проверить актуальное состояние, полномочия и версию объекта.
- **Услуга не подходит → C24** (exception, actor=barber, межролевая передача). До начала согласовать отмену и деньги.

### B13 · Начать работу

Роль: barber · Слой: back · Фаза: Визит · contract

Фронт: Показать активный визит, время и согласованные услуги.

Бэкенд: arrived → in_service, assignment/version guard; запрет параллельных визитов одного кресла.

API: CMD-SERVICE · Политики: общие инварианты

- **Получить услугу → C32** (happy, actor=system, межролевая передача). Проверить актуальное состояние, полномочия и версию объекта.
- **Расширить услугу → B14** (happy, actor=system). Есть желание клиента; проверка времени и цены.
- **Остановить услугу → B15** (exception, actor=system). Безопасность, самочувствие, поломка; зафиксировать факт без лишних medical данных.
- **Угроза или конфликт → B23** (exception, actor=system). Приоритет безопасности; приложение не заменяет экстренные службы.
- **Закрылось приложение мастера → S02** (exception, actor=system, межролевая передача). Service state сохраняется сервером, не завершается таймером UI.

### B14 · Нужно больше времени

Роль: barber · Слой: front · Фаза: Визит · contract

Фронт: Запросить дополнение, цену и длительность.

Бэкенд: Проверить следующий booking и ресурсы; approve клиента; при конфликте сократить согласованный scope или отдельный визит.

API: CMD-SCOPE · Политики: общие инварианты

- **Согласовать доплату → P23** (happy, actor=barber, межролевая передача). Explicit consent, новая quote; нельзя списать старый token без intent.
- **Продолжить прежний объём → C32** (recovery, actor=barber, межролевая передача). Следующее окно защищено; additions отклонены без ухудшения исходной услуги.

### B15 · Прервать услугу

Роль: barber · Слой: front · Фаза: Визит · contract

Фронт: Зафиксировать причину, оказанную часть и помощь.

Бэкенд: Service incident; безопасность, стоимость только фактически согласованного; спор/возврат в отдельном case.

API: CMD-SERVICE · Политики: общие инварианты

- **Разобрать последствия → O20** (handoff, actor=barber, межролевая передача). Не закрывать деньги до согласованного решения.

### B16 · Показать результат

Роль: barber · Слой: front · Фаза: Результат и расчёт · contract

Фронт: Сверить ожидания; можно поправить сразу.

Бэкенд: Result reviewed клиентом; фото не обязательны для закрытия услуги.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Записать Cut Passport → B17** (happy, actor=barber). Проверить актуальное состояние, полномочия и версию объекта.
- **Результат не устраивает → C33** (exception, actor=barber, межролевая передача). Обратная связь добровольна, без давления.

### B17 · Записать Cut Passport

Роль: barber · Слой: front · Фаза: Результат и расчёт · contract

Фронт: Параметры, продукт, совет, фото при согласии.

Бэкенд: Passport revision, author, visitId; клиент владеет приватностью. Публикация портфолио отдельным разрешением.

API: CMD-PASSPORT · Политики: общие инварианты

- **Закончить услугу → B18** (happy, actor=barber). Проверить актуальное состояние, полномочия и версию объекта.
- **Клиент не хочет фото → C19** (happy, actor=barber, межролевая передача). Параметры можно сохранить без фотографий.

### B18 · Закончить услугу

Роль: barber · Слой: back · Фаза: Результат и расчёт · contract

Фронт: Отдельно показать готовность результата и статус оплаты.

Бэкенд: in_service → service_completed; не помечать paid автоматически, invoice balance проверяется отдельно.

API: CMD-SERVICE · Политики: общие инварианты

- **Завершить визит → C34** (happy, actor=system, межролевая передача). Проверить актуальное состояние, полномочия и версию объекта.
- **Закрыть рабочую смену → B19** (happy, actor=system). Незавершённые cases переданы, не потеряны.

### B19 · Закрыть свою смену

Роль: barber · Слой: front · Фаза: Управление · contract

Фронт: Проверить незавершённые паспорта, визиты и оборудование.

Бэкенд: Shift close допускает явную передачу unresolved cases владельцу; аудит, часы и перерывы.

API: CMD-SHIFT-CLOSE · Политики: общие инварианты

- **Посмотреть начисление → B20** (happy, actor=barber). Опубликован statement для периода.
- **Следующая смена → B06** (happy, actor=barber). Новые server date/shift и active membership.

### B20 · Проверить начисление

Роль: barber · Слой: front · Фаза: Управление · contract

Фронт: Свои услуги, возвраты, чаевые и расчёт периода.

Бэкенд: Scoped earnings view; acknowledge либо dispute, staff не видит чужие начисления.

API: CMD-EARNINGS · Политики: POL-02

- **Есть расхождение → O22** (exception, actor=barber, межролевая передача). Dispute с evidence, исходный ledger не редактируется задним числом.
- **Подтвердить расчёт → O23** (happy, actor=barber, межролевая передача). Подтверждение statement не является банковской выплатой.

### B21 · Отказаться от условий

Роль: barber · Слой: front · Фаза: Команда · contract

Фронт: Отклонить предложение или обсудить новую версию.

Бэкенд: Decline invite/offer; доступ не активируется, будущая версия требует нового принятия.

API: CMD-INVITE-ACCEPT · Политики: общие инварианты

- **Обсудить другие условия → O09** (recovery, actor=barber, межролевая передача). Новая offer version требует нового принятия.
- **Завершить найм → O11** (exit, actor=barber, межролевая передача). Закрыть кандидатуру, отозвать trial capability.

### B22 · Уйти из команды

Роль: barber · Слой: front · Фаза: Управление · contract

Фронт: Сообщить дату и передать будущие визиты.

Бэкенд: Exit request не удаляет историю и не забирает клиентские фото; owner завершает offboarding.

API: CMD-SHIFT-REQUEST · Политики: общие инварианты

- **Начать завершение сотрудничества → O17** (handoff, actor=barber, межролевая передача). Владелец видит запрос, не автоматическое удаление.

### B23 · Клиент ведёт себя опасно

Роль: barber · Слой: front · Фаза: Визит · contract

Фронт: Остановить визит и позвать владельца; экстренная помощь вне приложения.

Бэкенд: Safety case с ограниченным доступом, остановка услуги; санкции только после review и возможности обращения.

API: CMD-INCIDENT · Политики: общие инварианты

- **Безопасно прервать → B15** (recovery, actor=barber). Инцидент владельцу и ясный статус визита.

### G00 · Открыть PRIME

Роль: guest · Слой: front · Фаза: Выбор · contract

Фронт: Посмотреть концепцию, филиал и цены без регистрации.

Бэкенд: Публичный каталог без PII, rate limits; аналитика без присвоения клиентской личности.

API: CMD-PUBLIC-CATALOG · Политики: общие инварианты

- **Выбрать филиал → G04** (happy, actor=guest). Проверить актуальное состояние, полномочия и версию объекта.
- **Начать с образа → G01** (happy, actor=guest). Портфолио опубликовано и consent действителен.
- **Начать с мастера → G02** (happy, actor=guest). Публичные active профили.
- **Начать со времени → G03** (happy, actor=guest). Availability read без гарантии hold.
- **Позвонить или узнать адрес → G08** (happy, actor=guest). Актуальный публичный контакт.
- **Уйти → G07** (exit, actor=guest). Нет созданных бизнес-операций.
- **Открыть гостевое приглашение → G10** (happy, actor=guest). Есть входящая ссылка GuestPass; не маркетинговая рассылка без согласия.

### G01 · Выбрать образ

Роль: guest · Слой: front · Фаза: Выбор · contract

Фронт: Смотреть разрешённое портфолио и сохранять локальный интерес.

Бэкенд: Показывать только опубликованные работы с действующим consent, фильтры услуги/длины.

API: CMD-PUBLIC-CATALOG · Политики: общие инварианты

- **Выбрать мастера → G02** (happy, actor=guest). Проверить актуальное состояние, полномочия и версию объекта.

### G02 · Выбрать мастера

Роль: guest · Слой: front · Фаза: Выбор · contract

Фронт: Навыки, работы и ближайшее окно; без выдуманных отзывов.

Бэкенд: Публичная версия профиля, только active membership и service skills.

API: CMD-PUBLIC-CATALOG · Политики: общие инварианты

- **Найти время → G03** (happy, actor=guest). Проверить актуальное состояние, полномочия и версию объекта.

### G03 · Найти время

Роль: guest · Слой: front · Фаза: Выбор · contract

Фронт: Первый свободный или любимый мастер, другой день/филиал.

Бэкенд: Availability read — подсказка, не бронь; timezone филиала, revision и validUntil.

API: CMD-AVAILABILITY · Политики: общие инварианты

- **Собрать черновик → G05** (happy, actor=guest). Проверить актуальное состояние, полномочия и версию объекта.

### G04 · Выбрать филиал

Роль: guest · Слой: front · Фаза: Выбор · contract

Фронт: Адрес, доступность входа, карта и часы.

Бэкенд: Branch active; геолокация необязательна, адрес доступен текстом.

API: CMD-PUBLIC-CATALOG · Политики: общие инварианты

- **Выбрать образ → G01** (happy, actor=guest). Проверить актуальное состояние, полномочия и версию объекта.

### G05 · Собрать черновик

Роль: guest · Слой: front · Фаза: Запись и оплата · contract

Фронт: Услуги, мастер, время и ориентировочная сумма.

Бэкенд: Локальный draft без реального hold; цена проверяется сервером перед подтверждением.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Продолжить с аккаунтом → G06** (happy, actor=guest). Проверить актуальное состояние, полномочия и версию объекта.

### G06 · Продолжить с аккаунтом

Роль: guest · Слой: front · Фаза: Запись и оплата · contract

Фронт: Объяснить, зачем вход для управления визитом, сохранить черновик.

Бэкенд: Сохранить scoped continuation, без role escalation и без доверия старой цене/слоту.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Выбрать способ входа → A00** (happy, actor=guest). Сохранить anonymous draft; binding к identity только после успешного auth и новой quote.

### G07 · Уйти без записи

Роль: guest · Слой: front · Фаза: Повтор · contract

Фронт: Закрыть сценарий без рассылок и скрытого заказа.

Бэкенд: Никаких payment/booking effects; локальный draft удаляется по политике.

API: см. серверный контракт состояния · Политики: общие инварианты

Явный выход; фоновые обязательства отдельно.

### G08 · Связаться с филиалом

Роль: guest · Слой: front · Фаза: Запись и оплата · contract

Фронт: Телефон, маршрут, часы; помощь без аккаунта.

Бэкенд: Контакт филиала из актуального каталога, не обещать состоявшийся звонок.

API: CMD-PUBLIC-CATALOG · Политики: общие инварианты

- **Прийти лично → G09** (happy, actor=guest). Филиал открыт; walk-in ещё не запись.

### G09 · Прийти без записи

Роль: guest · Слой: front · Фаза: Визит · contract

Фронт: Уточнить наличие окна на месте.

Бэкенд: Walk-in оформляет сотрудник с проверкой ресурса и согласием; не блокировать обслуживание отсутствием приложения.

API: CMD-AVAILABILITY · Политики: общие инварианты

- **Оформить визит на месте → C03** (happy, actor=guest, межролевая передача). Сотрудник с booking.create capability и согласие получателя; ephemeral client без обязательного приложения.
- **Нет места — оставить контакт филиала → G08** (recovery, actor=guest). Не собирать личные данные без цели.

### G10 · Получить приглашение в клуб

Роль: guest · Слой: front · Фаза: Выбор · contract

Фронт: Условия гостевого визита, срок и отправитель.

Бэкенд: GuestPass token без раскрытия истории дарителя; согласие получателя обязательно.

API: CMD-GUEST-PASS · Политики: POL-12

- **Принять гостевой визит → A00** (happy, actor=guest). Подтвердить identity, сохранить one-use claim continuation.

### G11 · Вернуться по ссылке

Роль: guest · Слой: front · Фаза: Выбор · contract

Фронт: Восстановить публичный путь; просроченная ссылка объяснена.

Бэкенд: Allowlisted deep link, проверить объект и срок; чужие/private данные только после auth.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Открыть актуальный каталог → G00** (recovery, actor=guest). Ссылка публичная и allowlisted.

### A00 · Выбрать способ входа

Роль: guest · Слой: front · Фаза: Запись и оплата · contract

Фронт: Telegram, Яндекс; MAX при готовом канале. Отказ не удаляет черновик.

Бэкенд: AuthTransaction с state/expiry/continuation. Ни один provider не задаёт роль сотрудника.

API: CMD-AUTH · Политики: POL-14

- **Войти через Telegram → A01** (happy, actor=guest). Проверить актуальное состояние, полномочия и версию объекта.
- **Выбрать Яндекс → A02** (happy, actor=guest). Registered redirect URI, state и PKCE.
- **Выбрать MAX → A03** (happy, actor=guest). Только если integration gate пройден; mini-app + trusted one-use handoff.

### A01 · Войти через Telegram

Роль: guest · Слой: front · Фаза: Запись и оплата · contract

Фронт: Открыть системный браузер или проверенный native flow.

Бэкенд: OIDC authorization code + PKCE S256; client secret только backend, проверить iss/aud/exp/signature и привязку state.

API: CMD-AUTH-CALLBACK · Политики: POL-14

- **Проверить ответ провайдера → A04** (happy, actor=guest). Проверить актуальное состояние, полномочия и версию объекта.
- **Отменить или не получить ответ → A05** (exception, actor=guest). Не создавать account/session без проверки.

### A02 · Войти через Яндекс

Роль: guest · Слой: front · Фаза: Запись и оплата · contract

Фронт: Запросить минимальный набор данных.

Бэкенд: Authorization code + PKCE S256, state и точный redirect URI; server exchange и user identity API.

API: CMD-AUTH-CALLBACK · Политики: POL-14

- **Вернуться из Яндекса → A04** (async, actor=guest). Exchange code сервером, связать state/PKCE.
- **Отказать Яндексу → A05** (exception, actor=guest). Закрыть transaction, сохранить безопасный draft.

### A03 · Подтвердиться через MAX

Роль: guest · Слой: front · Фаза: Запись и оплата · contract

Фронт: Открыть mini-app, подтвердить связку, вернуться в PRIME.

Бэкенд: Условный адаптер: проверить initData HMAC/auth_date и одноразовый challenge; standalone OIDC не предполагается. Feature gate до end-to-end spike.

API: CMD-AUTH-CALLBACK · Политики: POL-14

- **Вернуться из MAX → A04** (async, actor=guest). Backend validated initData + freshness + challenge; не доверять initDataUnsafe.
- **MAX недоступен → A05** (exception, actor=guest). Feature gate/нет приложения/невалидная подпись → другой способ.

### A04 · Проверить ответ провайдера

Роль: guest · Слой: back · Фаза: Запись и оплата · contract

Фронт: Ожидать завершения, не показывать вход раньше сервера.

Бэкенд: Consume state один раз, токены на сервере/защищённом хранилище; stale/replay/issuer mismatch отвергнуть.

API: CMD-AUTH, CMD-AUTH-CALLBACK · Политики: общие инварианты

- **Завершить профиль → A06** (happy, actor=system, межролевая передача). Проверить актуальное состояние, полномочия и версию объекта.
- **Ответ не прошёл проверку → A05** (exception, actor=system). Replay, expiry, state mismatch, недоступный provider; не утекать деталями identity.

### A05 · Вход отменён или недоступен

Роль: guest · Слой: front · Фаза: Запись и оплата · contract

Фронт: Повторить, выбрать другой способ или продолжить гостем.

Бэкенд: Закрыть AuthTransaction, не создавать пустой дубликат аккаунта.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Выбрать другой способ → A00** (recovery, actor=guest). Новая auth transaction; один принятый callback.
- **Остаться гостем → G00** (exit, actor=guest). Никаких staff или private client данных.

### A06 · Завершить профиль

Роль: client · Слой: front · Фаза: Запись и оплата · contract

Фронт: Имя и доступный подтверждённый контакт; условия и маркетинг отдельно.

Бэкенд: Account по provider+subject; обязательные условия versioned, promo consent optional и по каналам.

API: CMD-PROFILE · Политики: общие инварианты

- **Аккаунт готов → A07** (happy, actor=client). Проверить актуальное состояние, полномочия и версию объекта.
- **Не принимать обязательные условия → G00** (exit, actor=client, межролевая передача). Не активировать account; draft не создаёт заказ.

### A07 · Аккаунт готов

Роль: client · Слой: back · Фаза: Запись и оплата · contract

Фронт: Вернуться к сохранённой цели и показать доступные роли.

Бэкенд: Server session; переоценить draft, quote, slot. Membership проверяется отдельно от client identity.

API: CMD-SESSION · Политики: общие инварианты

- **Главная клиента → C00** (happy, actor=system). Проверить актуальное состояние, полномочия и версию объекта.
- **Продолжить настройку владельца → O01** (happy, actor=system, межролевая передача). Только verified owner grant + step-up; auth не создаёт owner grant.
- **Принять приглашение сотрудника → B03** (happy, actor=system, межролевая передача). Только pending invite, совпадающая подтверждённая identity и принятие текущих условий.
- **Активировать приглашение гостя → L09** (happy, actor=system). Valid GuestPass, consent получателя, claim once; не owner/staff grant.
- **Продолжить сохранённую запись → C09** (happy, actor=system). Draft complete; quote/hold предварительно переоценены, иначе к C03.

### A08 · Связать второй вход

Роль: client · Слой: front · Фаза: Управление · contract

Фронт: Повторно подтвердить текущий аккаунт и новый provider.

Бэкенд: Two-sided proof; unique provider subject. Email/телефон по совпадению не повод автоматически объединять аккаунты.

API: CMD-IDENTITY-LINK · Политики: общие инварианты

- **Provider уже связан с другим аккаунтом → A09** (exception, actor=client). Не объединять автоматически по совпавшему телефону/email.
- **Связка подтверждена → R00** (happy, actor=client). Proof обеих identities, unique provider-subject.

### A09 · Обнаружен другой аккаунт

Роль: client · Слой: front · Фаза: Управление · contract

Фронт: Объяснить коллизию; безопасное восстановление без потери визитов.

Бэкенд: Не объединять по PII; controlled recovery case и доказательство владения обеими identities.

API: CMD-IDENTITY-LINK · Политики: общие инварианты

- **Восстановить корректную связку → A10** (recovery, actor=client). Controlled identity recovery, audit и rate limit.

### A10 · Восстановить доступ

Роль: client · Слой: front · Фаза: Управление · contract

Фронт: Другой связанный вход или обращение; сохранить request ID.

Бэкенд: Rate limit, recovery audit, проверка владения; саппорт не просит CVV/пароль мессенджера.

API: CMD-RECOVERY · Политики: общие инварианты

- **Войти подтверждённым способом → A00** (recovery, actor=client, межролевая передача). Новая transaction, не bypass provider.

### A11 · Сменить роль

Роль: client · Слой: front · Фаза: Управление · contract

Фронт: Выбрать один из разрешённых рабочих контекстов.

Бэкенд: Server проверяет active membership при каждом запросе; client/barber/owner могут принадлежать одному person.

API: CMD-SESSION · Политики: POL-01

- **Режим владельца → O13** (happy, actor=client, межролевая передача). Server owner scope и active grant.
- **Режим барбера → B06** (happy, actor=client, межролевая передача). Server active staff membership для филиала.
- **Режим клиента → C00** (happy, actor=client). Own customer context, без staff impersonation.

### A12 · Выйти со всех устройств

Роль: client · Слой: back · Фаза: Управление · contract

Фронт: Подтвердить завершение сессий.

Бэкенд: Revoke refresh sessions, очистить sensitive cache; оплаченные визиты и компенсации продолжаются на сервере.

API: CMD-LOGOUT · Политики: общие инварианты

- **Вернуться в гостевой режим → G00** (exit, actor=system, межролевая передача). Local private cache очищен; серверные операции продолжаются.

### A13 · Нет доступа

Роль: client · Слой: front · Фаза: Управление · contract

Фронт: Объяснить отзыв роли, показать допустимый аккаунт и помощь.

Бэкенд: 403 без чужих данных, токен не заменяет active grant; audit access denial.

API: CMD-SESSION · Политики: POL-01

- **Перейти в разрешённый контекст → A11** (recovery, actor=client). Не использовать stale role cache.

### C00 · Главная клиента

Роль: client · Слой: front · Фаза: Выбор · contract

Фронт: Ближайший визит, образ, мастер, время и повтор.

Бэкенд: Агрегировать только свой контекст; skeleton/error/empty, нет фальшивого confirmed при stale cache.

API: CMD-SESSION · Политики: общие инварианты

- **Собрать услуги → C03** (happy, actor=client). Проверить актуальное состояние, полномочия и версию объекта.
- **Искать образ → C01** (happy, actor=client). Consent для public portfolio.
- **Сначала мастер → C02** (happy, actor=client). Проверка актуальности профиля.
- **Сначала время → C04** (happy, actor=client). Для финального расчёта обязательны услуги и ресурс.
- **Повторить результат → C05** (happy, actor=client). Есть доступный свой паспорт; иначе новый подбор.
- **Записать близкого → C45** (happy, actor=client). Плательщик не получает доступ к чужой истории.
- **Открыть настройки → R00** (happy, actor=client). Own identity.
- **Нужна помощь → C43** (happy, actor=client). Понятный case ID, без передачи чужих PII.
- **Управлять уведомлениями → C42** (happy, actor=client). Own preferences.

### C01 · Выбрать новый образ

Роль: client · Слой: front · Фаза: Выбор · contract

Фронт: Портфолио, вариант следующей формы и пожелания.

Бэкенд: Style reference связан с доступными услугами, не обещать гарантированный результат по фото.

API: CMD-PUBLIC-CATALOG · Политики: общие инварианты

- **Выбрать услуги образа → C03** (happy, actor=client). Референс — пожелание, услуги согласуются.

### C02 · Выбрать барбера

Роль: client · Слой: front · Фаза: Выбор · contract

Фронт: Навыки, ближайшее время или первый свободный.

Бэкенд: Service skills, branch, active membership; retired stylist → альтернативы без автоматической замены.

API: CMD-PUBLIC-CATALOG · Политики: общие инварианты

- **Выбрать окно → C04** (happy, actor=client). Проверить актуальное состояние, полномочия и версию объекта.

### C03 · Собрать услуги

Роль: client · Слой: front · Фаза: Запись и оплата · contract

Фронт: Длительность и сумма меняются вместе; дополнительные пожелания.

Бэкенд: Server quote по ServiceVersion, скидки/клуб валидируются сервером; zero/negative duration запрещены.

API: CMD-PUBLIC-CATALOG · Политики: общие инварианты

- **Выбрать барбера → C02** (happy, actor=client). Проверить актуальное состояние, полномочия и версию объекта.

### C04 · Выбрать окно

Роль: client · Слой: front · Фаза: Запись и оплата · contract

Фронт: Умные слоты, другой день/филиал, лист ожидания.

Бэкенд: Availability с креслом, навыком, сменой, буфером и существующими hold; время сервера.

API: CMD-AVAILABILITY · Политики: общие инварианты

- **Проверить свободный ресурс → S01** (happy, actor=client). Проверить актуальное состояние, полномочия и версию объекта.
- **Нет удобного окна → C13** (recovery, actor=client). Consent на ограниченные уведомления waitlist.

### C05 · Повторить прошлый образ

Роль: client · Слой: front · Фаза: Выбор · contract

Фронт: Открыть прошлый паспорт и уточнить изменения.

Бэкенд: Reference to passport version; проверить доступность мастера, актуальные услуги и цену, не копировать старую оплату.

API: CMD-PASSPORT-READ · Политики: общие инварианты

- **Собрать услуги → C03** (happy, actor=client). Проверить актуальное состояние, полномочия и версию объекта.

### C06 · Получить расчёт

Роль: client · Слой: back · Фаза: Запись и оплата · contract

Фронт: Показать полную цену, предоплату/оплату на месте и правила.

Бэкенд: Immutable Quote: price/duration/policyVersion/currency/expiresAt; stale quote требует нового подтверждения.

API: CMD-QUOTE · Политики: POL-03

- **Временно удержать слот → C07** (happy, actor=system). Проверить актуальное состояние, полномочия и версию объекта.

### C07 · Временно удержать слот

Роль: client · Слой: back · Фаза: Запись и оплата · contract

Фронт: Показать оставшееся время; не объявлять бронь окончательной.

Бэкенд: Atomic hold с уникальным ресурсным интервалом, TTL, revision; срок не продлевается бесконечно.

API: CMD-HOLD · Политики: POL-04

- **Проверить визит → C09** (happy, actor=system). Проверить актуальное состояние, полномочия и версию объекта.
- **Не удалось удержать → C08** (exception, actor=system). Atomic claim проиграл гонку; средства не списывать.
- **Время выбора истекло → C16** (exception, actor=system). Release hold by TTL; начатый платёж отправляется на reconciliation.

### C08 · Слот уже занят

Роль: client · Слой: front · Фаза: Запись и оплата · contract

Фронт: Сохранить услуги и предложить соседние окна.

Бэкенд: 409 conflict → свежая availability; не создавать второй charge и не удалять существующий визит.

API: CMD-AVAILABILITY · Политики: общие инварианты

- **Выбрать другое окно → C04** (recovery, actor=client). Сохранить service/master intent, обновить availability.

### C09 · Проверить визит

Роль: client · Слой: front · Фаза: Запись и оплата · contract

Фронт: Мастер, филиал, дата, цена, контакт, условия и способ оплаты.

Бэкенд: Guard quote/hold/policy/consent/contact; business command только после явного подтверждения.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Выбрать оплату → P00** (happy, actor=client). Проверить актуальное состояние, полномочия и версию объекта.
- **Изменить услуги → C03** (recovery, actor=client). Отпустить hold, новая длительность/quote.
- **Отказаться до подтверждения → C16** (exit, actor=client). Не отменять уже состоявшийся payment молча.

### C10 · Подтвердить запись

Роль: client · Слой: back · Фаза: Запись и оплата · contract

Фронт: Показать один pending запрос и его статус.

Бэкенд: Idempotent BookingSaga; validate hold/revision/payment policy. Деньги и слот — отдельные агрегаты.

API: CMD-BOOK · Политики: общие инварианты

- **Зафиксировать запись → S00** (happy, actor=system). Проверить актуальное состояние, полномочия и версию объекта.
- **Ответ сервера потерян → C11** (exception, actor=system). Сохраняется operationId; запрещён новый create наугад.

### C11 · Результат неизвестен

Роль: client · Слой: front · Фаза: Запись и оплата · contract

Фронт: Не нажимать повторную оплату; показать сверку и request ID.

Бэкенд: GET operation by id, bounded reconciliation, ни failure ни success не выводятся из timeout.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Узнать результат → S03** (recovery, actor=client). GET operationId, не повторять charge с новым ключом.

### C12 · Визит подтверждён

Роль: client · Слой: front · Фаза: До визита · contract

Фронт: Подтверждённый booking ID, адрес, календарь, подготовка.

Бэкенд: Только authoritative confirmed; outbox reminders; оплачено/к оплате показывается отдельно.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Запланировать напоминания → N00** (happy, actor=client). Проверить актуальное состояние, полномочия и версию объекта.
- **Управлять записью → C21** (happy, actor=client). Own confirmed booking.
- **Добавить важные пожелания → C44** (happy, actor=client). Добровольно, scope и retention.

### C13 · Лист ожидания

Роль: client · Слой: front · Фаза: Запись и оплата · contract

Фронт: Дни, мастер, диапазон времени, допустимый контакт и срок.

Бэкенд: Waitlist request с expiry/consent; без удержания средств и без гарантии места.

API: CMD-WAITLIST · Политики: POL-08

- **Освободился подходящий слот → C14** (async, actor=client). Matching criteria, fairness, offer expiry; не auto-book.
- **Выйти из листа → C00** (exit, actor=client). Отменить waitlist и pending offers.

### C14 · Предложено окно

Роль: client · Слой: front · Фаза: Запись и оплата · contract

Фронт: Принять до указанного срока или отказаться.

Бэкенд: Временное предложение одному кандидату или атомарный first-claim; offer ≠ confirmed booking.

API: CMD-AVAILABILITY, CMD-WAITLIST-OFFER, CMD-WAITLIST-CLAIM · Политики: POL-08

- **Принять окно → C06** (happy, actor=client). Offer ещё действителен; новая quote и atomic hold.
- **Не ответить вовремя → C15** (exception, actor=client). Server deadline, освободить offer exactly once.
- **Отказаться и ждать дальше → C13** (recovery, actor=client). Rate limit уведомлений, обновить критерии по желанию.

### C15 · Предложение истекло

Роль: client · Слой: front · Фаза: Запись и оплата · contract

Фронт: Остаться в листе, изменить пожелания или выйти.

Бэкенд: Release offer/hold once; fairness и dedupe, не слать одно окно бесконечно.

API: CMD-AVAILABILITY, CMD-WAITLIST-OFFER · Политики: POL-08

- **Продолжить ожидание → C13** (recovery, actor=client). Request ещё действителен, максимум повторов ограничен.
- **Закончить ожидание → C00** (exit, actor=client). Нет held capacity и pending payment.

### C16 · Передумать до записи

Роль: client · Слой: front · Фаза: Запись и оплата · contract

Фронт: Вернуться или закрыть; показать реальные незавершённые операции.

Бэкенд: Если платежа нет — release hold; если payment pending — отмена intent + reconcile, не забывать платеж.

API: см. серверный контракт состояния · Политики: POL-04

- **Завершить без операции → C00** (exit, actor=client). Нет pending payment; hold released.
- **Сверить уже начатую оплату → P13** (recovery, actor=client). Persisted operation exists; cancellation intent сохранён.

### C17 · Подготовиться к визиту

Роль: client · Слой: front · Фаза: До визита · contract

Фронт: Референс, что сохранить, тишина/общение и доступность.

Бэкенд: Visit preferences versioned, минимальные данные; отсутствие референса не блокирует услугу.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Прибыть в филиал → C29** (happy, actor=client). Проверить актуальное состояние, полномочия и версию объекта.
- **Добавить референс → C18** (happy, actor=client). Разрешение ОС и consent на private storage.
- **Обойтись без фото → C19** (happy, actor=client). Текстовый путь равноценен.

### C18 · Добавить фото

Роль: client · Слой: front · Фаза: До визита · contract

Фронт: Выбор камеры/галереи и отдельное согласие на хранение.

Бэкенд: Scoped upload session, content limits, metadata stripping, private media; photo consent не равно portfolio consent.

API: CMD-MEDIA · Политики: POL-10

- **Ошибка загрузки → C20** (exception, actor=client). Draft остаётся локально, отсутствие фото не отменяет booking.
- **Фото сохранено → C21** (happy, actor=client). Server finalize confirmed, private object assigned to booking.

### C19 · Отказать в фото

Роль: client · Слой: front · Фаза: До визита · contract

Фронт: Продолжить текстом без наказания за отказ.

Бэкенд: Не читать камеру/галерею, не создавать media; разрешение ОС и согласие хранения независимы.

API: см. серверный контракт состояния · Политики: POL-10

- **Продолжить без фото → C21** (happy, actor=client). No media effects.
- **Завершить услугу без фото → B18** (happy, actor=barber, межролевая передача). Контекст — завершение текущей услуги; отказ касается только фото, assignment и in_service проверены.

### C20 · Фото не загрузилось

Роль: client · Слой: front · Фаза: До визита · contract

Фронт: Сохранить локальный черновик, повторить или удалить.

Бэкенд: Идемпотентный upload finalize; orphan cleanup по TTL, отказ не отменяет booking.

API: CMD-MEDIA · Политики: общие инварианты

- **Повторить загрузку → C18** (recovery, actor=client). Тот же upload intent, без дублирования файлов.
- **Удалить черновик фото → C19** (exit, actor=client). Delete local draft + revoke orphan upload.

### C21 · Управлять визитом

Роль: client · Слой: front · Фаза: До визита · contract

Фронт: Маршрут, календарь, написать, перенести, отменить.

Бэкенд: Booking revision + policy snapshot; устаревшие ссылки пересматривают текущее состояние.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Подготовиться к визиту → C17** (happy, actor=client). Проверить актуальное состояние, полномочия и версию объекта.
- **Перенести → C22** (happy, actor=client). Booking movable, показать policy snapshot.
- **Отменить → C24** (happy, actor=client). Cancellation quote актуален.
- **Я заболел → C26** (exception, actor=client). Без обязательного диагноза и автоматического штрафа.
- **Я опаздываю → C27** (exception, actor=client). ETA, следующий визит не сдвигается молча.
- **Я на месте → C29** (happy, actor=client). Правильный филиал и актуальная дата.
- **Пропала сеть → S02** (exception, actor=client). Последний snapshot помечен stale, никакой новой автоматической оплаты.

### C22 · Перенести визит

Роль: client · Слой: front · Фаза: До визита · contract

Фронт: Выбрать новый слот и увидеть разницу цены/условий.

Бэкенд: Исходный визит остаётся подтверждённым до атомарной замены; new quote при изменении состава.

API: см. серверный контракт состояния · Политики: POL-05

- **Выбрать новый слот → C23** (happy, actor=client). New hold valid, old booking сохранён до commit.
- **Передумать переносить → C21** (exit, actor=client). Release new hold, оставить исходный booking.

### C23 · Подтвердить перенос

Роль: client · Слой: back · Фаза: До визита · contract

Фронт: Показать новое время после ответа сервера.

Бэкенд: Atomic move hold→booking and release old; компенсировать разницу платежа отдельной saga; cancel старых reminders.

API: CMD-MOVE · Политики: общие инварианты

- **Перенос подтверждён → C12** (happy, actor=system). Atomic move, reminders replaced, payment delta tracked.
- **Новое окно заняли → C08** (exception, actor=system). Исходный booking сохранён; показать его рядом с альтернативами.
- **Перенос конфликтует с отменой → S04** (exception, actor=system, межролевая передача). Одна операция выигрывает atomic transition, другой client получает новое состояние.

### C24 · Проверить отмену

Роль: client · Слой: front · Фаза: До визита · contract

Фронт: Ясно показать сумму возврата/обязательства и причины без обязательного диагноза.

Бэкенд: Cancellation quote по policy snapshot; версия+auth; штрафы не включать без утверждённого правила.

API: CMD-REFUND-QUOTE · Политики: POL-05

- **Подтвердить отмену → C25** (happy, actor=client). Version guard, принятое cancellation intent.
- **Сохранить визит → C21** (exit, actor=client). Никакой отмены до подтверждения.

### C25 · Визит отменён

Роль: client · Слой: back · Фаза: До визита · contract

Фронт: Статус отмены и отдельно ход возврата.

Бэкенд: Cancel booking, release resource, outbox waitlist, cancel reminders; refund pending не объявлять refunded.

API: CMD-CANCEL · Политики: общие инварианты

- **Вернуть предоплату → P16** (async, actor=system). Есть entitlement на refund и captured amount; cash/club отдельные ledger.
- **Выбрать другой день → C40** (happy, actor=system). Отмена confirmed, возврат может продолжаться независимо.
- **Предложить освободившееся окно → C13** (async, actor=system). Waitlist event; получатель другой клиент, права не передаются.

### C26 · Клиент заболел

Роль: client · Слой: front · Фаза: До визита · contract

Фронт: Быстро перенести/отменить; пожелать восстановления, не требовать медицинских данных.

Бэкенд: Reason category optional, empathetic exception policy review; не начислять автоматический штраф.

API: CMD-LATE · Политики: POL-05

- **Выздороветь и перенести → C22** (recovery, actor=client). Показать доступные даты и условия.
- **Отменить визит → C24** (recovery, actor=client). Причина optional, empathetic exception policy.

### C27 · Клиент опаздывает

Роль: client · Слой: front · Фаза: Визит · contract

Фронт: Сообщить примерное прибытие, увидеть варианты.

Бэкенд: Сравнить remaining service+buffer с next boundary; мастер/владелец подтверждает возможный scope.

API: CMD-LATE · Политики: POL-06

- **Мастер может принять → B12** (handoff, actor=client, межролевая передача). Длительности хватает; scope и цена согласованы обеими сторонами.
- **Не успеваем — перенести → C22** (recovery, actor=client). Старое окно освобождается только по accepted move/cancel.
- **Не успеваем — отменить → C24** (recovery, actor=client). Показать cancellation quote; никаких silent charges.

### C28 · Клиент не пришёл

Роль: client · Слой: back · Фаза: Визит · contract

Фронт: Показать пропущенный визит и путь к человеку, без обвинительного текста.

Бэкенд: После grace и проверки check-in открыть no-show case; не списывать карту по одному таймеру.

API: CMD-NOSHOW · Политики: POL-05

- **Объяснить обстоятельства → C43** (recovery, actor=system). Human review, штраф не автоматический, можно оспорить no-show.
- **Записаться заново → C40** (recovery, actor=system). Только после разрешения ограничений по опубликованной политике, новые условия видимы.

### C29 · Прибыть в филиал

Роль: client · Слой: front · Фаза: Визит · contract

Фронт: Показать визит, сообщить о прибытии; QR не обязателен.

Бэкенд: Проверить location/booking status, check-in сотрудником; геолокация не является доказательством услуги.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Отметить прибытие → B11** (happy, actor=client, межролевая передача). Проверить актуальное состояние, полномочия и версию объекта.
- **Пришёл раньше → C30** (happy, actor=client). Без требования немедленного обслуживания.
- **Другой филиал / адрес → C31** (exception, actor=client). Проверить назначенный branch.

### C30 · Прийти раньше

Роль: client · Слой: front · Фаза: Визит · contract

Фронт: Показать ожидание или согласованное раннее начало.

Бэкенд: Не занимать чужой интервал; early start только если ресурсы свободны и мастер согласен.

API: CMD-LATE · Политики: общие инварианты

- **Мастер готов раньше → B11** (handoff, actor=client, межролевая передача). Ресурсы свободны, согласие обеих сторон.
- **Подождать назначенного времени → C21** (happy, actor=client). Booking time не изменяется.

### C31 · Прийти не туда

Роль: client · Слой: front · Фаза: Визит · contract

Фронт: Показать правильный адрес и связаться с филиалом.

Бэкенд: Новый branch требует согласования ресурсов/цены; не подтверждать по GPS автоматически.

API: CMD-LATE · Политики: общие инварианты

- **Уточнить маршрут → G08** (recovery, actor=client, межролевая передача). Публичный адрес нужного филиала.
- **Сообщить задержку → C27** (recovery, actor=client). Связаться с назначенным филиалом.

### C32 · Получить услугу

Роль: client · Слой: front · Фаза: Визит · contract

Фронт: Видеть согласованный состав и возможность задать вопрос.

Бэкенд: in_service authoritative; аппликация может быть закрыта, состояние живёт на сервере.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Показать результат → B16** (happy, actor=client, межролевая передача). Проверить актуальное состояние, полномочия и версию объекта.

### C33 · Попросить изменить результат

Роль: client · Слой: front · Фаза: Результат и расчёт · contract

Фронт: Описать несовпадение; исправить сейчас или открыть обращение.

Бэкенд: Согласованный scope corrective work, availability и стоимость; не подменять первоначальный паспорт.

API: CMD-SCOPE · Политики: общие инварианты

- **Согласовать исправление → B12** (recovery, actor=client, межролевая передача). Новый scope, ресурсы и время; исходная версия результата сохранена.
- **Обратиться после визита → C36** (recovery, actor=client). Case доступен и без положительного отзыва.

### C34 · Завершить визит

Роль: client · Слой: front · Фаза: Результат и расчёт · contract

Фронт: Результат, остаток к оплате, чек и паспорт отдельно.

Бэкенд: service_completed и payment_settled — разные условия; closed только при разрешённых исключениях/передаче долга.

API: CMD-VISIT-CLOSE · Политики: общие инварианты

- **Закрыть визит в учёте → S07** (happy, actor=client). Услуга завершена, remaining balance=0 или явный audited receivable; чек/возврат имеют отдельные состояния.
- **Оплатить остаток на месте → P14** (happy, actor=client). Payment_due > 0, разрешённый метод.
- **Оплатить остаток онлайн → P00** (happy, actor=client). Новая payment intent только на remaining balance.
- **Открыть спор → C36** (exception, actor=client). Service completion не блокирует complaint.

### C35 · Оставить отзыв

Роль: client · Слой: front · Фаза: После визита · contract

Фронт: Честный отзыв, приватный feedback или пропуск.

Бэкенд: Один отзыв на завершённый визит с редакциями; moderation ≠ скрытие негатива; без требования положительного рейтинга.

API: CMD-REVIEW · Политики: POL-15

- **Сказать спасибо → C37** (happy, actor=client). Любой выбор рейтинга либо пропуск.
- **Рассказать о проблеме → C36** (exception, actor=client). Негатив не прячется за обращением.
- **Пропустить отзыв → C38** (exit, actor=client). Доступ к паспорту не зависит от рейтинга.

### C36 · Подать претензию

Роль: client · Слой: front · Фаза: После визита · contract

Фронт: Текст, доступные фото по желанию и ожидаемый результат.

Бэкенд: Case ID, срок ответа, escalation; не требовать публикации фото и не блокировать возврат за отзыв.

API: CMD-REVIEW · Политики: общие инварианты

- **Передать владельцу → O20** (handoff, actor=client, межролевая передача). Case SLA, доступ к согласованным материалам.

### C37 · Поблагодарить барбера

Роль: client · Слой: front · Фаза: После визита · contract

Фронт: Спасибо, чаевые по желанию, поделиться ссылкой.

Бэкенд: Чаевые отдельная операция/ledger при включённом канале; отказ не меняет качество обслуживания.

API: CMD-PAY, CMD-REVIEW · Политики: POL-15

- **Открыть результат → C38** (happy, actor=client). Чаевые не обязательны.
- **Оставить чаевые → P00** (happy, actor=client). Tip feature enabled, отдельный purpose/recipient и сумма; не invoice balance.

### C38 · Открыть Cut Passport

Роль: client · Слой: front · Фаза: После визита · contract

Фронт: Параметры и разрешённые до/после; исправление заметок.

Бэкенд: Immutable revisions и ownership; revoked media скрываются, технические параметры можно хранить отдельно.

API: CMD-PASSPORT-READ · Политики: общие инварианты

- **Выбрать следующий образ → C39** (happy, actor=client). Проверить актуальное состояние, полномочия и версию объекта.
- **Разрешить публикацию работы → R01** (happy, actor=client). Preview конкретных фото; private passport отдельно.
- **Посмотреть клуб → L00** (happy, actor=client). Не блокировать паспорт предложением клуба.
- **Рекомендовать другу → L10** (happy, actor=client). Добровольная ссылка, без автоматической отправки.

### C39 · Выбрать следующий образ

Роль: client · Слой: front · Фаза: Повтор · contract

Фронт: Повторить точно или изменить детали с барбером.

Бэкенд: Новый draft из версии паспорта; новый quote, без фонового списания.

API: CMD-PASSPORT-READ · Политики: общие инварианты

- **Записаться снова → C40** (happy, actor=client). Проверить актуальное состояние, полномочия и версию объекта.
- **Изменить образ → C01** (happy, actor=client). Новый draft, не менять прошлый passport.
- **Пока не записываться → C41** (exit, actor=client). Остановить recommendation cadence по выбору, без давления.

### C40 · Записаться снова

Роль: client · Слой: front · Фаза: Повтор · contract

Фронт: Предложить подходящий интервал, дату выбирает человек.

Бэкенд: New booking intent, связи previousVisitId/cohort; никакого авто-бронирования из напоминания.

API: CMD-PASSPORT-READ · Политики: общие инварианты

- **Повторить прошлый образ → C05** (happy, actor=client). Проверить актуальное состояние, полномочия и версию объекта.
- **Найти новое окно → C04** (happy, actor=client). Новый quote/hold, не auto-book.

### C41 · Взять паузу

Роль: client · Слой: front · Фаза: Повтор · contract

Фронт: Отложить уход за формой: поездка, болезнь, смена планов.

Бэкенд: Pause recommendation jobs до выбранной даты; сервисные сообщения о реальных обязательствах остаются отдельно.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Вернуться когда удобно → C00** (recovery, actor=client). Сохранённые права и история согласно consent.

### C42 · Настроить уведомления

Роль: client · Слой: front · Фаза: Управление · contract

Фронт: Каналы, время, сервисные события и маркетинг раздельно.

Бэкенд: Consent ledger + permission state; revoke действует на pending jobs, inbox сохраняет статус визита.

API: CMD-CONSENT, CMD-REMINDER · Политики: POL-07

- **Отключить маркетинг → N07** (happy, actor=client). Отзыв действует немедленно для новых/pending кампаний.
- **Изменить сервисный канал → N01** (happy, actor=client). Показать ограничения доставки и inbox fallback.

### C43 · Помощь человеку

Роль: client · Слой: front · Фаза: Управление · contract

Фронт: Открыть обращение, контакт филиала и номер операции.

Бэкенд: Support case без раскрытия чужой PII; SLA и escalation, разрешение требует audit.

API: CMD-CASE · Политики: POL-13

- **Создать обращение → S05** (async, actor=client, межролевая передача). Case сохранён с SLA и owner; система не обещает мгновенный ответ.

### C44 · Особые пожелания

Роль: client · Слой: front · Фаза: До визита · contract

Фронт: Тишина, доступность, сопровождающий, аллергия по желанию.

Бэкенд: Минимизация чувствительных данных, ограниченный срок и scope; подтвердить доступность услуги у филиала.

API: CMD-PROFILE · Политики: общие инварианты

- **Сохранить пожелания → C17** (happy, actor=client). Реальная доступность услуги подтверждается сотрудником.

### C45 · Записать другого человека

Роль: client · Слой: front · Фаза: Запись и оплата · contract

Фронт: Разделить плательщика и получателя, пригласить получателя.

Бэкенд: Recipient consent/age policy; не открывать паспорт другого человека плательщику. Подтверждение получателя до private data.

API: CMD-PROFILE · Политики: POL-12

- **Передать приглашение получателю → G10** (handoff, actor=client, межролевая передача). Отдельный recipient consent; minor policy обязательна до активации.

### P00 · Выбрать оплату

Роль: client · Слой: front · Фаза: Запись и оплата · contract

Фронт: Новая/сохранённая карта, доступный клубный зачёт или на месте.

Бэкенд: Allowed methods по merchant/policy/amount; payer и recipient раздельны; сумма только из quote.

API: см. серверный контракт состояния · Политики: POL-03

- **Ввести карту у провайдера → P01** (happy, actor=client). Проверить актуальное состояние, полномочия и версию объекта.
- **Хочу сохранить карту → P02** (happy, actor=client). Необязательное отдельное согласие, не предвыбранное.
- **Выбрать сохранённую карту → P04** (happy, actor=client). Active token belongs to payer.
- **Выбрать оплату на месте → P14** (happy, actor=client). Политика допускает payment_due booking; нулевая предоплата не online paid.
- **Применить клубный баланс услуг → P24** (happy, actor=client). Entitlement active and eligible; не денежный кошелёк.

### P01 · Ввести карту у провайдера

Роль: client · Слой: front · Фаза: Запись и оплата · contract

Фронт: Открыть защищённую форму ЮKassa.

Бэкенд: PAN/CVV не проходят через PRIME, не логируются; клиент получает confirmation flow, secret остаётся на сервере.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Создать платёж → P06** (happy, actor=client). Проверить актуальное состояние, полномочия и версию объекта.

### P02 · Разрешить сохранение карты

Роль: client · Слой: front · Фаза: Запись и оплата · contract

Фронт: Отдельный необязательный выбор и понятная цель.

Бэкенд: Сохранить consent version, только тогда save_payment_method=true; не равняется согласию на автоплатёж.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Перейти в платёжную форму → P01** (happy, actor=client). Consent recorded, save_payment_method flag.

### P03 · Сохранённый способ оплаты

Роль: client · Слой: back · Фаза: Результат и расчёт · contract

Фронт: Бренд и последние цифры; не обещать сохранение до ответа.

Бэкенд: Только при payment_method.saved=true сохранить provider ID, owner, masked metadata. CVV/PAN не хранить.

API: CMD-METHODS · Политики: общие инварианты

- **Продолжить визит → C12** (happy, actor=system). Booking уже confirmed; иначе C10/S00 сначала. Payment method activation не создаёт booking.
- **Удалить сохранённый способ → P05** (happy, actor=system). Reauth, active mandates показаны отдельно.

### P04 · Использовать сохранённую карту

Роль: client · Слой: front · Фаза: Запись и оплата · contract

Фронт: Выбрать свою карту и подтвердить конкретную сумму.

Бэкенд: Ownership token + explicit current payment intent; возможен новый challenge, declined token не означает потерю booking.

API: CMD-METHODS · Политики: общие инварианты

- **Подтвердить сумму → P06** (happy, actor=client). One explicit intent, quote и method owner проверены.

### P05 · Отвязать карту

Роль: client · Слой: back · Фаза: Управление · contract

Фронт: Показать, что будущие списания отключены; объяснить активные обязательства.

Бэкенд: Revoke local authorization, cancel renewal jobs; unlink не отменяет прошлый payment/refund. Действия provider по поддерживаемому API отдельно.

API: CMD-UNLINK-CARD · Политики: общие инварианты

- **Способ отключён → R00** (happy, actor=system). Future local charges blocked; past refund still traceable.

### P06 · Создать платёж

Роль: client · Слой: back · Фаза: Запись и оплата · contract

Фронт: Показать pending и ссылку провайдера.

Бэкенд: POST payment с persisted operationId/idempotence key и quote; purpose booking/deposit/club/tip раздельный, серверная сумма.

API: CMD-PAY · Политики: POL-11

- **Подтвердить в банке → P07** (happy, actor=system). Проверить актуальное состояние, полномочия и версию объекта.
- **Ответ create потерян → P12** (exception, actor=system). Persisted operation key, нельзя создавать новый платёж наугад.
- **Провайдер отказал → P11** (exception, actor=system). Только authoritative canceled/validation rejection без accepted charge.

### P07 · Подтвердить в банке

Роль: client · Слой: front · Фаза: Запись и оплата · contract

Фронт: 3DS/redirect, можно вернуться или отказаться.

Бэкенд: Return URL — только навигация; не источник succeeded. State связан с payment intent.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Ожидать статус оплаты → P08** (happy, actor=client). Проверить актуальное состояние, полномочия и версию объекта.
- **Закрыть приложение после банка → P12** (exception, actor=client). Возврат в приложение не требуется для server reconciliation.
- **Отказаться в форме банка → P11** (exception, actor=client). Проверить provider status, пока pending — идти в reconcile.

### P08 · Ожидать статус оплаты

Роль: client · Слой: back · Фаза: Запись и оплата · contract

Фронт: Ожидание, номер операции и безопасный выход из приложения.

Бэкенд: Webhook inbox + authenticated GET verify object/shop/amount/currency; dedupe; stale notification не понижает состояние.

API: CMD-WEBHOOK · Политики: общие инварианты

- **Платёж успешен → P10** (happy, actor=system). Проверить актуальное состояние, полномочия и версию объекта.
- **Банк авторизовал средства → P09** (async, actor=system). waiting_for_capture verified, expires_at сохранён.
- **Webhook не пришёл → P12** (exception, actor=system). Bounded polling/reconciliation, не optimistic paid.
- **Получен canceled → P11** (async, actor=system). Authentic GET status, сумма и merchant совпадают.

### P09 · Средства авторизованы

Роль: client · Слой: back · Фаза: Запись и оплата · contract

Фронт: Различать блокировку и окончательное списание.

Бэкенд: waiting_for_capture; expires_at провайдера, capture/cancel только при согласованном основании. Не держать авторизацию до далёкого визита.

API: CMD-PAYMENT-CAPTURE · Политики: общие инварианты

- **Подтвердить списание → P10** (async, actor=system). Ресурс гарантирован и policy intent допускает capture; provider succeeded verified.
- **Отменить авторизацию → P11** (recovery, actor=system). Booking не может состояться либо user cancel; cancel verified, не refund succeeded payment.

### P10 · Платёж успешен

Роль: client · Слой: back · Фаза: Результат и расчёт · contract

Фронт: Показать успешную операцию, затем проверенный статус заказа.

Бэкенд: succeeded immutable; ledger once, booking saga/club/tip continuation по purpose, outbox receipt.

API: CMD-PAYMENT-CAPTURE · Политики: общие инварианты

- **Подтвердить запись → C10** (happy, actor=system). purpose=booking/deposit, quote accepted; payment succeeded не означает confirmed booking до S00.
- **Сохранение карты подтверждено → P03** (async, actor=system). Только payment_method.saved=true и предшествующий consent.
- **Сформировать чек оплаты → P20** (async, actor=system). Provider succeeded, fiscalization scheme учитывает предоплату.
- **Удержание слота истекло → P25** (exception, actor=system, межролевая передача). Booking не committed, средства реально captured.
- **Активировать покупку клуба → L02** (async, actor=system). purpose=club, unique entitlement grant per payment.
- **Учесть чаевые → C37** (async, actor=system). purpose=tip, отдельный ledger; не повторять booking creation.

### P11 · Платёж отклонён / отменён

Роль: client · Слой: front · Фаза: Запись и оплата · contract

Фронт: Причина без обвинения; другой метод, повтор новым намерением или выход.

Бэкенд: canceled final; release obsolete hold, новый payment только после проверки старого. Дубликат callback не создаёт новый.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Попробовать другой метод → P00** (recovery, actor=client). Старый платёж terminal, новая явная intent и свежая quote.
- **Закончить попытку → C16** (exit, actor=client). Нет неразрешённого pending payment.

### P12 · Оплата неизвестна

Роль: client · Слой: front · Фаза: Запись и оплата · contract

Фронт: Сверяем, не платите второй раз; можно оставить обращение.

Бэкенд: Сетевой timeout не равен отказу; persist operation, reconcile before retry, ключ ЮKassa имеет ограниченный срок.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Начать сверку → P13** (recovery, actor=client). GET/local operation first, сохранённый idempotency key.

### P13 · Сверить платёж

Роль: client · Слой: back · Фаза: Запись и оплата · contract

Фронт: Обновить результат из сервера.

Бэкенд: GET provider + local operation/ledger, compare order amount; after idempotency window не повторять create вслепую.

API: CMD-RECONCILE · Политики: общие инварианты

- **Подтверждено succeeded → P10** (recovery, actor=system). Merchant, amount, currency, purpose и ledger проверены.
- **Подтверждено canceled → P11** (recovery, actor=system). Provider final state.
- **Статус не разрешился → S05** (exception, actor=system, межролевая передача). Retry budget исчерпан; durable case с ответственным, никаких повторных charges.

### P14 · Оплатить на месте

Роль: client · Слой: front · Фаза: Результат и расчёт · contract

Фронт: Показать остаток к оплате: наличные или терминал.

Бэкенд: Booking can be confirmed as payment_due по политике; cashier confirms amount and method, без фиктивного YooKassa payment.

API: CMD-CASH · Политики: общие инварианты

- **Подтвердить запись с оплатой позже → C10** (happy, actor=client). Service ещё не оказана; policy permits pay-on-site.
- **Принять оплату после услуги → P15** (handoff, actor=client, межролевая передача). Service complete, сотрудник имеет cashier capability, сумма реальна.

### P15 · Подтвердить оплату на месте

Роль: barber · Слой: back · Фаза: Результат и расчёт · contract

Фронт: Уполномоченный сотрудник подтверждает приём и чек.

Бэкенд: Separate cashier capability; audit, unique settlement, external terminal reference; если нет права — владелец.

API: CMD-CASH · Политики: общие инварианты

- **Выдать кассовый чек → P20** (async, actor=system, межролевая передача). Метод и сумма подтверждены, нет дублирования settlement.

### P16 · Запросить возврат

Роль: client · Слой: front · Фаза: После визита · contract

Фронт: Сумма, основание и статус рассмотрения.

Бэкенд: Refund entitlement/order version; сумма ≤ captured − successful/pending refunds. Не объявлять деньги возвращёнными при создании.

API: CMD-REFUND-QUOTE · Политики: общие инварианты

- **Создать согласованный возврат → P17** (happy, actor=client). Authorised entitlement; amount bounded including pending refunds, idempotency key.
- **Условия требуют рассмотрения → O20** (exception, actor=client, межролевая передача). Не выдавать автоматическое решение при споре.

### P17 · Возврат выполняется

Роль: client · Слой: back · Фаза: После визита · contract

Фронт: Показать pending и идентификатор, без обещанного срока банка.

Бэкенд: Idempotent refund object; webhook/GET reconciliation, cash возврат через отдельный audited процесс.

API: CMD-REFUND · Политики: общие инварианты

- **Провайдер подтвердил возврат → P18** (async, actor=system). Refund succeeded verified, ledger once.
- **Возврат не разрешён вовремя → P19** (exception, actor=system, межролевая передача). Unknown остаётся unknown; финальный canceled отличается от timeout.

### P18 · Возврат завершён

Роль: client · Слой: back · Фаза: После визита · contract

Фронт: Обновить статус возврата и чек.

Бэкенд: Refund succeeded → ledger once, сумма заказа/клуб/начисление мастера корректируются связанными записями.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Чек возврата → P20** (async, actor=system). Связать исходный receipt и сумму, исключить дубли.
- **Вернуться к записи → C40** (happy, actor=system). Возврат отражён, новый визит доброволен.

### P19 · Возврат требует внимания

Роль: owner · Слой: front · Фаза: После визита · contract

Фронт: Повторить сверку/передать финансовому ответственному.

Бэкенд: Timeout не считать failed; terminal canceled допускает исправленную новую операцию, SLA escalation и audit.

API: CMD-RECONCILE · Политики: POL-13

- **Исправить и повторить безопасно → P17** (recovery, actor=owner, межролевая передача). Сначала сверка предыдущего refund; новый intent только после terminal canceled.
- **Передать финансовому ответственному → S05** (handoff, actor=owner). SLA и evidence, обязательство не закрыто.

### P20 · Выдать чек

Роль: client · Слой: back · Фаза: Результат и расчёт · contract

Фронт: Показать чек или состояние его подготовки.

Бэкенд: Фискализация по выбранной схеме, отдельные события предоплаты/зачёта/возврата; accounting mapping утверждается до live.

API: CMD-RECEIPT · Политики: POL-11

- **Фискализация задержалась → P21** (exception, actor=system, межролевая передача). Payment succeeded не меняется; receipt_pending отдельное состояние.
- **Учесть готовый чек → S07** (happy, actor=system). Услуга завершена и remaining balance разрешён; чек предоплаты сам по себе не закрывает будущий визит.

### P21 · Чек ещё не готов

Роль: owner · Слой: front · Фаза: Результат и расчёт · contract

Фронт: Деньги уже учтены; показать очередь исправления.

Бэкенд: Receipt retry bounded + reconciliation; не списывать повторно и не менять succeeded на failed.

API: CMD-RECONCILE, CMD-RECEIPT · Политики: POL-11

- **Повторить выдачу чека → P20** (recovery, actor=owner, межролевая передача). Idempotent receipt request, retry budget.
- **Нужна ручная коррекция → S05** (handoff, actor=owner). Responsible finance owner, статус денег не переписывается.

### P22 · Спор по списанию

Роль: owner · Слой: front · Фаза: После визита · contract

Фронт: Показать факты и маршрут финансового разбирательства.

Бэкенд: Dispute/chargeback отдельно от обычного refund; заморозить спорное начисление, audit evidence, human review.

API: CMD-CASE-RESOLVE · Политики: общие инварианты

- **Исследовать обстоятельства → O20** (recovery, actor=owner). Refund и dispute координируются, исключить двойную компенсацию.

### P23 · Доплата / частичный возврат

Роль: client · Слой: front · Фаза: Результат и расчёт · contract

Фронт: Показать согласованную разницу за изменённую услугу.

Бэкенд: Новая price revision, explicit consent; остаток pay/refund saga. Нельзя незаметно увеличить исходный charge.

API: CMD-SCOPE · Политики: общие инварианты

- **Оплатить согласованную разницу → P06** (happy, actor=client). delta > 0 и новый explicit consent, purpose=adjustment.
- **Вернуть разницу → P16** (happy, actor=client). delta < 0, captured/refund bounds.
- **Оставить исходный состав → C32** (exit, actor=client). Нет нового согласия; никакого увеличения суммы.

### P24 · Зачесть клубный визит

Роль: client · Слой: back · Фаза: Запись и оплата · contract

Фронт: Показать списываемую привилегию и остаток к доплате.

Бэкенд: Reserve entitlement атомарно; commit при политике оказания услуги, release при отмене; не считать клуб фиктивным cash wallet.

API: CMD-ENTITLEMENT · Политики: POL-09

- **Привилегии достаточно → C10** (happy, actor=system). Reserved entitlement; booking commit сохраняет reservation, consumption только по policy.
- **Осталась доплата → P06** (happy, actor=system). Amount равен непокрытому остатку, entitlement reservation связан с order.

### P25 · Деньги пришли после потери слота

Роль: owner · Слой: back · Фаза: Запись и оплата · contract

Фронт: Объяснить ситуацию, предложить согласованное окно или возврат.

Бэкенд: Paid-unallocated saga; никогда не double-book. Refund обязательной компенсацией при невозможности подтвердить услугу.

API: CMD-RECONCILE · Политики: POL-04

- **Найти согласованную альтернативу → O16** (recovery, actor=system). Никогда не занимать чужое время, согласие клиента на новый вариант.
- **Компенсировать потерю слота → P16** (recovery, actor=system, межролевая передача). Captured деньги + нет подтверждённой услуги → refund entitlement.

### N00 · Запланировать напоминания

Роль: client · Слой: back · Фаза: До визита · contract

Фронт: Показать выбранные каналы и локальное время.

Бэкенд: Outbox по booking version; job id=booking/type/version/channel, server timezone, отмена при переносе.

API: CMD-NOTIFICATION · Политики: POL-07

- **Разрешить канал → N01** (happy, actor=system). Проверить актуальное состояние, полномочия и версию объекта.
- **Канал уже разрешён → N02** (async, actor=system). Consent и token active, deadline/version актуальны.

### N01 · Разрешить канал

Роль: client · Слой: front · Фаза: До визита · contract

Фронт: Push permission в контексте пользы; отказ оставляет inbox.

Бэкенд: OS permission отдельно от channel consent; device tokens и messenger bot-access не равны promo consent.

API: CMD-REMINDER · Политики: общие инварианты

- **Доставить уведомление → N02** (happy, actor=client). Проверить актуальное состояние, полномочия и версию объекта.
- **Не разрешать push → N03** (exit, actor=client). Без скрытого fallback; inbox остаётся доступен.

### N02 · Доставить уведомление

Роль: client · Слой: back · Фаза: До визита · contract

Фронт: Короткое сообщение без чувствительных деталей на lock screen.

Бэкенд: Channel adapter с retries/backoff, consent recheck, validity window; accepted provider ≠ seen человеком.

API: CMD-NOTIFICATION · Политики: POL-07

- **Прочитать напоминание → N04** (happy, actor=system). Проверить актуальное состояние, полномочия и версию объекта.
- **Канал не доставил → N03** (exception, actor=system). Provider rejection/token invalid/TTL; не трактовать как отказ клиента.
- **Человек не прочитал → N05** (exception, actor=system). Доставка не равна прочтению и не даёт основания штрафовать.

### N03 · Не доставлено

Роль: client · Слой: back · Фаза: До визита · contract

Фронт: Показать актуальное событие внутри приложения.

Бэкенд: Недействительный token удалить, fallback только при согласии; не спамить всеми каналами.

API: CMD-NOTIFICATION · Политики: POL-07

- **Попробовать согласованный канал → N08** (recovery, actor=system). Есть отдельный consent и verified contact; cross-channel dedupe.
- **Посмотреть внутри приложения → C21** (recovery, actor=system). In-app current status доступен независимо от push.

### N04 · Прочитать напоминание

Роль: client · Слой: front · Фаза: До визита · contract

Фронт: Открыть текущий визит, маршрут или перенос.

Бэкенд: Deep link перепроверяет auth/ownership/revision; read receipt не является согласием на услугу.

API: CMD-REMINDER · Политики: общие инварианты

- **Управлять визитом → C21** (happy, actor=client). Проверить актуальное состояние, полномочия и версию объекта.
- **Напомнить позже → N06** (happy, actor=client). До начала визита, snooze budget.
- **Открыть старую ссылку → N09** (exception, actor=client). Version stale/canceled, не показывать старое подтверждение.

### N05 · Забыть или пропустить

Роль: client · Слой: back · Фаза: Визит · contract

Фронт: Оставить возможность восстановиться, связаться и перенести.

Бэкенд: Нет прочтения ≠ no-show; только реальный start/grace/check-in может открыть missed case.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Время прошло, клиента нет → C28** (async, actor=system). start + grace, staff проверил check-in/контакт; не по отсутствию read receipt.
- **Клиент вспомнил и опаздывает → C27** (recovery, actor=system). Можно сообщить ETA и согласовать решение.

### N06 · Напомнить позже

Роль: client · Слой: front · Фаза: До визита · contract

Фронт: Выбрать один перенос напоминания.

Бэкенд: Snooze с max count/deadline, не после начала услуги; не меняет booking time.

API: CMD-REMINDER · Политики: общие инварианты

- **Поставить одно напоминание → N00** (async, actor=client). Новый job с тем же смыслом, supersede предыдущий.

### N07 · Отключить рассылку

Роль: client · Слой: back · Фаза: Управление · contract

Фронт: Сразу подтвердить отказ от маркетинга.

Бэкенд: Revoke channel consent и pending campaign jobs; важные обязательства доступны в inbox, без обхода отказа.

API: CMD-REMINDER · Политики: общие инварианты

- **Сохранить настройки → R00** (happy, actor=system). Не обходить отказ другим каналом.

### N08 · Разрешённый запасной канал

Роль: client · Слой: back · Фаза: До визита · contract

Фронт: Одна понятная попытка уведомления.

Бэкенд: Проверить подтверждённый адрес/контакт, consent и dedupe across channels; затем задача человеку при критичности.

API: CMD-NOTIFICATION · Политики: POL-07

- **Открыть сообщение → N04** (happy, actor=system). Auth и актуальность ссылки проверяются.
- **Связаться вручную при критичном изменении → S05** (handoff, actor=system, межролевая передача). Нет успешной доставки; owner task с допустимым контактом.

### N09 · Ссылка устарела

Роль: client · Слой: front · Фаза: До визита · contract

Фронт: Показать новое время/отмену и актуальные действия.

Бэкенд: Не воскрешать canceled booking по старой ссылке; no private content до auth.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Перейти к актуальному визиту → C21** (recovery, actor=client). Current booking accessible and owned.

### L00 · Посмотреть PRIME CLUB

Роль: client · Слой: front · Фаза: После визита · contract

Фронт: Понятные привилегии, стоимость, срок, пауза и отмена.

Бэкенд: Только published ClubPlanVersion; примеры маркетолога не являются утверждёнными тарифами.

API: см. серверный контракт состояния · Политики: POL-09

- **Выбрать план → L01** (happy, actor=client). Есть утверждённые terms/price/renewal/cancellation, иначе блокировать purchase.
- **Не вступать → C00** (exit, actor=client). Обычная запись доступна.

### L01 · Принять условия клуба

Роль: client · Слой: front · Фаза: После визита · contract

Фронт: Выбрать разовую покупку или явно разрешённое продление.

Бэкенд: Plan/consent snapshot; recurrence отдельный mandate с amount/cadence/change notice.

API: CMD-CLUB · Политики: POL-09

- **Оплатить клуб → P00** (happy, actor=client). purpose=club, planVersion, явный purchase consent; автопродление отдельное.

### L02 · Членство активно

Роль: client · Слой: back · Фаза: После визита · contract

Фронт: Показать период и доступные услуги/привилегии.

Бэкенд: Только settled purchase → immutable entitlement ledger; duplicate webhook не удваивает баланс.

API: см. серверный контракт состояния · Политики: POL-09

- **Использовать доступную услугу → L03** (happy, actor=system). Current period and eligibility.
- **Наступил срок продления → L04** (async, actor=system). Active recurrence mandate/token, notice delivered according to approved policy.
- **Пауза / отмена → L06** (happy, actor=system). Owner of membership, видимая дата прекращения.
- **Подарить гостевой визит → L08** (happy, actor=system). Правила плана допускают transferable entitlement.

### L03 · Применить привилегию

Роль: client · Слой: front · Фаза: Запись и оплата · contract

Фронт: Выбрать подходящий визит и увидеть остаток.

Бэкенд: Eligibility service/branch/period; concurrent redeem защищён unique reservation.

API: CMD-ENTITLEMENT · Политики: POL-09

- **Собрать клубный визит → C03** (happy, actor=client). Quote покажет entitlement и любую доплату.

### L04 · Продлить членство

Роль: client · Слой: back · Фаза: Повтор · contract

Фронт: Предупредить о новом периоде и сумме; можно отказаться.

Бэкенд: Scheduler only with active mandate/token; одна operation на период, не скрывать изменение цены.

API: CMD-MEMBERSHIP, CMD-RENEWAL · Политики: POL-09

- **Создать платёж за период → P06** (async, actor=system). Один ключ на membership+period, amount disclosed, mandate active.
- **Нет действующего способа / отказ → L05** (exception, actor=system). Не списывать новым token без consent, retry bounded.

### L05 · Продление не прошло

Роль: client · Слой: front · Фаза: Повтор · contract

Фронт: Обновить способ оплаты, оплатить вручную или завершить членство.

Бэкенд: Limited retry policy and grace draft; не накапливать бесконечные списания/долги.

API: CMD-RENEWAL · Политики: POL-09

- **Продлить вручную → P00** (recovery, actor=client). Explicit intent; сверить предыдущий renewal payment first.
- **Не продлевать → L07** (exit, actor=client). Показать срок оставшихся benefits и будущих booking.

### L06 · Пауза или отмена клуба

Роль: client · Слой: front · Фаза: Повтор · contract

Фронт: Показать дату прекращения, остаток и судьбу будущих записей.

Бэкенд: Cancel renewal atomically; refund/unused entitlement по утверждённым правилам, визиты не исчезают.

API: CMD-MEMBERSHIP · Политики: POL-09

- **Период закончился → L07** (async, actor=client). Mandate cancelled; старые финансовые обязательства не исчезают.
- **Вернуть неиспользованную часть → P16** (happy, actor=client). Только утверждённые terms и entitlement; сумма расчёта прозрачна.

### L07 · Период завершён

Роль: client · Слой: back · Фаза: Повтор · contract

Фронт: Показать обычные условия, доступ к истории сохраняется.

Бэкенд: Expire benefits, release invalid reserves with explicit customer resolution; паспорт не заложник членства.

API: CMD-RENEWAL · Политики: POL-09

- **Продолжить без клуба → C00** (happy, actor=system). История и паспорт сохраняются по consent.

### L08 · Подарить гостевой визит

Роль: client · Слой: front · Фаза: После визита · contract

Фронт: Выбрать доступную привилегию и ссылку без чужих данных.

Бэкенд: Reserve GuestPass, expiry, one-use claim; recipient identity independent from payer.

API: CMD-GUEST-PASS · Политики: POL-09

- **Получатель открывает ссылку → G10** (handoff, actor=client, межролевая передача). Claim token без PII дарителя, пользователь сам делится ссылкой.

### L09 · Принять гостевой визит

Роль: client · Слой: back · Фаза: Запись и оплата · contract

Фронт: Подтвердить условия, выбрать услуги и время.

Бэкенд: Claim once после auth и consent, entitlement получателю; запрет self-abuse по опубликованной политике.

API: CMD-GUEST-CLAIM · Политики: POL-09, POL-12

- **Выбрать гостевой визит → C03** (happy, actor=system). После успешного одноразового claim; услуги и срок ограничены terms.

### L10 · Пригласить друга

Роль: client · Слой: front · Фаза: Повтор · contract

Фронт: Добровольно поделиться ссылкой, без импорта адресной книги.

Бэкенд: Referral code attribution; не отправлять сообщение за человека; никаких скрытых reward promises.

API: CMD-REFERRAL · Политики: POL-15

- **Друг перешёл по ссылке → G11** (handoff, actor=client, межролевая передача). Attribution не авторизация, не раскрывает данные пригласившего.

### L11 · Учесть рекомендацию

Роль: client · Слой: back · Фаза: Повтор · contract

Фронт: Прозрачно показать результат после выполненного условия.

Бэкенд: Reward after eligible completed settled visit, one per rule, fraud review и reversal ledger при refund.

API: CMD-REFERRAL · Политики: POL-15

- **Показать начисление привилегии → C00** (happy, actor=system). Terms опубликованы; не выдумывать cash reward.

### R00 · Приватность и аккаунт

Роль: client · Слой: front · Фаза: Управление · contract

Фронт: Фото, каналы, связанные входы, карты, выгрузка и удаление.

Бэкенд: Capabilities per owner of data; отдельные consent records, activity/audit view.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Добавить способ входа → A08** (happy, actor=client). Reauth текущей сессии.
- **Отключить сохранённую карту → P05** (happy, actor=client). Проверить active mandates и pending operations.
- **Отозвать фотографии → R02** (happy, actor=client). Own media; финансовые документы не удалять через media API.
- **Запросить выгрузку → R03** (happy, actor=client). Reauth, request scope и защищённая delivery.
- **Удалить аккаунт → R04** (happy, actor=client). Reauth, показать последствия и obligations.
- **Телефон потерян → R07** (exception, actor=client). Другой trusted канал, identity verification.
- **Выйти со всех устройств → A12** (happy, actor=client). Own session, reauth для sensitive action.
- **Выбрать рабочий контекст → A11** (happy, actor=client). Только memberships, возвращённые сервером.
- **Настроить доступность → R08** (happy, actor=client). Настройки не влияют на права/цены.

### R01 · Разрешить портфолио

Роль: client · Слой: front · Фаза: После визита · contract

Фронт: Предпросмотр конкретных фото и каналов публикации.

Бэкенд: Granular revocable consent; private passport не публикуется автоматически, отказ не влияет на услугу.

API: CMD-MEDIA · Политики: POL-10

- **Опубликовать согласованный материал → C38** (happy, actor=client). Только перечисленные media/channel, действующий consent.
- **Передумать публиковать → R02** (recovery, actor=client). Отзыв consent и derivatives purge.

### R02 · Отозвать фото

Роль: client · Слой: back · Фаза: Управление · contract

Фронт: Убрать фото из приложения и портфолио; показать ход удаления.

Бэкенд: Revoke signed URLs, purge derivatives/CDN, provenance downstream; retention exceptions документируются и ограничивают доступ.

API: CMD-CONSENT · Политики: POL-10

- **Удаление медиа подтверждено → R00** (happy, actor=system). Проверен object/CDN/pending jobs status; partial failure в S05.
- **Не всё удалилось → S05** (exception, actor=system, межролевая передача). Durable purge task, limited retry, ответственный и статус клиенту.

### R03 · Выгрузить свои данные

Роль: client · Слой: back · Фаза: Управление · contract

Фронт: Подтверждение личности и готовность защищённой выгрузки.

Бэкенд: Async export с expiry, доступ только владельцу, exclude third-party private notes, audit.

API: CMD-EXPORT · Политики: общие инварианты

- **Выгрузка готова → R00** (async, actor=system). Expiring link после повторной identity check, не публичный URL.

### R04 · Удалить аккаунт

Роль: client · Слой: front · Фаза: Управление · contract

Фронт: Показать будущие визиты, возвраты и последствия.

Бэкенд: Deletion intent с reauth, revoke sessions; не терять финансовые обязательства и открытые cases.

API: CMD-DELETE · Политики: POL-01, POL-10, POL-16

- **Подтвердить удаление → R05** (happy, actor=client). Проверены step-up и отсутствие последнего owner grant. Сохранить минимальные обязательства по отдельной retention policy.
- **Отменить до исполнения → R00** (exit, actor=client). Если job ещё обратим; consumed deletion не отменять обещанием.
- **Сначала передать управление → O24** (recovery, actor=owner, межролевая передача). Текущая identity является последним владельцем; переход доступен только по уже существующему owner grant и после step-up.

### R05 · Завершить обязательства

Роль: client · Слой: back · Фаза: Управление · contract

Фронт: Отмена/перенос будущих визитов и статус возвратов.

Бэкенд: Saga cancellation/refund; сроки хранения по утверждённой матрице, минимальные финансовые записи отделены от профиля.

API: CMD-DELETE · Политики: POL-16

- **Есть незавершённый возврат → P16** (async, actor=system). Deletion не уничтожает payment mapping; limited-purpose records.
- **Завершить удаление профиля → R06** (happy, actor=system). Media erased, no active auth; unresolved finance вынесено в ограниченный case и явно сообщено.

### R06 · Профиль удалён

Роль: client · Слой: back · Фаза: Повтор · contract

Фронт: Подтвердить удаление доступных данных и явно назвать сохранённые обязательные записи.

Бэкенд: Tombstone/anonymize, no marketing, erase media jobs reconciled; повторный вход не восстанавливает старые данные автоматически.

API: см. серверный контракт состояния · Политики: общие инварианты

Явный выход; фоновые обязательства отдельно.

### R07 · Потерян телефон

Роль: client · Слой: front · Фаза: Управление · contract

Фронт: Другой вход, завершить сессии и восстановить доступ.

Бэкенд: Risk review и revoke device; PAN/CVV не используются как доказательство личности.

API: CMD-RECOVERY · Политики: общие инварианты

- **Отозвать сессии устройств → A12** (recovery, actor=client). Подтверждено владение аккаунтом.
- **Нет другого входа → A10** (recovery, actor=client). Human recovery без обхода доказательств личности.

### R08 · Доступность интерфейса

Роль: client · Слой: front · Фаза: Управление · contract

Фронт: Крупный шрифт, screen reader, тишина, reduced motion, текстовые альтернативы.

Бэкенд: Настройки не снижают право на запись; sensitive preference не уходит в общую аналитику.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Продолжить с настройками → C00** (happy, actor=client). Font scale, reader, reduced motion остаются рабочими.

### S00 · Зафиксировать запись

Роль: client · Слой: back · Фаза: Запись и оплата · contract

Фронт: Подтверждение только после commit.

Бэкенд: Atomic capacity claim/booking unique constraints; payment prerequisite зависит от policy; outbox commit с записью.

API: CMD-BOOK · Политики: общие инварианты

- **Визит подтверждён → C12** (happy, actor=system). Проверить актуальное состояние, полномочия и версию объекта.
- **Запись конфликтует → C08** (exception, actor=system). Нет successful payment; release resources/entitlement.
- **Оплачено, а слота нет → P25** (exception, actor=system, межролевая передача). Оплата подтверждена, booking commit невозможен → compensation saga.

### S01 · Проверить свободный ресурс

Роль: client · Слой: back · Фаза: Запись и оплата · contract

Фронт: Показать актуальные подходящие окна.

Бэкенд: Availability = shift ∩ skill ∩ equipment − bookings − holds − breaks; interval arithmetic, no overlap.

API: CMD-HOLD, CMD-AVAILABILITY · Политики: общие инварианты

- **Получить расчёт → C06** (happy, actor=system). Проверить актуальное состояние, полномочия и версию объекта.
- **Ресурс недоступен → C08** (exception, actor=system). Conflict authoritative, старый quote не подтверждается.

### S02 · Нет сети / приложение закрыто

Роль: client · Слой: front · Фаза: До визита · contract

Фронт: Локальный draft, последнее состояние и понятный offline status.

Бэкенд: Не ставить финансовые commands в слепую очередь; server operations продолжаются независимо от клиента.

API: см. серверный контракт состояния · Политики: общие инварианты

- **Сеть восстановилась → S03** (recovery, actor=client). Сначала authoritative fetch, затем reconcile pending intents.

### S03 · Восстановить состояние

Роль: client · Слой: back · Фаза: До визита · contract

Фронт: Сначала сверить актуальный статус, затем продолжить.

Бэкенд: Fetch operations/bookings revision, apply monotonic state, dedupe pending commands, refresh auth если истекла.

API: CMD-SESSION · Политики: общие инварианты

- **Подтверждение найдено → C12** (recovery, actor=system). booking=confirmed и owner identity matches; не по cached success.
- **Подтверждения нет, слот утрачен → C08** (recovery, actor=system). Payment reconciliation завершена или отдельно tracked.
- **Восстановить рабочий день → B06** (recovery, actor=system, межролевая передача). Continuation staff, active grant; scope не берётся из localStorage.
- **Сессия истекла → A00** (recovery, actor=system, межролевая передача). Сохранить только безопасный continuation, повторный auth.

### S04 · Разобрать конфликт изменений

Роль: owner · Слой: front · Фаза: Визит · contract

Фронт: Показать обе версии и актуальное состояние.

Бэкенд: Optimistic concurrency/409; не last-write-wins для денег, места, consent и прав.

API: CMD-SHIFT · Политики: общие инварианты

- **Пересмотреть актуальное состояние → O13** (recovery, actor=owner). Owner scope; пользовательский конфликт дополнительно сообщает текущий booking клиенту.

### S05 · Операционная очередь

Роль: owner · Слой: back · Фаза: После визита · contract

Фронт: Видимые unresolved cases, ответственный и срок.

Бэкенд: Retry budget exhausted → durable manual case, escalation, audit; не терять message в DLQ без владельца.

API: CMD-CASE, CMD-CASE-RESOLVE · Политики: POL-13, POL-16

- **Назначить ответственного → O13** (handoff, actor=system). Claim once, SLA timer, escalation если нет реакции.

### S06 · Закрыть обращение

Роль: owner · Слой: front · Фаза: Управление · contract

Фронт: Показать решение и подтверждённые компенсации.

Бэкенд: Resolution reason + linked authoritative outcomes; unresolved payment/refund не закрывается кнопкой оператора.

API: CMD-CASE-RESOLVE · Политики: POL-13

- **Сообщить результат по визиту → C21** (handoff, actor=owner, межролевая передача). Own booking, актуальный статус, privacy.
- **Учесть причины в отчёте → O23** (happy, actor=owner). Агрегированные обезличенные причины, не medical free text.

### S07 · Закрыть визит в учёте

Роль: client · Слой: back · Фаза: После визита · contract

Фронт: Услуга, расчёт, чек и результат отражены отдельно.

Бэкенд: Booking closed when service/payment obligations resolved or explicit audited receivable; immutable history, outbox retention.

API: CMD-VISIT-CLOSE · Политики: общие инварианты

- **Открыть Cut Passport → C38** (happy, actor=system). Проверить актуальное состояние, полномочия и версию объекта.
- **Оценить визит → C35** (happy, actor=system). Отзыв необязателен, без reward за положительную оценку.
- **Выполнено условие рекомендации → L11** (async, actor=system). Only eligible referred visit, no self-referral, unique reward ledger.

## Целевые серверные операции (не runtime API)

### CMD-AUTH · Identity

`POST /v1/auth/transactions` · actor=guest

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: state, expiresAt, provider, continuation

Согласованность: state + PKCE; callback consume once

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: unauthorized, expired, replay, provider_unavailable. События: AuthVerified, AuthRejected.

Узлы: A00, A04.

### CMD-INVITE · Invitation

`POST /v1/organizations/{org}/staff-invites` · actor=owner

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: candidateId, intendedScope, offerVersion, expiry; token generated on server, hash at rest

Согласованность: Idempotency-Key + organization revision

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: forbidden, version_conflict, consumed, revoked. События: StaffInvited.

Узлы: O10.

### CMD-SHIFT · Shift

`PUT /v1/branches/{branch}/shifts/{id}` · actor=owner

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: interval, skills, resources, affectedBookings

Согласованность: If-Match + audit reason

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: forbidden, overlap, version_conflict. События: ShiftChanged, AvailabilityInvalidated.

Узлы: O14, S04.

### CMD-QUOTE · Quote

`POST /v1/quotes` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: services, recipient, branch, currency, policyVersion

Согласованность: Deterministic quote inputs + expiry

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: stale_catalog, invalid_entitlement, missing_contact. События: QuoteCreated.

Узлы: C06.

### CMD-HOLD · SlotHold

`POST /v1/slot-holds` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: start/end UTC, timezone, quoteId, expiresAt

Согласованность: Idempotency-Key + resource exclusion constraint

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: slot_conflict, expired, resource_unavailable. События: SlotHeld, SlotReleased.

Узлы: C07, S01.

### CMD-BOOK · BookingSaga

`POST /v1/bookings` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: quoteId, holdId, paymentIntentId, policyAcceptance

Согласованность: Idempotency-Key + If-Match quote/hold

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: unknown, conflict, expired, payment_unresolved. События: BookingConfirmed, CompensationRequired.

Узлы: C10, S00.

### CMD-MOVE · Booking

`POST /v1/bookings/{id}/move` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: newHoldId, quoteId, acceptedDelta

Согласованность: Idempotency-Key + expectedRevision; old stays until commit

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: conflict, stale_revision, delta_unpaid. События: BookingMoved, PaymentAdjustmentRequested.

Узлы: C23.

### CMD-CANCEL · Booking

`POST /v1/bookings/{id}/cancel` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: reason optional, cancellationQuoteId

Согласованность: Idempotency-Key + expectedRevision + cancelQuote

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: in_service, stale_quote, stale_revision. События: BookingCanceled, RefundRequested, WaitlistSlotOpened.

Узлы: C25.

### CMD-PAY · Payment

`POST /v1/payment-intents` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: purpose, quoteId, ownedMethodId optional, saveConsent

Согласованность: Unique operation + persisted provider idempotence key; tips require an enabled verified recipient channel and separate quote/ledger

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: unknown, declined, duplicate, amount_changed, tip_channel_unavailable. События: PaymentPending, PaymentSucceeded, PaymentCanceled.

Узлы: P06, C37.

### CMD-WEBHOOK · ProviderInbox

`POST /v1/integrations/yookassa/events` · actor=system

Verified service identity only; never exposed as a client command.

Вход: provider object reference, verified shop/amount/currency

Согласованность: Dedupe object id+type+state; verify authenticated GET before mutation

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: invalid_object, mismatched_merchant, unavailable. События: ProviderStateReconciled.

Узлы: P08.

### CMD-REFUND · Refund

`POST /v1/orders/{id}/refunds` · actor=owner

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: paymentId, amountMinor, reason, orderRevision

Согласованность: Idempotency-Key, authorized entitlement, bounded pending+successful amount

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: over_refund, unknown, already_pending. События: RefundPending, RefundSucceeded, RefundAttentionRequired.

Узлы: P17.

### CMD-ARRIVE · Booking

`POST /v1/bookings/{id}/arrive` · actor=barber

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: observed arrival, server timestamp

Согласованность: Assignment/cashier scope as appropriate + revision

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: forbidden, canceled, wrong_branch. События: ClientArrived.

Узлы: B11.

### CMD-SERVICE · VisitSession

`POST /v1/bookings/{id}/service-events` · actor=barber

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: start, acceptedScope, complete, interruption reason

Согласованность: Idempotency-Key + expected state/revision

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: forbidden, invalid_state, price_unaccepted. События: ServiceStarted, ServiceCompleted.

Узлы: B13, B15, B18.

### CMD-PASSPORT · Passport

`POST /v1/visits/{id}/passport-revisions` · actor=barber

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: parameters, privateMediaIds, author

Согласованность: Assignment + consent + expectedRevision

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: consent_revoked, media_not_ready, revision_conflict. События: PassportSaved.

Узлы: B17.

### CMD-CONSENT · Consent

`PUT /v1/me/consents/{purpose}` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: purpose, channel/media scope, version, accepted

Согласованность: Idempotency-Key + version; revoke propagates

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: invalid_scope, stale_version. События: ConsentChanged, MediaPurgeRequested.

Узлы: C42, R02.

### CMD-CLUB · Membership/Entitlement

`POST /v1/club/memberships` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: planVersion, acceptedTerms, renewalConsent; activation only after verified settlement

Согласованность: Versioned plan, mandate, immutable ledger and unique period key

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: plan_unpublished, mandate_revoked, entitlement_used. События: MembershipPending, MembershipActivated.

Узлы: L01.

### CMD-CASE · SupportCase

`POST /v1/support/cases` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: category, operationId, contact consent, description

Согласованность: Idempotency-Key + accessible references

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: forbidden_reference, duplicate. События: CaseOpened, CaseEscalated.

Узлы: C43, S05.

### CMD-DELETE · DeletionSaga

`POST /v1/me/deletion-requests` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: accepted consequences, pending obligations

Согласованность: Step-up auth + operation identity

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: reauth_required, active_operation, last_owner. События: DeletionRequested, ErasureCompleted.

Узлы: R04, R05.

### CMD-ABSENCE · AbsenceIncident

`POST /v1/staff/me/absence-incidents` · actor=barber

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: time interval, category without diagnosis

Согласованность: Idempotency-Key + active membership

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: forbidden, invalid_interval. События: AvailabilityBlocked, ReassignmentRequired.

Узлы: B08, B09.

### CMD-OFFBOARD · Membership

`POST /v1/staff/{id}/offboarding` · actor=owner

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: effectiveAt, capabilities, affectedBookingIds

Согласованность: Step-up, expectedRevision, dependent booking handover

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: last_owner, forbidden, stale_revision. События: MembershipRevoked, SessionsRevoked.

Узлы: O17, O18.

### CMD-ORG · Organization

`POST /v1/organizations` · actor=owner

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: legalDisplayName, provisionToken; no payment secrets

Согласованность: Provisioning entitlement + step-up; public identity cannot self-grant owner

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: forbidden, duplicate. События: OrganizationProvisioned.

Узлы: O00, O01.

### CMD-BRANCH · Branch

`PUT /v1/organizations/{org}/branches/{id}` · actor=owner

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: address, timezone IANA, openingHours, resources, closure interval/reason

Согласованность: Tenant scope, If-Match, audit; closure schedules compensation before publication

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: forbidden, version_conflict, affected_bookings. События: BranchChanged, BranchClosurePlanned.

Узлы: O02, O19.

### CMD-CATALOG · ServiceCatalog

`PUT /v1/branches/{branch}/catalog/{id}` · actor=owner

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: name, durationMinutes, bufferMinutes, priceMinor, staffSkills, publication

Согласованность: Versioned catalog; issued quotes immutable until expiry

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: invalid_price, invalid_duration, version_conflict. События: CatalogVersionPublished.

Узлы: O03.

### CMD-POLICY · ServicePolicy

`POST /v1/organizations/{org}/policy-versions` · actor=owner

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: cancellation, deposit, grace, noShow, waitlist, notifications, club terms

Согласованность: Append-only publication; financial changes require owner approval and effectiveAt

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: incomplete_policy, version_conflict. События: PolicyVersionPublished.

Узлы: O04.

### CMD-MERCHANT · MerchantConnection

`POST /v1/organizations/{org}/merchant-connections` · actor=owner

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: merchantReference, environment, authorized vault reference, fiscal configuration

Согласованность: Step-up, tenant secret vault reference; sandbox/live mode explicit; no credentials in graph or logs

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: credentials_invalid, merchant_mismatch, fiscal_not_ready. События: MerchantVerified.

Узлы: O05.

### CMD-HIRING · Vacancy

`POST /v1/organizations/{org}/vacancies` · actor=owner

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: skills, branch, capacity, offerVersion

Согласованность: Scoped owner, versioned job conditions, applicant consent and retention

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: forbidden, invalid_terms. События: VacancyOpened.

Узлы: O06.

### CMD-CANDIDATE · Candidate

`POST /v1/vacancies/{id}/candidate-events` · actor=owner

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: consider, trial, offer, reject; reason, termsVersion, permitted contact

Согласованность: Revision + consent; trial is explicitly supervised, no client-data access by default

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: consent_missing, invalid_transition, version_conflict. События: CandidateReviewed, TrialScheduled, OfferIssued, CandidateRejected.

Узлы: O07, O08, O09, O11.

### CMD-INVITE-ACCEPT · StaffMembership

`POST /v1/staff-invites/{token}/accept` · actor=authenticated

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: authenticated identity, offerVersion, acceptance; no caller role field

Согласованность: Token hashed, expiry/single-use, intended identity and scope, accepted offer version; atomic grant

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: expired, revoked, already_consumed, identity_mismatch, offer_changed. События: StaffJoined, InviteRejected.

Узлы: B00, B01, B02, B03, B21.

### CMD-ONBOARD · StaffOnboarding

`PUT /v1/staff/me/onboarding` · actor=barber

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: profile, skills evidence, accepted policies, onboarding progress

Согласованность: Current membership; owner verifies required skills before bookable=true

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: forbidden, requirements_missing. События: OnboardingSubmitted, StaffReady.

Узлы: B04, B05.

### CMD-PUBLISH · Bookability

`POST /v1/branches/{branch}/publication` · actor=owner

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: expected configuration versions, publish flag

Согласованность: Atomic readiness check of services, staff, shifts, policy and payment configuration

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: staff_missing, no_shifts, policy_unapproved, payment_not_ready. События: BookingOpened.

Узлы: O12.

### CMD-OPERATIONS · OperationsReadModel

`GET /v1/branches/{branch}/operations` · actor=owner

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: branch, range UTC, cursor

Согласованность: Server scope + redaction; pagination, asOf/version, no merchant status inferred from UI

Ответ: Scoped read projection with asOf, revision and pagination when applicable; no state mutation.

Ошибки: forbidden, unavailable. События: read-only.

Узлы: O13, O23.

### CMD-SHIFT-REQUEST · ShiftRequest

`POST /v1/staff/me/shift-requests` · actor=barber

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: leave/resignation, interval, reason optional

Согласованность: Membership, expected schedule revision; request does not silently drop assigned bookings

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: forbidden, invalid_interval. События: ShiftChangeRequested.

Узлы: B07, B22.

### CMD-REASSIGN · ReassignmentSaga

`POST /v1/absence-incidents/{id}/reassignments` · actor=owner

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: affectedBookingIds, alternative holds, contact status

Согласованность: Reserve compatible resource; client acceptance for material change; old booking retained until commit

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: conflict, consent_pending, no_alternative. События: AlternativeOffered, BookingReassigned, CompensationRequired.

Узлы: O15, O16.

### CMD-DAY · StaffDayReadModel

`GET /v1/staff/me/day` · actor=barber

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: localDate, branchId, revision

Согласованность: Assignment and branch scopes, privacy-redacted projection, no public client directory

Ответ: Scoped read projection with asOf, revision and pagination when applicable; no state mutation.

Ошибки: forbidden, unavailable. События: read-only.

Узлы: B06, B10.

### CMD-SCOPE · VisitScopeQuote

`POST /v1/visits/{id}/scope-quotes` · actor=barber

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: requested change, estimated duration; separate clientAcceptance token

Согласованность: Expected visit revision; next booking protected; client accepts new price/time before mutation

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: next_booking_conflict, price_not_accepted, revision_conflict. События: ScopeQuoted, ScopeAccepted.

Узлы: B12, B14, C33, P23.

### CMD-INCIDENT · SafetyIncident

`POST /v1/visits/{id}/incidents` · actor=barber

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: category, pauseService, immediate assistance action

Согласованность: Assignment, minimally necessary facts, audited escalation; safety precedes payment workflow

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: forbidden, invalid_visit. События: ServicePaused, IncidentEscalated.

Узлы: B23.

### CMD-SHIFT-CLOSE · ShiftClose

`POST /v1/shifts/{id}/close` · actor=barber

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: expectedRevision, unresolvedVisitIds

Согласованность: Own shift, exception queue retained; never implies all payments captured

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: forbidden, active_visit. События: ShiftClosed, ShiftExceptionRecorded.

Узлы: B19.

### CMD-PAYROLL · BarberSettlement

`POST /v1/organizations/{org}/payroll-periods/{id}/close` · actor=owner

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: period, verified earningLines, adjustments with reasons

Согласованность: Versioned remuneration terms + immutable ledger; actual transfer is separate explicit operation

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: unresolved_dispute, incomplete_period, version_conflict. События: SettlementCalculated, SettlementApproved.

Узлы: O21.

### CMD-EARNINGS · EarningsReadModel

`GET /v1/staff/me/earnings` · actor=barber

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: period, cursor

Согласованность: Own staff identity; correction as append-only dispute, no editing ledger

Ответ: Scoped read projection with asOf, revision and pagination when applicable; no state mutation.

Ошибки: forbidden, unavailable. События: read-only.

Узлы: B20.

### CMD-RECONCILE · Settlement

`POST /internal/jobs/settlement-reconciliation` · actor=system

Verified service identity only; never exposed as a client command.

Вход: operationId, provider object IDs, cursor

Согласованность: Service identity, durable operation identity; provider GET and outbox retries; no public caller

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: provider_unavailable, mismatch, unknown. События: SettlementReconciled, ReconciliationAttentionRequired.

Узлы: O22, P13, P19, P21, P25.

### CMD-TRANSFER · OwnershipTransfer

`POST /v1/organizations/{org}/ownership-transfers` · actor=owner

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: recipientIdentity, expectedRevision, acceptanceProof

Согласованность: Step-up on both parties, intended recipient acceptance, two-party transaction; at least one owner at commit

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: last_owner, recipient_unverified, forbidden, version_conflict. События: OwnershipTransferred, SessionsRevoked.

Узлы: O24.

### CMD-PUBLIC-CATALOG · PublicCatalog

`GET /v1/public/branches/{branch}/catalog` · actor=guest

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: branch, language, cursor

Согласованность: Published, non-personal data only; no candidate/staff private fields

Ответ: Scoped read projection with asOf, revision and pagination when applicable; no state mutation.

Ошибки: not_found, unpublished, unavailable. События: read-only.

Узлы: G00, G01, G02, G04, G08, C01, C02, C03.

### CMD-AVAILABILITY · AvailabilityProjection

`GET /v1/public/availability` · actor=guest

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: branchId, serviceIds, barber preference, date

Согласованность: UTC interval + branch timezone; projection is indicative, authoritative exclusion at hold commit

Ответ: Scoped read projection with asOf, revision and pagination when applicable; no state mutation.

Ошибки: no_capacity, stale_catalog, unavailable. События: read-only.

Узлы: G03, G09, C04, C08, C14, C15, S01.

### CMD-AUTH-CALLBACK · AuthTransaction

`POST /v1/auth/transactions/{id}/complete` · actor=guest

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: provider response, transactionId; no trusted client role or email merge

Согласованность: Consume state once, code+PKCE backend exchange, issuer/audience/expiry checks; MAX gated until spike

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: expired, replay, invalid_signature, provider_unavailable, feature_disabled. События: IdentityVerified, SessionIssued.

Узлы: A01, A02, A03, A04.

### CMD-PROFILE · Profile

`PUT /v1/me/profile` · actor=authenticated

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: name, verified contact, accessibility preferences, recipient relationship

Согласованность: If-Match, field minimization, contact verification; recipient consent distinct from purchaser identity

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: unverified_contact, forbidden_field, version_conflict. События: ProfileUpdated.

Узлы: A06, C44, C45.

### CMD-SESSION · SessionContext

`GET /v1/me/context` · actor=authenticated

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: organization context, sinceVersion

Согласованность: Server grants + scope + revision; role switch only selects existing capability

Ответ: Scoped read projection with asOf, revision and pagination when applicable; no state mutation.

Ошибки: unauthorized, forbidden, revoked. События: read-only.

Узлы: A07, A11, A13, C00, S03.

### CMD-IDENTITY-LINK · IdentityLink

`POST /v1/me/identity-links` · actor=authenticated

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: new provider transaction proof

Согласованность: Recent reauth + verified second provider; never merge by display name or unverified email/phone

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: identity_already_linked, reauth_required, conflict. События: IdentityLinked, IdentityLinkConflict.

Узлы: A08, A09.

### CMD-RECOVERY · IdentityRecovery

`POST /v1/auth/recovery-cases` · actor=guest

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: provider proof or recovery case, safe contact

Согласованность: Rate limits, minimum proof, revoke lost session; no public account-existence leak

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: invalid_proof, rate_limited, manual_review. События: RecoveryStarted, SessionsRevoked.

Узлы: A10, R07.

### CMD-LOGOUT · Session

`POST /v1/me/sessions/revoke` · actor=authenticated

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: sessionIds or all; current session last

Согласованность: Current verified identity, per-session/all scope; invalidate refresh family and push device association

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: unauthorized. События: SessionsRevoked.

Узлы: A12.

### CMD-WAITLIST · WaitlistEntry

`POST /v1/waitlist-entries` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: branch/services/time windows/barber preference, notification consent

Согласованность: Deduplicate client preference; expires/cancelable, opt-in channel; no slot promised

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: consent_missing, invalid_window. События: WaitlistJoined.

Узлы: C13.

### CMD-WAITLIST-OFFER · WaitlistOffer

`POST /internal/jobs/waitlist-offers` · actor=system

Verified service identity only; never exposed as a client command.

Вход: vacated resource interval, policyVersion, queue cursor

Согласованность: Atomic ordered claim, offer expiry from server; capacity hold exclusive; expire once then offer next

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: no_capacity, expired, already_claimed. События: WaitlistOffered, WaitlistOfferExpired.

Узлы: C14, C15.

### CMD-WAITLIST-CLAIM · WaitlistOffer

`POST /v1/waitlist-offers/{id}/claim` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: expected offer version

Согласованность: Owner of entry, current server expiry, atomic claim to hold; booking still requires quote acceptance

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: expired, already_claimed, forbidden. События: WaitlistOfferClaimed.

Узлы: C14.

### CMD-MEDIA · PrivateMedia

`POST /v1/me/media-uploads` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: purpose, contentType, byteLength, digest; no public URL

Согласованность: Purpose-scoped consent; private short-lived upload URL; type/size scan, checksum, ACL, deletion propagation

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: consent_missing, too_large, unsupported_type, scan_failed. События: PrivateMediaReady, MediaRejected.

Узлы: C18, C20, R01.

### CMD-LATE · ArrivalEstimate

`POST /v1/bookings/{id}/arrival-updates` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: estimated arrival, reason category optional; no diagnosis

Согласованность: Own booking + revision; no automatic repricing or shortening without agreement

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: canceled, stale_revision, wrong_branch. События: ArrivalEstimateChanged, AssistanceRequested.

Узлы: C26, C27, C30, C31.

### CMD-NOSHOW · AttendanceReview

`POST /v1/bookings/{id}/no-show-reviews` · actor=barber

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: observed absence, contact attempts, expectedRevision

Согласованность: Assigned staff/owner, server grace elapsed, manual confirmation and audit; disputed arrival preserved

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: grace_not_elapsed, arrived, version_conflict. События: NoShowRecorded, NoShowDisputed.

Узлы: C28.

### CMD-CASH · CounterPayment

`POST /v1/orders/{id}/counter-payments` · actor=barber

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: amountMinor, cash/external_terminal, receipt reference

Согласованность: Explicit cashier capability, expected amount/version, idempotency; assigned barber alone insufficient

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: cashier_scope_required, amount_mismatch, duplicate. События: CounterPaymentRecorded, ReceiptRequested.

Узлы: P14, P15.

### CMD-METHODS · SavedPaymentMethod

`GET /v1/me/payment-methods` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: cursor

Согласованность: Identity owns token; masked details only, no PAN/CVV; reusable only if provider.saved=true

Ответ: Scoped read projection with asOf, revision and pagination when applicable; no state mutation.

Ошибки: unauthorized, unavailable. События: read-only.

Узлы: P03, P04.

### CMD-UNLINK-CARD · SavedPaymentMethod

`DELETE /v1/me/payment-methods/{id}` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: expectedRevision, acknowledge affected mandates

Согласованность: Ownership + reauth where needed; disable local future use, cancel dependent renewal mandate, audit

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: forbidden, active_charge, version_conflict. События: PaymentMethodDisabled, RenewalMandateRevoked.

Узлы: P05.

### CMD-REFUND-QUOTE · CancellationQuote

`POST /v1/bookings/{id}/cancellation-quotes` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: bookingRevision, reason optional

Согласованность: Versioned policy captured at booking; exact refund bound, pending adjustments included

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: in_service, stale_revision, unavailable. События: CancellationQuoted.

Узлы: C24, P16.

### CMD-PAYMENT-CAPTURE · PaymentSettlement

`POST /internal/jobs/payment-settlements` · actor=system

Verified service identity only; never exposed as a client command.

Вход: authorized paymentId, capture amount or cancellation decision

Согласованность: Authenticated worker, reservation allocation confirmed, provider current state/expiry, persisted idempotence key

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: expired, canceled, amount_exceeded, unknown. События: PaymentCaptured, AuthorizationCanceled.

Узлы: P09, P10.

### CMD-RECEIPT · FiscalReceipt

`GET /v1/me/orders/{id}/receipts` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: orderId

Согласованность: Owned order; receipt pending/ready/failed distinct from successful payment

Ответ: Scoped read projection with asOf, revision and pagination when applicable; no state mutation.

Ошибки: forbidden, pending, unavailable. События: read-only.

Узлы: P20, P21.

### CMD-NOTIFICATION · NotificationDelivery

`POST /internal/jobs/notification-deliveries` · actor=system

Verified service identity only; never exposed as a client command.

Вход: templateVersion, minimal payload, recipient reference

Согласованность: Outbox+dedupe booking/version/channel; current schedule and consent, quiet hours; no mass fallback without consent

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: channel_denied, unreachable, stale_booking, retry_exhausted. События: NotificationDelivered, NotificationFailed.

Узлы: N00, N02, N03, N08.

### CMD-REMINDER · ReminderPreference

`PUT /v1/me/bookings/{id}/reminders` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: channel, snoozeUntil, disabled, read event

Согласованность: Own booking; preferences distinct from OS permission and actual delivery

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: forbidden, invalid_time, channel_unavailable. События: ReminderPreferenceChanged.

Узлы: N01, N04, N06, N07, C42.

### CMD-MEMBERSHIP · ClubMembership

`PUT /v1/me/club/membership` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: autoRenew consent, pause/cancel effective date

Согласованность: Versioned plan and separate renewal mandate; respect paid period and reserved credits

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: plan_changed, active_entitlement_conflict. События: RenewalMandateChanged, MembershipPaused.

Узлы: L04, L06.

### CMD-RENEWAL · RenewalAttempt

`POST /internal/jobs/club-renewals` · actor=system

Verified service identity only; never exposed as a client command.

Вход: membershipId, periodKey

Согласованность: One attempt per membership/period; valid current mandate; no overlap/charge after revocation, bounded retries

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: mandate_revoked, payment_failed, unknown. События: RenewalSucceeded, RenewalFailed, MembershipExpired.

Узлы: L04, L05, L07.

### CMD-ENTITLEMENT · EntitlementLedger

`POST /v1/club/entitlement-reservations` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: entitlementId, bookingId, expectedRevision

Согласованность: Atomic reserve one usable credit per booking; consume only once at completed service; release on cancel

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: exhausted, expired, already_reserved. События: EntitlementReserved, EntitlementConsumed, EntitlementReleased.

Узлы: L03, P24.

### CMD-GUEST-PASS · GuestPass

`POST /v1/club/guest-passes` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: entitlementId, optional display message

Согласованность: Eligible membership, quota, server-generated single-use token, expiry; no friend contact uploaded without consent

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: quota_exceeded, expired. События: GuestPassIssued.

Узлы: L08, G10.

### CMD-GUEST-CLAIM · GuestPass

`POST /v1/club/guest-passes/{token}/claim` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: verified identity, guest eligibility

Согласованность: Authenticated intended beneficiary, atomic single claim, expiry; not a transferable identity token

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: expired, already_claimed, ineligible. События: GuestPassClaimed.

Узлы: L09.

### CMD-REFERRAL · Referral

`POST /v1/me/referrals` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: referralCode, qualifyingVisitId

Согласованность: Unique attribution, anti-self-referral; reward only after eligible completed non-refunded visit

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: self_referral, duplicate, ineligible, refunded. События: ReferralAttributed, RewardGranted, RewardReversed.

Узлы: L10, L11.

### CMD-REVIEW · VisitFeedback

`POST /v1/visits/{id}/feedback` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: score, text, private/public choice, category

Согласованность: Own completed visit, one revisable review; visibility choice, no public photo by default

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: visit_not_completed, forbidden, version_conflict. События: FeedbackSubmitted, CaseOpened.

Узлы: C35, C36, C37.

### CMD-PASSPORT-READ · PassportReadModel

`GET /v1/me/passports/{id}` · actor=client

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: revision, cursor

Согласованность: Own immutable revision history; photos consent/expiry checked, suggestions optional

Ответ: Scoped read projection with asOf, revision and pagination when applicable; no state mutation.

Ошибки: forbidden, deleted, media_unavailable. События: read-only.

Узлы: C05, C38, C39, C40.

### CMD-EXPORT · DataExport

`POST /v1/me/data-exports` · actor=authenticated

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: format, scope

Согласованность: Step-up, asynchronous immutable snapshot, expiring authenticated download, audit

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: reauth_required, already_running. События: DataExportReady.

Узлы: R03.

### CMD-CASE-RESOLVE · SupportCase

`POST /v1/support/cases/{id}/resolution` · actor=owner

Backend verifies identity, capability and resource scope on every request; graph role is descriptive, never authority.

Вход: resolution, next action owner, dueAt, linked operationIds

Согласованность: Authorized case scope, expected revision; escalation deadline, independent payment refund authority

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: forbidden, unresolved_payment, stale_revision. События: CaseResolved, CaseEscalated.

Узлы: O20, S05, S06, P22.

### CMD-VISIT-CLOSE · VisitClosure

`POST /internal/jobs/visit-close` · actor=system

Verified service identity only; never exposed as a client command.

Вход: visitId, expected revisions

Согласованность: Service complete + final balanced settlement + entitlement ledger; unknown payments stay pending, outbox atomic

Ответ: Current aggregate state and revision; operationId for asynchronous commands; safe code + retryable + correlationId on failure.

Ошибки: payment_unresolved, service_active, ledger_mismatch. События: VisitClosed, RepeatSuggestionEligible.

Узлы: C34, S07.

## Политики для решения

### POL-01 · Организация и роли

Одна организация PRIME с возможностью нескольких филиалов. Владелец может быть барбером и клиентом, но active context и API scope раздельны. Первого владельца заводит подтверждённая bootstrap-процедура.

### POL-02 · Занятость и расчёт барбера

Тип договора, ставка, процент, база начисления, чаевые и правила перерасчёта не утверждены. В графе versioned offer и отдельный payroll ledger; приём оплаты клиента не выплачивает зарплату.

### POL-03 · Предоплата

Проектная рекомендация: по умолчанию оплата на месте; предоплату включать по опубликованной политике услуги/клуба. Ставка configurable в basis points, default 0, не утверждённый тариф.

### POL-04 · Удержание окна

Демо-значение hold TTL 5 минут. Серверное время, ограниченные продления; expiry не забывает уже начатый платёж. Не совпадает с банковской авторизацией.

### POL-05 · Перенос и отмена

Версия правил фиксируется в заказе. Автоматические штрафы и списание за no-show выключены. Любое удержание требует заранее принятых условий и отдельного решения о правомерности; причина болезни без диагноза.

### POL-06 · Опоздание

Для демо grace 10 минут, не гарантия обслуживания. Решение: оставшееся время ≥ согласованная длительность + buffer и есть согласие мастера/клиента. Иначе перенос/отмена; следующий визит защищён.

### POL-07 · Уведомления

Демо cadence 24 часа и 2 часа до визита, если ещё актуально; snooze ограничен. Канал opt-in, quiet hours и timezone; критичное изменение уходит в очередь владельца при недоставке. Маркетинг отдельно.

### POL-08 · Лист ожидания

Демо offer TTL 15 минут. Справедливое согласованное правило очереди, atomic claim, без auto-book; предложенное окно может истечь.

### POL-09 · PRIME CLUB

Тарифы и остатки маркетолога — гипотеза. До утверждения плана purchase disabled. Раздельные entitlement, guest pass, mandate продления; неизменяемый ledger, не самодельный денежный кошелёк.

### POL-10 · Фото и чувствительные пожелания

Private passport по умолчанию, фото необязательны. Фото/портфолио/камера/маркетинг — разные разрешения. Retention, экспорт и удаление требуют конкретной матрицы до production; диагноз не собирать.

### POL-11 · ЮKassa и чеки

Один merchant по исходной модели; multi-merchant/split выплат не предполагать. Режим оплаты, фискальная схема, ставки/предмет расчёта и возвраты утверждаются с ответственными до live.

### POL-12 · Покупка для другого человека

Payer ≠ recipient. Нельзя передавать историю по оплате. Возраст/законный представитель/согласия — открытое решение; сценарий несовершеннолетнего блокируется до конкретной политики.

### POL-13 · Сроки и ручная поддержка

Демо: unresolved финансовая операция после ограниченного retry budget создаёт urgent case; целевой первый ответ 30 минут в рабочее время, не обещанный SLA. После рабочего времени показать реальное время ответа.

### POL-14 · Вход и платформы

Telegram/Яндекс — документированные flows, MAX — conditional handoff. Нужны зарегистрированные apps и secrets до интеграции; iOS alternative login/Apple guideline отдельно. Кнопки схемы не выполняют вход.

### POL-15 · Рекомендации и чаевые

Добровольный отзыв/рекомендация/чаевые. Rewards и tip provider включаются только после опубликованных правил и отдельного финансового потока; не награждать исключительно положительные отзывы.

### POL-16 · Закрытие и сохранность обязательств

Закрытие филиала, уход сотрудника и удаление аккаунта не уничтожают payment/refund mappings. Ответственный case остаётся до authoritative решения; техническая очередь не считается завершённым возвратом.

## Проверенные внешние документы

- [Telegram](https://core.telegram.org/bots/telegram-login) — OIDC authorization code + PKCE S256. Backend проверяет подпись, iss/aud/exp и state; phone и bot_access запрашиваются только по необходимости. Вход и разрешение на сообщения разделены. Проверено 2026-09-27.
- [Яндекс ID](https://yandex.ru/dev/id/doc/ru/codes/code-url) — Authorization code + PKCE S256 и state; токен обменивается сервером, redirect URI зарегистрирован. Минимальные scopes и доказанная identity вместо слияния по email. Проверено 2026-09-27.
- [MAX](https://dev.max.ru/docs/webapps/validation) — Документирован mini-app initData с HMAC-SHA256 и auth_date. Для native PRIME нужен проверенный одноразовый handoff между mini-app и приложением. Самостоятельный MAX OIDC здесь не подтверждён; кнопку включать только после интеграционного spike, fallback Telegram/Яндекс. Проверено 2026-09-27.
- [ЮKassa: состояния платежа](https://yookassa.ru/developers/payment-acceptance/getting-started/payment-process) — pending → waiting_for_capture/succeeded/canceled. succeeded и canceled финальны. expires_at авторизации берётся у провайдера; длинную запись нельзя обеспечивать бессрочным банковским hold. Возврат отдельным объектом. Проверено 2026-09-27.
- [ЮKassa: сохранение карты](https://yookassa.ru/developers/payment-acceptance/scenario-extensions/recurring-payments/save-payment-method/save-during-payment) — После отдельного согласия передать save_payment_method; сохранить идентификатор только при payment_method.saved=true. В PRIME — provider ID и маска, PAN/CVV не принимать. Первичная привязка в этой модели происходит при платеже; отдельная нулевая привязка требует проверки доступности магазина. Проверено 2026-09-27.
- [ЮKassa: уведомления](https://yookassa.ru/developers/using-api/webhooks) — Входящий webhook — сигнал для обработки. Архитектурное решение PRIME: durable inbox, проверка актуального объекта authenticated GET, суммы/валюты/магазина, дедупликация и монотонное состояние. Browser return URL не подтверждает оплату. Проверено 2026-09-27.
- [ЮKassa: идемпотентность](https://yookassa.ru/developers/using-api/interaction-format) — Idempotence-Key повторяет одну операцию с теми же параметрами; гарантия провайдера ограничена 24 часами. PRIME хранит собственную operation identity дольше; после окна сначала сверка, не слепой повтор POST. Проверено 2026-09-27.
- [ЮKassa: чеки](https://yookassa.ru/developers/payment-acceptance/receipts/54fz/other-services/basics) — Фискальный сценарий выбирается с бухгалтерией и настройками магазина. В модели отдельные состояния чека оплаты, предоплаты/зачёта и возврата; сбой чека не запускает второй платёж. Проверено 2026-09-27.
- [Apple: Login Services](https://developer.apple.com/app-store/review/guidelines/#login-services) — Перед iOS release проверить применимость 4.8 при сторонних способах входа и добавить подходящий равноценный вариант, например Sign in with Apple. Выбор провайдеров в графе не подтверждает готовность к App Review. Проверено 2026-09-27.
