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

Locali Office — Product Requirements Document

1. Что это

Locali Office — back-office система для управления ресторанным бизнесом. Охватывает полный цикл: организационная структура, кадры, меню, склад, бухгалтерия, кассовые операции, отчётность.

Система работает как источник истины для справочных данных и синхронизирует их на POS-терминалы через Kafka и REST API.

Для развертывания системы локально, прочитайте local-deployment.md

Для кого

РольЧто делает в системе
Владелец сетиКонтролирует финансы, настраивает корпорацию, блокирует периоды
УправляющийУправляет подразделениями, принимает смены, контролирует остатки
БухгалтерВедёт план счетов, создаёт проводки, платежи, ПКО, акты услуг
Менеджер закупокОформляет накладные, работает с контрагентами, контролирует оплаты
Менеджер менюУправляет номенклатурой, техкартами, ценами
HR-менеджерВедёт сотрудников, должности, явки, ставки оплаты
Кассир / ОфициантРаботает через POS — смены, чеки, оплаты

2. Бизнес-контексты

Система разделена на 9 независимых модулей (bounded contexts). Каждый описан в отдельном PRD:

КонтекстЧто делаетМасштабPRD
АутентификацияJWT-вход, сессии, контроль доступа3 эндпоинтаauth.md
ОрганизацияКорпорации, юрлица, подразделения, контрагенты~25 эндпоинтов, 7 контроллеровorganization.md
КадрыСотрудники, должности, явки, ставки~30 эндпоинтов, 5 контроллеровstaffing.md
Управление менюНоменклатура, группы, техкарты, цены, модификаторы~80 эндпоинтов, 14 контроллеровmenu-management.md
Складской учётНакладные, инвентаризации, списания, остатки~40 эндпоинтов, 6 контроллеровinventory.md
Бухгалтерский учётПлан счетов, проводки, платежи, ПКО, акты~35 эндпоинтов, 9 контроллеровaccounting.md
ЗакупкиМетоды оплаты, платёжные системы~10 эндпоинтов, 2 контроллераpurchasing.md
POSТерминалы, кассовые смены, чеки~12 эндпоинтов, 3 контроллераpos.md
ОтчётностьОтчёты по выручке (денормализованная read-model)~3 эндпоинта, 1 контроллерreporting.md

3. Как модули связаны между собой

3.1 Карта зависимостей

┌──────────────┐
│ ОТЧЁТНОСТЬ │
│ (read-model │
│ выручки) │
└──┬────────┬──┘
читает │ │ читает
из POS │ │ из Организации
│ │
┌─────────────▼┐ ┌───▼──────────────┐
│ POS │ │ ОРГАНИЗАЦИЯ │
│ (смены, │ │ (корпорация, │
│ чеки) │ │ подразделения) │
└──────────────┘ └──┬──┬──┬─────────┘
│ │ │
┌─────────────┘ │ └──────────────┐
│ │ │
┌────────▼──────┐ ┌───────▼───────┐ ┌────────▼────────┐
│ БУХГАЛТЕРИЯ │ │ СКЛАД │ │ УПРАВЛЕНИЕ МЕНЮ │
│ (проводки, │ │ (накладные, │ │ (номенклатура, │
│ платежи) │ │ остатки) │ │ техкарты) │
└───────────────┘ └───────────────┘ └─────────────────┘
┌───────────────┐ ┌───────────────┐ (справочные данные
│ ЗАКУПКИ │ │ КАДРЫ │ для склада, POS,
│ (методы │ │ (сотрудники, │ отчётности)
│ оплаты) │ │ явки) │
└───────────────┘ └───────┬───────┘
│ события
┌───────────────┐ │
│ АУТЕНТИФИКА- │◄────────┘
│ ЦИЯ (сессии) │ (увольнение → удаление сессий)
└───────────────┘

3.2 Ключевые зависимости

Организация — фундамент. Все модули зависят от неё:

  • Корпорация — корневая сущность, определяет timezone, учётный день, метод списания, даты блокировки
  • Подразделения — используются в складе (склады), POS (терминалы), ценообразовании, явках
  • Юрлица — для накладных, платежей, актов
  • Контрагенты — поставщики и клиенты

Меню — справочник товаров. На номенклатуру ссылаются:

  • Склад (позиции накладных, инвентаризаций, остатки)
  • POS (позиции чеков)
  • Отчётность (аналитика по блюдам)

Кадры → Аутентификация. При увольнении или смене пароля — инвалидация сессий.

Склад ↔ Бухгалтерия. Накладные и акты — основания для платежей. Счета — для проводок при инвентаризации и списании.

Закупки → POS и Склад. Методы оплаты используются в чеках и актах реализации.


4. Сквозные механизмы

4.1 Блокировка периодов

Корпорация задаёт две даты:

БлокировкаЭффектГде проверяется
Предварительная (preBlockingDate)Предупреждение при создании документа в закрытом периодеСклад, Бухгалтерия, Меню
Окончательная (finalBlockingDate)Полный запрет создания/изменения документовСклад, Бухгалтерия, Меню

Правило: предварительная дата не может быть позже окончательной.

4.2 Учётная дата

Рестораны работают до 2-4 ночи. Чтобы ночные операции относились к «вчерашнему» дню, корпорация настраивает время начала учётного дня (например, 06:00).

Пример (начало дня = 06:00):

  • 23:00 5 марта → учётная дата = 5 марта
  • 03:00 6 марта → учётная дата = 5 марта (до 06:00 — ещё «вчера»)
  • 07:00 6 марта → учётная дата = 6 марта

