# `src/shared/types` 规范核查报告 v2

> 核查日期：2026-06-18（第二轮）
> 核查范围：`src/shared/types/` 目录下所有前后端文件 + 关联使用方
> 依据文档：项目规则、编码规范、架构影响地图 004、架构数据 005
> 应用技能：`vercel-react-best-practices`、`web-artifacts-builder`、`web-design-guidelines`
> 前置版本：[student_bug.md](./student_bug.md)（v1）

---

## 〇、修正进度总览

| 类别 | v1 问题数 | 已修正 | 未修正 | 新发现 | v2 合计 |
|------|-----------|--------|--------|--------|---------|
| 高危违规 | 8 | 5 | 3 | 2 | 5 |
| 中危违规 | 6 | 2 | 4 | 1 | 5 |
| 低危违规 | 3 | 0 | 3 | 0 | 3 |
| React 性能 | 3 | 0 | 3 | 0 | 3 |
| Web 界面 | 3 | 0 | 3 | 0 | 3 |
| 文档同步 | 3 | 0 | 3 | 1 | 4 |
| **合计** | **23** | **7** | **16** | **4** | **20** |

**修正率**：7/23 = 30.4%

---

## 一、已修正问题（7 项 ✅）

### ✅ BUG-A01：Prettier 分号违规 — 已修正
- **文件**：[action-state.ts](../src/shared/types/action-state.ts)
- **v1 状态**：使用分号结尾，违反 `.prettierrc` 的 `"semi": false`
- **v2 验证**：第 9-14 行已移除所有分号，符合规范

### ✅ BUG-A02：缺少 JSDoc 文档注释 — 已修正
- **文件**：[action-state.ts](../src/shared/types/action-state.ts)
- **v1 状态**：`ActionState<T>` 无 JSDoc
- **v2 验证**：第 1-8 行已补充 JSDoc，说明 `success`/`message`/`errors`/`data` 各字段语义

### ✅ BUG-P01：权限点命名不一致 — 已修正
- **文件**：[permissions.ts](../src/shared/types/permissions.ts)
- **v1 状态**：`EXAM_PROCTOR_READ: "exam:proctor_read"` 使用下划线
- **v2 验证**：第 94 行已改为 `"exam:proctor:read"`，统一冒号分隔

### ✅ BUG-P04：`DataScope` 缺少 JSDoc — 已修正
- **文件**：[permissions.ts](../src/shared/types/permissions.ts)
- **v2 验证**：第 110-120 行已补充 JSDoc，说明 6 种 type 的适用角色

### ✅ BUG-P05：`AuthContext` 缺少 JSDoc — 已修正
- **文件**：[permissions.ts](../src/shared/types/permissions.ts)
- **v2 验证**：第 129-136 行已补充 JSDoc，说明各字段语义

### ✅ BUG-X01：`exams/actions.ts` 类型导入违规 — 已修正
- **文件**：[exams/actions.ts](../src/modules/exams/actions.ts)
- **v2 验证**：第 4 行已改为 `import type { ActionState } from "@/shared/types/action-state"`

### ✅ BUG-X02：`questions/actions.ts` 类型导入违规 — 已修正
- **文件**：[questions/actions.ts](../src/modules/questions/actions.ts)
- **v2 验证**：第 7 行已改为 `import type { ActionState } from "@/shared/types/action-state"`

---

## 二、未修正问题（16 项 ❌）

### 2.1 permissions.ts — 严重度：高

#### ❌ BUG-P02：`Permissions` 常量缺少 `satisfies` 类型约束（未修正）
- **位置**：[permissions.ts:106](../src/shared/types/permissions.ts)
- **问题**：仍为 `as const`，未用 `satisfies` 验证所有值均为字符串
- **规范依据**：编码规范 4.2.3
- **改进建议**：
  ```typescript
  } as const satisfies Record<string, string>
  ```

#### ❌ BUG-P03：`AuthContext.roles` 类型过于宽松（未修正）
- **位置**：[permissions.ts:139](../src/shared/types/permissions.ts)
- **问题**：`roles: string[]` 允许任意字符串，但项目角色是有限集合
- **改进建议**：定义 `Role` 联合类型，`AuthContext.roles` 改为 `Role[]`

#### ❌ BUG-P06：`DataScope.class_members` 缺少关联数据（未修正）
- **位置**：[permissions.ts:124](../src/shared/types/permissions.ts)
- **问题**：`{ type: "class_members" }` 不携带 classIds，data-access 层需重复查询
- **改进建议**：`{ type: "class_members"; classIds: string[] }`

---

### 2.2 action-state.test.ts — 严重度：中

