=test_update_homework_tests_and_work_log
Some checks failed
CI / build-deploy (push) Has been cancelled

This commit is contained in:
SpecialX
2026-03-19 13:16:49 +08:00
parent eb08c0ab68
commit 99f116cb64
70 changed files with 7470 additions and 20220 deletions

View File

@@ -1,76 +0,0 @@
# Auth UI Implementation Details
**Date**: 2025-12-23
**Author**: Senior Frontend Engineer
**Module**: Auth (`src/modules/auth`)
---
## 1. 概述 (Overview)
本文档记录了登录 (`/login`) 和注册 (`/register`) 页面的前端实现细节。遵循 Vertical Slice Architecture 和 Pixel-Perfect UI 规范。
## 2. 架构设计 (Architecture)
### 2.1 目录结构
所有认证相关的业务逻辑和组件均封装在 `src/modules/auth` 下,保持了高内聚。
```
src/
├── app/
│ └── (auth)/ # 路由层 (Server Components)
│ ├── layout.tsx # 统一的 AuthLayout 容器
│ ├── login/page.tsx
│ └── register/page.tsx
├── modules/
│ └── auth/ # 业务模块
│ └── components/ # 模块私有组件
│ ├── auth-layout.tsx # 左右分屏布局
│ ├── login-form.tsx # 登录表单 (Client Component)
│ └── register-form.tsx # 注册表单 (Client Component)
```
### 2.2 渲染策略
* **Server Components**: 页面入口 (`page.tsx`) 和布局 (`layout.tsx`) 默认为服务端组件,负责元数据 (`Metadata`) 和静态结构渲染。
* **Client Components**: 表单组件 (`*-form.tsx`) 标记为 `'use client'`处理交互逻辑状态管理、表单提交、Loading 状态)。
## 3. UI/UX 细节
### 3.1 布局 (Layout)
采用 **Split Screen (分屏)** 设计:
* **左侧 (Desktop Only)**:
* 深色背景 (`bg-zinc-900`),强调品牌沉浸感。
* 包含 Logo (`Next_Edu`) 和用户证言 (`Blockquote`)。
* 使用 `hidden lg:flex` 实现响应式显隐。
* **右侧**:
* 居中对齐的表单容器。
* 移动端优先 (`w-full`),桌面端限制最大宽度 (`sm:w-[350px]`)。
### 3.2 交互 (Interactions)
* **Loading State**: 表单提交时按钮进入 `disabled` 状态并显示 `Loader2` 旋转动画。
* **Micro-animations**:
* 按钮 Hover 效果。
* 链接 Hover 下划线 (`hover:underline`).
* **Feedback**: 模拟了 3 秒的异步请求延迟,用于演示加载状态。
## 4. 错误处理 (Error Handling)
### 4.1 模块级错误边界
* **Scoped Error Boundary**: `src/app/(auth)/error.tsx` 仅处理 Auth 模块内的运行时错误。
* 显示友好的 "Authentication Error" 提示。
* 提供 "Try again" 按钮重置状态。
### 4.2 模块级 404
* **Scoped Not Found**: `src/app/(auth)/not-found.tsx` 处理 Auth 模块内的无效路径。
* 引导用户返回 `/login` 页面,防止用户迷失。
## 5. 组件复用
* 使用了 `src/shared/components/ui` 中的标准 Shadcn 组件:
* `Button`, `Input`, `Label` (新增).
* 图标库统一使用 `lucide-react`.
## 5. 后续计划 (Next Steps)
* [ ] 集成 `next-auth` (Auth.js) 进行实际的身份验证。
* [ ] 添加 Zod Schema 进行前端表单验证。
* [ ] 对接后端 API (`src/modules/auth/actions.ts`).

View File

