feat(portal-shell): v2.0 P1-P4 token migration + unit tests + prod endpoint + e2e
P1: 31 widget 旧纸感令牌批量迁移到 shadcn 标准(1104 次替换) - bg-paper→bg-background / bg-surface→bg-card / text-ink→text-foreground - 保留 button.tsx 中 bg-accent(shadcn 标准 hover 语义令牌) P2: v2.0 新增组件单元测试补齐(5 文件 81 用例) - permission-bitmap: 24 用例(含 GRADE_READ 重复去重) - route-permissions: 26 用例(4 张表优先级 + AND/OR 语义) - notify: 12 用例(sonner toast 双重性质 vi.hoisted mock) - use-error-report: 9 用例(jsdom Blob vi.stubGlobal mock) - plugin-boundary: 10 用例(错误边界 + 骨架变体) P3: 错误上报端点生产替换(后端 /api/v1/log) - api-gateway: internal/log/handler.go(slog 结构化日志,64KB 限制,204 返回) - main.go: 注册 POST /api/v1/log 路由 - useErrorReport: 环境感知端点(prod→/api/v1/log,dev→/api/log) P4: E2E 测试(3 文件 30 用例) - streaming: 4 用例(React 19 use() + Suspense,act 包裹 render) - error-boundaries: 6 用例(三级错误边界层级 L1/L2/L3) - security-boundaries: 20 用例(L1 角色门禁 + L2 权限点 + L3 数据范围) - vitest setup: IS_REACT_ACT_ENVIRONMENT + jest-dom matchers 验证:typecheck 0 错误 / lint 0 错误 / build 6 路由 / 206 测试全部通过
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
> 版本:2.0
|
||||
> 日期:2026-07-17
|
||||
> 状态:已落地(v2.1 M8-M12 完成 + v1.1 数据抽象与 GraphQL 加固完成 + v2.0 shadcn 标准化 + 三层安全边界 + 流式渲染 + 三级错误处理完成 + P0 全部验证通过:typecheck 0 错误 / lint 0 错误 / build 6 路由生成成功)
|
||||
> 状态:已落地(v2.1 M8-M12 完成 + v1.1 数据抽象与 GraphQL 加固完成 + v2.0 shadcn 标准化 + 三层安全边界 + 流式渲染 + 三级错误处理完成 + P0-P4 全部验证通过:typecheck 0 错误 / lint 0 错误 / build 6 路由生成成功 / 206 测试全部通过)
|
||||
> 架构范式:Modular Monolith + Micro-kernel(单 Next.js App Router 容器 + 插件化仪表盘)
|
||||
> 关联文档:
|
||||
>
|
||||
@@ -1146,52 +1146,58 @@ portal-shell 的关键架构决策记录在 004 文档的 ADR 章节,此处为
|
||||
|
||||
- [x] `pnpm run lint` + `pnpm run typecheck` 零错误(v2.0:含 2 个 auto-generated 文件警告,可忽略)
|
||||
- [x] `pnpm run build` 通过(v2.0:Next.js 16 Turbopack,6 路由生成成功:`/` / `/_not-found` / `/api/health` / `/api/log` / `/api/ready` / `/shell/[[...route]]`)
|
||||
- [x] `pnpm run test` 95/95 通过(lib/api 7 domain 55 用例 + 安全栈 10 用例 + Shell/Lifecycle/Context 30 用例)
|
||||
- [x] `pnpm run test` 206/206 通过(lib/api 7 domain 55 用例 + 安全栈 10 用例 + Shell/Lifecycle/Context 30 用例 + v2.0 新增组件单元测试 81 用例 + v2.0 E2E 测试 30 用例)
|
||||
- [x] 0 处 widget 内联 gql 字面量(强制,arch:scan 违规检测)
|
||||
- [x] 所有新代码遵守 shadcn 标准令牌(v2.0:ESLint 强制,无硬编码颜色/字体/任意值)
|
||||
- [x] 31 个 widget 旧纸感令牌全部迁移到 shadcn 标准(P1:1104 次替换,arch:scan 零违规)
|
||||
- [x] apollo-router 启用 APQ + PQ Manifest + 深度/成本/批量限制
|
||||
- [x] 50 个 GraphQL resolver @auth 审计完成(35 TS + 15 Python),19 个 TS resolver 补齐 @RequirePermission
|
||||
- [x] arch.db 更新,004 文档同步
|
||||
- [x] **v2.0 README 同步**:本文件 v2.0,004 同步更新 ADR-044/045/046/047
|
||||
- [x] **v2.0 流式渲染验证**:首屏 HTML 直出骨架,Config resolve 后流式注入(本地 Docker 验证)
|
||||
- [x] **v2.0 P2 单元测试**:5 文件 81 用例(权限位图 24 + 路由权限 26 + notify 12 + useErrorReport 9 + PluginBoundary 10)
|
||||
- [x] **v2.0 P3 生产端点**:api-gateway POST /api/v1/log + useErrorReport 环境感知端点切换
|
||||
- [x] **v2.0 P4 E2E 测试**:3 文件 30 用例(流式渲染 4 + 三级错误边界 6 + 三层安全边界 20)
|
||||
- [ ] Shell 首屏 LCP < 2s(需真实环境压测验证)
|
||||
- [ ] 插件加载耗时 < 500ms(dynamic import 缓存命中后,需真实环境验证)
|
||||
- [ ] 单元测试覆盖率 ≥ 80%(当前覆盖核心纯函数 + lib/api 全量,admin domain 仅 4 用例待补,插件组件测试待补,v2.0 新增组件测试待补)
|
||||
- [ ] E2E 测试(tests/e2e/portal-shell.spec.ts,待补,含 v2.0 流式渲染 + 三级错误边界场景)
|
||||
- [ ] 单元测试覆盖率 ≥ 80%(当前覆盖核心纯函数 + lib/api 全量 + v2.0 新增组件全量,admin domain 仅 4 用例待补,插件组件渲染测试待补)
|
||||
- [ ] E2E 测试(tests/e2e/ 真实浏览器场景,含 admin 改配置 → 用户刷新生效、apollo-router 深度限制)
|
||||
- [ ] 视觉回归测试(5 种 layout 截图,待补,含 v2.0 shadcn 标准化对比)
|
||||
- [ ] 生产部署前 APOLLO_REQUIRE_PQ_MANIFEST=true + APOLLO_ROUTER_INTROSPECTION=false 写入部署 env
|
||||
- [ ] 31 个 widget 旧纸感令牌批量迁移到 shadcn 标准(P1 阶段,arch:scan 违规检测)
|
||||
|
||||
### 11.3 测试矩阵
|
||||
|
||||
| 测试类型 | 范围 | 文件 | 状态 |
|
||||
| -------- | --------------------------------------------- | ---------------------------------------------------------- | ----------------- |
|
||||
| 单元测试 | PluginLifecycle 纯函数 | `src/shell/__tests__/PluginLifecycle.test.ts` | ✅ 12 用例 |
|
||||
| 单元测试 | Registry 插件注册 | `src/shell/__tests__/Registry.test.ts` | ✅ 6 用例 |
|
||||
| 单元测试 | plugin-context URL 上下文 | `src/lib/__tests__/plugin-context.test.ts` | ✅ 12 用例 |
|
||||
| 单元测试 | lib/api universal domain | `src/lib/api/__tests__/universal.test.ts` | ✅ 6 用例 |
|
||||
| 单元测试 | lib/api sidebar domain | `src/lib/api/__tests__/sidebar.test.tsx` | ✅ 9 用例 |
|
||||
| 单元测试 | lib/api topbar domain | `src/lib/api/__tests__/topbar.test.tsx` | ✅ 9 用例 |
|
||||
| 单元测试 | lib/api teacher domain | `src/lib/api/__tests__/teacher.test.tsx` | ✅ 7 用例 |
|
||||
| 单元测试 | lib/api student domain | `src/lib/api/__tests__/student.test.tsx` | ✅ 9 用例 |
|
||||
| 单元测试 | lib/api parent domain | `src/lib/api/__tests__/parent.test.tsx` | ✅ 11 用例 |
|
||||
| 单元测试 | lib/api admin domain | `src/lib/api/__tests__/admin.test.tsx` | ✅ 4 用例(待补) |
|
||||
| 单元测试 | PQ Manifest + APQ + 深度限制 | `src/lib/api/__tests__/security.test.ts` | ✅ 10 用例 |
|
||||
| 单元测试 | 权限位图 base36 编解码(v2.0) | `packages/shared-ts/__tests__/permission-bitmap.test.ts` | 🚧 待补 |
|
||||
| 单元测试 | 路由权限配置表 + checkRoutePermission(v2.0) | `src/shared/lib/__tests__/route-permissions.test.ts` | 🚧 待补 |
|
||||
| 单元测试 | notify 统一封装(v2.0) | `src/shared/lib/__tests__/notify.test.ts` | 🚧 待补 |
|
||||
| 单元测试 | useErrorReport 节流逻辑(v2.0) | `packages/hooks/__tests__/use-error-report.test.ts` | 🚧 待补 |
|
||||
| 单元测试 | PluginBoundary 三件套(v2.0) | `src/shared/components/__tests__/plugin-boundary.test.tsx` | 🚧 待补 |
|
||||
| 单元测试 | PropsMerger 三层合并 | 待补 | 🚧 |
|
||||
| 单元测试 | 各插件组件渲染 | 待补 | 🚧 |
|
||||
| E2E | 登录 → 加载 layout → 渲染插件 → 切换 layout | `tests/e2e/portal-shell.spec.ts` | ⏳ |
|
||||
| E2E | admin 改配置 → 用户刷新生效 | `tests/e2e/plugin-config.spec.ts` | ⏳ |
|
||||
| E2E | apollo-router 拒绝 11 层嵌套查询 | `tests/e2e/graphql-depth-limit.spec.ts` | ⏳ |
|
||||
| E2E | apollo-router 拒绝未知 PQ hash | `tests/e2e/graphql-pq-manifest.spec.ts` | ⏳ |
|
||||
| E2E | 流式渲染 + 三级错误边界(v2.0) | `tests/e2e/streaming-and-error-boundary.spec.ts` | ⏳(v2.0) |
|
||||
| E2E | 三层安全边界 + 权限位图(v2.0) | `tests/e2e/security-boundary.spec.ts` | ⏳(v2.0) |
|
||||
| 视觉回归 | 5 种 layout 截图对比 | `tests/visual/portal-shell.spec.ts` | ⏳ |
|
||||
| 视觉回归 | shadcn 标准化对比(v2.0) | `tests/visual/shadcn-migration.spec.ts` | ⏳(v2.0) |
|
||||
| 测试类型 | 范围 | 文件 | 状态 |
|
||||
| -------- | --------------------------------------------------- | ---------------------------------------------------------- | ----------------- |
|
||||
| 单元测试 | PluginLifecycle 纯函数 | `src/shell/__tests__/PluginLifecycle.test.ts` | ✅ 12 用例 |
|
||||
| 单元测试 | Registry 插件注册 | `src/shell/__tests__/Registry.test.ts` | ✅ 6 用例 |
|
||||
| 单元测试 | plugin-context URL 上下文 | `src/lib/__tests__/plugin-context.test.ts` | ✅ 12 用例 |
|
||||
| 单元测试 | lib/api universal domain | `src/lib/api/__tests__/universal.test.ts` | ✅ 6 用例 |
|
||||
| 单元测试 | lib/api sidebar domain | `src/lib/api/__tests__/sidebar.test.tsx` | ✅ 9 用例 |
|
||||
| 单元测试 | lib/api topbar domain | `src/lib/api/__tests__/topbar.test.tsx` | ✅ 9 用例 |
|
||||
| 单元测试 | lib/api teacher domain | `src/lib/api/__tests__/teacher.test.tsx` | ✅ 7 用例 |
|
||||
| 单元测试 | lib/api student domain | `src/lib/api/__tests__/student.test.tsx` | ✅ 9 用例 |
|
||||
| 单元测试 | lib/api parent domain | `src/lib/api/__tests__/parent.test.tsx` | ✅ 11 用例 |
|
||||
| 单元测试 | lib/api admin domain | `src/lib/api/__tests__/admin.test.tsx` | ✅ 4 用例(待补) |
|
||||
| 单元测试 | PQ Manifest + APQ + 深度限制 | `src/lib/api/__tests__/security.test.ts` | ✅ 10 用例 |
|
||||
| 单元测试 | 权限位图 base36 编解码(v2.0) | `src/shared/lib/__tests__/permission-bitmap.test.ts` | ✅ 24 用例 |
|
||||
| 单元测试 | 路由权限配置表 + checkRoutePermission(v2.0) | `src/shared/lib/__tests__/route-permissions.test.ts` | ✅ 26 用例 |
|
||||
| 单元测试 | notify 统一封装(v2.0) | `src/shared/lib/__tests__/notify.test.ts` | ✅ 12 用例 |
|
||||
| 单元测试 | useErrorReport 节流逻辑(v2.0) | `src/shared/lib/__tests__/use-error-report.test.ts` | ✅ 9 用例 |
|
||||
| 单元测试 | PluginBoundary 三件套(v2.0) | `src/shared/components/__tests__/plugin-boundary.test.tsx` | ✅ 10 用例 |
|
||||
| E2E | 流式渲染(React 19 use() + Suspense)(v2.0) | `src/__tests__/e2e/streaming.test.tsx` | ✅ 4 用例 |
|
||||
| E2E | 三级错误边界层级(v2.0) | `src/__tests__/e2e/error-boundaries.test.tsx` | ✅ 6 用例 |
|
||||
| E2E | 三层安全边界(L1 角色 + L2 权限 + L3 范围)(v2.0) | `src/__tests__/e2e/security-boundaries.test.ts` | ✅ 20 用例 |
|
||||
| 单元测试 | PropsMerger 三层合并 | 待补 | 🚧 |
|
||||
| 单元测试 | 各插件组件渲染 | 待补 | 🚧 |
|
||||
| E2E | 登录 → 加载 layout → 渲染插件 → 切换 layout | `tests/e2e/portal-shell.spec.ts` | ⏳ |
|
||||
| E2E | admin 改配置 → 用户刷新生效 | `tests/e2e/plugin-config.spec.ts` | ⏳ |
|
||||
| E2E | apollo-router 拒绝 11 层嵌套查询 | `tests/e2e/graphql-depth-limit.spec.ts` | ⏳ |
|
||||
| E2E | apollo-router 拒绝未知 PQ hash | `tests/e2e/graphql-pq-manifest.spec.ts` | ⏳ |
|
||||
| E2E | 流式渲染 + 三级错误边界(v2.0) | `tests/e2e/streaming-and-error-boundary.spec.ts` | ⏳(v2.0) |
|
||||
| E2E | 三层安全边界 + 权限位图(v2.0) | `tests/e2e/security-boundary.spec.ts` | ⏳(v2.0) |
|
||||
| 视觉回归 | 5 种 layout 截图对比 | `tests/visual/portal-shell.spec.ts` | ⏳ |
|
||||
| 视觉回归 | shadcn 标准化对比(v2.0) | `tests/visual/shadcn-migration.spec.ts` | ⏳(v2.0) |
|
||||
|
||||
---
|
||||
|
||||
@@ -1248,10 +1254,10 @@ portal-shell 的关键架构决策记录在 004 文档的 ADR 章节,此处为
|
||||
| v1.1 FU-1 | 4 个 TS 子图 AuthMiddleware 覆盖 /graphql 路径 | ⏳ Follow-up |
|
||||
| v1.1 FU-2 | Python 子图(data-ana/ai)补 @RequirePermission 基础设施 | ⏳ Follow-up |
|
||||
| v1.1 FU-3 | admin domain 测试用例补齐(当前仅 4 用例) | ⏳ Follow-up |
|
||||
| **v2.0 P1** | **31 widget 旧纸感令牌批量迁移到 shadcn 标准** | ⏳ 规划 |
|
||||
| **v2.0 P2** | **v2.0 新增组件单元测试补齐**(权限位图 / 路由权限 / notify / useErrorReport / PluginBoundary) | ⏳ 规划 |
|
||||
| **v2.0 P3** | **错误上报端点生产替换**(后端 /api/v1/log) | ⏳ 规划 |
|
||||
| **v2.0 P4** | **E2E 测试**(流式渲染 + 三级错误边界 + 三层安全边界) | ⏳ 规划 |
|
||||
| **v2.0 P1** | **31 widget 旧纸感令牌批量迁移到 shadcn 标准** | ✅ 完成(2026-07-17) |
|
||||
| **v2.0 P2** | **v2.0 新增组件单元测试补齐**(权限位图 / 路由权限 / notify / useErrorReport / PluginBoundary) | ✅ 完成(2026-07-17) |
|
||||
| **v2.0 P3** | **错误上报端点生产替换**(后端 /api/v1/log) | ✅ 完成(2026-07-17) |
|
||||
| **v2.0 P4** | **E2E 测试**(流式渲染 + 三级错误边界 + 三层安全边界) | ✅ 完成(2026-07-17) |
|
||||
| P5(二期) | 第三方插件上传 + iframe 沙箱 | ⏳ 规划 |
|
||||
| P6(二期) | 插件市场在线商店 | ⏳ 规划 |
|
||||
| P7(二期) | canvas 拖拽编辑器 | ⏳ 规划 |
|
||||
|
||||
Reference in New Issue
Block a user