Entwicklung
Leitfaden für Beiträge zum Codebase: Setup, Monorepo-Struktur, Skripte, Konventionen, i18n.
Leitfaden für Beiträge zum Codebase: Setup, Monorepo-Struktur, Skripte, Konventionen, i18n.
Setup
git clone <repo> && cd simmetric-chat
pnpm install # installiert die Abhängigkeiten aller Packages
cp .env.example .env # Root-.env = einzige Runtime-Config; dann JWT_SECRET, COLLECTOR_SECRET bearbeiten
pnpm db:generate # Prisma Client (+ Fix Prisma 7/pnpm Symlink)
pnpm db:migrate # Migrationen anwenden (prisma migrate dev)
pnpm db:seed # Rollen, Berechtigungen, Config, Bootstrap-Admin
pnpm dev # startet server/collector/widget/frontend via turborepoPostgreSQL 16 lokal (z. B. docker compose -f docker/docker-compose.infra.yml up -d postgres). pnpm db:migrate wendet die Prisma-Migrationen an (packages/server/prisma/migrations); pnpm db:seed sät Rollen/Berechtigungen und den Bootstrap-Admin (admin / admin123, mustChangePassword=true). Die Migrationen sind additive-only: destruktive erfordern explizite Zustimmung (PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION) und pnpm audit:migrations regeneriert docs/MIGRATION_AUDIT.md zum Commit in derselben PR.
Monorepo-Struktur
pnpm workspaces + Turborepo. 5 Packages + Tauri:
| Package | Port | Stack | Rolle |
|---|---|---|---|
shared | - | TS + Zod | Typen, Schema, Konstanten (Leaf, nur zod) |
server | 3000 | Express + Prisma | API, RBAC, Agent, RAG FTS/RRF, Backup |
collector | 3210 | Express | Ingestion, Parsing, Embedding, Vector Store |
widget | 3211 | Express + Preact IIFE | Einbettbares Widget |
frontend | 5173 | Vite + React 19 + Tailwind | SPA Admin/Chat |
src-tauri | - | Rust + Tauri | Desktop-App |
Abhängigkeitsgraph: shared ← {server, collector, frontend, widget}. Strikte Modularität: server↔collector = HTTP only (COLLECTOR_SECRET); widget↔server = API key (X-Api-Key). Kein direkter Import zwischen server/collector/widget.
Gemeinsame Skripte
| Skript | Scope | Beschreibung |
|---|---|---|
pnpm dev | root | Turborepo: startet alle Services parallel |
pnpm build | root | Produktions-Build aller Packages (hängt von ^build ab) |
pnpm lint | root | ESLint 10 Flat Config, alle Packages |
pnpm typecheck | root | TypeScript Strict Mode |
pnpm test | root | Jest (5 Projekte, Postgres-free) via Turborepo |
pnpm test:all | root | Dieselben 5 Suiten via jest.config.cjs (reines Jest) |
pnpm test:e2e | root | Playwright |
pnpm db:generate | root | Regeneriert den Prisma Client |
pnpm db:migrate | server | prisma migrate dev |
pnpm db:seed | server | Seed Rollen/Berechtigungen/Config |
pnpm audit:migrations | server | Audit destruktiver Migrationen → docs/MIGRATION_AUDIT.md |
pnpm i18n:check | root | Prüft Übersetzungsparität über 8 Locales |
pnpm knip | root | Dead-Code-Gate (unbenutzte Dateien/Abhängigkeiten/Exports) |
pnpm license:check | server | Prüft die konfigurierte License ohne Server-Boot |
Skripte pro Package in packages/<pkg>/package.json. Turborepo cached Outputs und Abhängigkeiten zwischen Tasks. pnpm db:generate muss vor build/lint/typecheck/test laufen (die Turbo-Task build hängt davon ab).
Code-Konventionen
- TypeScript strict überall; kein ungerechtfertigtes
any(TargetES2022). - Zod für Input-Validierung (
shareddefiniert wiederverwendbare Schemas; validiert mitsafeParsein Route Handlern → 400 statt 500). - Prisma als ORM (Prisma 7, Driver Adapter); Schema in
packages/server/prisma/schema.prisma. Nienew PrismaClient(): Singleton aussrc/utils/prisma(Driver-Adapter-Pool +withSoftDelete()). - RBAC via Middleware:
requirePermission,requireAdmin,requireWorkspaceAccess(31 Berechtigungen inshared/src/constants/permissions.ts). - Error Handling: Antworten
{ error }(400/401/403/404/409/402/429/500); Zod-Validierung → 400 mitdetails; License Gating →402 { error, feature, tier }. - SSE für Chat-Streaming (
@microsoft/fetch-event-sourceim Frontend). - Logging: Env
LOG_LEVEL; nutze den konfigurierten Logger, kein direktesconsole.login Prod. - Commit: Conventional Commits (
feat:,fix:,docs:,refactor:...); eine logische Änderung pro Commit; ein[Unreleased]-Bullet inCHANGELOG.mdfür jede Änderung anpackages/*/src/**(pnpm changelog:check).
Frontend (React 19)
- 3-Tier-State (server-persisted / session / local) - TanStack Query für REST/CRUD, React Context für UI-State, fetchEventSource für SSE.
- shadcn/ui + Tailwind für Admin; das Widget nutzt Preact + Tailwind, KEIN shadcn (IIFE-Bundle).
- i18n via Hook; Dateien in
packages/frontend/src/i18n/<locale>/translation.json. - Chat-Shortcuts:
/model(PaletteCmd+K), VergleichCmd+Shift+M. - ESLint: React Compiler + rules-of-hooks
errorim Quellcode; Modulformat ESM (Root + Frontend) vs CommonJS (server/collector/shared/widget) - respektiere die tsconfig pro Package.
Server (Express)
- Routes in
src/routes/, Services insrc/services/, Middleware insrc/middleware/. - Agent in
src/agent/(orchestrator.ts,builtinSkills.ts,mcpClient.ts). - Config Env in
src/config/env.ts(Zod,process.exit(1)bei ungültigen Werten). - OpenAPI via
@openapiJSDoc-Annotationen → Swagger auf/api-docs. - Job Queue pg-boss (Postgres-backed): 8 Cron-Scheduler (Backup, MCP Health-Check, Reaper, Synthesis); die OCR- + Synthesis-Pipelines bleiben auf setInterval-10s-Poller. Multi-Instance-ready ohne Extra-Infrastruktur (siehe 02 - Architecture).
i18n
8 Locales mit konkreten Dateien: en, it, ru, de, fr, es, zh, pt (EN ist die Baseline; strikte Parität - keine Sprache darf zurückfallen). Füge die Keys in allen acht Dateien hinzu. pnpm i18n:check (Frontend + Widget) endet mit 1 bei fehlenden oder überzähligen Keys in irgendeinem Locale gegenüber en; der Widget-Check schlägt auch bei leeren String-Werten fehl. Das Locale-Set des Widgets ist gegen ALL_LANGUAGES des Frontends durch widgetLocalesParity.test.ts gepinnt - füge Sprachen an beiden Stellen gemeinsam hinzu/entferne sie.
Eine Feature hinzufügen (Workflow)
- Shared Schema - Typen/Zod in
packages/shared/src/. - Prisma - Modell + Migration (
pnpm db:migrate; Audit wenn destruktiv). - Server - Service + Route + RBAC/License-Middleware.
- Frontend - UI + Hook + i18n (alle 8 Sprachen).
- Test - Unit (Prisma Mock) + Integration (Worker DB) + E2E wenn user-facing.
- Docs - aktualisiere
docs/und OpenAPI@openapi; Changelog[Unreleased]wennsrc/berührt wird.
Gängige Erweiterungen
- Neue Agent-Skill:
registerSkillinserver/src/agent/builtinSkills.ts. - Neuer Endpoint: Route in
server/src/routes/+ Mount insrc/index.ts. - Neue Berechtigung:
PERMISSION_NAMESinshared/src/constants/permissions.ts+ Rollen. - Neuer LLM-Provider: Preset in
shared/src/constants/providerPresets.ts(geseedet inprovider_presets) + Handler inserver/src/agent/llmStreaming.ts+providerService. - Neue Backup-Destination: implementiere
IBackupDestinationProviderin den Backup-Providern des Enterprise-Plugins (services/backup/providers/).
Cross-Link
- Architektur: 02 - Architecture
- Testing: 11 - Testing
- API: 04 - API Reference