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.
- Outbox → Kafka — Outbox Scheduler забирает PENDING записи и публикует в Kafka (CloudEvents, тип
core.company.office.<entity>.<action>) - Шлюз — потребляет из Kafka, сохраняет в
inbound_events(сrevisionиsync_to_pos), upsert в свою БД - 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 знака (
Moneyvalue object) - Количества — точность 3 знака (
Quantityvalue object) - В API-ответах
Decimal→string - Ограничения на максимальные суммы для защиты от ошибок ввода
10. Валидация реквизитов
ИНН, КПП, БИК, расчётный счёт валидируются по правилам ФНС:
- ИНН юрлица — 10 цифр с контрольной суммой
- ИНН ИП — 12 цифр с контрольной суммой
- КПП — 9 цифр
- БИК — 9 цифр
- Расчётный счёт — 20 цифр