@@ -1,164 +0,0 @@
# 学校基础数据模块School实现文档与更新记录
**日期**: 2026-01-07
**作者**: Frontend Team
**状态**: 已实现
## 1. 范围
本文档覆盖管理端「School」域的基础数据维护页面Schools / Departments / Academic Year / Grades并记录相关实现约束与关键更新遵循 [003_frontend_engineering_standards.md](file:///c:/Users/xiner/Desktop/CICD/docs/architecture/003_frontend_engineering_standards.md) 的工程规范Vertical Slice、Server/Client 边界、质量门禁)。
## 2. 路由入口Admin
School 域路由位于 `src/app/(dashboard)/admin/school/*`,均显式声明 `export const dynamic = "force-dynamic"` 以避免构建期预渲染触发数据库访问。
- `/admin/school`:入口重定向到 Classes当前落点不在 `school` 模块内)
实现:[page.tsx](file:///c:/Users/xiner/Desktop/CICD/src/app/(dashboard)/admin/school/page.tsx)
- `/admin/school/schools`:学校维护(增删改)
实现:[page.tsx](file:///c:/Users/xiner/Desktop/CICD/src/app/(dashboard)/admin/school/schools/page.tsx)
- `/admin/school/departments`:部门维护(增删改)
实现:[page.tsx](file:///c:/Users/xiner/Desktop/CICD/src/app/(dashboard)/admin/school/departments/page.tsx)
- `/admin/school/academic-year`:学年维护(增删改 + 设为当前学年)
实现:[page.tsx](file:///c:/Users/xiner/Desktop/CICD/src/app/(dashboard)/admin/school/academic-year/page.tsx)
- `/admin/school/grades`:年级维护(增删改 + 指派年级组长/教研组长)
实现:[page.tsx](file:///c:/Users/xiner/Desktop/CICD/src/app/(dashboard)/admin/school/grades/page.tsx)
- `/admin/school/grades/insights`:年级维度作业统计(跨班级聚合)
实现:[page.tsx](file:///c:/Users/xiner/Desktop/CICD/src/app/(dashboard)/admin/school/grades/insights/page.tsx)
## 3. 模块结构Vertical Slice
School 模块位于 `src/modules/school`
```
src/modules/school/
├── components/
│ ├── schools-view.tsx
│ ├── departments-view.tsx
│ ├── academic-year-view.tsx
│ └── grades-view.tsx
├── actions.ts
├── data-access.ts
├── schema.ts
└── types.ts
```
边界约束:
- `data-access.ts` 包含 `import "server-only"`,仅用于服务端查询与 DTO 组装。
- `actions.ts` 包含 `"use server"`,写操作统一通过 Server Actions 并 `revalidatePath`
- `components/*` 为 Client 交互层表单、Dialog、筛选、行级操作调用 Server Actions 并用 `sonner` toast 反馈。
## 4. 数据访问data-access.ts
实现:[data-access.ts](file:///c:/Users/xiner/Desktop/CICD/src/modules/school/data-access.ts)
- `getSchools(): Promise<SchoolListItem[]>`
- `getDepartments(): Promise<DepartmentListItem[]>`
- `getAcademicYears(): Promise<AcademicYearListItem[]>`
- `getGrades(): Promise<GradeListItem[]>`
- join `schools` 获取 `school.name`
- 收集 `gradeHeadId/teachingHeadId` 并批量查询 `users` 以组装 `StaffOption`
- `getStaffOptions(): Promise<StaffOption[]>`
- 角色过滤 `teacher/admin`
- 排序 `name/email`,用于 Select 列表可用性
- `getGradesForStaff(staffId: string): Promise<GradeListItem[]>`
- 用于按负责人(年级组长/教研组长)反查关联年级
返回 DTO 类型定义位于:[types.ts](file:///c:/Users/xiner/Desktop/CICD/src/modules/school/types.ts)
## 5. 写操作actions.ts
实现:[actions.ts](file:///c:/Users/xiner/Desktop/CICD/src/modules/school/actions.ts)
通用约束:
- 输入校验:统一使用 [schema.ts](file:///c:/Users/xiner/Desktop/CICD/src/modules/school/schema.ts) 的 Zod schema
- 返回结构:统一使用 [ActionState](file:///c:/Users/xiner/Desktop/CICD/src/shared/types/action-state.ts)
- 刷新策略:对目标页面路径执行 `revalidatePath`
Departments
- `createDepartmentAction(formData)`
- `updateDepartmentAction(departmentId, formData)`
- `deleteDepartmentAction(departmentId)`
Academic Year
- `createAcademicYearAction(formData)`
- `updateAcademicYearAction(academicYearId, formData)`
- `deleteAcademicYearAction(academicYearId)`
-`isActive=true` 时,通过事务把其它学年置为非激活,保证唯一激活学年
Schools
- `createSchoolAction(formData)`
- `updateSchoolAction(schoolId, formData)`
- `deleteSchoolAction(schoolId)`
- 删除后会同时刷新 `/admin/school/schools``/admin/school/grades`
Grades
- `createGradeAction(formData)`
- `updateGradeAction(gradeId, formData)`
- `deleteGradeAction(gradeId)`
## 6. UI 组件components/*
Schools
- 实现:[schools-view.tsx](file:///c:/Users/xiner/Desktop/CICD/src/modules/school/components/schools-view.tsx)
- 交互:列表 + Dialog 表单(新增/编辑)+ 删除确认AlertDialog
Departments
- 实现:[departments-view.tsx](file:///c:/Users/xiner/Desktop/CICD/src/modules/school/components/departments-view.tsx)
- 交互:列表 + Dialog 表单(新增/编辑)+ 删除确认AlertDialog
Academic Year
- 实现:[academic-year-view.tsx](file:///c:/Users/xiner/Desktop/CICD/src/modules/school/components/academic-year-view.tsx)
- 交互:列表 + Dialog 表单(新增/编辑)+ 删除确认AlertDialog+ 设为当前学年isActive
Grades
- 实现:[grades-view.tsx](file:///c:/Users/xiner/Desktop/CICD/src/modules/school/components/grades-view.tsx)
- 交互:列表展示 + URL 驱动筛选(搜索/学校/负责人/排序)+ Dialog 表单(新增/编辑)+ 删除确认AlertDialog
- 负责人指派:
- 年级组长gradeHeadId
- 教研组长teachingHeadId
## 7. 关键交互与规则Grades
页面入口RSC 组装)在服务端并发拉取三类数据:
- 年级列表:`getGrades()`
- 学校选项:`getSchools()`
- 负责人候选:`getStaffOptions()`
实现:[page.tsx](file:///c:/Users/xiner/Desktop/CICD/src/app/(dashboard)/admin/school/grades/page.tsx)
### 7.1 URL State筛选/排序)
Grades 列表页的筛选状态 URL 化(`nuqs`
- `q`:关键字(匹配 grade/school
- `school`:学校过滤(`all` 或具体 schoolId
- `head`:负责人过滤(全部 / 两者缺失 / 缺年级组长 / 缺教研组长)
- `sort`:排序(默认/名称/更新时间等)
实现:[grades-view.tsx](file:///c:/Users/xiner/Desktop/CICD/src/modules/school/components/grades-view.tsx)
### 7.2 表单校验
Grades 的新增/编辑表单在客户端做轻量校验:
- 必填:`schoolId``name`
- `order`:非负整数
- 去重:同一学校下年级名称不允许重复(忽略大小写 + 规范化空格)
说明:
- 服务端写入前仍会经过 `UpsertGradeSchema` 校验schema.ts避免仅依赖客户端校验。
### 7.3 负责人选择Radix Select
Radix Select 约束:`SelectItem``value` 不能为 `""`(空字符串),否则会触发运行时错误。
当前实现策略:
- UI 中 “未设置” 选项使用占位值 `__none__`
-`onValueChange` 中将 `__none__` 映射回 `""` 存入本地表单 state
- 提交时依旧传递空字符串,由 `UpsertGradeSchema` 将其归一为 `null`
实现:[grades-view.tsx](file:///c:/Users/xiner/Desktop/CICD/src/modules/school/components/grades-view.tsx)
## 2. 更新记录2026-01-07
- 修复 Add Grades 弹窗报错:将 4 处 `<SelectItem value=\"\">` 替换为占位值 `__none__`,并在 `onValueChange` 中映射回 `\"\"`,保持“可清空选择/显示 placeholder”的行为不变。
- 修复新建年级按钮不可用:创建/编辑表单在状态变化时触发实时校验更新,避免校验状态滞后导致提交被禁用。
- 质量门禁:本地通过 `npm run lint``npm run typecheck`

View File

@@ -242,6 +242,35 @@
- **目的**: 创建考试基础信息。
- **关键组件**: `ExamForm`
- **AI 生成执行逻辑**:
- **入口**:
- 选择 `Assembly Mode``AI Generation`
- 表单增加 `aiQuestionCount``aiPrompt`,提交时走 `createAiExamAction`
- **请求数据组装**:
- 复用基础字段:`title``subject``grade``difficulty``totalScore``durationMin``scheduledAt`
- 可选字段:`aiQuestionCount``aiPrompt`
- **服务端校验**:
- `AiExamCreateSchema` 校验基础字段与 AI 字段
- 解析失败直接返回 `Invalid form data`
- **AI 调用**:
- 通过 `createAiChatCompletion` 发送系统提示与用户输入
- 使用 `env.AI_MODEL`,默认 `gpt-4o-mini`
- 期望输出 JSON仅包含 `sections``questions`
- **响应解析**:
- `extractJson` 支持从纯 JSON 或代码块中提取
- `AiExamResponseSchema` 校验题型与字段结构
- 无题目返回 `AI returned no questions`
- **题目裁剪与分值归一化**:
- 若设置题量,按顺序裁剪题目或分组
- `normalizeScores``totalScore` 归一化各题分值
- **题目落库**:
- 将 AI 题目转换为题库格式 `{ text, options }`
- 写入 `questions` 表,并记录 `authorId`
- **结构与关联写入**:
- 生成 `structure`(按分组或平铺题目)
- 写入 `exams` 表,同时写入 `exam_questions`
- **后续跳转**:
- 创建成功后跳转 `/teacher/exams/[id]/build` 继续编辑
### 3.17 组卷 `/teacher/exams/[id]/build`
实现:[exams/[id]/build/page.tsx](file:///e:/Desktop/CICD/src/app/(dashboard)/teacher/exams/%5Bid%5D/build/page.tsx)

View File

@@ -0,0 +1,154 @@
# 项目全量测试方案与执行反馈
**日期**: 2026-03-18
**角色**: 首席测试师
**范围**: `src/app` 页面路由、`src/modules` 业务模块、`src/app/api` 接口路由、工程质量门禁
---
## 1. 测试目标
- 建立一份可复用的全量测试方案,覆盖核心业务与工程质量门禁。
- 对当前代码库执行可落地的全量检查,输出可追溯反馈。
- 明确已验证范围、未验证范围、风险与后续建议。
---
## 2. 测试对象与覆盖边界
### 2.1 业务域
- 认证与会话:登录/注册、会话注入、路由守卫
- 教师端:工作台、班级、作业、考试、题库、教材
- 学生端:仪表盘、课程、作业、教材、课表
- 管理端:学校、年级、班级、部门、学年、洞察
- 家长端:仪表盘
- 设置与个人资料
### 2.2 技术域
- 页面路由编译与渲染入口(`src/app/**/page.tsx`
- API 路由编译与入口(`src/app/api/**/route.ts`
- 业务模块(`src/modules/**`
- 类型系统与静态检查TypeScript + ESLint
- 生产构建可通过性Next.js build
### 2.3 本次可执行边界说明
- 已执行静态与构建级全量验证lint、typecheck、build
- 已执行:页面路由与 API 路由清单级覆盖核对(基于代码库现状)。
- 未执行:依赖真实数据库与外部 AI 服务的端到端交互验证(当前环境未提供专用测试库与固定测试账号)。
---
## 3. 测试策略
### 3.1 质量门禁(必须通过)
1. ESLint 静态规范检查
2. TypeScript 类型检查
3. Next.js 生产构建
### 3.2 全量覆盖策略(按层)
1. 路由层:统计并核对全部页面与 API 路由入口文件是否可参与编译
2. 业务层:通过构建期依赖解析与类型系统覆盖模块间调用链
3. 集成层:以 `next build` 验证服务端组件、路由结构、导入关系、打包一致性
4. 回归层:输出缺口与风险,给出后续补测清单
### 3.3 通过标准
- `npm run lint` 退出码为 0
- `npm run typecheck` 退出码为 0
- `npm run build` 退出码为 0
- 无新增阻断级缺陷Blocker/Critical
---
## 4. 测试用例总表(主干)
| 用例ID | 级别 | 用例名称 | 执行方式 | 通过标准 |
|---|---|---|---|---|
| QA-GATE-001 | P0 | 代码规范检查 | `npm run lint` | 命令成功退出 |
| QA-GATE-002 | P0 | 类型系统检查 | `npm run typecheck` | 命令成功退出 |
| QA-GATE-003 | P0 | 生产构建检查 | `npm run build` | 构建成功 |
| QA-ROUTE-001 | P0 | 页面路由入口覆盖 | 路由文件清单核对 | 页面入口均存在 |
| QA-API-001 | P0 | API 路由入口覆盖 | 路由文件清单核对 | API 入口均存在 |
---
## 5. 路由覆盖清单(本次统计)
### 5.1 页面路由入口
- 共统计 `46` 个页面入口文件(`src/app/**/page.tsx`)。
- 覆盖角色:认证、教师、学生、管理端、家长、通用页面。
### 5.2 API 路由入口
- 共统计 `4` 个 API 入口文件(`src/app/api/**/route.ts`)。
- 覆盖接口:`auth``ai/chat``onboarding/status``onboarding/complete`
---
## 6. 执行记录与反馈
### 6.1 执行环境
- 操作系统Windows
- 项目目录:`E:\Desktop\CICD`
- 包管理器npm
### 6.2 结果总览
| 检查项 | 命令 | 结果 | 备注 |
|---|---|---|---|
| 代码规范 | `npm run lint` | 通过 | 退出码 0 |
| 类型检查 | `npm run typecheck` | 通过 | 退出码 0 |
| 生产构建 | `npm run build` | 通过 | 退出码 0构建期间出现 baseline-browser-mapping 数据过期提示 |
| 接口集成测试 | `npm run test:integration` | 通过 | 3 个测试文件10 条用例通过 |
| E2E 冒烟测试 | `npm run test:e2e:smoke` | 通过 | 本地优先使用系统 Chrome2 条用例通过 |
| E2E 全路由回归 | `npm run test:e2e:full-routes` | 通过 | 38 条用例通过,覆盖静态页面路由守卫与可达性 |
### 6.3 缺陷与风险
- 阻断级缺陷0
- 严重缺陷0
- 主要风险:跨角色真实业务数据写入链路仍需测试库与固定账号支撑,当前已完成路由级全覆盖回归。
- 次要风险:构建日志出现 `baseline-browser-mapping` 数据过期提示,建议在依赖维护窗口升级该依赖数据包。
### 6.4 结论
- 当前代码库在静态检查、类型系统与生产构建三道门禁均通过,可进入下一阶段联调或发布候选流程。
- 本次已完成企业级测试基线的第一阶段落地集成测试框架、E2E 框架、CI 质量门禁已接入。
- 本次已完成“代码级全量可构建性 + API 集成验证”并通过,未发现新增回归错误。
- 若要达到“发布级全链路验收”,仍需补充测试库与固定账号下的完整业务 E2E 场景。
---
## 7. 后续补测计划
- 增加端到端测试Playwright覆盖关键教师流创建考试 → 派发作业 → 提交批改。
- 增加 API 集成测试(鉴权、参数校验、错误码)。
- 增加数据层测试(测试库 + 回滚策略)验证查询过滤与 RBAC 边界。
---
## 8. 企业级实现落地清单(本次新增)
- 测试基础设施:
- 新增 Vitest 配置:`vitest.config.ts`
- 新增 Playwright 配置:`playwright.config.ts`
- 新增集成测试初始化:`tests/setup/integration.setup.ts`
- 集成测试用例:
- `tests/integration/api-ai-chat.route.test.ts`
- `tests/integration/api-onboarding-status.route.test.ts`
- `tests/integration/api-onboarding-complete.route.test.ts`
- E2E 冒烟用例:
- `tests/e2e/smoke-auth.spec.ts`
- E2E 全路由回归用例:
- `tests/e2e/full-route-regression.spec.ts`
- 工程脚本:
- `package.json` 新增 `test``test:ci``test:integration``test:e2e``test:e2e:smoke``test:e2e:full-routes`
- CI 门禁:
- `.gitea/workflows/ci.yml` 新增 Playwright Chromium 安装、集成测试、E2E 全量回归测试步骤

View File

@@ -1,261 +0,0 @@
# Next_Edu Design System Specs
**Version**: 1.4.0 (Updated)
**Status**: ACTIVE
**Role**: Chief Creative Director
**Philosophy**: "Data as Art" - Clean, Minimalist, Information-Dense.
---
## 1. 核心理念 (Core Philosophy)
Next_Edu 旨在对抗教育系统常见的信息过载。我们的设计风格深受 **International Typographic Style (国际主义设计风格)** 影响。
* **Precision (精准)**: 每一个像素的留白都有其目的。
* **Clarity (清晰)**: 通过排版和对比度区分层级,而非装饰性的色块。
* **Efficiency (效率)**: 专为高密度数据操作优化,减少视觉噪音。
---
## 2. 视觉基础 (Visual Foundation)
### 2.1 色彩系统 (Color System)
我们放弃 Hex 直选,全面采用 **HSL 语义化变量** 以支持完美的多主题适配。
#### **Base (基调)**
* **Neutral**: Zinc (锌色). 冷峻、纯净,无偏色。
* **Brand**: Deep Indigo (深靛蓝).
* `Primary`: 专业、权威,避免幼稚的高饱和蓝。
* 语义: `hsl(var(--primary))`
#### **Functional (功能色)**
| 语义 | 色系 | 用途 |
| :--- | :--- | :--- |
| **Destructive** | Red | 删除、危险操作、系统错误 |
| **Warning** | Amber | 需注意的状态、非阻断性警告 |
| **Success** | Emerald | 操作成功、状态正常 |
| **Info** | Blue | 一般性提示、帮助信息 |
#### **Surface Hierarchy (层级)**
1. **Background**: 应用底层背景。
2. **Card**: 内容承载容器,轻微提升层级。
3. **Popover**: 悬浮层、下拉菜单,最高层级。
4. **Muted**: 用于次级信息或禁用状态背景。
### 2.2 排版 (Typography)
* **Font Family**: `Geist Sans` > `Inter` > `System UI`.
* *Requirement*: 必须开启 `tabular-nums` (等宽数字) 特性,确保表格数据对齐。
* **Scale**:
* **Base Body**: 14px (0.875rem) - 提升信息密度。
* **H1 (Page Title)**: 24px, Tracking -0.02em, Weight 600.
* **H2 (Section Title)**: 20px, Tracking -0.01em, Weight 600.
* **H3 (Card Title)**: 16px, Weight 600.
* **Tiny/Caption**: 12px, Text-Muted-Foreground.
### 2.3 质感 (Look & Feel)
* **Borders**: `1px solid var(--border)`. 界面骨架,以此分割区域而非背景色块。
* **Radius**:
* `sm` (4px): Badges, Checkboxes.
* `md` (8px): **Default**. Buttons, Inputs, Cards.
* `lg` (12px): Modals, Dialogs.
* **Shadows**:
* Default: None (Flat).
* Hover: `shadow-sm` (仅用于可交互元素).
* Dropdown/Popover: `shadow-md`.
* *Ban*: 禁止使用大面积弥散阴影。
---
## 3. 核心布局 (App Shell)
### 3.1 架构 (Architecture)
我们采用了 `SidebarProvider` + `AppSidebar` 的组合模式,确保了布局的灵活性和移动端的完美适配。
* **Provider**: `SidebarProvider` (src/modules/layout/components/sidebar-provider.tsx)
* 管理侧边栏状态 (`expanded`, `isMobile`).
* 负责在移动端渲染 Sheet (Drawer)。
* 负责在桌面端渲染 Sticky Sidebar。
* **Key Prop**: `sidebar` (显式传递侧边栏组件)。
### 3.2 布局结构
```
+-------------------------------------------------------+
| Sidebar | Header (Sticky) |
| |-------------------------------------------|
| (Collap- | Main Content |
| sible) | |
| | +-------------------------------------+ |
| | | Card | |
| | | +---------------------------------+ | |
| | | | Data Table | | |
| | | +---------------------------------+ | |
| | +-------------------------------------+ |
| | |
+-------------------------------------------------------+
```
### 3.3 详细规范
#### **Sidebar (侧边栏)**
* **Width**: Expanded `260px` | Collapsed `64px` | Mobile `Sheet (Drawer)`.
* **Behavior**:
* Desktop: 固定左侧,支持折叠。
* Mobile: 默认隐藏,点击汉堡菜单从左侧滑出。
* **Navigation Item**:
* Height: `36px` (Compact).
* State:
* `Inactive`: `text-muted-foreground hover:text-foreground`.
* `Active`: `bg-sidebar-accent text-sidebar-accent-foreground font-medium`.
#### **Header (顶栏)**
* **Height**: `64px` (h-16).
* **Layout**: `flex items-center justify-between px-6 border-b`.
* **Components**:
1. **Breadcrumb**: 动态路径导航 (Dynamic Breadcrumb).
* **Implementation**: 基于 `usePathname()` 自动解析路由段。
* **Mapping**: 通过 `NAV_CONFIG``BREADCRUMB_MAP` 映射路径到友好标题 (e.g., `/teacher/textbooks` -> "Textbooks").
* **Filtering**: 自动过滤根角色路径 (e.g., `/teacher`) 以保持简洁。
2. **Global Search**: `Cmd+K` 触发,居中或靠右。
3. **User Nav**: 头像 + 下拉菜单。
#### **Main Content (内容区)**
* **Padding**: `p-6` (Desktop) / `p-4` (Mobile).
* **Max Width**: `max-w-[1600px]` (默认) 或 `w-full` (针对超宽报表)。
---
## 4. 导航与角色系统 (Navigation & Roles)
Next_Edu 支持多角色Multi-Tenant / Role-Based导航系统。
### 4.1 配置文件
导航结构已从 UI 组件中解耦,统一配置在:
`src/modules/layout/config/navigation.ts`
### 4.2 支持的角色 (Roles)
系统内置支持以下角色,每个角色拥有独立的侧边栏菜单结构:
* **Admin**: 系统管理员,拥有所有管理权限 (School Management, User Management, Finance)。
* **Teacher**: 教师,关注班级管理 (My Classes)、成绩录入 (Gradebook) 和日程。
* **Student**: 学生,关注课程学习 (My Learning) 和作业提交。
* **Parent**: 家长,关注子女动态和学费缴纳。
### 4.3 开发与调试
* **View As (Dev Mode)**: 在开发环境下,侧边栏顶部提供 "View As" 下拉菜单,允许开发者实时切换角色视角,预览不同角色的导航结构。
* **Implementation**: `AppSidebar` 组件通过读取 `NAV_CONFIG[currentRole]` 动态渲染菜单项。
---
## 5. 错误处理与边界情况 (Error Handling & Boundaries)
系统必须优雅地处理错误和边缘情况,避免白屏或无反馈。
### 5.1 全局错误边界 (Global Error Boundary)
* **Scope**: 捕获渲染期间的未处理异常。
* **UI**: 显示友好的错误页面(非技术堆栈信息),提供 "Try Again" 按钮重置状态。
* **Implementation**: 使用 React `ErrorBoundary` 或 Next.js `error.tsx`
### 5.2 404 Not Found
* **Design**: 必须保留 App Shell (Sidebar + Header),仅在 Main Content 区域显示 404 提示。
* **Content**: "Page not found" 文案 + 返回 Dashboard 的主操作按钮。
### 5.3 空状态 (Empty States)
当列表或表格无数据时,**严禁**只显示空白。
* **Component**: `EmptyState`
* **Composition**:
1. **Icon**: 线性风格图标 (muted foreground).
2. **Title**: 简短说明 (e.g., "No students found").
3. **Description**: 解释原因或下一步操作 (e.g., "Add a student to get started").
4. **Action**: (可选) "Create New" 按钮。
### 5.4 加载状态 (Loading States)
* **Initial Load**: 使用 `Skeleton` 骨架屏,模拟内容布局,避免 CLS (Content Layout Shift)。禁止使用全屏 Spinner。
* **Action Loading**: 按钮点击后进入 `disabled` + `spinner` 状态。
* **Table Loading**: 表格内容区域显示 3-5 行 Skeleton Rows。
### 5.5 表单验证 (Form Validation)
* **Style**: 错误信息显示在输入框下方,字号 `text-xs`,颜色 `text-destructive`
* **Input**: 边框变红 (`border-destructive`)。
---
## 6. 职责边界与协作 (Responsibility Boundaries)
**[IMPORTANT] 严禁越界修改 (Strict No-Modification Policy)**
为了维护大型项目的可维护性UI 工程师和开发人员必须遵守以下边界规则:
### 6.1 模块化原则 (Modularity)
* **Scope**: 开发者仅应对分配给自己的模块负责。例如,负责 "Dashboard" 的开发者**不应**修改 "Sidebar" 或 "Auth" 模块的代码。
* **Dependencies**: 如果你的模块依赖于其他模块的变更,**必须**先与该模块的负责人沟通,或在 PR 中明确标注。
### 6.2 共享组件 (Shared Components)
* **Immutable Core**: `src/shared/components/ui` 下的基础组件(如 Button, Card视为**核心库**。
* **Extension**: 如果基础组件不能满足需求优先考虑组合Composition或创建新的业务组件而不是修改核心组件的源码。
* **Modification Request**: 只有在发现严重 Bug 或需要全局样式调整时,才允许修改核心组件,且必须经过 Design Lead 审批。
### 6.3 样式一致性 (Consistency)
* **Global CSS**: `globals.css` 定义了系统的物理法则。严禁在局部组件中随意覆盖全局 CSS 变量。
* **Tailwind Config**: 禁止随意在组件中添加任意值Arbitrary Values, e.g., `w-[123px]`),必须使用 Design Token。
---
## 7. 组件设计规范 (Component Specs)
### 7.1 Card (卡片)
卡片是信息组织的基本单元。
* **Class**: `bg-card text-card-foreground border rounded-lg shadow-none`.
* **Header**: `p-6 pb-2`. Title (`font-semibold leading-none tracking-tight`).
* **Content**: `p-6 pt-0`.
### 7.2 Data Table (数据表格)
教务系统的核心组件。
* **Density**:
* `Default`: Row Height `48px` (h-12).
* `Compact`: Row Height `36px` (h-9).
* **Header**: `bg-muted/50 text-muted-foreground text-xs uppercase font-medium`.
* **Stripes**: 默认关闭。仅在列数 > 8 时开启 `even:bg-muted/50`
* **Actions**: 行操作按钮应默认隐形 (`opacity-0`)Hover 时显示 (`group-hover:opacity-100`),减少视觉干扰。
### 7.3 Feedback (反馈与通知)
* **Toast**: 使用 `Sonner` 组件。
* 位置: 默认右下角 (Bottom Right).
* 样式: 极简黑白风格 (跟随主题),支持撤销操作。
* 调用: `toast("Event has been created", { description: "Sunday, December 03, 2023 at 9:00 AM" })`.
* **Skeleton**: 加载状态必须使用 Skeleton 骨架屏,禁止使用全屏 Spinner。
* **Badge**: 状态指示器。
* `default`: 主要状态 (Primary).
* `secondary`: 次要状态 (Neutral).
* `destructive`: 错误/警告状态 (Error).
* `outline`: 描边风格 (Subtle).
---
## 8. 开发指南 (Developer Guide)
### 8.1 CSS Variables
所有颜色和圆角均通过 CSS 变量控制,定义在 `globals.css` 中。禁止在代码中 Hardcode 颜色值 (如 `#FFFFFF`, `rgb(0,0,0)` )。
### 8.2 Tailwind Utility 优先
优先使用 Tailwind Utility Classes。
*`text-sm text-muted-foreground`
*`.custom-text-class { font-size: 14px; color: #666; }`
### 8.3 Dark Mode
设计系统原生支持深色模式。只要正确使用语义化颜色变量(如 `bg-background`, `text-foreground`Dark Mode 将自动完美适配,无需额外编写 `dark:` 修饰符(除非为了特殊调整)。
### 8.4 组件库引用
所有 UI 组件位于 `src/shared/components/ui`
* `Button`: 基础按钮
* `Input`: 输入框
* `Select`: 下拉选择器 (New)
* `Sheet`: 侧边栏/抽屉
* `Sonner`: Toast 通知
* `Badge`: 徽章/标签
* `Skeleton`: 加载占位符
* `DropdownMenu`: 下拉菜单
* `Avatar`: 头像
* `Label`: 表单标签
* `EmptyState`: 空状态占位 (New)