--- comet_change: migrate-to-turborepo role: technical-design canonical_spec: openspec archived-with: 2026-07-02-migrate-to-turborepo status: final --- # Migrate to Turborepo Monorepo — Technical Design ## Architecture Overview ``` gongxue-base/ ├── apps/ │ ├── server/ # ← git mv backend → apps/server (NestJS API) │ ├── admin/ # ← git mv frontend → apps/admin (React + Vite) │ └── student/ # 未来:学生端 ├── packages/ │ └── typescript-config/ # 共享 TS 配置:base / nestjs / react-vite ├── package.json # npm workspaces + turbo 根脚本 ├── turbo.json # Turborepo 流水线 ├── .oxfmtrc.json # oxfmt 全局配置 ├── oxlint.config.ts # oxlint 全局配置(admin 前端) └── docker-compose.yml # 调整 build.context 路径 ``` ## Key Decisions ### 1. File Migration: `git mv` `node_modules/` 从未被 Git 追踪,因此 `git mv backend apps/server` 和 `git mv frontend apps/admin` 可以干净执行,完整保留文件历史。 ### 2. Package Manager: npm workspaces 用户指定沿用 npm。根 `package.json` 声明 `workspaces: ["apps/*", "packages/*"]`,所有根脚本委托 `turbo run` 执行。 ### 3. Build Orchestration: Turborepo `turbo.json` 定义六条流水线: | Task | 配置 | |------|------| | `build` | `dependsOn: ["^build"]`, outputs: `dist/**` | | `dev` | `cache: false`, `persistent: true` | | `lint` | 无特殊配置,各 workspace 自行定义工具 | | `test` | 无特殊配置 | | `format` | `cache: false` (oxfmt) | | `typecheck` | `dependsOn: ["^build"]` | ### 4. Toolchain: oxfmt + oxlint (mixed) - **oxfmt**:根目录 `.oxfmtrc.json`,映射 Prettier 配置 `{ singleQuote: true, trailingComma: "all" }` - **oxlint**:仅用于 `apps/admin`,覆盖 TypeScript + React 规则。`exhaustive-deps` 和 `react-refresh` 由 TypeScript compiler + code review 兜底 - **ESLint**:`apps/server` 保留,移除 Prettier 集成。保障 NestJS 装饰器类型检查 所有 workspace 统一使用 `lint` 脚本名,Turborepo 在 `turbo run lint` 时并行调度。 ### 5. Shared TypeScript Config `@gongxue/typescript-config` 包提供三个预设: | 预设 | 继承 | 用途 | |------|------|------| | `base.json` | — | 通用选项:ES2023、strictNullChecks、skipLibCheck | | `nestjs.json` | base | NestJS:nodenext module、experimentalDecorators、declaration | | `react-vite.json` | base | Vite + React:bundler resolution、jsx: react-jsx、noEmit | TypeScript 版本统一为 `~6.0.2`(从 server 5.7→6.0 和 admin 6.0 对齐)。 ### 6. Docker Compose 容器名 `dorm_billing_backend` / `dorm_billing_frontend` 保持不变,仅调整 `build.context`: - `backend: build: ./apps/server` - `frontend: build: ./apps/admin` ## Data Flow ``` npm run dev (根) │ ▼ turbo run dev │ ├──▶ apps/server (NestJS, :3003) ← ESLint, @gongxue/typescript-config/nestjs └──▶ apps/admin (Vite, :3002) ← oxlint, @gongxue/typescript-config/react-vite │ ▼ /api proxy → localhost:3003 ``` ## Testing Strategy ### Core Verification Chain 1. `npm install` — 所有 workspace 依赖正确安装,hoisting 无冲突 2. `npm run build` — server + admin 构建通过 3. `npm run lint` — server ESLint + admin oxlint 通过 4. `npm run format -- --check` — oxfmt 格式化检查通过 5. `npm run test --workspace=apps/server` — NestJS Jest 测试通过 ### Runtime Verification - `npm run dev` → server :3003 + admin :3002 并行启动 - admin Vite 代理 `/api` → `localhost:3003` 正常工作 ### Docker Verification - `docker compose build` — 所有镜像构建成功 - `docker compose up` — 所有服务启动并响应 ## Risks & Mitigations | Risk | Impact | Mitigation | |------|--------|------------| | `git mv` 后路径引用失效 | docker-compose、tsconfig extends、scripts | 逐文件验证,每步 commit | | oxlint 规则覆盖不全 | `exhaustive-deps`、`react-refresh` 缺失 | TS compiler + code review 兜底,明确文档化 | | TS 6.x + NestJS 生态兼容 | ts-jest、ts-node 可能报错 | 迁移后立即验证 build + test | | npm hoisting 行为变化 | 子项目可能拿到不兼容版本 | 重新 install 后逐 workspace 验证 |