Ингредиенты
(BR 1.12)
Справочник ингредиентов франшизы. Сырьё и полуфабрикаты для техкарт. Данные в Warehouse Service.
Список ингредиентов
Роут: /catalog/ingredients
API: GET /api/v1/ingredients
Колонки
| Колонка | Данные | Примечание |
|---|---|---|
| Название | name | Кликабельное — переход в карточку |
| Ед. изм. | unit_of_measure | |
| Статус | status | Бейдж: Активный / Неактивный. Franchise — кликабельный toggle |
| Техкарта | — | Бейдж “Есть” если у ингредиента есть техкарта (= полуфабрикат), иначе ”—“ |
Фильтры
| Фильтр | Тип | Значения | Default |
|---|---|---|---|
| Статус | Select | Все / Активный / Неактивный | Все |
Поиск
- Поле ввода с placeholder “Поиск по названию”
- Debounce 300ms
- Query param:
search
Пагинация
- 20 записей на страницу
Действия
| Кнопка | Видимость | Действие |
|---|---|---|
| ”Добавить ингредиент” | Franchise | Переход на /catalog/ingredients/new |
Действия строки (Franchise)
| Действие | Что происходит |
|---|---|
| Редактировать | Переход на /catalog/ingredients/:id/edit |
| Удалить | Модалка подтверждения. Ошибка INGREDIENT_IN_USE → toast “Ингредиент используется в рецептах” |
Состояния
| Состояние | Что показываем |
|---|---|
| Загрузка | Skeleton-таблица |
| Пусто | ”Ингредиенты пока не добавлены” + кнопка “Добавить” (Franchise) |
| Ошибка | ”Не удалось загрузить данные” + “Повторить” |
Ролевая видимость
- Franchise: все действия
- Franchisee/Manager: только просмотр (нет кнопок создания/удаления)
- Cashier: 403
Создание ингредиента
Роут: /catalog/ingredients/new
API: POST /api/v1/ingredients
| Поле | Тип | Обязательное | Валидация |
|---|---|---|---|
| Название | Text input | Да | Не пустое |
| Описание | Textarea | Нет | — |
| Ед. изм. | Select: г / кг / мл / л / шт | Да | — |
Кнопки: “Сохранить” / “Отмена” (возврат к списку).
После успеха: редирект на /catalog/ingredients/:id, toast “Ингредиент создан”.
Ошибки
| Код | Что показываем |
|---|---|
NAME_DUPLICATE | ”Ингредиент с таким названием уже существует” (inline под полем) |
VALIDATION_ERROR | Подсветка полей |
Карточка ингредиента
Роут: /catalog/ingredients/:id
API: GET /api/v1/ingredients/:id
Шапка
- Название ингредиента
- Бейдж статуса (active/inactive)
- Кнопки: “Редактировать” / “Удалить” (Franchise)
Табы: [Информация] [Техкарта]
Таб “Информация”
| Поле | Данные |
|---|---|
| Название | name |
| Описание | description или ”—“ |
| Ед. изм. | unit_of_measure |
| Дата создания | created_at |
Таб “Техкарта”
Если у ингредиента есть техкарта — он является полуфабрикатом.
API: GET /api/v1/tech-cards?ingredient_id={id}
Если техкарты нет:
- “Техкарта не создана” + кнопка “Создать техкарту” (Franchise)
POST /api/v1/tech-cardsсingredient_id
Если есть — тот же UI что на товаре:
- Шапка: выход (output_weight + output_unit), статус
- Таблица ингредиентов (рекурсия: ингредиент содержит другие ингредиенты)
- “Добавить ингредиент” → модалка поиска (из того же справочника)
- Inline-редактирование весов и потерь
- Cooking description (textarea, auto-save)
- Кнопка “Убрать” для каждого ингредиента
Ролевой доступ:
- Franchise: CRUD техкарты
- Franchisee/Manager: read-only
- Cashier: таб скрыт
Редактирование ингредиента
Роут: /catalog/ingredients/:id/edit
API: PATCH /api/v1/ingredients/:id
Те же поля что при создании, предзаполненные.
Ед. изм. заблокирована если ингредиент используется в рецептах (
INGREDIENT_IN_USE)
Переходы
| Откуда | Куда | Триггер |
|---|---|---|
| Список | Карточка | Клик по названию |
| Список | Создание | Кнопка “Добавить” |
| Карточка | Редактирование | Кнопка “Редактировать” |
| Создание | Карточка | После сохранения |
| Редактирование | Карточка | После сохранения / “Отмена” |