docs(known-issues): log enterprise architecture normalization work experience
Some checks failed
CI / scheduled-backup (push) Failing after 1m32s
CI / backup-verify (push) Has been skipped
CI / weekly-dr-drill (push) Failing after 0s
CI / build-deploy (push) Has been cancelled
CI / security-scan (push) Has been cancelled
Lighthouse CI / lighthouse (push) Has been cancelled

This commit is contained in:
SpecialX
2026-07-07 20:25:33 +08:00
parent dbb124bf17
commit e3d132dc1b
2 changed files with 226 additions and 223 deletions

View File

@@ -11,7 +11,7 @@
### 1.1 i18n
| 场景 | 规则 |
|------|------|
| ------------------------ | -------------------------------------------------------------------------------- |
| key 命名 | 禁止包含 `.`,不同字段用驼峰,同字段多角色变体用嵌套对象 |
| 动态 key 调用 | `t()` 参数为动态变量时必须包含完整嵌套路径(`t(\`type.${type}\`)`而非`t(type)` |
| ICU 参数 | 单花括号 `{level}`,多参数直接并列 `{count} 题 · {subject}` |
@@ -24,7 +24,7 @@
### 1.2 Next.js 配置与运行时
| 场景 | 技术/规则 |
|------|----------|
| --------------------------------- | ---------------------------------------------------------------------------------- |
| Node.js 服务端驱动 | `serverExternalPackages: ["mysql2"]` 标记为外部包 |
| 输出模式 | `output: "standalone"` |
| Tailwind v4 排除非源码 | `globals.css` 中 `@source not "../../docs";` 防止 docs 字符串被扫描成类 |
@@ -38,7 +38,7 @@
### 1.3 Server/Client Component 边界
| 场景 | 规则 |
|------|------|
| --------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| "use server" 文件 | 只能导出 `async function`;常量放 `types.ts`/`constants.ts`;同步函数放 `lib/`;禁止值 re-export类型 re-export 允许 |
| Client Component 依赖隔离 | 不得 import server-only 文件;`import { db }` 的文件不得被客户端 import |
| Server Component 传递函数 | 禁止向 Client Component 传递函数,改传纯数据 + 在客户端调用 Server Action |
@@ -48,7 +48,7 @@
### 1.4 数据库与 Drizzle
| 场景 | 规则 |
|------|------|
| -------------------------- | ----------------------------------------------------------------------------------------------- |
| schema.ts 修改后 | 必须 `npm run db:push` 或 `npm run db:migrate` 同步数据库 |
| `Unknown column` 报错 | 先 `SHOW COLUMNS FROM 表名` 对比实际结构与 schema.ts |
| 迁移文件管理 | 必须录入 `_journal.json`;编号唯一不可复用;`__drizzle_migrations` 表必须记录 hash |
@@ -61,7 +61,7 @@
### 1.5 状态管理
| 场景 | 技术 |
|------|------|
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 5 层状态模型 | L1 URL(nuqs) · L2 Server(TanStack Query) · L3 Client(Zustand slice) · L4 Global UI(Zustand ui-store + ModalRoot) · L5 Form(react-hook-form + zodResolver) |
| Zustand selector | 单字段 selector 优于 `useShallow` 多字段包装 |
| useOptimistic | 乐观更新(消息星标、成绩编辑、考勤提交),`addOptimistic` 必须在 transition 或 action 内调用 |
@@ -71,7 +71,7 @@
### 1.6 性能优化
| 场景 | 技术 |
|------|------|
| ---------------------- | --------------------------------------------------------------------------- |
| 批量 INSERT | `db.insert().values([...])` 单次写入 |
| 批量 UPDATE | `sql.join` + `CASE WHEN` 单次执行 |
| 递归删除 | 批量收集后代 ID + `inArray` 单次删除,禁止递归逐个 |
@@ -89,7 +89,7 @@
### 1.7 设计令牌
| 场景 | 规则 |
|------|------|
| -------------------- | --------------------------------------------------------------------- |
| 禁止硬编码颜色 | TSX/TS/CSS 中不得出现 `#hex`,用 `hsl(var(--*))` 或 Tailwind 类 |
| 禁止硬编码字体 | 不得出现 `'Inter'`/`'Fraunces'`/`'JetBrains Mono'` 字面量 |
| 禁止硬编码字号 | 不得出现 `font-size: Npx`,用 `var(--font-size-1~9)` |
@@ -101,7 +101,7 @@
### 1.8 TypeScript
| 场景 | 规则 |
|------|------|
| ---------------- | ------------------------------------------------------------------------------- |
| 禁止 `any` | 未知类型用 `unknown` + 类型守卫 |
| 禁止 `as` 断言 | 除非从 `unknown` 转换或测试中(需注释原因) |
| 类型守卫优先 | JSON.parse 结果经 `unknown` 中转 + 守卫localStorage/URL param/HTTP 响应需守卫 |
@@ -115,7 +115,7 @@
### 1.9 API 路由
| 场景 | 规则 |
|------|------|
| ---------------- | ------------------------------------------------------------------------------------------------------ |
| 响应信封 | `{ success, message?, errorCode?, data? }` 与 `ActionState<T>` 对齐 |
| 错误→状态码 | PermissionDeniedError→403 / NotFoundError→404 / ValidationError→400 / BusinessError→400 / 其他→500 |
| 统一异常处理 | `withApiErrorHandler(handler)` HOF 消除重复 try/catch |
@@ -129,7 +129,7 @@
### 1.10 日志系统
| 场景 | 规则 |
|------|------|
| ------------------ | ---------------------------------------------------------------------------------------------- |
| 服务端日志 | `createModuleLogger("module-name")` + pino禁止 `console.*` |
| 日志参数顺序 | `log.error({ err: error, userId }, "操作描述")` |
| 错误对象字段名 | `err`(不是 `error` |
@@ -141,7 +141,7 @@
### 1.11 测试
| 场景 | 规则 |
|------|------|
| ---------------------------- | --------------------------------------------------------------------------------- |
| Vitest + Next.js 16 缓存测试 | server-only alias 到空 stub`cache()` 包装函数测试需 mock |
| Playwright 检测 | 检查 HTTP 状态码 + pageerror循环外注册一次+ 可见错误元素,不检查 HTML content |
| testTimeout | ts-morph 解析慢arch-scan 测试设置 60000ms |
@@ -149,7 +149,7 @@
### 1.12 ESLint 与验证命令
| 场景 | 命令/规则 |
|------|----------|
| -------------------- | ---------------------------------------------------------------------- |
| 类型检查 | `npx tsc --noEmit` |
| Lint | `npm run lint` |
| 开发服务器 | `npm run dev` |
@@ -170,7 +170,7 @@
### 2.1 lesson-preparation备课
| 场景 | 规则 |
|------|------|
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| Zustand store 拆 slice | mutation 方法包装 history`pushHistory` + `set``updateNodePosition` 不推 historyhydrate/replaceDoc 清空历史history 栈上限 `MAX_HISTORY` |
| 撤销/重做快捷键 | `metaKey \|\| ctrlKey` 区分 MacShift+Z 或 Y 重做;`preventDefault` |
| 自动保存失败 UI | toast.error + 断网时不触发 + 监听 online/offline + saveError 显示重试按钮 |
@@ -196,7 +196,7 @@
### 2.2 exams / homework / grades
| 场景 | 规则 |
|------|------|
| ------------- | ------------------------------------------------------------------------ |
| AI 出题 | `exams/ai-pipeline.ts` + `createAiChatCompletion` + JSON 解析 + Zod 校验 |
| 作业化考试 | `sourceExamId` 外键关联;`homeworkSubmissions` + `homeworkAnswers` 表 |
| 批改事务 | `db.transaction` 包裹多步写 |
@@ -206,7 +206,7 @@
### 2.3 messaging / notifications
| 场景 | 规则 |
|------|------|
| ---------------- | -------------------------------------------------------------------- |
| 消息星标乐观更新 | `useOptimistic<boolean>` + `useTransition` + `addOptimisticStarred` |
| 消息列表星标 Map | `useOptimistic<Map<string, boolean>>`key=messageId |
| 撤回不乐观更新 | 需服务端返回判断 2 分钟窗口 |
@@ -217,14 +217,14 @@
### 2.4 attendance
| 场景 | 规则 |
|------|------|
| ----------------------- | ------------------------------------------------------------------------------------------ |
| 考勤提交乐观更新 | `useOptimistic<boolean>` 保留 form action 模式(`useFormStatus` 依赖 form action promise |
| 不用 useTransition 包裹 | 会导致 form action 立即返回、`useFormStatus` 不可靠 |
### 2.5 school / classes / scheduling
| 场景 | 规则 |
|------|------|
| ------------------------ | ------------------------------------------------------------------------------------ |
| school data-access 拆分 | `data-access-{departments,grades,subjects,classrooms,semesters,schools}.ts` + barrel |
| 角色判断迁出 data-access | `lib/school-permissions.ts` 导出 `getSchoolsForUser(userId)` |
| promoteGrades 事务 | `db.transaction` 包裹 select + update 循环 |
@@ -236,7 +236,7 @@
### 2.6 audit / rbac
| 场景 | 规则 |
|------|------|
| -------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| 破坏性操作用专属权限 | `AUDIT_LOG_PURGE` ≠ `AUDIT_LOG_READ` |
| 权限点注册全链路 | `permissions.ts` → `ROLE_PERMISSIONS_SEED` → `permission-bitmap.ts` → `permission-catalog.ts` → i18n `rbac.json` 五处同步 |
| 审计日志保留管理 | `AUDIT_RETENTION_MANAGE` 权限点 |
@@ -244,7 +244,7 @@
### 2.7 parent
| 场景 | 规则 |
|------|------|
| ------------------ | ------------------------------------------------------------------- |
| parent actions.ts | app/ 必须调用 `@/modules/parent/actions`,不直接 import data-access |
| 路由权限校验 | 同时校验 `parentId` + `studentId` 防止信息泄露 |
| dashboard 数据获取 | `Promise.all` / `Promise.allSettled` 并行 |
@@ -253,8 +253,8 @@
### 2.8 shared
| 场景 | 规则 |
|------|------|
| session.ts 单一入口 | shared/lib/* 不再静态 import @/auth |
| ----------------------- | ---------------------------------------------------------------------------------------------- |
| session.ts 单一入口 | shared/lib/\* 不再静态 import @/auth |
| dynamic import 打破循环 | `session.ts` 内部 `dynamic import("@/auth")` |
| 重复 helper 提取 | `serializeDate` / `downloadBase64File` / `getInitials` / `isRecord` / `extractQuestionPreview` |
| ROLE_NAMES 常量 | 替代 DB 查询中硬编码角色名 |
@@ -270,7 +270,10 @@
### 2026-07-07
| 时间 | 模块 | 经验 |
|------|------|------|
| ----- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 22:30 | 全局 | 企业级架构规范化 P2 完成CI 新增 Unit test 阶段;创建 /api/health 端点 + Dockerfile HEALTHCHECK安装 @next/bundle-analyzer`npm run analyze` 触发noUncheckedIndexedAccess 评估 419 错误,推迟到独立迭代(记入 tech-debt TD-P1-001 |
| 22:10 | 全局 | 企业级架构规范化 P1 完成:创建 LICENSE专有协议/CHANGELOG/CONTRIBUTING/SECURITY 大仓文档;安装 husky + lint-staged + commitlintpre-commit 运行 eslint+prettiercommit-msg 校验 conventional commits 格式;填充 tech-debt.mdP0/P1/P2 分级 + 已解决项) |
| 21:50 | 全局 | 企业级架构规范化 P0 完成arch:scan @public JSDoc 标记豁免机制12 个登录前/公开/内部工具 Action递归 CTE 识别间接调用链requireAiPermission 等辅助函数);修复 9 个真违规parent 5 个 requireAuth→requirePermission + settings 1 个显式校验 + 3 个 @public 豁免);拆分 5 个超长文件schema.ts 2245→29+27子文件、invalidation-map.ts 1195→50+6子文件、messaging/actions.ts 973→47+5子文件、textbooks/data-access.ts 907→15+6子文件、questions/data-access.ts 828→48+4子文件违规数 32→0 |
| 21:30 | 全局 | 004 架构文档 V3 重构:从"影响地图"升级为"架构设计文档"14 章节 912 行。核心 mermaid 图:系统边界图 + 三层架构图 + 模块依赖全景图35 模块分层)+ 认证 sequenceDiagram + 权限系统架构图 + 数据访问分层图 + 5 层状态模型图 + 跨模块协作 sequenceDiagram + 考试全生命周期 sequenceDiagram跨 4 模块)+ 令牌分层架构图 + API 路由分类图 + 错误→状态码映射图 + userId/permission 影响链。模块细节移至各模块 README004 聚焦架构层面:技术栈选型/分层规则/依赖深度统计/循环依赖处理/权限 3 道防线/缓存策略/状态层选用规则/聚合层模式/事件驱动闭环/硬性约束/性能原则/安全原则/架构决策记录 |
| 20:56 | 全模块 | 35 个模块 README 重写为完整架构文档:每个含 mermaid 架构图graph TB 分层)+ 2-3 个 流程图sequenceDiagram/flowchart+ 技术栈表格 + 文件结构(行数来自 arch.db+ 依赖关系双向表 + 关键约束 + 架构决策表。标杆 textbooks/README.md 251 行。arch:query 提供真实数据(模块统计/文件清单/依赖关系/技术标签)。并行子代理执行时 arch:scan 可能因竞争报 FOREIGN KEY 错误,串行执行正常 |
| 12:56 | onboarding/parent/messaging | data-access 审计 Phase 0 P0 修复完成6 项onboarding 加 server-only + DB 操作下沉parent 新建 actions.ts6 个 Server Actionmessaging data-access.ts1089 行)拆分为 5 子文件 + barrel |
@@ -282,13 +285,13 @@
### 2026-07-06
| 时间 | 模块 | 经验 |
|------|------|------|
| ----- | ---- | ------------------------------------------------------------------------------------------------- |
| 23:50 | 全局 | 文档体系重设计计划制定arch.db 扫描器 + 004 瘦身 + 005 废弃 + known-issues 精简 + 35 模块 README |
### 2026-07-05
| 时间 | 模块 | 经验 |
|------|------|------|
| ---- | --------------------------- | ---------------------------------------------------------------------------------------------------- |
| 全天 | 全局 | V5 状态管理重构 Phase 1-3 完成notify 替换为 zustand + ModalRootuseDialogState 评估结论(不采用) |
| 全天 | 全局 | 性能预算重构Phase 1 配置基线 + Phase 2 Bundle 预算 + Phase 3 数据层优化 + Phase 4 组件渲染优化 |
| 全天 | questions/search | FULLTEXT 索引 + MATCH AGAINST BOOLEAN MODE 替代 LIKE '%xxx%' |
@@ -299,7 +302,7 @@
### 2026-07-04
| 时间 | 模块 | 经验 |
|------|------|------|
| ---- | ---- | -------------------------------------------------------------------------------------------- |
| 全天 | 全局 | API 规范化重构:响应信封 + 错误→状态码映射 + SSE 工具 + withApiErrorHandler HOF |
| 全天 | 全局 | 设计令牌专项重构双层令牌架构Primitive + Semantic+ ESLint 强制约束 |
| 全天 | 全局 | PWA 支持manifest.ts + viewport + 触控友好panOnDrag/zoomOnPinch/zoomOnDoubleClick=false |
@@ -307,37 +310,37 @@
### 2026-07-02
| 时间 | 模块 | 经验 |
|------|------|------|
| ---- | ------------------ | ------------------------------------------------------------------------------------- |
| 全天 | lesson-preparation | V5 备课模块场景缺口修复Zustand slice + history + 自动保存 + Tiptap Image + 打印视图 |
### 2026-06-26
| 时间 | 模块 | 经验 |
|------|------|------|
| ---- | ------- | ------------------------------------------------------------------------------------------ |
| 全天 | student | 学生端路由权限校验修复:`homework:submit` → `CLASS_READ`;新增 `loading.tsx` + `error.tsx` |
| 全天 | classes | teacher/classes/* 路由权限校验修复:统一 `CLASS_READ` |
| 全天 | classes | teacher/classes/\* 路由权限校验修复:统一 `CLASS_READ` |
### 2026-06-24
| 时间 | 模块 | 经验 |
|------|------|------|
| ---- | ------ | ------------------------------------------------------------------------ |
| 全天 | grades | 成绩录入支持按试卷录入:`getExamsForGradeEntry` / `getExamForGradeEntry` |
| 全天 | shared | `ROLE_NAMES` 常量替代 DB 硬编码角色名;`extractQuestionPreview` 共享工具 |
### 2026-06-23
| 时间 | 模块 | 经验 |
|------|------|------|
| ---- | ------ | ------------------------------------------------------------------------------------------------------------------- |
| 全天 | shared | Action 错误处理统一:`handleActionError` / `safeActionCall` / `BusinessError` / `NotFoundError` / `ValidationError` |
### 2026-06-22
| 时间 | 模块 | 经验 |
|------|------|------|
| ---- | ------- | -------------------------------- |
| 全天 | classes | teacher/classes 路由权限审计修复 |
### 2026-06-17
| 时间 | 模块 | 经验 |
|------|------|------|
| ---- | ---- | ------------------------------------------------------------------ |
| 全天 | 全局 | 004 架构影响地图首次编写4227 行,后于 2026-07-07 瘦身至 458 行) |

Binary file not shown.