# Техподдержка онлайн-школы ЕГЭ На сайте два чата поддержки. Пользователь пишет в общий чат, сотрудник — в служебный. Оба чата ведут историю и передают сообщения в панель оператора. Уточнения продолжают ту же заявку. Оператор видит историю, проверяет предложенный черновик и отправляет ответ в диалог. [Схема процесса и план внедрения](support-process-and-pilot.pdf) ## Запуск Клонируйте репозиторий или распакуйте исходники релиза. Откройте PowerShell в папке с `server.mjs`. Понадобится Node.js 24 или новее. Устанавливать зависимости не нужно. ```powershell node server.mjs ``` Оставьте терминал открытым и перейдите в браузер. `Ctrl+C` останавливает сервер. По умолчанию работает локальное демо с правилами и учебными шаблонами. В нём можно открыть оба чата и проверить модерацию без API-ключа. - [Чат пользователей](http://127.0.0.1:8787/site-chat) - [Чат сотрудников](http://127.0.0.1:8787/staff-chat) - [Панель оператора](http://127.0.0.1:8787/) Если хотите хранить настройки в файле, скопируйте `.env.example` в `.env`, заполните нужные параметры и запустите `node --env-file=.env server.mjs`. Настройки также можно задать через переменные окружения PowerShell. ## Что проверить 1. В чате пользователей отправьте «Не открывается вебинар, который уже идёт». Вторым сообщением добавьте «Пишет 503, смотрю с телефона». В панели откройте одну заявку и проверьте оба сообщения в истории. 2. Отправьте ответ из карточки заявки. Он появится в том же чате. Кнопка сохранения черновика хранит внутренний текст, а отправка добавляет реплику в историю. 3. В новом пользовательском диалоге попросите выдать права администратора или прислать внутренние данные другого ученика. В чате появится отказ, а сообщение можно найти в папке «Спам». Строки из случайных букв тоже попадают туда. 4. Добавьте мат к описанию обычной проблемы. Чат попросит писать вежливо. Повторите в том же диалоге, чтобы увидеть предупреждение о возможной блокировке. Сама блокировка учётной записи остаётся действием оператора по правилам школы. 5. В чате сотрудников отправьте «Нужны права для нового куратора». Заявка попадёт во внутреннюю очередь на проверку полномочий. Если сотрудник сообщает о текущем сбое у учеников, заявку поднимет пользовательский приоритет. В панели доступны правки категории, черновика и статуса, ручной ввод и выгрузка CSV. Для отдельного обращения начните новый диалог в чате. Правила против бессмысленных сообщений и мата действуют в обоих чатах. Ограничение на запрос админских прав и закрытой информации относится к пользовательскому чату. Демо отправляет в спам клавиатурный шум, явные заглушки и короткие бессвязные фразы, которые распознают локальные правила. В режиме ИИ модель дополнительно оценивает смысл последнего сообщения с учётом диалога. Коды ошибок и короткие уточнения остаются в заявке. ## Выход и очистка базы Кнопка «Выход» закрывает текущий экран. При выходе из чата браузер забывает открытый диалог. Для продолжения работы используйте кнопку возврата на странице выхода. В панели оператора нажмите «Очистить буфер» и подтвердите удаление. Из SQLite удалятся все заявки, включая спам, и история обоих чатов. Для следующего обращения откройте новый диалог. Очистка применяется к базе, которую использует запущенный сервер. ## Подключение к сайту школы Сервис слушает `127.0.0.1`. При интеграции сайт проксирует нужные страницы и маршруты чатов, а панель и операторские API размещает в закрытой зоне. Укажите внешний HTTPS-адрес сайта без пути в `SUPPORT_WEB_ORIGIN`, например `https://school.example`. При проксировании передайте локальный `Host` сервиса, например `127.0.0.1:8787`. Для нового диалога используется `POST /api/chat/users/sessions` или `POST /api/chat/staff/sessions`. Идентификатор сессии даёт доступ к её истории. Храните его как секрет диалога и передавайте только его участнику. Для отправки `POST /api/chat/{users|staff}/sessions/{id}/messages` принимает JSON `{ "requestId": "", "text": "..." }`. При повторной доставке используйте тот же `requestId`. История доступна через `GET /api/chat/{users|staff}/sessions/{id}`. В режиме ИИ создавайте служебную сессию только с сервера сайта после проверки роли сотрудника. Передайте `Authorization: Bearer `. Держите секрет в окружении серверов и передайте браузеру только ID созданного диалога, например через `/staff-chat#session=`. Открытый служебный чат деморежима предназначен для локальной проверки. Для старой интеграции разовых заявок доступен `POST /api/intake/site` с `SUPPORT_SITE_TOKEN` и JSON `{ "externalId": "<стабильный ID>", "text": "..." }`. Для диалога с ответами и уточнениями используйте маршруты сессий. ## Режим ИИ с Qwen3.6 35B Остановите запущенное демо и укажите настройки в PowerShell. Для ключа AI Studio нужна область `yc.ai.foundationModels.execute`, для сервисного аккаунта — роль `ai.languageModels.user`. [Документация Yandex AI Studio](https://aistudio.yandex.ru/ru/docs/ai-studio/operations/generation/completions-structured). ```powershell $env:SUPPORT_MODE = 'llm' $env:SUPPORT_PROVIDER = 'yandex' $env:YANDEX_FOLDER_ID = Read-Host 'Идентификатор каталога' $env:YANDEX_API_KEY = [System.Net.NetworkCredential]::new('', (Read-Host 'Ключ AI Studio' -AsSecureString)).Password node server.mjs ``` Запросы тарифицируются по токенам. Правила доступа и предупреждения срабатывают на сервере, а черновики модели отображаются оператору. [Тарифы Yandex AI Studio](https://aistudio.yandex.ru/ru/docs/ai-studio/pricing). ## Хранение и материалы SQLite создаётся в `data/support.sqlite`. Чтобы использовать историю предыдущей версии, остановите сервер и перенесите папку `data` в распакованный проект. Для пути базы и порта доступны `SUPPORT_DB` и `SUPPORT_PORT`. Для CSV в Excel при необходимости выберите UTF-8 и разделитель «запятая». Для демонстрации используйте учебные тексты. Оператор проверяет закрытые сведения в админке, выдаёт права по согласованной заявке и добавляет материалы в датасет с согласия автора. - [Постановка для разработки](assignment-ege-support.md) - [Инструкция для модели](triage-prompt.md) - [Лог работы с ИИ](ai-log.md) - [История версий](CHANGELOG.md) ## Проверки перед релизом ```powershell node --test ``` Проверки используют временную SQLite и синтетические обращения. Ключ модели не нужен. ## Публикация в Gitea Для первой публикации создайте в Gitea пустой репозиторий `ege-support-prototype`. Скопируйте его URL для клонирования. В папке проекта выполните следующие команды. Сначала просмотрите список подготовленных файлов, затем сделайте коммит. ```powershell git init -b main git add -- .gitignore .env.example package.json README.md CHANGELOG.md server.mjs classify.mjs chat-policy.mjs examples.mjs triage-prompt.md public test ai-log.md assignment-ege-support.md support-process-and-pilot.pdf git diff --cached --name-only git commit -m "Prepare release v0.1.0" $repoUrl = Read-Host 'URL для клонирования из Gitea' git remote add origin $repoUrl git push -u origin main git tag -a v0.1.0 -m "Release v0.1.0" git push origin v0.1.0 ``` В Gitea откройте раздел **Releases**, создайте релиз для тега `v0.1.0` и возьмите описание из `CHANGELOG.md`. Если репозиторий уже содержит коммиты, сначала клонируйте его и внесите проект в существующую историю. [Документация Gitea о релизах](https://docs.gitea.com/api/1.26/operations/repo-create-release/).