# 02 · 代码风格 | 项 | 内容 | | --- | --- | | 文档版本 | V1.0(2026-11-02) | | 依据 | 技术架构 §2.2 / §2.3 / §10.1 | | 适用范围 | `apps/` `packages/` `prisma/` `infra/` 全部 TypeScript / JavaScript | | 强制级别 | 强制(标注「建议」的除外) | > 格式问题交给 Prettier(见 [03](03-格式化与Lint.md)),本文只约定**格式化管不到**的部分。 --- ## 1 命名 | 对象 | 规则 | 示例 | | --- | --- | --- | | 目录 / 文件 | kebab-case | `ai-routes/`、`script-task.service.ts` | | React 组件文件 | PascalCase.tsx | `ScriptCard.tsx` | | 变量 / 函数 | camelCase | `nextCursor`、`resolveScope()` | | 类型 / 接口 / 类 | PascalCase | `MediaTask`、`StorageProvider` | | 常量(模块级不可变) | UPPER_SNAKE | `MAX_UPLOAD_MB` | | 布尔 | `is/has/can/should` 前缀 | `isArchived`、`hasPermission` | | 事件回调 | 属性 `onXxx`,处理器 `handleXxx` | `onSelect` / `handleSelect` | | 异步动作 | 动词开头,返回 Promise | `createBatch()` | | 数据库表 / 列 | snake_case(Prisma `@@map` / `@map`) | `media_tasks`、`customer_id` | | 权限点常量 | `UPPER_SNAKE`,与库内 code 一致 | `SCRIPT_APPROVE` | - `CS-01` 禁止拼音命名(`shangpin`);业务术语用 PRD 术语表英文(`briefCard`、`videoDirection`、`shot`)。 - `CS-02` 单字母变量只允许循环下标 `i/j` 与泛型 `T/K/V`。 - `CS-03` 缩写词按单词大小写:`s3Key`、`httpClient`、`ulid`,不写 `S3Key` / `HttpClient` 混排。 --- ## 2 类型 - `CS-04` `strict: true`,禁止 `any`、隐式 `any`、`@ts-ignore`;确需忽略用 `@ts-expect-error` 并写原因。 - `CS-05` 禁止用 `as` 做类型断言绕过检查;只允许「收窄断言」(`as const`、`as unknown as X` 需注释理由)。 - `CS-06` 对外导出的函数 / 方法**必须显式标注返回类型**,内部函数可推断。 - `CS-07` 对象契约用 `interface`,联合 / 工具 / 映射类型用 `type`;二者不混用于同一实体。 - `CS-08` 业务枚举用 `as const` 对象 + 派生联合类型,**禁止 TS `enum`**;库内枚举由字典表提供(Prisma enum 仅用于永不扩展的封闭集合,需迁移评审说明)。 - `CS-09` 泛型参数 ≥ 2 个或含义不清时必须命名(``),禁止全用 `T`。 - `CS-10` 禁止在业务代码中出现 `object`、`Function`、`{}` 作为类型;用具体形状或 `Record`。 --- ## 3 函数与结构 - `CS-11` 函数单一职责,建议 ≤ 50 行;超过则拆分。 - `CS-12` 参数 > 3 个必须用对象参数;可选参数不用位置占位。 - `CS-13` 嵌套 ≤ 3 层,用**早返回**替代 `else` 链。 - `CS-14` 禁止魔法值:数字 / 字符串常量抽到 `constants` 或读取系统配置(PRD R-26)。 - `CS-15` 单文件 ≤ 400 行;超出按职责拆分(Controller / Service / Repository 各自成文件)。 - `CS-16` 禁止循环依赖;跨包引用只从包 `index.ts` 出口导入。 --- ## 4 错误处理 - `CS-17` 统一抛 `AppError(code, message, details?)`,`code` 取错误码表(见 [04](04-API与路由规范.md) §4);**禁止 `throw new Error('...')` 直接面向用户**。 - `CS-18` 禁止 `catch` 后空吞;要么处理、要么包装后重抛,并保留 `cause`。 - `CS-19` `async` 函数必须有 `await` 或显式 `void`;禁止 floating promise。 - `CS-20` 外部调用(AI / 存储 / ffmpeg)必须设置超时 + 分类重试;**内容违规类错误不重试**。 - `CS-21` 任务(BullMQ)处理器必须**幂等**:以 `taskItemId` 为幂等键,重复执行结果一致。 - `CS-22` 前端错误:路由级 ErrorBoundary + 请求层统一 toast,禁止页面内零散 `alert`。 --- ## 5 注释与文档 - `CS-23` 注释解释**为什么**,不复述代码;业务规则必须引用 PRD 编号:`// R-04 查询必须带 customer_id`。 - `CS-24` 导出 API 写 JSDoc(用途、参数、错误码、副作用);内部实现按需。 - `CS-25` TODO 格式:`// TODO(@owner, 2026-12-01): 原因与后续`;禁止无主 TODO。 - `CS-26` 禁止提交注释掉的整段代码;历史查 git。 - `CS-27` 不写「本次改动」「新增」这类时间性注释,注释描述当下状态。 --- ## 6 导入顺序 按组排序,组间空行,组内按字母序(由 ESLint `simple-import-sort` 自动修复): ``` 1. Node 内置(node:fs) 2. 第三方(@nestjs/*、zod) 3. workspace 包(@lingxi/shared、@lingxi/ui) 4. 应用内绝对路径(~/ 或 @/) 5. 相对路径(./、../) 6. 样式 / 资源(*.css、*.svg?raw) ``` - `CS-28` 禁止 `import * as X` 整包导入(图标包、UI 包尤甚,会破坏 tree-shaking)。 - `CS-29` 图标只从 `packages/ui/icons.ts` 导入语义名(`import { IconScript } from '@lingxi/ui/icons'`),禁直接引 `remixicon` 具体路径。 - `CS-30` 禁 `export *` 聚合无审阅的公共 API;`index.ts` 显式列出导出。 --- ## 7 React / 前端 - `CS-31` 只用函数组件 + Hooks;禁 class 组件、禁 `React.FC`(返回类型写 `ReactNode` / `JSX.Element`)。 - `CS-32` 服务端数据只用 TanStack Query(`useQuery` / `useMutation`);**禁止**在 `useEffect` 里手写 fetch + 自建缓存。 - `CS-33` 全局状态只放跨页共享且非服务端数据(Zustand);页面内状态用 `useState` / `useReducer`,禁止为省 props 上全局。 - `CS-34` 列表 `key` 用业务 ID,禁止 `index`。 - `CS-35` 组件文件导出一个主组件;子组件同文件时用内部函数,跨文件复用必须提为独立组件。 - `CS-36` 样式只用 Semi design token(`cssVar`)/ CSS Modules;**禁止散落十六进制色值**、禁止行内 style 做主题。 - `CS-37` 文案集中在 `packages/ui/locale`(zh-CN),组件内不写死中文用户可见文案(日志与注释除外)。 - `CS-38` 表单走 `packages/form-engine` 的 schema 渲染;**禁止**在业务页面手写动态字段映射(会绕过白名单校验)。 --- ## 8 后端 - `CS-39` 分层职责:Controller 只解析入参 / 组装响应;Service 承载业务规则与状态机;Repository 是唯一访问 Prisma 的层。 - `CS-40` Repository 方法**必须接收 `ScopeContext`** 作为首个参数,禁止在 Repository 内部从全局取当前用户。 - `CS-41` 模块间只通过 Service 接口或领域事件通信;禁止跨模块注入 `PrismaService` 直接查表。 - `CS-42` 状态迁移集中在 Service 的状态机函数内,禁止 Controller 直接改 `status` 字段。 - `CS-43` 事务边界在 Service;事务内**禁止**外部 IO(AI 调用、HTTP、对象存储)。 - `CS-44` 队列任务只做「可重试的纯执行」,业务校验与成本预占在 API 层完成。 --- ## 9 检查清单 - [ ] 命名符合 §1,无拼音、无缩写混排 - [ ] 无 `any` / `@ts-ignore` / 滥用 `as` - [ ] 函数 ≤ 50 行、文件 ≤ 400 行、嵌套 ≤ 3 层 - [ ] 错误统一 `AppError`,无空 catch - [ ] 队列任务幂等,外部调用有超时 - [ ] 图标 / UI 从统一出口导入 - [ ] 业务规则注释带 R-xx - [ ] 无魔数、无硬编码阈值