Влияет на: кассовые смены, отчёты по выручке, складские документы.

4.3 Синхронизация с POS

Офис — источник истины для справочных данных. При изменении сервис в одной транзакции обновляет сущность (с инкрементом version) и записывает в outbox_events.

  1. Outbox → Kafka — Outbox Scheduler забирает PENDING записи и публикует в Kafka (CloudEvents, тип core.company.office.<entity>.<action>)
  2. Шлюз — потребляет из Kafka, сохраняет в inbound_eventsrevision и sync_to_pos), upsert в свою БД
  3. POS ← Шлюз — POS общается только со шлюзом: WebSocket (real-time) + GET /api/sync?last_synced_revision=N (recovery)

Синхронизируются: номенклатура, группы, цены, модификаторы, техкарты, методы оплаты, организационные сущности.

4.4 Мягкое удаление

Ключевые справочники поддерживают isDeleted с возможностью восстановления. Удалённые записи скрыты по умолчанию, доступны через фильтр showDeleted.

Затрагивает: сотрудники, должности, подразделения, контрагенты, методы оплаты, счета, типы внесений/изъятий, номенклатура.

4.5 Аудит критичных операций

СущностьЧто логируется
ЯвкиКто создал, закрыл, изменил, удалил (с описанием изменений)
СотрудникиВсе изменения профиля
Методы оплатыВсе изменения конфигурации
Приказы об изменении ценКто и когда проводил/отменял

5. Ключевые сущности

Организационная иерархия

Корпорация (сеть ресторанов)
└── Юрлицо (ООО «Вкусно», ИП Иванов)
└── Подразделение (Ресторан на Тверской)
├── Склад (Основной склад)
├── Кухня (Горячий цех)
├── Зал (Основной зал)
├── Торговая точка (Терраса)
└── Дочернее подразделение...

Товарная иерархия

Группа номенклатуры (Горячие блюда)
└── Номенклатура (Стейк Рибай)
├── Техкарта (рецептура v1, v2...)
│ └── Ингредиенты (говядина 300г, соль 5г...)
├── Цены (по подразделениям)
├── Модификаторы (соус, гарнир)
├── Штрих-коды
├── Единицы измерения (кг, шт, порция)
└── Пищевая ценность (КБЖУ)

Документооборот

Накладная (приход товара) ──────► Складские остатки ◄────── Инвентаризация (коррекция)
Акт списания (порча) ──────► Уменьшение остатков
Акт реализации (продажа) ──────► Уменьшение остатков + выручка
Кассовая смена ──────► Чеки ──────► Отчёт по выручке
Платёж (за накладную/акт) ──────► Проводка (двойная запись)

6. Жизненные циклы документов

Накладная

ЧЕРНОВИК ─── подтверждение ──► ПОДТВЕРЖДЕНА ─── закрытие ──► ЗАКРЫТА
│ │
└── отмена ──► ОТМЕНЕНА └── отмена (откат остатков) ──► ОТМЕНЕНА
  • Черновик — редактирование позиций, цен, количеств
  • Подтверждена — товар принят на склад, остатки обновлены, суммы рассчитаны
  • Закрыта — расчёты завершены
  • Отменена — аннулирована

Кассовая смена

ОТКРЫТА ─── закрытие ──► ЗАКРЫТА ─── приёмка ──► ПРИНЯТА
│ НЕ ПРИНЯТА
└── проверка ──► ТРЕБУЕТ ПРОВЕРКИ ──► ПРИНЯТА
НЕ ПРИНЯТА

Инвентаризация / Списание / Акт реализации / Акт услуг / Приказ об изменении цен

ЧЕРНОВИК ─── проведение ──► ПРОВЕДЁН
└── отмена ──► ОТМЕНЁН

Явка сотрудника

ОТКРЫТА ─── закрытие ──► ЗАКРЫТА
└── автоматически через 24ч ──► ПРОСРОЧЕНА

7. Роли и доступ

Тип пользователяДоступМожет логиниться
АдминистраторВсе корпорацииДа
Пользователь корпорацииТолько своя корпорацияДа
ТерминальныйТехаккаунт POSНет (только API)

Все данные изолированы по корпорациям — corporationId проверяется на каждый запрос через CorporationGuard.


8. Автоматизация

ПроцессТриггерДействие
Просроченные явкиКаждый час (cron)Явки в OPEN >24ч → OVERDUE, автоматический расчёт заработка
Очистка сессийЕжедневно в 3:00 (cron)Удаление просроченных JWT-сессий (>30 дней)
Инвалидация сессийСобытие: увольнение / смена пароляВсе сессии пользователя удаляются
Синхронизация с POSСобытие: изменение справочникаСервис пишет в outbox_events в транзакции
Outbox-доставкаПериодически (scheduler)Забор PENDING записей из outbox_events, публикация в Kafka

9. Денежные расчёты

  • Все суммы — через Decimal.js (не float)
  • Денежные значения — точность 2 знака (Money value object)
  • Количества — точность 3 знака (Quantity value object)
  • В API-ответах Decimalstring
  • Ограничения на максимальные суммы для защиты от ошибок ввода

10. Валидация реквизитов

ИНН, КПП, БИК, расчётный счёт валидируются по правилам ФНС:

  • ИНН юрлица — 10 цифр с контрольной суммой
  • ИНН ИП — 12 цифр с контрольной суммой
  • КПП — 9 цифр
  • БИК — 9 цифр
  • Расчётный счёт — 20 цифр