#### ❌ BUG-T01：测试覆盖率不足（未修正）
- **位置**：[action-state.test.ts:4-33](../src/shared/types/action-state.test.ts)
- **问题**：仅测试 3 种基本状态，缺少多字段错误、falsy data、空 message 等边界用例
- **规范依据**：编码规范十「工具函数覆盖率目标 100%」

#### ❌ BUG-T02：测试描述缺少行为意图（未修正）
- **位置**：[action-state.test.ts:4](../src/shared/types/action-state.test.ts)
- **问题**：`describe("ActionState")` 过于宽泛
- **改进建议**：`describe("ActionState 类型构造")`

---

### 2.3 tsconfig.json — 严重度：中

#### ❌ BUG-C01：`target` 低于规范要求（未修正）
- **位置**：[tsconfig.json:3](../tsconfig.json)
- **问题**：`"target": "ES2017"`，编码规范 4.1 要求 `"ES2022"`

#### ❌ BUG-C02：缺少 `noUncheckedIndexedAccess`（未修正）
- **位置**：[tsconfig.json](../tsconfig.json)
- **问题**：未启用，`ROLE_PERMISSIONS[name]` 在 name 不存在时返回 `Permission[]` 而非 `Permission[] | undefined`

#### ❌ BUG-C03：缺少 `noImplicitReturns` 等（未修正）
- **位置**：[tsconfig.json](../tsconfig.json)
- **问题**：未启用 `noImplicitReturns`、`noFallthroughCasesInSwitch`、`forceConsistentCasingInFileNames`

---

### 2.4 React 性能（应用 `vercel-react-best-practices`）

#### ❌ PERF-01：`use-permission.ts` 回调函数未 memoize（未修正）
- **位置**：[use-permission.ts:11-25](../src/shared/hooks/use-permission.ts)
- **问题**：`hasPermission`/`hasAnyPermission`/`hasAllPermissions`/`hasRole` 每次渲染创建新引用
- **违反规则**：`rerender-functional-setstate`、`rerender-memo`
- **改进建议**：使用 `useCallback` 包裹

#### ❌ PERF-02：`permissions`/`roles` 数组未 memoize（未修正）
- **位置**：[use-permission.ts:8-9](../src/shared/hooks/use-permission.ts)
- **问题**：`?? []` 每次创建新数组引用，导致下游依赖项失效
- **违反规则**：`rerender-derived-state`
- **改进建议**：使用 `useMemo` 包裹

#### ❌ PERF-03：`as` 断言使用（未修正）
- **位置**：[use-permission.ts:8-9](../src/shared/hooks/use-permission.ts)
- **问题**：`as Permission[]`、`as string[]` 违反编码规范 4.2.3
- **改进建议**：依赖 `next-auth.d.ts` 类型增强，移除断言

#### `use-permission.ts` 完整改进示例

```typescript
import { useCallback, useMemo } from "react"
import { useSession } from "next-auth/react"
import type { Permission } from "@/shared/types/permissions"

export function usePermission() {
  const { data: session } = useSession()

  const permissions = useMemo(
    () => (session?.user?.permissions ?? []) as Permission[],
    [session?.user?.permissions]
  )
  const roles = useMemo(
    () => (session?.user?.roles ?? []) as string[],
    [session?.user?.roles]
  )

  const hasPermission = useCallback(
    (permission: Permission): boolean => permissions.includes(permission),
    [permissions]
  )
  const hasAnyPermission = useCallback(
    (...perms: Permission[]): boolean => perms.some((p) => permissions.includes(p)),
    [permissions]
  )
  const hasAllPermissions = useCallback(
    (...perms: Permission[]): boolean => perms.every((p) => permissions.includes(p)),
    [permissions]
  )
  const hasRole = useCallback(
    (role: string): boolean => roles.includes(role),
    [roles]
  )

  return { permissions, roles, hasPermission, hasAnyPermission, hasAllPermissions, hasRole }
}
```

---

### 2.5 Web 界面规范（应用 `web-design-guidelines`）

#### ❌ UI-01：权限状态可能导致 hydration mismatch（未修正）
- **位置**：[use-permission.ts:7](../src/shared/hooks/use-permission.ts)
- **问题**：`useSession()` 服务端返回 `null`/`loading`，客户端 hydration 后权限 UI 闪烁
- **违反规则**：Hydration Safety

#### ❌ UI-02：权限不足重定向未反映在 URL（未修正）
- **位置**：[proxy.ts:75-76](../src/proxy.ts)
- **问题**：重定向到默认页时未携带原始路径，用户不知「为何被重定向」
- **违反规则**：Navigation & State「URL reflects state」
- **改进建议**：携带 `?from=originalPath&reason=forbidden`

