Files
NextEdu/docs/architecture/audit/archive/data-access-audit-v1-data.json

172 lines
11 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"version": "v1",
"createdAt": "2026-07-07",
"scope": {
"dataAccessFiles": 86,
"actionsFilesAudited": 15,
"totalFilesAudited": 101
},
"summary": {
"totalIssues": 230,
"bySeverity": {
"P0": 17,
"P1": 48,
"P2": 105,
"P3": 60
},
"byDimension": {
"pattern": 54,
"performance": 71,
"architecture": 58,
"structure": 47
}
},
"metrics": {
"serverOnlyMissing": 2,
"cacheFnMissingEstimated": 60,
"filesOver800Lines": 3,
"filesOver1000Lines": 1,
"filesOver20Exports": 5,
"asAssertionsNonExempt": 2,
"anyUsage": 0,
"consoleErrorCount": 25,
"nPlusOnePatterns": 11,
"likeFullScanPatterns": 7,
"selectStarCount": 35,
"noLimitQueries": 18,
"crossModuleSchemaAccess": 7,
"businessLogicInDataAccess": 18,
"unprotectedTransactions": 4,
"actionsPermissionIssues": 4,
"actionsDirectDB": 1
},
"moduleHeatmap": [
{ "module": "messaging", "p0": 1, "p1": 4, "total": 5, "risk": "critical" },
{ "module": "classes", "p0": 1, "p1": 4, "total": 14, "risk": "critical" },
{ "module": "school", "p0": 0, "p1": 5, "total": 8, "risk": "critical" },
{ "module": "lesson-preparation", "p0": 1, "p1": 3, "total": 28, "risk": "high" },
{ "module": "scheduling", "p0": 1, "p1": 2, "total": 6, "risk": "high" },
{ "module": "adaptive-practice", "p0": 1, "p1": 2, "total": 4, "risk": "high" },
{ "module": "elective", "p0": 0, "p1": 3, "total": 7, "risk": "high" },
{ "module": "textbooks", "p0": 2, "p1": 1, "total": 11, "risk": "high" },
{ "module": "onboarding", "p0": 2, "p1": 0, "total": 2, "risk": "medium" },
{ "module": "grades", "p0": 0, "p1": 2, "total": 4, "risk": "medium" },
{ "module": "questions", "p0": 1, "p1": 1, "total": 11, "risk": "medium" },
{ "module": "audit", "p0": 1, "p1": 1, "total": 3, "risk": "medium" },
{ "module": "parent", "p0": 1, "p1": 0, "total": 1, "risk": "medium" },
{ "module": "attendance", "p0": 0, "p1": 1, "total": 9, "risk": "medium" },
{ "module": "files", "p0": 0, "p1": 4, "total": 13, "risk": "medium" },
{ "module": "exams", "p0": 1, "p1": 0, "total": 1, "risk": "low" },
{ "module": "course-plans", "p0": 1, "p1": 0, "total": 5, "risk": "low" },
{ "module": "homework", "p0": 0, "p1": 1, "total": 2, "risk": "low" },
{ "module": "diagnostic", "p0": 0, "p1": 1, "total": 2, "risk": "low" }
],
"p0Issues": [
{ "id": "G4-003", "file": "src/modules/audit/actions.ts", "lines": "L192-225", "ruleId": "A-08", "title": "purgeAuditLogsAction 用读权限执行物理删除", "category": "security" },
{ "id": "G4-002", "file": "src/modules/parent/", "lines": "—", "ruleId": "A-08", "title": "parent 模块缺失 actions.ts3 页面直访 data-access", "category": "security" },
{ "id": "G2-001", "file": "src/modules/exams/data-access.ts", "lines": "L1", "ruleId": "P-01", "title": "缺 import server-only", "category": "security" },
{ "id": "G5-001", "file": "src/modules/onboarding/data-access.ts", "lines": "L1", "ruleId": "P-01", "title": "缺 import server-only", "category": "security" },
{ "id": "G1-001", "file": "src/modules/textbooks/data-access-graph.ts", "lines": "L7-121", "ruleId": "A-06", "title": "直查 questions + diagnostic 模块表", "category": "architecture" },
{ "id": "G3-002", "file": "src/modules/scheduling/data-access.ts", "lines": "L8-17", "ruleId": "A-06", "title": "直查 classes/users/subjects 三模块表", "category": "architecture" },
{ "id": "G3-003", "file": "src/modules/scheduling/data-access-class-schedule.ts", "lines": "L28-158", "ruleId": "A-02", "title": "data-access 含校验+状态机业务逻辑", "category": "architecture" },
{ "id": "G5-002", "file": "src/modules/onboarding/actions.ts", "lines": "L15-76", "ruleId": "A-09", "title": "actions 直查 DB", "category": "architecture" },
{ "id": "G4-001", "file": "src/modules/messaging/data-access.ts", "lines": "L1-1089", "ruleId": "S-01", "title": "1089 行超 1000 硬限", "category": "structure" },
{ "id": "G1-002", "file": "src/modules/questions/data-access.ts", "lines": "L294-315", "ruleId": "F-01", "title": "deleteQuestionRecursive 递归 N+1", "category": "performance" },
{ "id": "G1-003", "file": "src/modules/questions/data-access.ts", "lines": "L350-378", "ruleId": "F-01", "title": "deleteQuestionsBatch 循环 N+1", "category": "performance" },
{ "id": "G1-004", "file": "src/modules/lesson-preparation/data-access-comments.ts", "lines": "L128-140", "ruleId": "F-01", "title": "deleteComment 递归 N+1", "category": "performance" },
{ "id": "G1-005", "file": "src/modules/textbooks/data-access.ts", "lines": "L426-458", "ruleId": "F-01", "title": "reorderChapters 循环 UPDATE", "category": "performance" },
{ "id": "G3-001", "file": "src/modules/classes/data-access.ts", "lines": "L17-313", "ruleId": "P-03", "title": "24+ 读函数未走 cacheFn", "category": "performance" },
{ "id": "G3-004", "file": "src/modules/classes/data-access-teacher.ts", "lines": "L92-116", "ruleId": "F-01", "title": "getTeacherClassesRaw 2N+1", "category": "performance" },
{ "id": "G3-005", "file": "src/modules/course-plans/data-access.ts", "lines": "L324-331", "ruleId": "F-01", "title": "reorderCoursePlanItems N+1 + 未包裹事务", "category": "performance" },
{ "id": "G2-003", "file": "src/modules/adaptive-practice/data-access-analytics.ts", "lines": "L311-384", "ruleId": "F-01", "title": "getTeacherClassPracticeOverviewsRaw 2N+1", "category": "performance" }
],
"roadmap": {
"phase0": {
"name": "紧急安全修复",
"priority": "immediate",
"tasks": [
{ "id": "G2-001", "effort": "XS", "action": "添加 import server-only 到 exams/data-access.ts" },
{ "id": "G5-001", "effort": "XS", "action": "添加 import server-only 到 onboarding/data-access.ts" },
{ "id": "G4-002", "effort": "M", "action": "新建 parent/actions.ts3 页面改调 Action" },
{ "id": "G4-003", "effort": "S", "action": "audit purge 权限点新增 + 替换" },
{ "id": "G4-004", "effort": "S", "action": "audit retention 权限点替换" },
{ "id": "G5-002", "effort": "S", "action": "onboarding/actions.ts 移除直查 DB" }
]
},
"phase1": {
"name": "P0 架构与性能修复",
"priority": "high",
"tasks": [
{ "batch": "1.1", "ids": ["G1-001", "G3-002", "G1-031", "G1-032", "G1-033"], "effort": "L", "action": "跨模块 schema 直查治理" },
{ "batch": "1.2", "ids": ["G4-001", "G4-005", "G4-006", "G4-007", "G4-008"], "effort": "L", "action": "messaging 拆分" },
{ "batch": "1.3", "ids": ["G1-002", "G1-003", "G1-004", "G1-005", "G3-001", "G3-004", "G3-005", "G2-003"], "effort": "L", "action": "N+1 热路径修复" },
{ "batch": "1.4", "ids": ["G3-003", "G3-024", "G3-025"], "effort": "M", "action": "scheduling 业务逻辑下移" },
{ "batch": "1.5", "ids": ["G5-003", "G5-004"], "effort": "L", "action": "elective 业务逻辑拆分" }
]
},
"phase2": {
"name": "P1 性能与结构优化",
"priority": "medium",
"tasks": [
{ "batch": "2.1", "ids": ["G1-006", "G1-007", "G1-008", "G1-009", "G3-017", "G4-010"], "effort": "L", "action": "LIKE 全表扫描治理" },
{ "batch": "2.2", "ids": ["G3-007", "G2-005"], "effort": "M", "action": "超长文件拆分" },
{ "batch": "2.3", "ids": ["G3-007", "G3-008", "G3-009", "G3-010", "G3-011"], "effort": "L", "action": "school 模块重构" },
{ "batch": "2.4", "ids": ["G5-005", "G5-006", "G5-007"], "effort": "M", "action": "files 模块错误处理重构" },
{ "batch": "2.5", "ids": ["G3-006", "G3-012", "G3-025", "G4-009"], "effort": "S", "action": "事务包裹修复" },
{ "batch": "2.6", "ids": ["G1-011", "G1-012", "G1-013", "G1-050", "G1-051", "G1-052", "G1-053", "G3-031", "G3-032", "G3-041", "G3-044"], "effort": "M", "action": "无 LIMIT 查询保护" }
]
},
"phase3": {
"name": "P2 模式标准化",
"priority": "low",
"tasks": [
{ "batch": "3.1", "ids": ["G1-021", "G1-022", "G1-023", "G1-024", "G3-001"], "effort": "M", "action": "cacheFn 全量补齐" },
{ "batch": "3.2", "ids": ["G1-039-049", "G3-009", "G3-026-028", "G5-007"], "effort": "M", "action": "SELECT * 改显式列" },
{ "batch": "3.3", "ids": ["G3-021", "G3-047", "G1-025"], "effort": "S", "action": "日期 helper 提取" },
{ "batch": "3.4", "ids": ["G1-026", "G1-027", "G3-020", "G3-036"], "effort": "M", "action": "重复 helper 提取" },
{ "batch": "3.5", "ids": ["G1-034-036", "G1-066", "G1-067", "G3-046"], "effort": "M", "action": "JSDoc 补齐" }
]
},
"phase4": {
"name": "P3 风格优化",
"priority": "optional",
"tasks": [
{ "ids": ["G3-029", "G3-030"], "effort": "XS", "action": "as widening 断言改类型标注" },
{ "ids": ["G1-060-065"], "effort": "XS", "action": "非空断言 ! 改类型守卫" },
{ "ids": ["G3-048"], "effort": "S", "action": "export * 改显式 re-export" },
{ "ids": ["G3-018"], "effort": "XS", "action": "死代码删除" }
]
}
},
"crossModuleRecommendations": {
"newSharedHelpers": [
{ "name": "toISODateString", "path": "src/shared/lib/date-utils.ts", "replaces": ["attendance/serializeDate", "scheduling/serializeDate", "school/toIso", "course-plans/toIso"] },
{ "name": "buildScopeFilter", "path": "src/shared/lib/scope-filter.ts", "replaces": ["attendance/buildScopeFilter", "grades/buildScopeFilter"] }
],
"newCrossModuleInterfaces": [
{ "name": "getActiveStudentIdsByClassIds", "module": "classes", "callers": ["adaptive-practice", "attendance"] },
{ "name": "getGradeNamesByIds", "module": "school", "callers": ["textbooks", "lesson-preparation"] },
{ "name": "getQuestionCountByKpIds", "module": "questions", "callers": ["textbooks"] },
{ "name": "getKpMasteryByTextbookId", "module": "diagnostic", "callers": ["textbooks"] }
],
"newPermissions": [
{ "name": "AUDIT_LOG_PURGE", "description": "审计日志物理删除", "roles": ["admin"] },
{ "name": "AUDIT_RETENTION_MANAGE", "description": "审计保留策略配置", "roles": ["admin"] }
]
},
"architectureDocGaps": [
"parent 模块缺失 actions.ts - 004 文档模块清单未标注",
"onboarding/actions.ts 直查 DB - 005 文档 dependencyMatrix 需修正",
"messaging/data-access.ts 拆分后 - 005 文档 modules.messaging.exports 需更新",
"新增权限点 AUDIT_LOG_PURGE / AUDIT_RETENTION_MANAGE - 005 文档 permissions 需补记",
"新增 shared/lib/date-utils.ts - 004/005 shared 模块清单需补记"
],
"sourceOutputs": [
"docs/architecture/audit/g1-audit-output.json",
"docs/architecture/audit/g2-data-access-audit.json",
"docs/architecture/audit/g3-audit-output.json",
"docs/architecture/audit/g4-audit-output.json",
"docs/architecture/audit/g5-audit-output.json"
]
}