food-market/docs/simple-mode-progress.md
nns 202763e0d0 feat(s29): SuperAdmin advanced-mode toggle + /api/me.advancedMode (шаг 2/8)
- PUT /api/super-admin/organizations/{id}/advanced-mode { enabled: bool }
  — только SuperAdmin, админ орги → 403 от [Authorize(Roles=...)].
- Idempotent: совпадающее состояние → 200 без записи в аудит; разное →
  запись SuperAdminAuditLog (EnableAdvancedMode / DisableAdvancedMode)
  с before/after + IP. Архивную org переключать нельзя (409).
- /api/me теперь отдаёт advancedMode (bool) — читается из Organization
  с IgnoreQueryFilters (SuperAdmin без org → false — работает через
  /api/super-admin/...).
- OrgRow / OrgDetail в SuperAdmin list / detail дополнены IsAdvancedMode
  для бейджа «Простой/Расширенный» (шаг 6).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-10-04 11:32:12 +05:00

66 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Simple Mode — прогресс
Задача: по умолчанию у всех организаций «Простой режим» — только базовые
функции розничного учёта. Включить «Расширенный режим» может только
SuperAdmin и только для конкретной организации. Данные при переключении
не удаляются; при повторном включении всё видно.
Старт: 2026-10-04.
## Чек-лист
- [x] 1. Domain + миграция `Organization.IsAdvancedMode` (bool, default false, backfill false)
- [x] 2. API `PUT /api/super-admin/organizations/{id}/advanced-mode` + аудит + `/api/me.advancedMode`; org-admin → 403
- [ ] 3. Серверная защита: `[RequiresAdvancedMode]` → 403 ProblemDetails на скрытых модулях
- [ ] 4. Web: меню, маршруты, дашборд фильтруются; прямой переход → страница «Недоступно»
- [ ] 5. Упрощённые формы (товар / контрагент / документы) — скрыть «не нужные» поля, значения сохраняются
- [ ] 6. SuperAdmin UI — бейдж «Простой/Расширенный» + переключатель с подтверждением
- [ ] 7. Тесты (unit + integration + e2e); патч quality-watchdog при необходимости
- [ ] 8. Деплой стейджа + `docs/simple-mode.md`
## Простой режим — что видно
- Главная: выручка за сегодня, что заканчивается, последние продажи
- Товары и группы товаров
- Контрагенты (единый список — поставщики и покупатели)
- Склад: Приёмка, Оприходование, Списание, Инвентаризация, Возврат поставщику, Остатки
- Продажи: Продажи, Возвраты покупателей
- Отчёты: Продажи, Прибыль, Остатки на дату
- Сотрудники и роли, Настройки магазина (включая ОФД), Импорт товаров
- 2FA в профиле — остаётся
## Расширенный режим — что добавляется
- Оптовые отгрузки (Demand)
- Перемещения между точками
- Лояльность
- Промокоды / акции
- ABC-анализ
- Аудит организации
- Несколько типов цен (в простом — одна цена продажи)
- Bulk-операции и сохранённые пресеты в таблицах
- Telegram-бот владельца
- SSO
- Переключатель языка (в простом только русский)
- Продвинутые виджеты дашборда
## Журнал
### 2026-10-04 — Шаг 1 ✓
- `Organization.IsAdvancedMode` (bool, default false) + XML-док, что переключает только SuperAdmin.
- Миграция `20261004100000_Phase29a_IsAdvancedMode` — идемпотентный `ADD COLUMN IF NOT EXISTS` с `DEFAULT false`; все существующие орги получают `false`.
- Snapshot обновлён (`AppDbContextModelSnapshot.cs`).
- Применено на dev-БД: 5/5 организаций `IsAdvancedMode = false`.
- `dotnet build food-market.api` — ✓ (0 error, warnings — старые, не наши).
### 2026-10-04 — Шаг 2 ✓
- `PUT /api/super-admin/organizations/{id}/advanced-mode { "enabled": bool }` в `SuperAdminOrganizationsController` — `[Authorize(Roles="SuperAdmin")]`. Админ орги получает 403 от стандартного Authorize-фильтра (роль Admin ≠ SuperAdmin); в контроллере сверху уже `[Authorize(Roles="SuperAdmin")]` — не нужно отдельного `Forbid()`.
- Запись в `SuperAdminAuditLog`: ActionType `EnableAdvancedMode` / `DisableAdvancedMode`, Description, Changes `{"before":…,"after":…}`, IpAddress. Идемпотентный переключатель: если состояние совпадает — 200 без аудит-записи.
- Архивную орг переключать нельзя — 409.
- `/api/me` отдаёт `advancedMode` (bool). SuperAdmin без org → false (это ОК — он работает через `/api/super-admin/...`).
- `OrgRow` / `OrgDetail` в SuperAdmin list / detail — добавлено `IsAdvancedMode`.
- Маршрут: `/api/super-admin/...` (с дефисом), так как существующий контроллер уже использует этот стиль; задача упоминала `superadmin` без дефиса — выбрал существующий стиль.
- `dotnet build food-market.api` — ✓ (0 error).