11 KiB
11 KiB
项目规则
架构图优先规则
任何任务开始前,必须先查阅架构影响地图,通过图定位代码和模块。
- 先图后码:执行任何分析、修改、搜索任务时,首先运行
npm run arch:scan更新 arch.db,再通过npm run arch:query查询目标模块、函数、依赖关系,结合阅读docs/architecture/004_architecture_impact_map.md定位架构设计意图,最后按图索骥读取源码 - 图未覆盖则先补图:如果发现项目中存在 arch.db 未记录的模块、函数、表、路由等,必须先运行
npm run arch:scan重新扫描,然后检查 004 是否需要补充 - 改码必同步图:对源码的任何修改完成后,必须运行
npm run arch:scan更新 arch.db;若架构设计意图有变化,同步更新 004
架构文档清单
| 文档 | 用途 |
|---|---|
docs/architecture/004_architecture_impact_map.md |
架构设计意图唯一源(人类可读) |
docs/architecture/006_k12_feature_checklist.md |
标准功能模块清单 |
docs/architecture/007_gap_audit_report.md |
差距审计报告 |
docs/architecture/008_module_role_mapping.md |
模块角色映射 |
docs/architecture/roadmap/ |
长远规划(tech-debt/decoupling/pending-features) |
docs/architecture/audit/ |
架构审查报告与归档(含已废弃的 005 JSON、004 V1) |
docs/troubleshooting/known-issues.md |
已知问题速查(场景→技术映射 + 工作经验日志) |
注:005_architecture_data.json 已废弃归档至
audit/archive/,结构化数据查询统一通过 arch.db
需要同步图的场景
- 新增/删除/重命名导出函数、组件、Hook、类型
- 修改函数签名(参数、返回类型)
- 修改权限点(Permissions 常量)或角色-权限映射
- 新增/删除数据库表
- 新增/删除路由页面或 API 路由
- 修改模块间依赖关系
- 新增模块
同步方式
- 修改源码后运行
npm run arch:scan更新 arch.db(强制) - 若架构设计意图变化,同步更新
docs/architecture/004_architecture_impact_map.md - 若发现新的"场景→技术"映射或工作经验,更新
docs/troubleshooting/known-issues.md
架构元数据库规则(arch.db)
arch.db 是代码结构唯一源,AI 工作前必须运行 npm run arch:scan 更新。
- arch.db 取代 005 JSON:模块、函数、调用关系、依赖关系、技术标签查询 arch.db,不手动维护结构化数据文件
- 查询命令:
npm run arch:query -- sql "<SQL>"自定义 SQL 查询npm run arch:query -- module-deps查模块依赖npm run arch:query -- module-reverse-deps <module>查反向依赖npm run arch:query -- symbol-refs <symbol>查符号引用链npm run arch:query -- tech-usage <tag>查技术使用npm run arch:query -- violations查架构违规
- arch.db 不替代 004:arch.db 是"代码现状",004 是"设计意图",两者互补
编码规范
详细规范见 docs/standards/coding-standards.md,以下为核心强制规则。
代码质量规则
- 每次修改后运行
npm run lint和npx tsc --noEmit确保零错误 - Server Action 必须使用
requirePermission()进行权限校验 - 前端组件禁止使用
role === "xxx"硬编码,统一使用usePermission().hasPermission() - 单文件行数遵循企业级规范:
- 配置文件、常量文件、类型定义文件:无限制
- React 组件:建议 ≤ 500 行(复杂表单/大型表格可放宽至 800 行)
- Server Actions / Data Access 模块:建议 ≤ 800 行
- 工具函数:建议 ≤ 40 行
- 自定义 Hook:建议 ≤ 80 行
- 超过建议行数时应考虑拆分(如 data-access 拆分为多个按职责划分的文件)
- 硬性上限:任何文件不超过 1000 行,超过必须拆分
架构分层规则
- 严格三层架构,依赖方向单向:
app → modules → shared app/只能调用modules/的 Server Actions 和 data-access,不直接访问 DBmodules/之间通过对方 data-access 通信,不直接查询对方 DB 表shared/是被依赖方,不得反向依赖@/auth、@/proxy或任何modules/*
模块标准结构
src/modules/[module]/
├─ actions.ts # Server Actions(编排层)
├─ data-access.ts # 数据访问层(可拆分为 data-access-*.ts)
├─ schema.ts # Zod 验证(可选)
├─ types.ts # 类型定义
├─ components/ # 模块专属组件
└─ hooks/ # 模块专属 Hook(可选)
TypeScript 规则
- 禁止
any:未知类型用unknown并做类型守卫 - 禁止
as断言(除非从unknown转换或测试中,需注释原因) - 函数返回值必须显式标注,特别是
Promise<T> - 仅用于类型的导入必须使用
import type - 可选链后禁止跟非空断言
!
命名规范
- 目录:kebab-case(
user-profile/) - 组件文件:PascalCase(
UserProfile.tsx) - Hook 文件:camelCase(
useAuth.ts) - 变量/函数:camelCase,布尔值用
is/has/can/should前缀 - 常量:UPPER_SNAKE_CASE(
MAX_RETRY_COUNT) - 类/接口:PascalCase,接口不加
I前缀
组件规范
- 组件必须为纯函数,使用
function声明 - 页面组件(
page.tsx)使用默认导出;其余组件使用具名导出 - 默认服务端组件,需要交互时才添加
"use client"(必须位于文件第一行) - 不使用
React.FC,直接用函数声明 + 显式标注 props 类型
Server Action 规范
- 每个 Action 必须调用
requirePermission()进行权限校验 - 输入使用 Zod 验证,验证失败返回结构化错误
- 返回值统一采用
ActionState<T>类型 - 使用
revalidatePath精确刷新缓存
Tailwind 规范
- 使用
cn()工具函数管理条件类名 - 禁止字符串拼接动态类名(
bg-${color}-500) - 禁止使用任意值(
w-[137px]),除非有充分理由并注释 - 设计令牌在
src/app/styles/tokens/目录中分层定义,通过@theme inline暴露为 Tailwind 类
设计令牌规范(强制)
- 禁止硬编码颜色: TSX/TS/CSS 中不得出现
#hex颜色字面量,统一使用hsl(var(--*))或 Tailwind 类bg-* - 禁止硬编码字体: 不得出现
'Inter'/'Fraunces'/'JetBrains Mono'字面量,使用var(--font-family-sans/serif/mono) - 禁止硬编码字号: 不得出现
font-size: Npx,使用var(--font-size-1~9) - 禁止 Tailwind 任意值: 不得使用
w-[Npx]/h-[Npx]/p-[Npx]等,映射到--space-*或 Tailwind 默认阶梯 - 豁免场景(需
// eslint-disable-next-line no-restricted-syntax -- <reason>注释):- PWA manifest(
src/app/manifest.ts) - 邮件 HTML 内联样式(
src/modules/notifications/channels/email-channel.ts) - 图表 SVG 固定画布尺寸(recharts 选择器中的
#ccc/#fff) - loading.tsx 占位骨架
- Dialog 固定宽度等无法令牌化的设计固定尺寸
- PWA manifest(
- 令牌文件分布:
src/app/styles/tokens/(primitive/semantic-light/semantic-dark/lesson-preparation/tailwind-theme/index) - 令牌分层:
- Layer 1 Primitive(
primitive.css):原始色板/字号/间距/阴影,业务代码不直接引用 - Layer 2 Semantic(
semantic-light.css+semantic-dark.css):语义令牌,业务代码唯一引用入口 - 模块命名空间(
lesson-preparation.css):--lp-*令牌,明暗双份 - Tailwind 暴露(
tailwind-theme.css):@theme inline将 Semantic 令牌暴露为bg-*/text-*/font-*类
- Layer 1 Primitive(
- 改令牌必同步图: 修改令牌定义后,同步更新
docs/architecture/004_architecture_impact_map.md与 arch.db(npm run arch:scan) - ESLint 强制约束:
no-restricted-syntax: 禁止#hex字面量design-tokens/no-hardcoded-fonts: 禁止'Inter'/'Fraunces'/'JetBrains Mono'字面量(单词边界匹配,不影响Interval/Interactive等标识符)- 白名单:
primitive.css(令牌定义)、email-channel.ts(邮件 HTML)、manifest.ts(PWA)
安全规范
- 禁止
dangerlySetInnerHTML(如必须使用,先用 DOMPurify 清洗) - JWT/session ID 存储在 httpOnly + Secure + SameSite=Strict 的 Cookie 中
- 服务端环境变量不加
NEXT_PUBLIC_前缀 - 环境变量使用
@t3-oss/env-nextjs+ Zod 校验(已实现于src/env.mjs)
提交规范
- 使用 Conventional Commits 格式:
feat(scope): description - 类型:
feat,fix,chore,docs,style,refactor,test,perf,ci - 提交前必须运行
npm run lint和npx tsc --noEmit确保零错误
问题记录规则
所有工作完成后,必须将遇到的问题记录到 docs/troubleshooting/known-issues.md(索引式速查手册)。
必须记录的场景
| 场景 | 记录要求 |
|---|---|
| 构建报错(dev/build/lint/tsc) | 记录到"全局经验"对应主题分区 |
| 运行时异常(白屏/API 报错/数据加载失败) | 记录到"模块经验"对应模块分区 |
| 框架/库版本兼容问题 | 记录到"全局经验: Next.js 配置与运行时" |
| 依赖配置问题(serverExternalPackages/webpackIgnore 等) | 记录到"全局经验: Next.js 配置与运行时" |
| 架构约束违规 | 记录到"全局经验"对应主题分区 |
记录格式
索引式表格,指明"场景→技术/规则"映射,不写多行代码示例:
### X.X 主题分区
| 场景 | 技术/规则 |
|------|----------|
| 简述场景 | 正确做法(一句话) |
记录要求
- 索引式:场景→技术/规则映射,不写代码示例和错误示范列
- 去重:同类问题在原条目补充,不重复创建
- 引用架构规则:架构分层、模块结构等规则引用 004 和 project_rules,不重复
- 工作经验日志:在"工作经验日志"区按时间倒序追加(50 条上限),记录"做了什么/学到什么/下次注意"
AI 工作强制流程
所有 AI 工作必须遵循此流程,违反即违规。
阶段 1: 上下文加载
npm run arch:scan更新 arch.dbnpm run arch:query -- module-deps查目标模块依赖npm run arch:query -- symbol-refs <目标函数>查调用链- 阅读
src/modules/[模块]/README.md读模块工作流程 - 查
docs/troubleshooting/known-issues.md"模块经验" 分区读相关经验
阶段 2: 执行工作
- 按规划执行
- 修改代码后立即运行
npm run arch:scan更新 arch.db - 运行
npx tsc --noEmit和npm run lint确保零错误
阶段 3: 经验沉淀(强制,不可跳过)
- 在
docs/troubleshooting/known-issues.md"工作经验日志" 区追加一条记录:- 日期 + 时间
- 模块
- 做了什么 + 学到什么
- 若发现新的"场景→技术"映射 → 提炼到对应模块分区
- 若发现新的架构决策 → 更新 004
- 若代码结构变化 →
npm run arch:scan确认 arch.db 已更新