[English](../../docs.en/back-docs/system-messages-management.md) | **Русский** # Техническое задание: управление системными сообщениями ## 1. Цель и контекст - Обеспечить управляемое отображение системных сообщений на главной странице (`/`, компонент `HomeView.vue`) и добавить административный интерфейс для их создания и модерации в разделе контента (`/content`, компонент `ContentListView.vue`). - Системные сообщения должны поддерживать статусы «черновик» и «опубликовано», храниться в базе данных и быть доступны через REST API. ## 2. Актуальное состояние - Главная страница строится компонентом `HomeView.vue` и отображает чат ассистента (`ChatInterface.vue`), в котором выделены системные сообщения (`Message.vue`) по признаку `message.role === 'system'`. - Раздел контента (`ContentListView.vue`) содержит карточки переходов: «Создать страницу», «Шаблоны», «Публичные», «Настройка», «Внутренние». Карточки ведут на существующие маршруты `content-create`, `content-templates`, `content-published`, `content-settings`, `content-internal`. - В проекте отсутствуют сущности и API для системных сообщений; текущий `pagesService.js` работает только со страницами (`/pages`). ## 3. Новые пользовательские сценарии - **Просмотр системных сообщений (главная, `/`):** - Опубликованные системные сообщения подгружаются в чат ассистента и отображаются в виде свернутых карточек с кликабельным заголовком. - При клике на заголовок сообщение раскрывается: в ленте чата отображается полный текст сообщения **или** отправляется предзаготовленный ответ от ИИ ассистента (контент «ответа» хранится вместе с сообщением и выбирается по флагу `reply_type`). - Сообщения должны явно маркироваться как системные (цвет, иконка). При повторном открытии пользователь видит последнее состояние раскрытия; возможно локальное запоминание «прочитано». - **Раздел «Системные сообщения» (`/content`):** - На странице `/content` появляется новая карточка «Системные сообщения» с кнопкой «Подробнее». Переход ведёт на страницу с пользовательской таблицей (`/content/system-messages/table`), построенной на уже существующих компонентах таблиц (см. `UserTablesList.vue`), без отдельного дэшборда карточек. - Таблица отображает системные сообщения построчно, с возможностью множественного выбора через чекбоксы; доступные массовые действия: публикация, снятие с публикации, перевод в черновики, удаление. - Для каждого сообщения по клику «Подробнее» (внутри строки) открывается просмотр/редактирование с формой (см. ниже). - **Создание/редактирование (`/content/system-messages/create`, `/content/system-messages/:id/edit`):** - Форма с полями: заголовок, краткое описание, основной текст (Markdown/HTML), тип ответа (`inline` — показывать контент, `assistant_reply` — отправлять подготовленный ответ от ассистента), поле «Ответ ассистента» (активно при `assistant_reply`), тег важности (info/warning/danger), дата начала публикации (опционально), дата окончания (опционально), флаг отображения гостям. - Кнопки: «Сохранить как черновик», «Опубликовать». При редактировании — «Обновить», «Снять с публикации», «Удалить». - Проверки: обязательность заголовка и основного текста (или ответа ассистента в соответствующем режиме); валидация дат (окончание ≥ начало). - **Работа с таблицей системных сообщений:** - Колонки: чекбокс выбора, заголовок (кликабелен), статус, тип ответа, период действия, целевая аудитория (гости/авторизованные/все), дата создания, автор. - Массовые действия выполняются для выбранных строк; одиночные действия доступны через контекстное меню/кнопки в строке (редактировать, опубликовать, снять с публикации, удалить). ## 4. Требования к интерфейсу - В `ContentListView.vue` в сетку `management-blocks` добавить карточку «Системные сообщения» с кнопкой `Подробнее`. По дизайну карточка должна соответствовать существующим блокам (заголовок, описание, кнопка). - Страница с таблицей системных сообщений: - Использовать `BaseLayout` и локальные стили (`scoped`). - Таблица поддерживает сортировку, фильтрацию по статусам и поиск по заголовку. - Чекбоксы в шапке и строках для массового выбора; панель действий появляется при наличии выбора. - Кнопка «Создать сообщение» открывает форму создания. - Форма создания/редактирования: - Rich-text (минимум Markdown) с предпросмотром и счётчиками символов/слов. - Переключатель режима показа (`inline`/`assistant_reply`) с условным отображением поля «Ответ ассистента» (можно использовать ``). - Поле для выбора иконки/цвета по `severity` (статические пресеты). - Главная страница: - Системные сообщения отображаются в блоке чата как свернутые карточки (`system-message-collapsed`). При клике заголовок разворачивает карточку (`system-message-expanded`) или инициирует отправку ассистента (UI показывает «сообщение от ассистента»). - Для развёрнутых сообщений предусмотреть кнопку «Свернуть» и (опционально) «Отметить как прочитанное». Состояние хранить в `localStorage`. ## 5. Маршрутизация и компоненты - Добавить маршруты в `router/index.js`: - - `/content/system-messages/table` → `SystemMessagesTableView.vue` - - `/content/system-messages/create` → `SystemMessageCreateView.vue` - - `/content/system-messages/:id` → `SystemMessageDetailsView.vue` (просмотр) - - `/content/system-messages/:id/edit` → `SystemMessageEditView.vue` - При необходимости для модальных/вложенных маршрутов можно использовать дочерние маршруты или именованные вью. - Создать соответствующие Vue-компоненты в `src/views/content/system-messages/` и общий набор переиспользуемых элементов (таблица, форма, фильтры, массовые действия) в `src/components/system-messages/`. - Создать сервис `src/services/systemMessagesService.js` с методами для нового API. ## 6. Требования к API и данным - **Новая таблица** `system_messages` (PostgreSQL): - `id` (uuid, pk) - `title` (text, not null) - `summary` (text, nullable) - `content` (text, not null) - `reply_type` (enum: inline, assistant_reply; default inline) - `assistant_reply_content` (text, nullable; требуется при `reply_type = assistant_reply`) - `severity` (enum: info, warning, danger; default info) - `status` (enum: draft, published; not null) - `visible_for` (enum: all, authenticated, guests; default all) - `publish_at` (timestamp, nullable) - `expire_at` (timestamp, nullable) - `created_at`, `updated_at` - `created_by`, `updated_by` (references users/identities, nullable) - `slug` (text, уникальный, для адресации по ссылке при необходимости) - **REST API (Express):** - `GET /system-messages` (пагинация, фильтры по статусу, поиску) - `GET /system-messages/published` (фильтрация по дате/аудитории; публичная) - `GET /system-messages/:id` (доступ только авторизованным редакторам) - `POST /system-messages` (создание; права `MANAGE_LEGAL_DOCS`) - `PATCH /system-messages/:id` (редактирование; проверка статусов) - `DELETE /system-messages/:id` (мягкое удаление или физическое) - `POST /system-messages/:id/publish` и `POST /system-messages/:id/unpublish` (опционально, если не использовать PATCH) - Все защищённые эндпоинты должны требовать авторизацию и права (см. `permissions.js`, `usePermissions`). - Добавить новую миграцию (`backend/scripts/run-migrations.js`) и ORM/SQL-файлы в существующем формате проекта. - Обновить логирование и обработку ошибок `winston`, добавить валидацию входных данных (например, `Joi` или кастомную). ## 7. Логика отображения на фронтенде - `HomeView.vue`: - При инициализации запрашивать опубликованные системные сообщения (учитывая текущую аудиторию) через `systemMessagesService.getPublished({ includeExpired: false })`. - Кэшировать ответ в сторе или локальном состоянии; при подписке на WebSocket можно предусмотреть `system_message_updated` событие. - Добавить обработчик раскрытия: по клику на заголовок либо подставлять полный текст сообщения (`inline`), либо инициировать цепочку отправки `assistant_reply_content` в чат (без участия пользователя). - Добавить обработчик скрытия сообщения, сохраняющий идентификатор в `localStorage` и фильтрующий локально. - `ContentListView.vue`: - Добавить новую карточку «Системные сообщения» в сетку `management-blocks`, не нарушая адаптивную сетку (обновить `grid-template-columns` при необходимости). - Страницы списков: - Реализовать пагинацию (lazy loading или обычная), сортировку по дате. - Для статусов использовать цветовые бейджи (info/warning/danger). - Форма создания: - Поддерживать сабмит через `yarn lint`-friendly код; валидация на клиенте (например, с использованием `computed`/`watch`). - При успешной публикации перенаправлять на список опубликованных; при сохранении черновика — оставаться на странице с уведомлением. ## 8. Требования к безопасности и доступу - Сценарии создания/изменения доступны только ролям с `PERMISSIONS.MANAGE_LEGAL_DOCS`. - Публичный список (`GET /system-messages/published`) фильтрует по: - `status === 'published'`. - `publish_at <= now()` (или null). - `expire_at > now()` (или null). - `visible_for` проверяется на основе контекста (гость/авторизованный). - При выдаче через чат скрывать поля `created_by`, `updated_by`, внутренние метки. - Учитывать CSRF, CORS, rate-limit (перенять конфиг из существующих роутов). ## 9. Тестирование - **Backend:** - Юнит-тесты для CRUD в `tests/system-messages/*.test.js` (Mocha). - Проверка фильтров publish/expire и доступа по ролям. - Тест миграции (откат/применение). - **Frontend:** - Юнит-тесты Vue (если настроены) для основных компонентов (форма, список). - E2E (при наличии) — сценарий: создание черновика → публикация → отображение на главной. - **Регрессионные проверки:** - Убедиться, что существующий список контента и чат ассистента продолжают работать без ошибок (`yarn lint`, `yarn test`). ## 10. Интеграция и DevOps - Обновить `docker-compose.yml` при необходимости (например, добавить миграции в стартовый процесс). - Убедиться, что новые переменные окружения (если будут, например, лимиты количества сообщений) документированы в `README.md` и `setup-instruction.md`. - Добавить скрипт seeding (опционально) для тестовых системных сообщений. ## 11. Открытые вопросы - Нужно ли хранить историю публикаций (auditing)? Если да — предусмотреть таблицу `system_messages_history`. - Требуется ли поддержка многоязычности? (При отсутствии — ограничение на один язык, RU). - Нужно ли уведомление по WebSocket при появлении новых сообщений? (Если да — добавить событие в `wsHub.js`). ## 12. Итоговые артефакты - Backend: новые маршруты, контроллеры, сервис, миграция. - Frontend: новые страницы и сервис, обновлённые маршруты и компоненты `HomeView`, `ContentListView`. - Документация: обновление `README.md` (раздел запуск), `application-description.md` или `tables-system.md` при изменении схем, настоящая спецификация.