#### ❌ UI-03：错误消息缺少修复步骤（未修正）
- **位置**：[auth-guard.ts:13](../src/shared/lib/auth-guard.ts)
- **问题**：`Permission denied: ${permission}` 仅描述问题，未提供下一步
- **违反规则**：Content & Copy「Error messages include fix/next step」

---

## 三、v2 新发现问题（4 项 🆕）

### 🆕 NEW-01：`USER_PROFILE_UPDATE` 权限点语义分组不当 — 严重度：中
- **位置**：[permissions.ts:41-45](../src/shared/types/permissions.ts)
- **问题**：`USER_PROFILE_UPDATE` 放在 `// School management` 分组下（第 40 行注释），与 `SCHOOL_MANAGE`/`GRADE_MANAGE`/`USER_MANAGE` 同组，但语义上它是「用户自助更新个人资料」，不属于学校管理
- **改进建议**：独立为 `// User` 分组
  ```typescript
  // User (用户自助)
  USER_PROFILE_UPDATE: "user:profile_update",
  ```

### 🆕 NEW-02：`questions/actions.ts` 全文件使用分号 — 严重度：中
- **位置**：[questions/actions.ts](../src/modules/questions/actions.ts)
- **问题**：全文件 62 处使用分号结尾，违反 `.prettierrc` 的 `"semi": false`，且与 `exams/actions.ts`（无分号）风格冲突
- **规范依据**：编码规范十五、统一工具配置
- **改进建议**：运行 `npx prettier --write src/modules/questions/actions.ts` 自动修复

### 🆕 NEW-03：`ROLE_PERMISSIONS` 键类型未约束 — 严重度：中
- **位置**：[permissions.ts:5](../src/shared/lib/permissions.ts)（lib 层）
- **问题**：`ROLE_PERMISSIONS: Record<string, Permission[]>` 键类型为 `string`，允许任意字符串作为角色名，与 BUG-P03 同源问题
- **改进建议**：配合 BUG-P03 新增 `Role` 类型后，改为 `Record<Role, Permission[]>`

### 🆕 NEW-04：权限点数量与文档记录严重不符 — 严重度：低
- **位置**：[permissions.ts](../src/shared/types/permissions.ts) vs [004 文档](../docs/architecture/004_architecture_impact_map.md)
- **问题**：permissions.ts 现有 **61 个权限点**（v1 时 54 个，新增 7 个：`EXAM_SUBMIT`、`USER_PROFILE_UPDATE`、`LESSON_PLAN_CREATE/READ/UPDATE/DELETE/PUBLISH`），但 004 文档第 436 行仍记录「54 个权限点常量」，第 1541 行仍记录「54 个权限点」
- **改进建议**：更新 004 文档为「61 个权限点」

---

## 四、架构文档同步问题（4 项）

### ❌ DOC-01：004 文件行数与权限点数记录过期（未修正 + 数量变化）
- **位置**：[004_architecture_impact_map.md:436](../docs/architecture/004_architecture_impact_map.md)
- **v1 问题**：记录 92 行，实际 114 行
- **v2 现状**：记录仍为 `92 | 54 个权限点常量`，实际 **142 行 | 61 个权限点 + DataScope + AuthContext**
- **改进建议**：更新为 `142 行 | 61 个权限点 + DataScope + AuthContext`

### ❌ DOC-02：005 JSON 中 `DataScope` 字段顺序与代码不一致（未修正）
- **位置**：[005_architecture_data.json:1035](../docs/architecture/005_architecture_data.json)
- **问题**：JSON 中顺序为 `all, owned, class_taught, grade_managed, class_members, children`，代码中为 `all, owned, class_members, grade_managed, class_taught, children`

### ❌ DOC-03：缺少 `Role` 类型定义记录（未修正）
- **问题**：若按 BUG-P03 新增 `Role` 类型，需在 005 JSON 补充记录

### 🆕 DOC-04：005 JSON 权限点数量未同步（新发现）
- **位置**：[005_architecture_data.json:63-125](../docs/architecture/005_architecture_data.json)
- **问题**：JSON 中 `permissions` 节点已包含新增的 `EXAM_SUBMIT`、`USER_PROFILE_UPDATE`、`LESSON_PLAN_*`（共 61 个），但 004 文档仍记录 54 个，两文档不一致
- **改进建议**：以 005 JSON 为准，更新 004 文档的权限点数量

---

## 五、问题汇总统计（v2）

