ТЗ v3 (актуальное): ядро, границы, минимум

Документ фиксирует согласованные требования на текущем этапе.

## 1) Границы маршрутизации и шаблонов (зафиксировано)

- Поддерживаются 2 зоны:

  - `site/*` — фронт

  - `site/admin/*` — админка (менеджер/администратор)

- Согласование шаблона с «админским» материалом: если материал из БД уже прошёл проверку прав, но имеет `crm_materials.access` не ниже порога **админ-зоны** (константа `Application::ADMIN_ZONE_MIN_ACCESS`, по умолчанию `5`), а запрос пришёл **без** префикса `/admin/`, ядро делает редирект на тот же путь в `/admin/...` (сохраняется query string). Публичные страницы обычно `access = 0`; кабинет пользователя — часто `1`–`3` и остаётся на фронтовом шаблоне.


## 2) Совместимость с БД


- Новая система не меняет существующие имена таблиц/полей/типов.

- Цель: полная обратная совместимость с текущей БД `diy_crm`.

- При изменениях применять только совместимые доработки (без ломающих переименований).


## 3) Типы модулей


- Разрешённые типы модулей:

  - `frontend`

  - `backend`

  - `service`

  - `widget`


## 4) Таблицы БД по свежему дампу


Таблицы в актуальном дампе `trio_crm.sql`:


- `crm_blog`

- `crm_customers`

- `crm_user`

- `crm_materials`

- `crm_menu`

- `crm_page_modules`

- `crm_images`

- `crm_delivery`

- `crm_payment`

- `crm_products`

- `crm_sales`

- `crm_sale_items`

- `crm_sale_status`


Важно: используется фактическое имя `crm_sale_items` (не `crm_sales_items`).


## 5) Стартовые записи в `crm_materials`


Актуальные записи (по дампу, `deleted_at IS NULL`):


- `index` → `FrontendPageModule`

- `login` → `FrontendLoginModule`

- `register` → `FrontendLoginModule`

- `forgot` → `FrontendLoginModule`

- `logout` → `FrontendLoginModule`

- `404` → `FrontendPageModule`

- `dashboard` → `AdminSettingsModule`

- `cabinet` → `AdminCabinetModule`

- `setup` → `AdminSetupModule`

- `demo` → `FrontendPageModule`

- `materials` → `AdminMaterialsModule`

- `menu` → `AdminMenuModule`

- `greed` → `FrontendPageModule`

- `blog` → `FrontendBlogModule`

- `blog-admin` → `AdminBlogModule`


Примечание: в текущей схеме `url` хранится как slug без префикса `admin`, зона определяется роутером.


## 5.1) Актуальные записи в `crm_menu`


Ключевые пункты меню из свежего дампа:


- `mainmenu`: `/`, `/demo`, `/login`, `/blog`, `greed`

- `left`: `/admin/dashboard`, `/admin/setup`, `/admin/materials`, `/admin/menu`, `/admin/blog-admin`, `/admin/logout`


## 5.2) Актуальные записи в `crm_page_modules`


Зафиксированные блоки:


- `WidgetMenuModule` в позиции `mainmenu` (`target=mainmenu`)

- `WidgetMenuModule` в позиции `left` (`target=left`)

- `WidgetSwitcherModule` в позиции `switch` (`target=switch`)


## 6) Модули: выполнено и запланировано


### Выполнено


- `FrontendPageModule`

- `FrontendLoginModule`

- `FrontendBlogModule`

- `AdminCabinetModule`

- `AdminSettingsModule`

- `AdminMaterialsModule`

- `AdminMenuModule`

- `AdminBlogModule`

- `AdminSetupModule`

- `WidgetMenuModule`

- `WidgetSwitcherModule`


### Запланировано


- `AdminOrdersModule`

- `AdminProductsModule`

- `AdminCategoriesModule`


Примечание: отдельный `AdminPageModule` не планируется, так как редактирование материалов страниц уже реализовано через `AdminMaterialsModule`.


## 7) Структура каталогов модулей


- `modules/frontend/*`

- `modules/backend/*`

- `modules/service/*`

- `modules/widget/*`


## 8) Архитектурный roadmap (следующий этап)


### Components


Базовые доменные компоненты:


- `Catalog`

- `Order`

- `Blog`

- `User`

- `Integration` (платежи/доставка/внешние интеграции)


### Plugins


Минимум 5 событий:


- `order.created`

- `order.status.changed`

- `comment.created`

- `ttn.checked`

- `user.registered`


### Plugins: этап внедрения (зафиксировано)


