Sviluppo
Guida per contribuire al codebase: setup, struttura monorepo, script, convenzioni, i18n.
Guida per contribuire al codebase: setup, struttura monorepo, script, convenzioni, i18n.
Prerequisiti: Node.js >=24.0.0 (enforced da engines.node nel root package.json), pnpm 12.8.1 (pinnato via packageManager), PostgreSQL 16 (DEVELOPMENT.md row-time).
Setup
git clone <repo> && cd simmetric-chat
pnpm install # installa dipendenze tutti i package
cp .env.example .env # .env radice = unica config runtime; poi edita JWT_SECRET, COLLECTOR_SECRET
pnpm db:generate # client Prisma (+ fix symlink Prisma 7/pnpm)
pnpm db:migrate # applica le migrazioni (prisma migrate dev)
pnpm db:seed # ruoli, permessi, config, admin bootstrap
pnpm dev # avvia server/collector/widget/frontend via turborepoPostgreSQL 16 in locale (es. docker compose -f docker/docker-compose.infra.yml up -d postgres). pnpm db:migrate applica le migrazioni Prisma (packages/server/prisma/migrations); pnpm db:seed semina ruoli/permessi e l'admin bootstrap (admin / admin123, mustChangePassword=true). Le migrazioni sono additive-only: le destructive richiedono consenso esplicito (PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION) e pnpm audit:migrations rigenera docs/MIGRATION_AUDIT.md da committare nella stessa PR.
Struttura monorepo
pnpm workspaces + Turborepo. 5 package + Tauri:
| Package | Porta | Stack | Ruolo |
|---|---|---|---|
shared | - | TS + Zod | Tipi, schema, costanti (leaf, dip solo zod) |
server | 3000 | Express + Prisma | API, RBAC, agent, RAG FTS/RRF, backup |
collector | 3210 | Express | Ingestione, parsing, embedding, vector store |
widget | 3211 | Express + Preact IIFE | Widget embeddabile |
frontend | 5173 | Vite + React 19 + Tailwind | SPA admin/chat |
src-tauri | - | Rust + Tauri | Desktop app |
Grafo dipendenze: shared ← {server, collector, frontend, widget}. Modularità strict: server↔collector = HTTP only (COLLECTOR_SECRET); widget↔server = API key (X-Api-Key). Nessun import diretto tra server/collector/widget.
Script comuni
| Script | Scope | Descrizione |
|---|---|---|
pnpm dev | root | Turborepo: avvia tutti i servizi in parallelo |
pnpm build | root | Build produzione tutti i package (dipende da ^build) |
pnpm lint | root | ESLint 10 flat config, tutti i package |
pnpm typecheck | root | TypeScript strict mode |
pnpm test | root | Jest (5 progetti, Postgres-free) via Turborepo |
pnpm test:all | root | Stesse 5 suite via jest.config.cjs (Jest puro) |
pnpm test:e2e | root | Playwright |
pnpm db:generate | root | Rigenera il client Prisma |
pnpm db:migrate | server | prisma migrate dev |
pnpm db:seed | server | Seed ruoli/permessi/config |
pnpm audit:migrations | server | Audit migrazioni destructive → docs/MIGRATION_AUDIT.md |
pnpm i18n:check | root | Verifica parità traduzioni 8 locale |
pnpm knip | root | Dead-code gate (file/dipendenze/export inutilizzati) |
pnpm license:check | server | Verifica licenza configurata senza boot del server |
Script per-package in packages/<pkg>/package.json. Turborepo cachea output e dipendenze tra task. pnpm db:generate deve girare prima di build/lint/typecheck/test (task turbo build dipende da esso).
Convenzioni di codice
- TypeScript strict ovunque; niente
anynon giustificato (targetES2022). - Zod per validazione input (
shareddefinisce gli schema riutilizzabili; valida consafeParsenei route handler → 400 invece di 500). - Prisma come ORM (Prisma 7, driver adapter); schema in
packages/server/prisma/schema.prisma. Mainew PrismaClient(): singleton dasrc/utils/prisma(pool driver-adapter +withSoftDelete()). - RBAC via middleware:
requirePermission,requireAdmin,requireWorkspaceAccess(44 permessi inshared/src/constants/permissions.ts). - Error handling: risposte
{ error }(400/401/403/404/409/402/429/500); validazione Zod → 400 condetails; license gating →402 { error, feature, tier }. - SSE per streaming chat (
@microsoft/fetch-event-sourcelato frontend). - Logging:
LOG_LEVELenv; usa il logger configurato, nonconsole.logdiretto in prod. - Commit: formato Conventional Commits (
feat:,fix:,docs:,refactor:...); una modifica logica per commit; un bullet[Unreleased]inCHANGELOG.mdper ogni modifica apackages/*/src/**(pnpm changelog:check).
Frontend (React 19)
- State 3-tier (server-persisted / session / local) - TanStack Query per REST/CRUD, React Context per UI state, fetchEventSource per SSE.
- shadcn/ui + Tailwind per l'admin; widget usa Preact + Tailwind, NO shadcn (IIFE bundle).
- i18n via hook; file in
packages/frontend/src/i18n/<locale>/translation.json. - Shortcut chat:
/model(paletteCmd+K), confrontoCmd+Shift+M. - ESLint: React Compiler + rules-of-hooks
errorin sorgente; module format ESM (root + frontend) vs CommonJS (server/collector/shared/widget) - rispetta il tsconfig per package. - Il Vite proxy retry hook NON si rimuove: il server (
tsx watch) parte più lento di Vite (~1s);packages/frontend/vite.config.tsinstalla un handleronErrorche riprovaECONNREFUSEDfino a 8 volte su ~4s (solo GET/HEAD - i body POST/SSE non vengono mai replayati) e poi restituisce un 502 conciso. L'handler di default sversa uno stackAggregateErrorsu ogni cold start.
Server (Express)
- Route in
src/routes/, servizi 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)se invalide). - OpenAPI via annotazioni
@openapiJSDoc → Swagger su/api-docs. - Job queue pg-boss (Postgres-backed): 12 cron-style schedulers (MCP health-check, MCP reaper, synthesis reaper, weekly fidelity sampling, vector cleanup, upload-draft reaping, chat-message retention, hourly token-quota reset, DLP document scan/backfill, MCP OAuth token refresh, daily connector health sweep) + un guard self-heal delle code;
initWikiConsistencySchedulergira come intervallo in-process. Le pipeline OCR + synthesis restano su setInterval 10s poller (dev e prod). Multi-instance-ready senza infrastruttura extra (vedi 02 - Architecture).
i18n
8 locale con file concreti: en, it, ru, de, fr, es, zh, pt (EN è la baseline; parità strict - nessuna lingua può restare indietro). Aggiungi le chiavi in tutti e otto i file. pnpm i18n:check (frontend + widget) esce 1 su chiavi mancanti o extra in qualunque locale rispetto a en; il widget check fallisce anche su valori stringa vuoti. Il set locale del widget è pinnato contro ALL_LANGUAGES del frontend da widgetLocalesParity.test.ts - aggiungi/rimuovi lingue in entrambi i posti insieme.
Aggiungere una feature (workflow)
- Schema shared - tipi/Zod in
packages/shared/src/. - Prisma - modello + migrazione (
pnpm db:migrate; audit se destructive). - Server - servizio + route + middleware RBAC/license.
- Frontend - UI + hook + i18n (tutte le 8 lingue).
- Test - unit (Prisma mock) + integration (worker DB) + E2E se user-facing.
- Docs - aggiorna
docs/e OpenAPI@openapi; changelog[Unreleased]se toccasrc/.
Estensioni comuni
- Nuova skill agente:
registerSkillinserver/src/agent/builtinSkills.ts. - Nuovo endpoint: route in
server/src/routes/+ mount insrc/index.ts. - Nuovo permesso:
PERMISSION_NAMESinshared/src/constants/permissions.ts+ ruoli. - Nuovo provider LLM: preset in
shared/src/constants/providerPresets.ts(seedato inprovider_presets) + handler inserver/src/agent/llmStreaming.ts+providerService. - Nuova destinazione backup: implementa
IBackupDestinationProvidernei provider backup del plugin Enterprise (services/backup/providers/).
Provenienza v0.28.1
| Affermazione | Fonte |
|---|---|
44 permessi (PERMISSION_NAMES) | packages/shared/src/constants/permissions.ts (conteggio row-time, probe 35-02) - F-RBAC-1 |
Node.js >=24.0.0 (engines.node), pnpm 12.8.1 (packageManager), PostgreSQL 16 | docs/DEVELOPMENT.md (§ Prerequisites, row-time) |
| Il Vite proxy retry hook (8 riprova GET/HEAD, POST/SSE mai replayati) | docs/DEVELOPMENT.md (§ Proxy, row-time) |
| pg-boss: 12 cron-style schedulers + self-heal guard; wiki-consistency in-process; OCR/URL + synthesis poller 10s | docs/ARCHITECTURE.md:175-176 (row-time) |
Riferimento operativo - Simmetric Chat v0.28.1 (docs aggiornate 2026-10-02, census SHA `aca5b8ff`).
Cross-link
- Architettura: 02 - Architecture
- Testing: 11 - Testing
- API: 04 - API Reference