| 严重度 | 数量 | 问题编号 |
|--------|------|----------|
| 高 | 3 | BUG-P02, BUG-P03, BUG-P06 |
| 中 | 5 | BUG-T01, BUG-T02, BUG-C01, BUG-C02, NEW-01 |
| 低 | 3 | BUG-C03, DOC-02, DOC-03 |
| 性能 | 3 | PERF-01, PERF-02, PERF-03 |
| 界面 | 3 | UI-01, UI-02, UI-03 |
| 文档 | 3 | DOC-01, DOC-04, NEW-03 |
| **合计** | **20** | |

---

## 六、修复优先级建议（v2 调整）

### P0（立即修复 — 影响类型安全与一致性）
1. BUG-C01、BUG-C02、BUG-C03：升级 `tsconfig.json`（**v1 未修复，升级为 P0**）
2. NEW-02：`questions/actions.ts` 分号违规（Prettier 一致性）
3. BUG-P02：`Permissions` 添加 `satisfies`

### P1（本迭代修复 — 影响可维护性）
4. BUG-P03 + NEW-03：新增 `Role` 类型，`ROLE_PERMISSIONS` 改为 `Record<Role, Permission[]>`
5. PERF-01、PERF-02、PERF-03：`use-permission.ts` 性能优化
6. NEW-01：`USER_PROFILE_UPDATE` 语义分组调整

### P2（下迭代修复 — 增强健壮性）
7. BUG-T01、BUG-T02：补充测试用例
8. BUG-P06：`DataScope.class_members` 携带 classIds
9. UI-01、UI-02、UI-03：界面规范改进

### P3（文档同步）
10. DOC-01、DOC-04：更新 004 文档权限点数量（54 → 61）和行数（92 → 142）
11. DOC-02、DOC-03：同步 005 JSON 字段顺序，补充 `Role` 类型记录

---

## 七、v1 → v2 修正对比

| v1 编号 | 问题 | v1 严重度 | v2 状态 | 备注 |
|---------|------|-----------|---------|------|
| BUG-A01 | action-state.ts 分号 | 高 | ✅ 已修正 | 移除分号 |
| BUG-A02 | action-state.ts JSDoc | 高 | ✅ 已修正 | 补充 JSDoc |
| BUG-P01 | 权限点命名 | 高 | ✅ 已修正 | `exam:proctor:read` |
| BUG-P02 | Permissions satisfies | 高 | ❌ 未修正 | — |
| BUG-P03 | Role 类型 | 高 | ❌ 未修正 | — |
| BUG-P04 | DataScope JSDoc | 高 | ✅ 已修正 | 补充 JSDoc |
| BUG-P05 | AuthContext JSDoc | 高 | ✅ 已修正 | 补充 JSDoc |
| BUG-P06 | class_members classIds | 高 | ❌ 未修正 | — |
| BUG-T01 | 测试覆盖率 | 中 | ❌ 未修正 | — |
| BUG-T02 | 测试描述 | 中 | ❌ 未修正 | — |
| BUG-X01 | exams import type | 中 | ✅ 已修正 | — |
| BUG-X02 | questions import type | 中 | ✅ 已修正 | — |
| BUG-C01 | tsconfig target | 中 | ❌ 未修正 | — |
| BUG-C02 | noUncheckedIndexedAccess | 中 | ❌ 未修正 | — |
| BUG-C03 | noImplicitReturns | 低 | ❌ 未修正 | — |
| PERF-01 | useCallback | 性能 | ❌ 未修正 | — |
| PERF-02 | useMemo | 性能 | ❌ 未修正 | — |
| PERF-03 | as 断言 | 性能 | ❌ 未修正 | — |
| UI-01 | hydration mismatch | 界面 | ❌ 未修正 | — |
| UI-02 | URL 状态 | 界面 | ❌ 未修正 | — |
| UI-03 | 错误消息 | 界面 | ❌ 未修正 | — |
| DOC-01 | 004 行数记录 | 低 | ❌ 未修正 | 行数从 114→142，差距更大 |
| DOC-02 | 005 字段顺序 | 低 | ❌ 未修正 | — |
| DOC-03 | Role 记录 | 低 | ❌ 未修正 | — |

---

## 八、验证命令

修复完成后应运行以下命令确保零错误：

```bash
npm run lint
npx tsc --noEmit
npm run test:unit -- action-state
npx prettier --check "src/shared/types/**/*.ts" "src/modules/questions/actions.ts"
```

---

> 报告生成人：AI Agent（GLM-5.2）
> 核查方法：v1 对比审查 + 架构图比对 + 技能规则匹配
> 版本：v2.0