Внедрение выполняется поэтапно, чтобы избежать перегрузки и упростить отладку.


#### Этап 1 (реализовано)


- Ввести базовый `PluginManager` (register/dispatch, без усложнений).

- Подключить события:

  - `order.created`

  - `order.status.changed`

  - `user.registered`

- Реализовать плагины:

  - `AuditLogPlugin`

  - `OrderStatusNotifyPlugin`

  - `UserRegisteredNotifyPlugin`


Статус: каркас реализован (PluginManager, config/plugins.php, плагины, подключение в DI и Application).


#### Этап 2 (после стабилизации)


- `OrderCreatedTelegramPlugin` для `order.created`.

- `StockReservePlugin` для `order.created` и/или `order.status.changed`.

- `DeliveryStatusSyncPlugin` для `ttn.checked`.


#### Этап 3 (после запуска блога/комментариев)


- `CommentModerationPlugin` для `comment.created`.

- `CommentNotifyPlugin` для `comment.created`.


#### Правила производительности и надежности


- Не добавлять тяжёлые внешние запросы в критический путь без таймаутов.

- Ошибки плагинов логировать, не ломая основной сценарий (кроме явно критичных кейсов).

- Внедрять плагины по одному с коротким циклом наблюдения.


#### Тест в бою (обязательно)


- После Этапа 1 — наблюдение 5–7 дней:

  - ошибки в логах по событиям/плагинам;

  - задержка пользовательских сценариев (создание заказа, смена статуса);

  - корректность уведомлений и аудит-следа.

- При стабильной работе — переход к Этапу 2.


### Helpers


- 8–10 утилитных helper-функций (format/date/slug/url/image/text и т.д.).


## 9) Стандарт форм в админке


- Для create/edit форм backend-модулей использовать `universalform.js`:

  - форма с классом `ajax-form`

  - блок `.form-message` внутри формы

  - JSON-ответы success/error

  - при необходимости `redirect` в JSON

  - сохранять fallback для обычного POST


## 10) Сравнение со старой системой: что сделано и зачем


Ниже — зафиксированные отличия v3 от прежней монолитной схемы и практическая польза.


### Архитектура и код


- **Модульность по типам** (`frontend` / `backend` / `service` / `widget`) — проще находить код, подключать виджеты и не смешивать фронт с админкой в одном «комке».

- **DI и фабрика контейнера** — единая точка регистрации сервисов и алиасов модулей, проще тестировать и расширять без правок «везде подряд».

- **Две зоны маршрутизации** (`site/*` и `site/admin/*`) — явная граница фронта и админки, без разрастания третьих зон и лишних шаблонных контуров.

- **Плагины (`PluginManager`, конфиг событий)** — побочные эффекты (аудит, уведомления) выносятся из ядра и модулей; меньше риска переписывать бизнес-логику при добавлении интеграций.


### Безопасность и формы


- **CSRF на POST** — снижение риска подделки запросов по сравнению с типичными старыми формами без единого стандарта.

- **Стандарт админских форм** (`ajax-form`, `universalform.js`, JSON-ответы) — предсказуемое поведение, меньше полных перезагрузок и дублирования обработчиков.


### Контент и данные


- **Отдельные модули под задачи** — материалы страниц (`AdminMaterialsModule` с ограничением `FrontendPageModule`), меню (`AdminMenuModule`), блог (`AdminBlogModule` + `FrontendBlogModule`, статьи в `crm_blog`) — яснее ответственность и схема данных, чем один универсальный экран «всё в одном».

- **Мягкое удаление** (`deleted_at`) там, где это внедрено — возможность отката и аудита без потери строк в БД.

- **Документированный срез БД в ТЗ** — список таблиц и стартовых записей по дампу упрощает развёртывание и сравнение окружений.


### UX админки и мультиязычность


- **Единообразие экранов редактирования** (табы RU/UK/SEO, типы полей, кнопки) — меньше когнитивной нагрузки у редакторов.

- **Учёт языка в формах** (в т.ч. админ-логин) — интерфейс согласован с префиксом `/ru` и ожиданиями пользователя.


### Что это дало в целом


- **Меньше связности** между фичами: проще вносить изменения локально и реже ломать несвязанное.

- **Быстрее онбординг** разработчика за счёт структуры каталогов, ТЗ и правил в репозитории.

- **Готовность к росту** — блог, меню, плагины и админ-модули добавляются без переписывания ядра по образцу уже принятых модулей.


---


Статус документа: актуален на текущий этап разработки v3.