2026-09-10 11:40:20 +07:00
2026-08-31 20:28:25 +07:00
2026-07-12 18:05:52 +07:00
2026-08-18 23:05:48 +07:00
2026-09-10 03:51:22 +07:00
2026-09-10 11:40:20 +07:00
2026-09-10 03:51:22 +07:00
2026-08-19 23:31:37 +07:00
2026-09-10 11:40:20 +07:00
2026-09-10 11:40:20 +07:00
2026-09-10 03:51:22 +07:00
2026-08-20 23:17:52 +07:00
2026-09-09 12:30:40 +07:00
2026-09-02 00:21:27 +07:00
2026-07-11 13:14:30 +07:00
2026-07-19 21:18:16 +07:00
2026-06-28 17:24:14 +00:00
2026-06-28 17:24:14 +00:00
fix
2026-09-10 03:59:53 +07:00
2026-09-09 12:30:40 +07:00
2026-09-09 20:35:05 +07:00
fix
2026-09-09 20:31:05 +07:00

evening_detective_server

Шалон для Go сервисов (имя репо должно быть snake case) Методы http должны быть с префиксом /api

Инициализация

make generate
go mod tidy
docker compose -f docker-compose-db.yml up -d
cp .env.example .env
mkdir migrations

Запуск

make run

Сборка

make build-builder
make build-linux

По умолчанию используется архитектура Docker-среды. Для другой архитектуры укажите, например, make build-linux GOARCH=arm64 или make build-linux GOARCH=amd64.

Миграции

goose -dir ./migrations create {migration name} sql
goose -dir ./migrations postgres "user=postgres password=postgres host=localhost dbname=evening_detective_server sslmode=disable" up

Тестирование

make test

PDF с QR-кодами команд

Кнопка «QR команд» на странице управления игрой скачивает GET /api/games/{id}/teams/qr.pdf с авторизацией организатора, автора или администратора. Без команд кнопка скрыта; прямой запрос для пустой игры возвращает FailedPrecondition.

Модуль internal/modules/team_qr_pdf формирует A4 в книжной ориентации, 12 карточек (3 × 4) с названиями команд и пунктирными линиями для разрезания. Имя файла: YYYY-MM-DD_Название игры.pdf, дата берётся из games.start_at. Недопустимые символы имени файла заменяются на _.

Для рабочих ссылок задайте APP_BASE_URL — тот же публичный адрес приложения, который используется существующими QR-кодами фронтенда (VITE_API_URL). Пустой или некорректный адрес приводит к ошибке скачивания. PDF не сохраняется в хранилище и отдаётся с Cache-Control: no-store.

Шрифт DejaVu Sans Condensed встроен в бинарник вместе с лицензией; системные шрифты не нужны. Поддерживается кириллица, длинные названия переносятся и уменьшаются до размера 6 pt. Символы вне BMP (например, emoji) вызывают явную ошибку генерации из-за ограничения PDF-библиотеки.

Закрывашка сценария

Автор (или администратор) сохраняет закрывашку через PUT /api/scenarios/{id}/conclusion:

{"conclusion":{"text":"Разгадка дела","video":"ending_abc.mp4"}}

Видео сначала загружается через POST /api/files/upload (MP4/WebM, до 64 МБ); в video передаётся возвращённое имя файла. Текст и видео можно задавать отдельно. {"conclusion":null} удаляет закрывашку. Она возвращается в story.conclusion полного сценария, но не передаётся в историю игроков, включая MCP. Закрывашка переносится вместе с ZIP-архивом; действуют общие лимиты импорта архива (32 МБ на архив и отдельный файл).

Документация и юридические документы

  • docs/TERMS.md — Пользовательское соглашение (оферта); раздаётся сервером по постоянному URL /api/terms;
  • docs/PRIVACY.md — Политика конфиденциальности и обработки персональных данных (152-ФЗ); раздаётся сервером по постоянному URL /api/privacy;
  • docs/CONSENT.md — текст согласия на обработку ПДн для формы регистрации (URL /api/consent);
  • docs/COMPLIANCE.md — чек-лист приведения сервиса в соответствие с документами.

