12 KiB
企业级架构规范化设计
日期: 2026-07-07 状态: 已批准 范围: P0 安全合规 + P1 大仓工程基建 + P2 配置升级 实施策略: 方案 A(严格分阶段,每阶段独立提交)
1. 背景与目标
1.1 现状诊断
通过 arch:query violations + 配置文件审查 + 文档检查,发现 14 个维度的企业级/大仓规范缺口,按严重级别分类:
P0 严重(影响安全/规范底线)
- 32 个 Server Action 缺
requirePermission()校验(集中在 ai/auth/parent/settings/rbac/onboarding) - 5 个文件超过 1000 行硬性上限(
schema.ts2245 行、invalidation-map.ts1195 行、messaging/actions.ts973 行、textbooks/data-access.ts907 行、questions/data-access.ts828 行)
P1 工程基建缺口
- 缺大仓标配文档: LICENSE / CHANGELOG.md / CONTRIBUTING.md / SECURITY.md / .env.example
- 缺提交期前钩子: 无 husky + lint-staged + commitlint,提交规范仅靠自觉
docs/architecture/roadmap/tech-debt.md是空壳(11 行无内容)
P2 配置不完整
tsconfig.json中noUncheckedIndexedAccess: false- CI 不跑 unit test(
ci.yml跳过test:unit) package.json无engines/packageManager字段- 无 bundle-analyzer / coverage 阈值 /
/api/health端点 / API 文档
1.2 目标
- P0: 消除所有架构违规(
arch:query violations输出仅剩已知豁免) - P1: 大仓文档齐全 + 提交规范工具链强制 + tech-debt 可追踪
- P2: TypeScript 严格模式全量开启 + CI 覆盖 unit test + 可观测性补充
2. 设计决策
| 决策点 | 选择 | 理由 |
|---|---|---|
| 实施范围 | 全部 P0+P1+P2 | 完整治理 |
| 豁免机制 | JSDoc @public 标记 |
显式标记、可审计、与代码同源 |
| noUncheckedIndexedAccess | 一次性开启+全量修复 | 一步到位,避免债务拖延 |
| scripts 治理 | 本次不做,记入 tech-debt | 范围可控 |
| 提交钩子 | husky + lint-staged + commitlint | 全套强制规范 |
| LICENSE | 专有协议(内部项目) | 不计划开源 |
| 实施策略 | 方案 A(严格分阶段) | 每阶段可独立验证+回滚 |
3. 阶段 1: P0 安全合规
3.1 Server Action 权限治理
3.1.1 arch:scan 豁免标记机制
修改 scripts/arch-scan/scanner.ts:扫描函数时识别 JSDoc 中的 @public 标记,将该函数标记为 is_public: true 存入 symbols 表。
修改 scripts/arch-scan/query.ts 的 violations 命令:过滤掉 is_public: true 的 Server Action。
3.1.2 合理豁免清单(加 @public 标记,共 ~12 个)
| 文件 | 函数 | 豁免理由 |
|---|---|---|
auth/actions.ts |
registerAction | 注册(登录前) |
auth/actions.ts |
checkEmailAvailabilityAction | 邮箱可用性检查(注册时) |
auth/actions.ts |
preflightTwoFactorAction | 2FA 预检(登录中) |
invitation-codes/actions.ts |
validateInvitationCodeAction | 邀请码校验(注册时) |
onboarding/actions.ts |
getOnboardingStatusAction | 引导状态查询(登录后但引导前) |
onboarding/actions.ts |
completeOnboardingAction | 完成引导(引导阶段) |
settings/actions-security.ts |
preflightTwoFactorAction | 2FA 预检(登录中) |
settings/actions-security.ts |
verifyTwoFactorForLogin | 2FA 验证(登录中) |
rbac/actions.ts |
isAdminRole | 内部辅助函数(非对外 Action) |
shared/lib/audit-logger.ts |
logAudit | 基础设施(非 Action,被 Action 调用) |
shared/lib/change-logger.ts |
logDataChange | 基础设施(同上) |
shared/lib/login-logger.ts |
logLoginEvent | 基础设施(同上) |
3.1.3 真违规修复清单(补 requirePermission,共 ~20 个)
| 文件 | 函数 | 权限点 |
|---|---|---|
ai/actions.ts |
suggestSimilarQuestionsAction | QUESTION_READ |
ai/actions.ts |
suggestGradingAction | HOMEWORK_GRADE |
ai/actions.ts |
generateLessonContentAction | LESSON_PLAN_CREATE |
ai/actions.ts |
generateQuestionVariantAction | QUESTION_CREATE |
ai/actions.ts |
analyzeWeaknessAction | DIAGNOSTIC_READ |
ai/actions.ts |
explainErrorAction | ERROR_BOOK_READ |
leave-requests/actions.ts |
listMyLeaveRequests | LEAVE_REQUEST_READ(自身) |
lesson-preparation/actions.ts |
duplicateLessonPlanFormAction | LESSON_PLAN_CREATE |
parent/actions.ts |
getChildrenAction | PARENT_DASHBOARD_VIEW |
parent/actions.ts |
getChildBasicInfoAction | PARENT_DASHBOARD_VIEW |
parent/actions.ts |
getChildDashboardDataAction | PARENT_DASHBOARD_VIEW |
parent/actions.ts |
getParentDashboardDataAction | PARENT_DASHBOARD_VIEW |
parent/actions.ts |
getChildNameListAction | PARENT_DASHBOARD_VIEW |
parent/actions.ts |
verifyParentChildRelationAction | PARENT_DASHBOARD_VIEW |
settings/actions-service.ts |
updateProfileAction | USER_PROFILE_UPDATE(自身) |
settings/actions.ts |
getAiProviderSummaries | SYSTEM_SETTINGS_READ |
settings/actions.ts |
upsertAiProviderAction | SYSTEM_SETTINGS_MANAGE |
settings/actions.ts |
testAiProviderAction | SYSTEM_SETTINGS_MANAGE |
settings/actions.ts |
deleteAiProviderAction | SYSTEM_SETTINGS_MANAGE |
settings/actions.ts |
canConfigurePublicAiProvider | SYSTEM_SETTINGS_READ |
注: 若上述权限点不存在,需在 shared/types/permissions.ts 新增并注册到 ROLE_PERMISSIONS_SEED + permission-bitmap.ts + permission-catalog.ts + i18n rbac.json 五处。
3.2 超长文件拆分
3.2.1 shared/db/schema.ts (2245 行) → 按域拆分
src/shared/db/
├─ schema.ts # barrel: re-export 所有
├─ schema/
│ ├─ users.ts # users + userRoles + parentStudentRelations
│ ├─ academic.ts # classes + subjects + grades + textbooks + chapters + knowledgePoints
│ ├─ exams.ts # exams + examQuestions + homeworkAssignments + submissions + answers
│ ├─ grades.ts # gradeRecords + gradeStats
│ ├─ attendance.ts # attendanceRecords + attendanceRules
│ ├─ messaging.ts # conversations + messages + messageReadStatus
│ ├─ notifications.ts # notifications + notificationPreferences
│ ├─ audit.ts # auditLogs + changeLogs
│ ├─ rbac.ts # roles + permissions + rolePermissions
│ ├─ files.ts # files + fileReferences
│ ├─ scheduling.ts # classSchedule + timeSlots
│ └─ misc.ts # 其余表
3.2.2 shared/lib/cache/invalidation-map.ts (1195 行) → 按模块拆分
src/shared/lib/cache/
├─ invalidation-map.ts # barrel + registerInvalidationMaps
├─ invalidation/
│ ├─ exams.ts
│ ├─ homework.ts
│ ├─ grades.ts
│ ├─ attendance.ts
│ ├─ messaging.ts
│ ├─ textbooks.ts
│ └─ ...
3.2.3 messaging/actions.ts (973 行) → 按职责拆分
src/modules/messaging/
├─ actions.ts # barrel
├─ actions-conversations.ts # 会话 CRUD
├─ actions-messages.ts # 消息发送/撤回
├─ actions-starred.ts # 星标
└─ actions-read.ts # 已读状态
3.2.4 textbooks/data-access.ts (907 行) → 按实体拆分
src/modules/textbooks/
├─ data-access.ts # barrel + 核心
├─ data-access-graph.ts # 已有
├─ data-access-chapters.ts # 章节 CRUD
└─ data-access-knowledge-points.ts # 知识点 CRUD
3.2.5 questions/data-access.ts (828 行) → 按职责拆分
src/modules/questions/
├─ data-access.ts # barrel + 核心 CRUD
└─ data-access-search.ts # FULLTEXT 检索
4. 阶段 2: P1 大仓工程基建
4.1 大仓文档
| 文件 | 内容 |
|---|---|
LICENSE |
"Copyright (c) 2026 EazyGame. 保留所有权利。未经许可不得复制、修改、分发。" |
CHANGELOG.md |
Keep-a-changelog 格式,初始 ## [1.0.0] - 2026-07-07 条目(记录文档体系重设计完成) |
CONTRIBUTING.md |
分支策略(main 保护) + Conventional Commits + 提交前检查(lint+tsc) + 模块 README 维护规则 + arch:scan 同步 |
SECURITY.md |
漏洞报告流程 + 安全联系人 + 响应 SLA + 不公开披露策略 |
.env.example |
从 src/env.mjs 提取所有键(DATABASE_URL/NEXTAUTH_SECRET/NEXTAUTH_URL/AI keys/...)含注释说明 |
4.2 提交规范工具链
4.2.1 依赖安装
npm install -D husky lint-staged @commitlint/cli @commitlint/config-conventional @next/bundle-analyzer
4.2.2 配置文件
.husky/pre-commit:npx lint-staged.husky/commit-msg:npx commitlint --edit $1commitlint.config.js: extends conventional + scope-enum(35 模块名)lint-staged.config.js:*.{ts,tsx}→eslint --fix+prettier --write;*.md→prettier --writepackage.jsonscripts:"prepare": "husky"
4.3 tech-debt.md 填充
整理待解决技术债(从 known-issues 工作经验日志 + 本次诊断补充):
- scripts 目录混放治理(.sh/.ps1/.js/.mjs/.ts 统一)
- API 文档自动化(OpenAPI 生成)
- proctoring 模块的 exams 依赖未被 arch.db 捕获(scanner 改进)
- FULLTEXT 索引迁移工具化
- client-error 上报机制完善(Task 12-14)
- React Flow 移除后的历史包袱清理
5. 阶段 3: P2 配置升级
5.1 TypeScript 严格化
tsconfig.json:"noUncheckedIndexedAccess": true- 全量修复类型错误: 数组索引
arr[0]→arr[0]!或arr.at(0) ?? defaultValue;对象索引obj[key]→ 显式判空
5.2 CI 完善
ci.yml 修改:
- Lint → Unit test → Typecheck → Architecture scan → Integration → E2E → Build
vitest.unit.config.ts 加 coverage:
coverage: {
provider: "v8",
lines: 60,
functions: 60,
branches: 60,
statements: 60,
}
package.json 补充字段:
{
"engines": { "node": ">=22" },
"packageManager": "npm@10.9.0"
}
5.3 可观测性补充
/api/health 路由:
// src/app/api/health/route.ts
export async function GET() {
return Response.json({
status: "ok",
uptime: process.uptime(),
timestamp: new Date().toISOString(),
version: process.env.npm_package_version,
});
}
Dockerfile 加 HEALTHCHECK(审查现有 Dockerfile 后修改):
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD wget -qO- http://localhost:3000/api/health || exit 1
bundle-analyzer:
package.jsonscripts:"analyze": "ANALYZE=true next build"next.config.ts包装@next/bundle-analyzer
5.4 API 文档
docs/api/README.md: 17 个路由清单 + 请求/响应 schema 示例(从 withApiErrorHandler 与 ActionState 推导)
6. 验收标准
| 阶段 | 验收项 |
|---|---|
| P0 | npm run arch:query -- violations 仅剩 0 个真违规(豁免项不报);npx tsc --noEmit 0 错误;npm run lint 0 错误;5 个超长文件全部 < 1000 行 |
| P1 | LICENSE/CHANGELOG.md/CONTRIBUTING.md/SECURITY.md/.env.example 存在;npm run prepare 安装 husky 钩子;commitlint 拒绝非规范提交;tech-debt.md 含至少 6 条待解决项 |
| P2 | noUncheckedIndexedAccess: true 且 tsc 0 错误;CI 跑 unit test;/api/health 返回 200;npm run analyze 可用;package.json 含 engines+packageManager |
7. 实施约束
- 每阶段开始前
git commit一次快照(用户要求"实施前提交备份") - 每阶段完成后
git commit+git push - 每阶段必须通过
npx tsc --noEmit+npm run lint+npm run arch:scan - 阶段 1 完成后更新
docs/troubleshooting/known-issues.md工作经验日志 - 阶段 3 完成后更新
docs/architecture/004_architecture_impact_map.md(若架构意图变化) - 全程不改
project_rules.md除非有新的强制规则
8. 不在本次范围
- scripts 目录治理(记入 tech-debt)
- OpenAPI 自动生成(记入 tech-debt,本次仅手写静态文档)
- 分支保护策略(Gitea 配置,不在代码层)
- 数据库迁移工具化(已有 drizzle-kit)
- 客户端错误上报机制完善(Task 12-14,独立项目)