返回文档
指南 10

开发

为 codebase 贡献的指南:setup、monorepo 结构、脚本、约定、i18n。

3 分钟阅读

为 codebase 贡献的指南:setup、monorepo 结构、脚本、约定、i18n。

Setup

bash
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(+ 修复 Prisma 7/pnpm symlink)
pnpm db:migrate         # 应用迁移(prisma migrate dev)
pnpm db:seed            # 角色、权限、config、bootstrap admin
pnpm dev                # 通过 turborepo 启动 server/collector/widget/frontend

PostgreSQL 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)
server3000Express + PrismaAPI、RBAC、agent、RAG FTS/RRF、backup
collector3210Express摄取、解析、embedding、vector store
widget3211Express + Preact IIFE可嵌入 widget
frontend5173Vite + React 19 + TailwindSPA admin/chat
src-tauri-Rust + Tauri桌面应用

依赖图:shared ← {server, collector, frontend, widget}。严格模块化:server↔collector = 仅 HTTP(COLLECTOR_SECRET);widget↔server = API key(X-Api-Key)。server/collector/widget 之间没有直接 import。

常用脚本

脚本Scope描述
pnpm devrootTurborepo:并行启动所有服务
pnpm buildroot所有 package 的生产构建(依赖 ^build)
pnpm lintrootESLint 10 flat config,所有 package
pnpm typecheckrootTypeScript strict mode
pnpm testrootJest(5 个项目,Postgres-free)via Turborepo
pnpm test:allroot同样 5 个 suite via jest.config.cjs(纯 Jest)
pnpm test:e2erootPlaywright
pnpm db:generateroot重新生成 Prisma client
pnpm db:migrateserverprisma migrate dev
pnpm db:seedserverSeed 角色/权限/config
pnpm audit:migrationsserver破坏性迁移审计 → docs/MIGRATION_AUDIT.md
pnpm i18n:checkroot校验 8 个 locale 的翻译对等性
pnpm kniprootDead-code gate(未使用的文件/依赖/export)
pnpm license:checkserver不启动 server 校验已配置的 license

每个 package 的脚本在 packages/<pkg>/package.json 中。Turborepo 缓存 task 之间的 output 和依赖。pnpm db:generate 必须在 build/lint/typecheck/test 之前运行(turbo task build 依赖它)。

代码约定

  • 全局 TypeScript strict;无不合理的 any(target ES2022)。
  • Zod 用于输入校验(shared 定义可复用 schema;在 route handler 中用 safeParse 校验 → 400 而非 500)。
  • Prisma 作为 ORM(Prisma 7,driver adapter);schema 在 packages/server/prisma/schema.prisma。绝不 new PrismaClient():从 src/utils/prisma 使用 singleton(driver-adapter pool + withSoftDelete())。
  • RBAC via 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 用于聊天 streaming(前端使用 @microsoft/fetch-event-source)。
  • Logging:env LOG_LEVEL;使用配置好的 logger,生产环境不要直接 console.log。
  • Commit:Conventional Commits 格式(feat:、fix:、docs:、refactor:...);每次 commit 一次逻辑变更;对 packages/*/src/** 的每处变更在 CHANGELOG.md 中添加一个 [Unreleased] bullet(pnpm changelog:check)。

Frontend(React 19)

  • 3-tier state(server-persisted / session / local)- REST/CRUD 用 TanStack Query,UI 状态用 React Context,SSE 用 fetchEventSource。
  • admin 使用 shadcn/ui + Tailwind;widget 使用 Preact + Tailwind,不用 shadcn(IIFE bundle)。
  • i18n via hook;文件在 packages/frontend/src/i18n/<locale>/translation.json。
  • 聊天快捷键:/model(palette Cmd+K)、对比 Cmd+Shift+M。
  • ESLint:源码中 React Compiler + rules-of-hooks error;模块格式 ESM(root + frontend)vs CommonJS(server/collector/shared/widget)- 遵守每个 package 的 tsconfig。

Server(Express)

  • Route 在 src/routes/,service 在 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 通过 @openapi JSDoc 注解 → 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;严格对等 - 任何语言都不能落后)。在全部八个文件中添加 key。pnpm i18n:check(frontend + widget)在任何 locale 相对 en 缺少 或多余 key 时退出 1;widget check 在空字符串值上也会失败。widget 的 locale 集合由 widgetLocalesParity.test.ts 对照 frontend 的 ALL_LANGUAGES 固定 - 在两个位置一起添加/移除语言。

添加功能(workflow)

  1. Shared schema - 类型/Zod 在 packages/shared/src/。
  2. Prisma - 模型 + 迁移(pnpm db:migrate;破坏性则 audit)。
  3. Server - service + route + RBAC/license middleware。
  4. Frontend - UI + hook + i18n(全部 8 种语言)。
  5. Test - unit(Prisma mock)+ integration(worker DB)+ E2E(若 user-facing)。
  6. Docs - 更新 docs/ 和 OpenAPI @openapi;若触及 src/ 则更新 changelog [Unreleased]。

常见扩展

  • 新 agent skill:在 server/src/agent/builtinSkills.ts 中 registerSkill。
  • 新 endpoint:route 在 server/src/routes/ + 在 src/index.ts 中 mount。
  • 新权限: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 destination:在 Enterprise 插件的 backup provider 中实现 IBackupDestinationProvider(services/backup/providers/)。

交叉链接