Юридические эндпоинты:

  • POST /api/auth/signup — регистрация; требует accept_terms: true и accept_privacy: true (факт акцепта фиксируется в таблице user_agreements);
  • DELETE /api/auth/delete-account — удаление учётной записи и персональных данных (авторизован JWT, подтверждение паролем в HTTP-заголовке X-Password).

Агент «Юрист по ПО» (DSH)

В каталоге agents/software-lawyer лежит агент-пресет для DeepSeek Harness: специализированный консультант по правовым вопросам разработки ПО (лицензии, авторские права, персональные данные 152-ФЗ/GDPR, договоры). Отвечает на основе встроенной базы знаний (skills/software-law/references/), без внешних API.

Установка (копирует пресет в ~/.dsh/.agent-presets/software-lawyer):

./agents/software-lawyer/install.sh

После установки пресет «Юрист по ПО» появится в списке агентов при создании новой сессии в веб-интерфейсе DSH. Повторная установка с перезаписью: ./agents/software-lawyer/install.sh --force.

Структура:

  • agent.cordis.yml — композиция агента (полный набор инструментов, как у пресета standard, + персона юриста и скилл-база);
  • preset.yml — отображаемое имя и описание;
  • skills/software-law/ — база знаний: SKILL.md (правила консультаций) и references/ (лицензии, авторские права, ПДн, договоры).

MCP-сервер (встроен в основной сервис)

MCP-сервер (Model Context Protocol) встроен в основной бинарь и доступен как HTTP-эндпоинт /api/mcp (streamable HTTP) на REST-gateway — чтобы LLM-клиент (Claude Desktop, IDE с MCP-поддержкой и т.п.) мог играть в «Вечерний детектив». Инструменты вызывают игровые сервисы напрямую, отдельный процесс не нужен.

Ходы через make_move сохраняются с actions.via_mcp = true; через REST/gRPC — с false. Отметку задаёт сервер, клиент её не передаёт. У старых ходов значение false: их источник не отслеживался. Это отметка канала MCP, а не гарантия того, кто фактически играет.

Инструменты:

Инструмент Назначение
connect Подключиться к игре по ссылке /team-story/{id}?password=...; возвращает id команды, пароль и текущую историю
get_team_story История команды: точки, двери, улики, вопросы дела + инфо об игре (по паролю команды, без авторизации)
make_move Ход команды в точку по её коду; возвращает обновлённую историю (по паролю команды, без авторизации)
submit_answers Ответы команды на вопросы дела (массив {question_code, answer}); возвращает обновлённую историю (по паролю команды, без авторизации)

Ссылку на игру (/team-story/{id}?password=...) выдаёт команде организатор личным каналом — например, вместе с паролем. Принимаются относительные и абсолютные ссылки (в т.ч. с любым хостом): HTTP-запросы по ним не выполняются, из ссылки берутся только id команды и пароль. Игроку авторизация не нужна: команда идентифицируется паролем из ссылки.

Запуск — обычный запуск основного сервиса:

make run

MCP-эндпоинт: http://localhost:8090/api/mcp. ВНИМАНИЕ: REST-gateway слушает :8090 (gRPC — :8080), а docker-compose.yml публикует наружу только 8080 — для доступа к /api/mcp извне нужна публикация порта 8090 в compose либо проксирование пути /api/mcp через reverse-proxy (nginx/caddy). Эндпоинт публичный (как и REST /api/teams/{id}/story); секрет — пароль команды.

Подключение к MCP-клиенту (пример для Claude Desktop / аналогов):

{
  "mcpServers": {
    "evening-detective": {
      "type": "http",
      "url": "http://localhost:8090/api/mcp"
    }
  }
}
S
Description
Сервер для игры "Вечерний детектив"
Readme 2.8 GiB
Languages
Go 99.6%
PLpgSQL 0.2%
Makefile 0.2%