Разработка
Руководство для контрибьюторов в codebase: setup, структура monorepo, скрипты, конвенции, i18n.
Руководство для контрибьюторов в codebase: setup, структура monorepo, скрипты, конвенции, i18n.
Setup
git clone <repo> && cd simmetric-chat
pnpm install # устанавливает зависимости всех package
cp .env.example .env # корневой .env = единственный runtime config; затем отредактируй JWT_SECRET, COLLECTOR_SECRET
pnpm db:generate # Prisma client (+ fix symlink Prisma 7/pnpm)
pnpm db:migrate # применяет миграции (prisma migrate dev)
pnpm db:seed # роли, разрешения, config, bootstrap admin
pnpm dev # запускает server/collector/widget/frontend через turborepoPostgreSQL 16 локально (например, docker compose -f docker/docker-compose.infra.yml up -d postgres). pnpm db:migrate применяет миграции Prisma (packages/server/prisma/migrations); pnpm db:seed сеет роли/разрешения и bootstrap admin (admin / admin123, mustChangePassword=true). Миграции additive-only: деструктивные требуют явного согласия (PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION), и pnpm audit:migrations регенерирует docs/MIGRATION_AUDIT.md для коммита в той же PR.
Структура monorepo
pnpm workspaces + Turborepo. 5 package + Tauri:
| Package | Порт | Stack | Роль |
|---|---|---|---|
shared | - | TS + Zod | Типы, schema, константы (leaf, зависимость только zod) |
server | 3000 | Express + Prisma | API, RBAC, agent, RAG FTS/RRF, backup |
collector | 3210 | Express | Ингестия, parsing, embedding, vector store |
widget | 3211 | Express + Preact IIFE | Встраиваемый виджет |
frontend | 5173 | Vite + React 19 + Tailwind | SPA admin/chat |
src-tauri | - | Rust + Tauri | Desktop-приложение |
Граф зависимостей: shared ← {server, collector, frontend, widget}. Строгая модульность: server↔collector = только HTTP (COLLECTOR_SECRET); widget↔server = API key (X-Api-Key). Никаких прямых импортов между server/collector/widget.
Общие скрипты
| Скрипт | Scope | Описание |
|---|---|---|
pnpm dev | root | Turborepo: запускает все сервисы параллельно |
pnpm build | root | Продакшен-сборка всех package (зависит от ^build) |
pnpm lint | root | ESLint 10 flat config, все package |
pnpm typecheck | root | TypeScript strict mode |
pnpm test | root | Jest (5 проектов, Postgres-free) через Turborepo |
pnpm test:all | root | Те же 5 suite через jest.config.cjs (чистый Jest) |
pnpm test:e2e | root | Playwright |
pnpm db:generate | root | Регенерирует Prisma client |
pnpm db:migrate | server | prisma migrate dev |
pnpm db:seed | server | Seed ролей/разрешений/config |
pnpm audit:migrations | server | Аудит деструктивных миграций → docs/MIGRATION_AUDIT.md |
pnpm i18n:check | root | Проверяет паритет переводов по 8 locale |
pnpm knip | root | Dead-code gate (неиспользуемые файлы/зависимости/export) |
pnpm license:check | server | Проверяет настроенную лицензию без boot сервера |
Скрипты по package в packages/<pkg>/package.json. Turborepo кэширует output и зависимости между task'ами. pnpm db:generate должен выполняться до build/lint/typecheck/test (task turbo build зависит от него).
Конвенции кода
- TypeScript strict везде; никаких необоснованных
any(targetES2022). - Zod для валидации входа (
sharedопределяет переиспользуемые schema; валидируйsafeParseв route handler → 400 вместо 500). - Prisma как ORM (Prisma 7, driver adapter); schema в
packages/server/prisma/schema.prisma. Никогдаnew PrismaClient(): singleton изsrc/utils/prisma(driver-adapter pool +withSoftDelete()). - RBAC через middleware:
requirePermission,requireAdmin,requireWorkspaceAccess(31 разрешение вshared/src/constants/permissions.ts). - Error handling: ответы
{ error }(400/401/403/404/409/402/429/500); Zod-валидация → 400 сdetails; license gating →402 { error, feature, tier }. - SSE для стриминга чата (
@microsoft/fetch-event-sourceна фронтенде). - Logging: env
LOG_LEVEL; используй настроенный logger, не прямойconsole.logв prod. - Commit: формат Conventional Commits (
feat:,fix:,docs:,refactor:...); одно логическое изменение на commit; bullet[Unreleased]вCHANGELOG.mdна каждое изменениеpackages/*/src/**(pnpm changelog:check).
Frontend (React 19)
- 3-tier state (server-persisted / session / local) - TanStack Query для REST/CRUD, React Context для UI-состояния, fetchEventSource для SSE.
- shadcn/ui + Tailwind для admin; виджет использует Preact + Tailwind, НЕ shadcn (IIFE bundle).
- i18n через hook; файлы в
packages/frontend/src/i18n/<locale>/translation.json. - Chat shortcuts:
/model(палитраCmd+K), сравнениеCmd+Shift+M. - ESLint: React Compiler + rules-of-hooks
errorв исходниках; формат модулей ESM (root + frontend) vs CommonJS (server/collector/shared/widget) - соблюдай tsconfig каждого package.
Server (Express)
- Routes в
src/routes/, сервисы вsrc/services/, middleware вsrc/middleware/. - Agent в
src/agent/(orchestrator.ts,builtinSkills.ts,mcpClient.ts). - Config env в
src/config/env.ts(Zod,process.exit(1)при невалидных значениях). - OpenAPI через
@openapiJSDoc-аннотации → Swagger на/api-docs. - Job queue pg-boss (Postgres-backed): 8 cron scheduler (backup, MCP health-check, reaper, synthesis); пайплайны OCR + synthesis остаются на setInterval 10s poller. Multi-instance-ready без дополнительной инфраструктуры (см. 02 - Architecture).
i18n
8 locale с конкретными файлами: en, it, ru, de, fr, es, zh, pt (EN - baseline; строгий паритет - ни один язык не может отставать). Добавляй ключи во все восемь файлов. pnpm i18n:check (frontend + widget) выходит 1 при отсутствующих или лишних ключах в любом locale относительно en; widget check также падает на пустых строковых значениях. Набор locale виджета запинован против ALL_LANGUAGES фронтенда через widgetLocalesParity.test.ts - добавляй/удаляй языки в обоих местах вместе.
Добавление функции (workflow)
- Shared schema - типы/Zod в
packages/shared/src/. - Prisma - модель + миграция (
pnpm db:migrate; audit если деструктивная). - Server - сервис + route + middleware RBAC/license.
- Frontend - UI + hook + i18n (все 8 языков).
- Test - unit (Prisma mock) + integration (worker DB) + E2E если user-facing.
- Docs - обнови
docs/и OpenAPI@openapi; changelog[Unreleased]если затрагиваетsrc/.
Частые расширения
- Новый agent skill:
registerSkillвserver/src/agent/builtinSkills.ts. - Новый endpoint: route в
server/src/routes/+ mount вsrc/index.ts. - Новое разрешение:
PERMISSION_NAMESвshared/src/constants/permissions.ts+ роли. - Новый LLM provider: preset в
shared/src/constants/providerPresets.ts(seed вprovider_presets) + handler вserver/src/agent/llmStreaming.ts+providerService. - Новое назначение backup: реализуй
IBackupDestinationProviderв backup-провайдерах Enterprise-плагина (services/backup/providers/).
Cross-link
- Архитектура: 02 - Architecture
- Testing: 11 - Testing
- API: 04 - API Reference