# Boltun AI Telegram-бот на Node.js + TypeScript + grammY, AI через Mastra (DeepSeek напрямую или через OpenRouter). Хранилище — SQLite (better-sqlite3). ## Команды - `pnpm dev` — seed личностей + запуск с автоперезагрузкой (читает `.env`) - `pnpm seed` / `pnpm seed:dev` — синхронизировать личности из `constants/personas.ts` + `prompts/personas/*.md` с БД - `pnpm typecheck` — проверка типов - `pnpm build` / `pnpm start` — сборка в `dist/` и запуск - Node.js 24 (`.nvmrc`); Mastra требует Node >= 22.13 ## Архитектура Зависимости идут сверху вниз: `bot` → `services` → `repositories` → `libs`. Сборка всех слоёв (composition root) — в `src/index.ts`. ``` src/ index.ts — создание зависимостей и запуск бота config.ts — чтение и валидация env types.ts — доменные типы (Persona, ChatMessage, ChatMember) constants/ — список личностей (id, название) и прочие константы scripts/ — отдельные точки входа (seed) libs/ — инфраструктура без бизнес-логики (SQLite и миграции, чтение промптов, форматирование Telegram) repositories/ — только SQL и маппинг строк в доменные типы, по репозиторию на таблицу services/ — бизнес-логика; зависят от репозиториев, не знают про grammY assistant/ — AI на Mastra: агент, промпты, tools bot/ — grammY: сборка бота, общие хелперы ответа handlers/ — тонкие Composer'ы: разбор команды → вызов сервиса → ответ prompts/ — тексты промптов: system.md (правила бота) и personas/.md ``` - Промпты храним только в `prompts/*.md`, не в коде. - Личности не редактируются из чата: источник правды — код и `prompts/`, в БД их кладёт `seed`. - Изменения схемы БД — через `migrate` в `libs/db.ts` (у пользователей уже есть базы). - Каждый модуль — фабрика `createX(deps)`, тип экспортируется как `ReturnType`. - Хендлеры не ходят в репозитории напрямую — только через сервисы. - Правила доступа (только админы) — в `bot/create-bot.ts` через `bot.filter`. ## Стиль кода - Пиши функционально: стрелочные функции и фабрики (`const createX = (...) => ({ ... })`), без классов. - Не используй ключевое слово `function` — только `const fn = (...) => ...`. - Не используй `let` (и `var`) — только `const`; вместо циклов с мутацией — `map`/`filter`/`reduce`/рекурсия. - Отделяй пустой строкой объявления констант и логические блоки друг от друга. - Импорты локальных файлов — с расширением `.js` (ESM, `module: NodeNext`). - Тексты для пользователей бота и комментарии — на русском.