Commit graph

6 commits

Author SHA1 Message Date
nns 276cba22f8 feat(s29): SuperAdmin UI — бейдж + переключатель расширенного режима (шаг 6/8)
- SuperAdminOrganizationsPage:
  - OrgRow.isAdvancedMode добавлен.
  - Новая колонка «Режим» — бейдж «Простой» (slate) / «Расширенный»
    (violet).
  - Кнопка-экшн (иконка Sparkles) открывает модалку подтверждения
    с разной копией для вкл/выкл; успешный PUT → list.refetch().
  - Выкл-копия напоминает что данные НЕ удаляются и переключение
    обратимо; вкл-копия перечисляет открывающиеся модули.

Переключение из карточки организации — отложено, список-страница
с бейджем и кнопкой закрывает UX.

pnpm run build — ✓ 2.02s, 0 TS errors.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-10-04 11:50:18 +05:00
nns 792ea0fd41 feat(s29): простой режим — упрощённые формы товара/контрагента/приёмки (шаг 5/8)
Везде формула: simpleMode = me && !me.advancedMode && !SuperAdmin.
Значения скрытых полей в state сохраняются и при save на сервер
отправляются как есть; данные НЕ стираются.

- ProductEditPage: скрыты Артикул (auto-gen), Описание, Страна,
  Эталонная цена, Ставка НДС, «В т.ч. НДС», Валюта закупки,
  «Услуга», «Маркируемый», Максимальный остаток, не-retail типы
  цен в блоке «Цены продажи».
- CounterpartiesPage: скрыты Юр.название, Страна, Email, Банк,
  Р.счёт, БИК, Контактное лицо. Остаются: Название, Тип лица,
  БИН/ИИН, Адрес, Телефон, Заметки.
- SupplyEditPage: колонка «Валюта» всегда скрыта в простом режиме
  (одна валюта по умолчанию).

«Поставщик/Покупатель»-галочки отложены — требуют новых колонок
IsSupplier/IsBuyer на Counterparty (новая функциональность).

pnpm run build — ✓ 2.36s, 0 TS errors.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-10-04 11:48:23 +05:00
nns 67c1b590ad feat(s29): web — простой режим скрывает меню / маршруты / виджеты (шаг 4/8)
- AdvancedModeGuard — render-guard: простой режим + не-SuperAdmin → страница
  «Недоступно в простом режиме» с текстом + кнопкой «На главную».
  SuperAdmin пропускается, чтобы можно было проверить работу после
  переключения.
- useMe (+ локальные MeResponse) расширены полем advancedMode: boolean.
- AppLayout.buildNav(roles, advancedMode) — в простом режиме скрыты:
  priceTypes, transfers, demands, promotions, loyaltyPrograms/Cards,
  reportAbc, auditLog, LanguageSwitcher.
- App.tsx — скрытые маршруты обёрнуты в <AdvancedModeGuard>:
  /catalog/price-types, /inventory/transfers*, /sales/demands*,
  /loyalty/programs, /loyalty/cards, /promotions, /audit-log,
  /reports/abc.
- DashboardPage — в простом режиме скрыты виджеты «Топ товаров» и
  «Маржа». Остаются KPI, график продаж, «Последние продажи», «Низкий
  остаток».
- Данные скрытых модулей НЕ удаляются при выключении режима; при
  повторном включении всё видно.

pnpm run build — ✓ 2.6s, 0 TS errors.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-10-04 11:43:10 +05:00
nns 921bca076c feat(s29): [RequiresAdvancedMode] + гейтинг скрытых модулей (шаг 3/8)
- RequiresAdvancedModeAttribute (TypeFilterAttribute → IAsyncAuthorizationFilter):
  читает Organization.IsAdvancedMode по org_id-claim через AppDbContext,
  кэш 30 с, инвалидация после переключения. SuperAdmin bypass. На отказ
  возвращает 403 ProblemDetails с code=advanced-mode-required.
- Атрибут навешен на контроллеры:
  Sales/DemandsController, Inventory/TransfersController,
  Loyalty/LoyaltyCardsController + LoyaltyProgramsController,
  Promotions/PromotionsController, Reports/AbcReportController,
  Admin/OrgAuditLogController, Telegram/TelegramBindingController,
  Common/UserPresetsController.
- И на отдельные действия:
  Catalog/PriceTypesController POST/PUT/DELETE (GET доступен — товары
  используют retail-прайс),
  Catalog/ProductsController POST /bulk-update.
- SuperAdmin toggle (шаг 2) инвалидирует кэш фильтра после SaveChangesAsync.
- SSO (Auth/ExternalAuthController) гейтится UI, а не атрибутом: endpoint
  инициируется анонимом без org_id в токене.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-10-04 11:38:10 +05:00
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
nns 4342318c2c feat(s29): Organization.IsAdvancedMode + миграция Phase29a (шаг 1/8)
Simple/Advanced mode: по умолчанию у всех организаций «простой» режим
(IsAdvancedMode=false) — виден только базовый розничный учёт. Включить
«расширенный» режим может только SuperAdmin через отдельный API; в
настройках магазина переключателя нет.

Данные скрытых модулей при переключении НЕ удаляются; при повторном
включении всё снова видно.

- Organization.IsAdvancedMode (bool, default false) + XML-док
- EF-миграция Phase29a — идемпотентный ADD COLUMN IF NOT EXISTS DEFAULT false
- AppDbContextModelSnapshot обновлён
- Применено на dev-БД: 5/5 организаций → IsAdvancedMode=false

docs/simple-mode-progress.md — чек-лист + журнал.

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