# TurboHR 完整测试场景清单（含输入输出示例数据）

> **版本**: v1.0  
> **更新日期**: 2026-08-01  
> **测试环境**: https://on.hr8ai.top  
> **管理端账号**: `13800000010` / `12345678`（王建国·北京·PRO 套餐）  
> **第二租户**: `13800000020` / `12345678`（李明华·深圳·ENTERPRISE 套餐）  
> **第三租户**: `13800000030` / `12345678`（赵雪梅·杭州·FREE 套餐）  
> **平台管理端**: SUPER_ADMIN 账号  
> **员工端**: 员工手机号 + 密码或验证码  

---

## 目录

1. [认证与账户域](#1-认证与账户域)
2. [工作台与仪表盘域](#2-工作台与仪表盘域)
3. [花名册与员工档案域](#3-花名册与员工档案域)
4. [考勤排班域](#4-考勤排班域)
5. [薪税管理域](#5-薪税管理域)
6. [社保公积金域](#6-社保公积金域)
7. [解聘补偿域](#7-解聘补偿域)
8. [合规风控域](#8-合规风控域)
9. [规章制度域](#9-规章制度域)
10. [AI 顾问域](#10-ai-顾问域)
11. [工作流程域](#11-工作流程域)
12. [特殊状态台账域](#12-特殊状态台账域)
13. [日历与事件域](#13-日历与事件域)
14. [通知管理域](#14-通知管理域)
15. [系统设置域](#15-系统设置域)
16. [模板管理域](#16-模板管理域)
17. [证据链域](#17-证据链域)
18. [公司文件域](#18-公司文件域)
19. [审计日志域](#19-审计日志域)
20. [薪酬分析仪表盘域](#20-薪酬分析仪表盘域)
21. [平台管理端域](#21-平台管理端域)
22. [员工端 Portal 域](#22-员工端-portal-域)
23. [数据导入导出域](#23-数据导入导出域)
24. [全局搜索与命令面板域](#24-全局搜索与命令面板域)
25. [企业全流程端到端场景](#25-企业全流程端到端场景)

---

## 1. 认证与账户域

### TC-AUTH-001 管理端登录（正确凭证）

| 项目 | 内容 |
|------|------|
| **Input** | `phone: "13800000010"`, `password: "12345678"`, `remember: true` |
| **Process** | POST `/api/v1/auth/login` → 访问 `/login`，填入手机号和密码，点击「登录」 |
| **Output** | HTTP 200，响应 `{ success: true, data: { user: { id, orgId, name: "王建国", phone: "13800000010", role: "ADMIN" }, accessToken: "eyJ...", refreshToken: "eyJ..." } }`。页面跳转至 `/`，顶部显示「王建国」，localStorage 持久化 token |

### TC-AUTH-002 管理端登录（错误密码）

| 项目 | 内容 |
|------|------|
| **Input** | `phone: "13800000010"`, `password: "wrongpass"` |
| **Process** | POST `/api/v1/auth/login` |
| **Output** | HTTP 401，响应 `{ success: false, error: { code: "UNAUTHORIZED", message: "手机号或密码错误" } }`。页面显示「手机号或密码错误」，不跳转 |

### TC-AUTH-003 管理端登录（空字段校验）

| 项目 | 内容 |
|------|------|
| **Input** | `phone: ""`, `password: ""` |
| **Process** | 不填任何字段，点击「登录」 |
| **Output** | 前端表单校验提示「请输入手机号」「请输入密码」，不发起 API 请求 |

### TC-AUTH-004 注册新企业

| 项目 | 内容 |
|------|------|
| **Input** | `orgName: "测试科技有限公司"`, `contactName: "张三"`, `phone: "13900001111"`, `password: "Test1234"`, `code: "123456"` |
| **Process** | POST `/api/v1/auth/register` |
| **Output** | HTTP 201，响应 `{ success: true, data: { orgId: "xxx", userId: "xxx" } }`。跳转至 `/login`，提示「注册成功，请登录」 |

### TC-AUTH-005 忘记密码

| 项目 | 内容 |
|------|------|
| **Input** | `phone: "13800000010"`, `code: "123456"`, `newPassword: "NewPass123"` |
| **Process** | 1. POST `/api/v1/auth/forgot-password/send-code` `{ phone: "13800000010" }`；2. POST `/api/v1/auth/forgot-password/verify` `{ phone, code, newPassword }` |
| **Output** | 第一步 HTTP 200 `{ success: true, message: "验证码已发送" }`；第二步 HTTP 200 `{ success: true, message: "密码修改成功" }`。跳转至 `/login` |

### TC-AUTH-006 Token 自动刷新

| 项目 | 内容 |
|------|------|
| **Input** | 过期的 accessToken，有效的 refreshToken |
| **Process** | 1. 登录后手动篡改 localStorage 中 accessToken 为 `invalid_token`；2. 触发任意 API 请求如 GET `/api/v1/dashboard` |
| **Output** | 拦截器收到 401 → POST `/api/v1/auth/refresh` `{ refreshToken }` → 获取新 accessToken → 原请求重试成功。localStorage 更新为新 token |

### TC-AUTH-007 未登录路由保护

| 项目 | 内容 |
|------|------|
| **Input** | 未登录状态（清空 localStorage） |
| **Process** | 直接访问 `/roster`、`/money`、`/settings`、`/termination` 等受保护路由 |
| **Output** | 自动重定向至 `/login`，URL 变为 `https://on.hr8ai.top/login` |

### TC-AUTH-008 退出登录

| 项目 | 内容 |
|------|------|
| **Input** | 已登录状态 |
| **Process** | 点击顶部导航栏「退出」按钮 |
| **Output** | localStorage 清除 `auth-storage`，QueryClient 缓存清空，跳转至 `/login` |

---

## 2. 工作台与仪表盘域

### TC-DASH-001 工作台概览加载

| 项目 | 内容 |
|------|------|
| **Input** | 已登录管理端（orgId: 北京公司） |
| **Process** | GET `/api/v1/dashboard` |
| **Output** | HTTP 200，返回 `{ greeting: "下午好！今天有 4 件事需要处理", stats: { employeeCount: 6, highRiskCount: 4, todoCount: 4, monthlyOvertimePay: 0 }, todos: [...4条], payrollSummary: { month: "2026-08", totalPay: 0, ... }, monthlyActivities: { newContracts: 0, terminations: 0, ... }, yearCostSummary: { year: "2026", ... } }`。页面渲染统计卡片、待办列表、成本分析 |

### TC-DASH-002 待办事项列表（按优先级排序）

| 项目 | 内容 |
|------|------|
| **Input** | 已登录，存在 4 条 PENDING RiskItem |
| **Process** | GET `/api/v1/dashboard`，解析 `todos` 数组 |
| **Output** | `todos` 按优先级排序，示例：`[{ id: "r1", type: "TERMINATION", priority: "URGENT", title: "孙美丽处于孕期/哺乳期，解聘受限", deadline: "2026-08-01", employeeName: "孙美丽" }, { id: "r2", type: "CONTRACT", priority: "HIGH", title: "刘大壮的合同已到期520天未续签", deadline: "2026-08-04", employeeName: "刘大壮" }, ...]` |

### TC-DASH-003 待办标记已处理

| 项目 | 内容 |
|------|------|
| **Input** | `todoId: "r1"` |
| **Process** | PATCH `/api/v1/dashboard/todos/r1/resolve` |
| **Output** | HTTP 200，`{ success: true }`。该待办从列表消失，toast 提示「已标记为已处理」，dashboard 数据刷新 |

### TC-DASH-004 待办忽略

| 项目 | 内容 |
|------|------|
| **Input** | `todoId: "r2"` |
| **Process** | PATCH `/api/v1/dashboard/todos/r2/ignore` |
| **Output** | HTTP 200，`{ success: true }`。该待办从列表消失，toast 提示「已忽略」 |

### TC-DASH-005 批量标记已处理

| 项目 | 内容 |
|------|------|
| **Input** | `ids: ["r1", "r2", "r3"]` |
| **Process** | PATCH `/api/v1/dashboard/todos/batch-resolve` `{ ids: ["r1","r2","r3"] }` |
| **Output** | HTTP 200，`{ success: true, data: { resolved: 3 } }`。3 条待办消失，选中集合清空 |

### TC-DASH-006 批量忽略

| 项目 | 内容 |
|------|------|
| **Input** | `ids: ["r1", "r2"]` |
| **Process** | PATCH `/api/v1/dashboard/todos/batch-ignore` `{ ids: ["r1","r2"] }` |
| **Output** | HTTP 200，`{ success: true, data: { ignored: 2 } }`。2 条待办消失，选中集合清空 |

### TC-DASH-007 合规健康度评分

| 项目 | 内容 |
|------|------|
| **Input** | 已登录 |
| **Process** | GET `/api/v1/dashboard/health-check` |
| **Output** | `{ year: 2026, totalScore: 80, level: "warning", dimensions: [{ key: "contract", name: "合同管理", score: 100, findings: [...], recommendations: [...] }, { key: "salary_social", name: "薪酬社保", score: 100 }, { key: "attendance", name: "考勤加班", score: 100 }, { key: "policy", name: "规章制度", score: 60 }, { key: "termination", name: "解聘合规", score: 100 }, { key: "evidence", name: "证据链", score: 20 }], summary: "整体用工存在中等风险（80分），建议优先处理低分维度问题" }`。页面渲染环形评分图 + 6 维度卡片 |

### TC-DASH-008 成本分析

| 项目 | 内容 |
|------|------|
| **Input** | `month: "2026-08"` |
| **Process** | GET `/api/v1/dashboard/cost-analysis?month=2026-08` |
| **Output** | `{ current: { totalCost: 53000, perCapita: 8833.33 }, monthOnMonth: { prevTotal: 51000, change: 2000, changePercent: 3.9 }, yearOnYear: { lastYearTotal: 0, change: 0 }, factors: [], departmentCost: [] }`。页面渲染环比/同比卡片、人均成本 |

### TC-DASH-009 人力信息总览

| 项目 | 内容 |
|------|------|
| **Input** | 已登录 |
| **Process** | GET `/api/v1/dashboard/workforce-stats` |
| **Output** | `{ gender: { male: 3, female: 3 }, ageGroups: [{ range: "25-35", count: 4 }, { range: "35-45", count: 2 }], education: [{ level: "大专", count: 3 }, { level: "本科", count: 2 }, { level: "硕士", count: 1 }], tenure: [{ range: "1-3年", count: 2 }, { range: "3-5年", count: 3 }, { range: "5-10年", count: 1 }] }`。页面渲染性别/年龄/学历/司龄分布图 |

### TC-DASH-010 入离职趋势

| 项目 | 内容 |
|------|------|
| **Input** | `months: 12` |
| **Process** | GET `/api/v1/dashboard/turnover-stats?months=12` |
| **Output** | `{ months: ["2025-09","2025-10",...,"2026-08"], hired: [0,1,0,...,0], left: [0,0,0,...,0], current: [6,7,7,...,6], turnoverRate: [0,0,...,0] }`。页面渲染 12 个月趋势折线图 |

### TC-DASH-011 绩效统计

| 项目 | 内容 |
|------|------|
| **Input** | `period: "2026"` |
| **Process** | GET `/api/v1/dashboard/performance-stats?period=2026` |
| **Output** | `{ periods: ["2026-Q1","2026-Q2","2026-Q3"], data: [], avgScore: 0 }` 或空数据时页面显示「暂无数据」 |

### TC-DASH-012 合同到期预警弹窗

| 项目 | 内容 |
|------|------|
| **Input** | 已登录，存在即将到期合同 |
| **Process** | GET `/api/v1/roster/contracts/expiring` |
| **Output** | `[{ id: "c1", employeeName: "孙美丽", contractType: "FIXED", endDate: "2025-08-30", daysLeft: -336 }, ...]`。页面顶部显示红色预警条，点击展开弹窗显示到期员工列表 |

### TC-DASH-013 任务中心

| 项目 | 内容 |
|------|------|
| **Input** | 已登录 |
| **Process** | 访问 `/`，查看「任务中心」区域 |
| **Output** | 显示 `5 项待处理`，包含草稿发薪批次、未完成月度办理等待办分类 |

### TC-DASH-014 年度价值报告

| 项目 | 内容 |
|------|------|
| **Input** | `year: 2026` |
| **Process** | GET `/api/v1/dashboard/annual-value?year=2026` |
| **Output** | `{ year: 2026, sections: [...], overallScore: 75, highlights: [...] }`。页面渲染年度价值报告卡片 |

---

## 3. 花名册与员工档案域

### TC-ROSTER-001 花名册分页列表

| 项目 | 内容 |
|------|------|
| **Input** | `page: 1, pageSize: 10, status: "ACTIVE", department: ""` |
| **Process** | GET `/api/v1/roster?page=1&pageSize=10&status=ACTIVE` |
| **Output** | `{ data: [{ id: "e1", name: "刘大壮", idCardMasked: "110****1001", department: "生产车间", status: "ACTIVE", salary: 8500, contractType: "FIXED", contractStatus: "EXPIRED", contractEndDate: "2025-02-27" }, ...共6条], pagination: { page: 1, pageSize: 10, total: 6, totalPages: 1 }, globalRiskStats: { expiring: 0, expired: 3, unsigned: 0 } }` |

### TC-ROSTER-002 花名册搜索

| 项目 | 内容 |
|------|------|
| **Input** | `search: "孙"` |
| **Process** | GET `/api/v1/roster?search=孙&page=1&pageSize=10` |
| **Output** | `{ data: [{ id: "e4", name: "孙美丽", department: "行政部", status: "ACTIVE", salary: 11000 }], pagination: { total: 1 } }` |

### TC-ROSTER-003 花名册筛选（合同状态）

| 项目 | 内容 |
|------|------|
| **Input** | `contractStatus: "EXPIRED"` |
| **Process** | GET `/api/v1/roster?contractStatus=EXPIRED` |
| **Output** | `{ data: [孙美丽(已过期), 陈秀英(已过期), 刘大壮(已过期)], pagination: { total: 3 } }`。页面顶部显示红色风险提醒条 |

### TC-ROSTER-004 花名册筛选（部门）

| 项目 | 内容 |
|------|------|
| **Input** | `department: "生产车间"` |
| **Process** | GET `/api/v1/roster?department=生产车间` |
| **Output** | `{ data: [刘大壮, 陈秀英, 赵铁柱, 周大伟], pagination: { total: 4 } }` |

### TC-ROSTER-005 部门列表

| 项目 | 内容 |
|------|------|
| **Input** | 无 |
| **Process** | GET `/api/v1/roster/departments` |
| **Output** | `["生产车间", "行政部", "质检部"]` |

### TC-ROSTER-006 添加员工

| 项目 | 内容 |
|------|------|
| **Input** | `{ name: "测试员工", gender: "男", department: "生产车间", phone: "13900009999", idCard: "110101199001011001", salary: 8000, hireDate: "2026-08-01", contractType: "FIXED", years: 3, probation: 3, probationSalary: 6400, bank: "工商银行", account: "6222020100019999", emergency: "测试父", emergencyPhone: "13800009998", address: "北京市朝阳区测试路1号" }` |
| **Process** | POST `/api/v1/employees` |
| **Output** | HTTP 201，`{ success: true, data: { id: "new-emp-id", name: "测试员工", status: "ACTIVE" } }`。列表刷新显示新员工 |

### TC-ROSTER-007 员工详情档案

| 项目 | 内容 |
|------|------|
| **Input** | `employeeId: "e1"`（刘大壮） |
| **Process** | GET `/api/v1/roster/e1/profile` |
| **Output** | `{ employee: { id: "e1", name: "刘大壮", gender: "男", department: "生产车间", phone: "13900001001", salary: 8500, hireDate: "2022-03-01" }, contracts: [{ type: "FIXED", startDate: "2022-03-01", endDate: "2025-02-27", status: "EXPIRED" }], disciplinary: [], attendance: [], training: [], performance: [], payslips: [...6条], attachments: [] }` |

### TC-ROSTER-008 调薪

| 项目 | 内容 |
|------|------|
| **Input** | `employeeId: "e1"`, `{ newSalary: 9500, effectiveDate: "2026-08-01", reason: "年度调薪" }` |
| **Process** | POST `/api/v1/roster/e1/salary-change` |
| **Output** | HTTP 200，`{ success: true }`。员工档案薪资更新为 9500 |

### TC-ROSTER-009 调岗

| 项目 | 内容 |
|------|------|
| **Input** | `employeeId: "e1"`, `{ newDepartment: "质检部", effectiveDate: "2026-08-01", reason: "业务调整" }` |
| **Process** | POST `/api/v1/roster/e1/department-change` |
| **Output** | HTTP 200，`{ success: true }`。员工部门更新为「质检部」 |

### TC-ROSTER-010 添加违纪记录

| 项目 | 内容 |
|------|------|
| **Input** | `employeeId: "e1"`, `{ violationDate: "2026-08-01", description: "迟到3次", action: "口头警告", evidence: "考勤记录" }` |
| **Process** | POST `/api/v1/roster/e1/disciplinary` |
| **Output** | HTTP 201，`{ success: true, data: { id: "d1", violationDate: "2026-08-01", description: "迟到3次" } }`。档案违纪 tab 显示新记录 |

### TC-ROSTER-011 添加考勤记录

| 项目 | 内容 |
|------|------|
| **Input** | `employeeId: "e1"`, `{ date: "2026-08-01", checkIn: "08:50", checkOut: "18:10", status: "NORMAL" }` |
| **Process** | POST `/api/v1/roster/e1/attendance` |
| **Output** | HTTP 201，`{ success: true, data: { id: "a1", date: "2026-08-01" } }` |

### TC-ROSTER-012 添加培训记录

| 项目 | 内容 |
|------|------|
| **Input** | `employeeId: "e1"`, `{ date: "2026-08-01", course: "安全生产培训", hours: 8, result: "合格" }` |
| **Process** | POST `/api/v1/roster/e1/training` |
| **Output** | HTTP 201，`{ success: true, data: { id: "t1", course: "安全生产培训" } }` |

### TC-ROSTER-013 添加绩效记录

| 项目 | 内容 |
|------|------|
| **Input** | `employeeId: "e1"`, `{ period: "2026-Q3", score: 85, comment: "工作积极" }` |
| **Process** | POST `/api/v1/roster/e1/performance` |
| **Output** | HTTP 201，`{ success: true, data: { id: "p1", period: "2026-Q3", score: 85 } }` |

### TC-ROSTER-014 添加合同

| 项目 | 内容 |
|------|------|
| **Input** | `{ employeeId: "e1", type: "FIXED", startDate: "2026-08-01", years: 3, probation: 3, probationSalary: 7600 }` |
| **Process** | POST `/api/v1/employees/contracts` |
| **Output** | HTTP 201，`{ success: true, data: { id: "c-new", type: "FIXED", startDate: "2026-08-01", endDate: "2029-07-31" } }` |

### TC-ROSTER-015 批量续签预检

| 项目 | 内容 |
|------|------|
| **Input** | `contractIds: ["c1", "c2", "c3"]` |
| **Process** | POST `/api/v1/employees/contracts/preview-renew` `{ contractIds: ["c1","c2","c3"] }` |
| **Output** | `{ data: [{ contractId: "c1", employeeName: "孙美丽", oldEndDate: "2025-08-30", newEndDate: "2028-08-29" }, ...] }` |

### TC-ROSTER-016 批量续签

| 项目 | 内容 |
|------|------|
| **Input** | `{ contractIds: ["c1", "c2"], years: 3 }` |
| **Process** | POST `/api/v1/employees/contracts/batch-renew` |
| **Output** | HTTP 200，`{ success: true, data: { renewed: 2 } }`。合同状态更新为正常 |

### TC-ROSTER-017 删除员工

| 项目 | 内容 |
|------|------|
| **Input** | `employeeId: "e-new"`（测试员工） |
| **Process** | DELETE `/api/v1/employees/e-new` |
| **Output** | HTTP 200，`{ success: true }`。列表中该员工消失 |

### TC-ROSTER-018 员工重新入职

| 项目 | 内容 |
|------|------|
| **Input** | `employeeId: "e-resigned"`, `{ hireDate: "2026-08-01", department: "生产车间", salary: 8000, contractType: "FIXED", years: 3 }` |
| **Process** | POST `/api/v1/employees/e-resigned/rehire` |
| **Output** | HTTP 200，`{ success: true, data: { status: "ACTIVE" } }`。员工状态从 RESIGNED 变为 ACTIVE |

### TC-ROSTER-019 附件管理

| 项目 | 内容 |
|------|------|
| **Input** | `employeeId: "e1"`, `{ name: "身份证复印件", url: "/uploads/id-card.jpg", type: "image" }` |
| **Process** | POST `/api/v1/attachments`；GET `/api/v1/attachments/e1` |
| **Output** | 创建返回 HTTP 201；列表返回 `[{ id: "att1", name: "身份证复印件", url: "/uploads/id-card.jpg" }]` |

---

## 4. 考勤排班域

### TC-ATT-001 考勤确认列表

| 项目 | 内容 |
|------|------|
| **Input** | `month: "2026-08", department: "", status: ""` |
| **Process** | GET `/api/v1/attendance?month=2026-08` |
| **Output** | `{ data: [], total: 0, stats: { total: 0, pending: 0, confirmed: 0, objected: 0 } }`。页面显示「本月暂无考勤确认记录」 |

### TC-ATT-002 考勤统计

| 项目 | 内容 |
|------|------|
| **Input** | `month: "2026-08"` |
| **Process** | GET `/api/v1/attendance/stats?month=2026-08` |
| **Output** | `{ total: 0, pending: 0, confirmed: 0, objected: 0, attendanceRate: 0 }` |

### TC-ATT-003 班次列表

| 项目 | 内容 |
|------|------|
| **Input** | 无 |
| **Process** | GET `/api/v1/attendance/shifts` |
| **Output** | `[{ id: "s1", name: "早班", startTime: "08:00", endTime: "17:00", color: "#4CAF50" }, { id: "s2", name: "晚班", startTime: "16:00", endTime: "23:00", color: "#FF9800" }]` 或空数组 |

### TC-ATT-004 创建班次

| 项目 | 内容 |
|------|------|
| **Input** | `{ name: "早班", startTime: "08:00", endTime: "17:00", color: "#4CAF50", restStart: "12:00", restEnd: "13:00" }` |
| **Process** | POST `/api/v1/attendance/shifts` |
| **Output** | HTTP 201，`{ success: true, data: { id: "s1", name: "早班", startTime: "08:00", endTime: "17:00" } }` |

### TC-ATT-005 更新班次

| 项目 | 内容 |
|------|------|
| **Input** | `id: "s1"`, `{ name: "早班A", startTime: "08:00", endTime: "17:30" }` |
| **Process** | PUT `/api/v1/attendance/shifts/s1` |
| **Output** | HTTP 200，`{ success: true }`。班次名称更新为「早班A」 |

### TC-ATT-006 删除班次

| 项目 | 内容 |
|------|------|
| **Input** | `id: "s1"` |
| **Process** | DELETE `/api/v1/attendance/shifts/s1` |
| **Output** | HTTP 200，`{ success: true }`。班次列表中该班次消失 |

### TC-ATT-007 排班（按日期）

| 项目 | 内容 |
|------|------|
| **Input** | `date: "2026-08-01"` |
| **Process** | GET `/api/v1/attendance/shift-assignments?date=2026-08-01` |
| **Output** | `{ data: [{ id: "sa1", employeeId: "e1", employeeName: "刘大壮", shiftId: "s1", shiftName: "早班", date: "2026-08-01" }] }` 或空数组 |

### TC-ATT-008 批量排班

| 项目 | 内容 |
|------|------|
| **Input** | `items: [{ employeeId: "e1", shiftId: "s1", date: "2026-08-01" }, { employeeId: "e2", shiftId: "s1", date: "2026-08-01" }]` |
| **Process** | POST `/api/v1/attendance/shift-assignments/batch` `{ items: [...] }` |
| **Output** | HTTP 200，`{ success: true, data: { created: 2 } }` |

### TC-ATT-009 每日出勤

| 项目 | 内容 |
|------|------|
| **Input** | `date: "2026-08-01"` |
| **Process** | GET `/api/v1/attendance/daily?date=2026-08-01` |
| **Output** | `{ data: [{ employeeId: "e1", employeeName: "刘大壮", shiftName: "早班", checkIn: "08:50", checkOut: "18:10", status: "NORMAL", overtime: 0 }] }` |

### TC-ATT-010 月度报表

| 项目 | 内容 |
|------|------|
| **Input** | `month: "2026-08"` |
| **Process** | GET `/api/v1/attendance/monthly-report?month=2026-08` |
| **Output** | `{ data: [{ employeeId: "e1", employeeName: "刘大壮", normalDays: 22, lateTimes: 0, earlyLeaveTimes: 0, absentDays: 0, overtimeHours: 0, leaveDays: 0 }] }` |

### TC-ATT-011 发布考勤

| 项目 | 内容 |
|------|------|
| **Input** | `month: "2026-08"` |
| **Process** | POST `/api/v1/attendance/publish` `{ month: "2026-08" }` |
| **Output** | HTTP 200，`{ success: true, data: { id: "pub1", month: "2026-08", status: "PUBLISHED" } }`。发布状态变为「已发布」 |

### TC-ATT-012 取消发布

| 项目 | 内容 |
|------|------|
| **Input** | `id: "pub1"` |
| **Process** | POST `/api/v1/attendance/publish/pub1/cancel` |
| **Output** | HTTP 200，`{ success: true }`。发布状态变为「未发布」 |

### TC-ATT-013 批量确认考勤

| 项目 | 内容 |
|------|------|
| **Input** | `{ month: "2026-08", all: true }` |
| **Process** | POST `/api/v1/attendance/batch-confirm` `{ month: "2026-08", all: true }` |
| **Output** | HTTP 200，`{ success: true, data: { confirmed: 6 } }` |

### TC-ATT-014 请假记录

| 项目 | 内容 |
|------|------|
| **Input** | 无（列表）；创建：`{ employeeId: "e1", type: "事假", startDate: "2026-08-05", endDate: "2026-08-06", reason: "家事" }` |
| **Process** | GET `/api/v1/attendance/leaves`；POST `/api/v1/attendance/leaves` |
| **Output** | 列表返回 `[{ id: "l1", employeeName: "刘大壮", type: "事假", startDate: "2026-08-05", endDate: "2026-08-06" }]`；创建返回 HTTP 201 |

---

## 5. 薪税管理域

### TC-PAY-001 发薪批次列表

| 项目 | 内容 |
|------|------|
| **Input** | `status: "", type: "", fromDate: "", toDate: ""` |
| **Process** | GET `/api/v1/payroll2/batches` |
| **Output** | `[]` 或 `[{ id: "b1", name: "2026年8月常规发薪", month: "2026-08", type: "NORMAL", status: "DRAFT", employeeCount: 6, totalPay: 53000 }]` |

### TC-PAY-002 创建发薪批次

| 项目 | 内容 |
|------|------|
| **Input** | `{ name: "2026年8月常规发薪", month: "2026-08", type: "NORMAL" }` |
| **Process** | POST `/api/v1/payroll2/batches` |
| **Output** | HTTP 201，`{ success: true, data: { id: "b1", name: "2026年8月常规发薪", month: "2026-08", type: "NORMAL", status: "DRAFT", employeeCount: 0 } }` |

### TC-PAY-003 批次添加人员

| 项目 | 内容 |
|------|------|
| **Input** | `batchId: "b1"`, `employeeIds: ["e1", "e2", "e3", "e4", "e5", "e6"]` |
| **Process** | POST `/api/v1/payroll2/batches/b1/employees` `{ employeeIds: ["e1","e2","e3","e4","e5","e6"] }` |
| **Output** | HTTP 200，`{ success: true, data: { added: 6 } }`。批次 employeeCount 变为 6 |

### TC-PAY-004 批次条目更新（手动调薪）

| 项目 | 内容 |
|------|------|
| **Input** | `batchId: "b1"`, `employeeId: "e1"`, `{ baseSalary: 9000, overtimePay: 0, allowance: 500, deduction: 0, bonus: 1000 }` |
| **Process** | PUT `/api/v1/payroll2/batches/b1/entries/e1` |
| **Output** | HTTP 200，`{ success: true }`。条目 totalPay 自动计算更新 |

### TC-PAY-005 算薪前 AI 校验

| 项目 | 内容 |
|------|------|
| **Input** | `batchId: "b1"` |
| **Process** | GET `/api/v1/payroll2/batches/b1/pre-check` |
| **Output** | `{ status: "ok", warnings: [], errors: [], suggestions: [{ type: "OVERTIME", message: "刘大壮本月加班36小时，超过法定上限" }] }` 或 `{ status: "ok", warnings: [], errors: [] }` |

### TC-PAY-006 归档批次

| 项目 | 内容 |
|------|------|
| **Input** | `batchId: "b1"` |
| **Process** | POST `/api/v1/payroll2/batches/b1/archive` |
| **Output** | HTTP 200，`{ success: true }`。批次状态变为 `ARCHIVED` |

### TC-PAY-007 取消归档

| 项目 | 内容 |
|------|------|
| **Input** | `batchId: "b1"` |
| **Process** | POST `/api/v1/payroll2/batches/b1/unarchive` |
| **Output** | HTTP 200，`{ success: true }`。批次状态回退为 `DRAFT` |

### TC-PAY-008 发布工资条

| 项目 | 内容 |
|------|------|
| **Input** | `batchId: "b1"` |
| **Process** | POST `/api/v1/payroll2/batches/b1/publish` |
| **Output** | HTTP 200，`{ success: true }`。员工端可见工资条 |

### TC-PAY-009 定时发送工资条

| 项目 | 内容 |
|------|------|
| **Input** | `batchId: "b1"`, `scheduledAt: "2026-08-15T10:00:00Z"` |
| **Process** | POST `/api/v1/payroll2/batches/b1/schedule` `{ scheduledAt: "2026-08-15T10:00:00Z" }` |
| **Output** | HTTP 200，`{ success: true, data: { scheduledAt: "2026-08-15T10:00:00Z" } }` |

### TC-PAY-010 薪酬模版列表

| 项目 | 内容 |
|------|------|
| **Input** | 无 |
| **Process** | GET `/api/v1/payroll2/template` |
| **Output** | `[{ id: "t1", name: "基本工资", type: "INCOME", formula: "baseSalary", sortOrder: 1 }, { id: "t2", name: "加班费", type: "INCOME", formula: "overtimePay", sortOrder: 2 }, { id: "t3", name: "社保扣除", type: "DEDUCTION", formula: "socialEmp", sortOrder: 3 }]` |

### TC-PAY-011 创建模版项

| 项目 | 内容 |
|------|------|
| **Input** | `{ name: "交通补贴", type: "INCOME", formula: "allowance", sortOrder: 5 }` |
| **Process** | POST `/api/v1/payroll2/template` |
| **Output** | HTTP 201，`{ success: true, data: { id: "t-new", name: "交通补贴" } }` |

### TC-PAY-012 加班费记录

| 项目 | 内容 |
|------|------|
| **Input** | `month: "2026-08"` |
| **Process** | GET `/api/v1/payroll/overtime?month=2026-08` |
| **Output** | `[{ id: "o1", employeeId: "e1", employeeName: "刘大壮", month: "2026-08", weekdayHours: 10, weekendHours: 0, holidayHours: 0, totalPay: 500 }]` 或空数组 |

### TC-PAY-013 保存加班费记录

| 项目 | 内容 |
|------|------|
| **Input** | `{ employeeId: "e1", month: "2026-08", weekdayHours: 10, weekendHours: 8, holidayHours: 0 }` |
| **Process** | POST `/api/v1/payroll/overtime` |
| **Output** | HTTP 201，`{ success: true, data: { id: "o1", totalPay: 850, weekdayHours: 10, weekendHours: 8 } }`。加班费按配置自动计算 |

### TC-PAY-014 加班费配置

| 项目 | 内容 |
|------|------|
| **Input** | 无（查看）；`{ weekdayRate: 1.5, weekendRate: 2.0, holidayRate: 3.0 }`（保存） |
| **Process** | GET `/api/v1/payroll/overtime/config`；POST `/api/v1/payroll/overtime/config` |
| **Output** | 查看返回 `{ weekdayRate: 1.5, weekendRate: 2.0, holidayRate: 3.0 }`；保存返回 HTTP 200 |

### TC-PAY-015 个税试算

| 项目 | 内容 |
|------|------|
| **Input** | `{ month: "2026-08", employeeId: "e1", baseSalary: 8500, overtimePay: 500, allowance: 0, socialEmp: 892.5, housingEmp: 850, specialDeduction: 2000 }` |
| **Process** | POST `/api/v1/payroll/tax-preview` |
| **Output** | `{ taxableIncome: 5407.5, tax: 540.75, netPay: 7609.75, details: { rate: "10%", deduction: 210 } }` |

### TC-PAY-016 删除批次

| 项目 | 内容 |
|------|------|
| **Input** | `batchId: "b1"` |
| **Process** | DELETE `/api/v1/payroll2/batches/b1` |
| **Output** | HTTP 200，`{ success: true }`。批次从列表消失 |

### TC-PAY-017 批次重命名

| 项目 | 内容 |
|------|------|
| **Input** | `batchId: "b1"`, `name: "8月第一批"` |
| **Process** | PUT `/api/v1/payroll2/batches/b1/name` `{ name: "8月第一批" }` |
| **Output** | HTTP 200，`{ success: true }`。批次名称更新 |

---

## 6. 社保公积金域

### TC-SOC-001 社保配置（按城市）

| 项目 | 内容 |
|------|------|
| **Input** | `city: "北京"` |
| **Process** | GET `/api/v1/social/config?city=北京` |
| **Output** | `{ id: "sc1", city: "北京", pensionOrg: 16, pensionEmp: 8, medicalOrg: 9.8, medicalEmp: 2, unemploymentOrg: 0.5, unemploymentEmp: 0.5, injuryOrg: 0.2, maternityOrg: 0.8, baseMin: 6326, baseMax: 33891, effectiveFrom: "2024-07-01", isCurrent: true }` |

### TC-SOC-002 公积金配置

| 项目 | 内容 |
|------|------|
| **Input** | `city: "北京"` |
| **Process** | GET `/api/v1/social/housing-config?city=北京` |
| **Output** | `{ id: "hc1", city: "北京", housingOrg: 12, housingEmp: 12, baseMin: 6326, baseMax: 33891, effectiveFrom: "2024-07-01", isCurrent: true }` |

### TC-SOC-003 社保计算

| 项目 | 内容 |
|------|------|
| **Input** | `base: 8500, city: "北京"` |
| **Process** | POST `/api/v1/social/calculate` `{ base: 8500, city: "北京" }` |
| **Output** | `{ base: 8500, orgTotal: 8500 * 0.273 = 2320.5, empTotal: 8500 * 0.105 = 892.5, details: { pensionOrg: 1360, pensionEmp: 680, medicalOrg: 833, medicalEmp: 170, ... } }` |

### TC-SOC-004 公积金计算

| 项目 | 内容 |
|------|------|
| **Input** | `base: 8500, city: "北京"` |
| **Process** | POST `/api/v1/social/housing-calculate` `{ base: 8500, city: "北京" }` |
| **Output** | `{ base: 8500, orgTotal: 1020, empTotal: 1020, rate: 12 }` |

### TC-SOC-005 创建社保配置版本

| 项目 | 内容 |
|------|------|
| **Input** | `{ city: "北京", effectiveFrom: "2025-07-01", pensionOrg: 16, pensionEmp: 8, medicalOrg: 9.8, medicalEmp: 2, unemploymentOrg: 0.5, unemploymentEmp: 0.5, injuryOrg: 0.2, maternityOrg: 0.8, baseMin: 6821, baseMax: 35283 }` |
| **Process** | POST `/api/v1/social/config/versions` |
| **Output** | HTTP 201，`{ success: true, data: { id: "sc2", effectiveFrom: "2025-07-01", isCurrent: false } }` |

### TC-SOC-006 社保配置版本列表

| 项目 | 内容 |
|------|------|
| **Input** | `city: "北京"` |
| **Process** | GET `/api/v1/social/config/versions?city=北京` |
| **Output** | `[{ id: "sc1", effectiveFrom: "2024-07-01", isCurrent: true, baseMin: 6326, baseMax: 33891 }, { id: "sc2", effectiveFrom: "2025-07-01", isCurrent: false, baseMin: 6821, baseMax: 35283 }]` |

### TC-SOC-007 AI 社保建议

| 项目 | 内容 |
|------|------|
| **Input** | `{ city: "北京", effectiveFrom: "2025-07-01", type: "social" }` |
| **Process** | POST `/api/v1/social/ai-suggest` |
| **Output** | `{ suggestion: "建议根据北京市2025年度社保缴费基数上下限调整配置，下限预计调整为6821元，上限35283元", confidence: 0.85, recommendedConfig: { baseMin: 6821, baseMax: 35283 } }` |

### TC-SOC-008 月度办理状态

| 项目 | 内容 |
|------|------|
| **Input** | `month: "2026-08"` |
| **Process** | GET `/api/v1/social/monthly-process/status?month=2026-08` |
| **Output** | `{ social: false, housing: false, socialCompletedAt: null, housingCompletedAt: null }` |

### TC-SOC-009 月度变动（社保增减员）

| 项目 | 内容 |
|------|------|
| **Input** | `month: "2026-08"` |
| **Process** | GET `/api/v1/social/monthly-changes?month=2026-08` |
| **Output** | `{ additions: [{ employeeId: "e1", employeeName: "刘大壮", reason: "新入职", base: 8500 }], reductions: [], current: [{ employeeId: "e1", employeeName: "刘大壮", base: 8500 }] }` |

### TC-SOC-010 公积金月度变动

| 项目 | 内容 |
|------|------|
| **Input** | `month: "2026-08"` |
| **Process** | GET `/api/v1/social/housing/monthly-changes?month=2026-08` |
| **Output** | `{ additions: [...], reductions: [...], current: [...] }` |

### TC-SOC-011 完成月度办理

| 项目 | 内容 |
|------|------|
| **Input** | `{ month: "2026-08", type: "social" }` |
| **Process** | POST `/api/v1/social/monthly-process/complete` `{ month: "2026-08", type: "social" }` |
| **Output** | HTTP 200，`{ success: true }`。状态更新为已完成 |

### TC-SOC-012 专项附加扣除批量

| 项目 | 内容 |
|------|------|
| **Input** | `month: "2026-08"` |
| **Process** | GET `/api/v1/social/special-deduction/batch?month=2026-08` |
| **Output** | `[{ employeeId: "e1", employeeName: "刘大壮", housing: 1000, education: 1000, elderly: 0, total: 2000 }]` |

### TC-SOC-013 保存专项附加扣除

| 项目 | 内容 |
|------|------|
| **Input** | `{ employeeId: "e1", month: "2026-08", housing: 1000, education: 1000, elderly: 0, medical: 0 }` |
| **Process** | POST `/api/v1/social/special-deduction` |
| **Output** | HTTP 200，`{ success: true }` |

### TC-SOC-014 活跃申报员工

| 项目 | 内容 |
|------|------|
| **Input** | `month: "2026-08"` |
| **Process** | GET `/api/v1/social/active-declaration?month=2026-08` |
| **Output** | `{ employees: [{ employeeId: "e1", employeeName: "刘大壮", base: 8500, socialStatus: "ACTIVE", housingStatus: "ACTIVE" }] }` |

### TC-SOC-015 商业保险方案列表

| 项目 | 内容 |
|------|------|
| **Input** | 无 |
| **Process** | GET `/api/v1/commercial-insurance/plans` |
| **Output** | `[{ id: "ci1", name: "雇主责任险", insurer: "平安保险", premium: 200, coverage: 500000, enrolledCount: 6 }]` 或空数组 |

### TC-SOC-016 创建商业保险方案

| 项目 | 内容 |
|------|------|
| **Input** | `{ name: "雇主责任险", insurer: "平安保险", premium: 200, coverage: 500000, startDate: "2026-01-01", endDate: "2026-12-31" }` |
| **Process** | POST `/api/v1/commercial-insurance/plans` |
| **Output** | HTTP 201，`{ success: true, data: { id: "ci1", name: "雇主责任险" } }` |

---

## 7. 解聘补偿域

### TC-TERM-001 解聘列表

| 项目 | 内容 |
|------|------|
| **Input** | `status: "", department: ""` |
| **Process** | GET `/api/v1/termination/drafts` |
| **Output** | `{ data: [], pagination: { total: 0 } }` 或 `[{ id: "t1", employeeName: "刘大壮", reason: "协商解除", status: "DRAFT", estimatedCompensation: 8500 }]` |

### TC-TERM-002 创建解聘草稿

| 项目 | 内容 |
|------|------|
| **Input** | `{ employeeId: "e1", reason: "协商解除", reasonDetail: "业务调整", lastDay: "2026-08-31" }` |
| **Process** | POST `/api/v1/termination/draft` |
| **Output** | HTTP 201，`{ success: true, data: { id: "td1", employeeId: "e1", employeeName: "刘大壮", reason: "协商解除", status: "DRAFT" } }` |

### TC-TERM-003 解聘风险评估

| 项目 | 内容 |
|------|------|
| **Input** | `employeeId: "e1", reason: "协商解除"` |
| **Process** | GET `/api/v1/termination/assess/e1?reason=协商解除` |
| **Output** | `{ riskLevel: "LOW", riskScore: 20, factors: [{ factor: "入职年限", description: "入职4.4年", impact: "medium" }, { factor: "合同状态", description: "合同已到期", impact: "low" }], recommendations: ["建议协商解除，支付N经济补偿"] }` |

### TC-TERM-004 解聘清单

| 项目 | 内容 |
|------|------|
| **Input** | `reason: "协商解除", employeeId: "e1"` |
| **Process** | GET `/api/v1/termination/checklist/协商解除?employeeId=e1` |
| **Output** | `{ items: [{ id: "cl1", title: "解除协议签署", required: true, completed: false }, { id: "cl2", title: "经济补偿支付", required: true, completed: false }, { id: "cl3", title: "工作交接", required: true, completed: false }, { id: "cl4", title: "社保公积金减员", required: true, completed: false }] }` |

### TC-TERM-005 更新草稿

| 项目 | 内容 |
|------|------|
| **Input** | `draftId: "td1"`, `{ reason: "协商解除", compensation: 37400, compensationMonths: 4.4, lastDay: "2026-08-31", checklist: [{ id: "cl1", completed: true }] }` |
| **Process** | PUT `/api/v1/termination/draft/td1` |
| **Output** | HTTP 200，`{ success: true }` |

### TC-TERM-006 提交审批

| 项目 | 内容 |
|------|------|
| **Input** | `draftId: "td1"` |
| **Process** | POST `/api/v1/termination/draft/td1/submit` |
| **Output** | HTTP 200，`{ success: true }`。状态变为 `PENDING_APPROVAL` |

### TC-TERM-007 审批通过

| 项目 | 内容 |
|------|------|
| **Input** | `draftId: "td1"`, `comment: "同意解聘，补偿金额合理"` |
| **Process** | POST `/api/v1/termination/draft/td1/approve` `{ comment: "同意解聘，补偿金额合理" }` |
| **Output** | HTTP 200，`{ success: true }`。状态变为 `APPROVED` |

### TC-TERM-008 审批驳回

| 项目 | 内容 |
|------|------|
| **Input** | `draftId: "td2"`, `comment: "补偿金额过高，请重新核算"` |
| **Process** | POST `/api/v1/termination/draft/td2/reject` `{ comment: "补偿金额过高，请重新核算" }` |
| **Output** | HTTP 200，`{ success: true }`。状态变为 `DRAFT`，附带驳回意见 |

### TC-TERM-009 执行解聘

| 项目 | 内容 |
|------|------|
| **Input** | `draftId: "td1"` |
| **Process** | POST `/api/v1/termination/draft/td1/execute` |
| **Output** | HTTP 200，`{ success: true }`。状态变为 `EXECUTED`，员工状态变为 `RESIGNED`，社保公积金自动减员 |

### TC-TERM-010 撤销解聘

| 项目 | 内容 |
|------|------|
| **Input** | `draftId: "td1"` |
| **Process** | POST `/api/v1/termination/draft/td1/cancel` |
| **Output** | HTTP 200，`{ success: true }`。状态变为 `CANCELLED` |

### TC-TERM-011 撤回离职记录

| 项目 | 内容 |
|------|------|
| **Input** | `recordId: "tr1"` |
| **Process** | DELETE `/api/v1/termination/tr1/revoke` |
| **Output** | HTTP 200，`{ success: true }`。员工状态恢复为 `ACTIVE` |

### TC-TERM-012 批量预览

| 项目 | 内容 |
|------|------|
| **Input** | `items: [{ employeeId: "e1", reason: "协商解除" }, { employeeId: "e2", reason: "协商解除" }]` |
| **Process** | POST `/api/v1/termination/batch/preview` `{ items: [...] }` |
| **Output** | `{ data: [{ employeeId: "e1", employeeName: "刘大壮", estimatedCompensation: 37400, riskLevel: "LOW" }, { employeeId: "e2", employeeName: "陈秀英", estimatedCompensation: 7500, riskLevel: "LOW" }] }` |

---

## 8. 合规风控域

### TC-RISK-001 风险中心列表

| 项目 | 内容 |
|------|------|
| **Input** | 已登录 |
| **Process** | GET `/api/v1/dashboard/risks` |
| **Output** | `[{ id: "r1", type: "CONTRACT", level: "high", priority: "URGENT", title: "刘大壮的合同已到期520天未续签", employeeName: "刘大壮", employeeId: "e1", deadline: "2026-08-04", actionUrl: "/roster" }, { id: "r2", type: "TERMINATION", level: "high", priority: "URGENT", title: "孙美丽处于孕期/哺乳期，解聘受限", employeeName: "孙美丽", employeeId: "e4", deadline: "2026-08-01" }, { id: "r3", type: "CONTRACT", level: "high", title: "孙美丽的合同已到期336天未续签", employeeName: "孙美丽" }, { id: "r4", type: "CONTRACT", level: "high", title: "陈秀英的合同已到期49天未续签", employeeName: "陈秀英" }]` |

### TC-RISK-002 风险分布统计

| 项目 | 内容 |
|------|------|
| **Input** | 已登录 |
| **Process** | GET `/api/v1/dashboard`，解析 `topRisks` 和风险分布 |
| **Output** | `{ contractRisk: 3, salaryRisk: 0, terminationRisk: 1 }`。页面渲染风险分布饼图 |

### TC-RISK-003 用工体检诊断

| 项目 | 内容 |
|------|------|
| **Input** | 已登录 |
| **Process** | GET `/api/v1/dashboard/health-check`；访问 `/tools/health-check` |
| **Output** | 6 维度评分：`{ contract: 100, salary_social: 100, attendance: 100, policy: 60, termination: 100, evidence: 20 }`，总分 80，等级 `warning` |

### TC-RISK-004 体检诊断历史

| 项目 | 内容 |
|------|------|
| **Input** | 已登录 |
| **Process** | GET `/api/v1/dashboard/health-check/history` |
| **Output** | `[{ id: "hc1", year: 2025, totalScore: 75, level: "warning", createdAt: "2025-12-01" }, { id: "hc2", year: 2026, totalScore: 80, level: "warning", createdAt: "2026-01-01" }]` |

### TC-RISK-005 保存体检诊断

| 项目 | 内容 |
|------|------|
| **Input** | 无（自动保存当前诊断快照） |
| **Process** | POST `/api/v1/dashboard/health-check/save` |
| **Output** | HTTP 200，`{ success: true, data: { id: "hc-new", year: 2026, totalScore: 80 } }` |

### TC-RISK-006 医疗期计算器

| 项目 | 内容 |
|------|------|
| **Input** | `employeeId: "e1"` 或手动输入 `workYears: 4, age: 41, condition: "普通疾病"` |
| **Process** | 访问 `/tools/medical-period`，输入参数计算 |
| **Output** | `{ medicalPeriod: 6, description: "本单位工作年限4年，医疗期为6个月", startDate: "2026-08-01", endDate: "2027-01-31" }` |

---

## 9. 规章制度域

### TC-POL-001 制度列表

| 项目 | 内容 |
|------|------|
| **Input** | `page: 1, pageSize: 10, status: ""` |
| **Process** | GET `/api/v1/policies?page=1&pageSize=10` |
| **Output** | `{ data: [], pagination: { total: 0 } }` 或 `[{ id: "p1", title: "员工考勤管理制度", status: "PUBLISHED", currentStep: 4, createdAt: "2026-07-01" }]` |

### TC-POL-002 创建制度

| 项目 | 内容 |
|------|------|
| **Input** | `{ title: "员工考勤管理制度", category: "考勤", content: "第一章 总则\n第一条 为规范..." }` |
| **Process** | POST `/api/v1/policies` |
| **Output** | HTTP 201，`{ success: true, data: { id: "p1", title: "员工考勤管理制度", status: "DRAFT", currentStep: 1 } }` |

### TC-POL-003 制度详情

| 项目 | 内容 |
|------|------|
| **Input** | `id: "p1"` |
| **Process** | GET `/api/v1/policies/p1` |
| **Output** | `{ id: "p1", title: "员工考勤管理制度", category: "考勤", content: "第一章 总则...", status: "DRAFT", currentStep: 1, steps: [{ step: 1, name: "起草", completed: true }, { step: 2, name: "讨论", completed: false }, { step: 3, name: "协商", completed: false }, { step: 4, name: "公示", completed: false }] }` |

### TC-POL-004 推进民主程序步骤

| 项目 | 内容 |
|------|------|
| **Input** | `id: "p1"`, `step: 2, note: "已组织职工代表大会讨论"` |
| **Process** | POST `/api/v1/policies/p1/advance-step` `{ step: 2, note: "已组织职工代表大会讨论" }` |
| **Output** | HTTP 200，`{ success: true }`。currentStep 变为 2，step 2 标记为 completed |

### TC-POL-005 更新制度

| 项目 | 内容 |
|------|------|
| **Input** | `id: "p1"`, `{ title: "员工考勤管理制度（修订版）", content: "第一章 总则\n第一条..." }` |
| **Process** | PUT `/api/v1/policies/p1` |
| **Output** | HTTP 200，`{ success: true }` |

### TC-POL-006 删除制度

| 项目 | 内容 |
|------|------|
| **Input** | `id: "p1"` |
| **Process** | DELETE `/api/v1/policies/p1` |
| **Output** | HTTP 200，`{ success: true }`。列表中该制度消失 |

### TC-POL-007 阅读签收统计

| 项目 | 内容 |
|------|------|
| **Input** | `id: "p1"` |
| **Process** | GET `/api/v1/policies/p1/read-stats` |
| **Output** | `{ total: 6, read: 3, unread: 3, readRate: 50, details: [{ employeeId: "e1", employeeName: "刘大壮", readAt: "2026-08-01T10:00:00Z" }, { employeeId: "e2", employeeName: "陈秀英", readAt: null }] }` |

---

## 10. AI 顾问域

### TC-AI-001 智能问答

| 项目 | 内容 |
|------|------|
| **Input** | `{ type: "CHAT", question: "员工入职没签合同怎么办？" }` |
| **Process** | POST `/api/v1/ai/consultation` `{ type: "CHAT", question: "员工入职没签合同怎么办？" }` |
| **Output** | HTTP 200，`{ success: true, data: { conversationId: "conv1", answer: "根据《劳动合同法》第十条规定，建立劳动关系应当订立书面劳动合同。已建立劳动关系未同时订立书面劳动合同的，应当自用工之日起一个月内订立...", confidence: 0.92, sources: [{ title: "劳动合同法第十条", url: "" }] } }` |

### TC-AI-002 上下文问答

| 项目 | 内容 |
|------|------|
| **Input** | `{ question: "我们公司有多少人合同到期了？", context: { orgId: "xxx", employeeData: true } }` |
| **Process** | POST `/api/v1/ai/context-ask` |
| **Output** | `{ answer: "根据您的花名册数据，目前有3名员工合同已到期：刘大壮（到期520天）、孙美丽（到期336天）、陈秀英（到期49天）。建议尽快续签合同...", confidence: 0.88 }` |

### TC-AI-003 合同审查

| 项目 | 内容 |
|------|------|
| **Input** | `contractText: "甲方：XX公司\n乙方：张三\n第一条 合同期限：本合同为固定期限劳动合同，自2026年1月1日起至2026年12月31日止..."` |
| **Process** | POST `/api/v1/ai/review` `{ contractText: "..." }` |
| **Output** | `{ reviewId: "rv1", issues: [{ severity: "HIGH", clause: "第一条", issue: "合同期限不足一年，试用期不得超过一个月", suggestion: "建议将试用期调整为不超过一个月" }, { severity: "MEDIUM", clause: "第三条", issue: "未约定加班费计算基数", suggestion: "建议明确加班费计算基数为基本工资" }], overallScore: 75, summary: "合同存在2处风险点，建议修改后签署" }` |

### TC-AI-004 合同审查上传文件

| 项目 | 内容 |
|------|------|
| **Input** | `FormData { file: contract.pdf }` |
| **Process** | POST `/api/v1/ai/review/upload` (multipart/form-data) |
| **Output** | `{ extractedText: "甲方：XX公司\n乙方：...", fileName: "contract.pdf" }` |

### TC-AI-005 案例匹配

| 项目 | 内容 |
|------|------|
| **Input** | `scenario: "员工试用期被辞退，公司未支付经济补偿"` |
| **Process** | POST `/api/v1/ai/match-case` `{ scenario: "员工试用期被辞退，公司未支付经济补偿" }` |
| **Output** | `{ cases: [{ id: "case1", title: "张某诉某科技公司违法解除劳动合同案", court: "北京市朝阳区人民法院", result: "劳动者胜诉", keyPoints: ["试用期辞退需证明不符合录用条件", "未支付经济补偿属于违法解除"], relevance: 0.92 }], summary: "类似案件中劳动者胜诉率较高，建议谨慎处理试用期辞退" }` |

### TC-AI-006 案例转待办

| 项目 | 内容 |
|------|------|
| **Input** | `{ caseId: "case1", action: "审查当前试用期辞退流程", assignee: "王建国" }` |
| **Process** | POST `/api/v1/ai/case-to-todo` |
| **Output** | HTTP 200，`{ success: true, data: { todoId: "todo-new", title: "审查当前试用期辞退流程" } }` |

### TC-AI-007 风险预测

| 项目 | 内容 |
|------|------|
| **Input** | 已登录，访问 AI 顾问「风险预测」tab |
| **Process** | POST `/api/v1/ai/consultation` `{ type: "PREDICT" }` |
| **Output** | `{ predictions: [{ riskType: "CONTRACT_EXPIRY", description: "未来30天内无合同到期", severity: "LOW" }, { riskType: "TERMINATION_RISK", description: "孙美丽处于孕期，解聘受限", severity: "HIGH" }] }` |

### TC-AI-008 对话历史

| 项目 | 内容 |
|------|------|
| **Input** | `type: "CHAT"` |
| **Process** | GET `/api/v1/ai/conversations?type=CHAT` |
| **Output** | `[{ id: "conv1", title: "员工入职没签合同怎么办？", type: "CHAT", createdAt: "2026-08-01T10:00:00Z", messageCount: 2 }, { id: "conv2", title: "加班费计算", type: "CHAT", createdAt: "2026-08-01T11:00:00Z" }]` |

### TC-AI-009 删除对话

| 项目 | 内容 |
|------|------|
| **Input** | `id: "conv1"` |
| **Process** | DELETE `/api/v1/ai/conversations/conv1` |
| **Output** | HTTP 200，`{ success: true }`。对话从历史列表消失 |

### TC-AI-010 RAG 知识库列表

| 项目 | 内容 |
|------|------|
| **Input** | 无 |
| **Process** | GET `/api/v1/ai/rag/list` |
| **Output** | `[{ id: "rag1", title: "劳动合同法全文", category: "法律条文", createdAt: "2026-01-01" }, { id: "rag2", title: "社保缴纳指南", category: "政策文件", createdAt: "2026-02-01" }]` |

### TC-AI-011 RAG 添加知识

| 项目 | 内容 |
|------|------|
| **Input** | `{ title: "2026年最低工资标准", content: "北京市2026年最低工资标准为2420元/月...", category: "政策文件" }` |
| **Process** | POST `/api/v1/ai/rag/add` |
| **Output** | HTTP 201，`{ success: true, data: { id: "rag-new", title: "2026年最低工资标准" } }` |

### TC-AI-012 RAG 帮助搜索

| 项目 | 内容 |
|------|------|
| **Input** | `query: "试用期最长可以约定几个月", topK: 8` |
| **Process** | POST `/api/v1/ai/rag/help-search` `{ query: "试用期最长可以约定几个月", topK: 8 }` |
| **Output** | `{ results: [{ id: "rag1", title: "劳动合同法全文", snippet: "第十九条 劳动合同期限三个月以上不满一年的，试用期不得超过一个月...", score: 0.95 }] }` |

---

## 11. 工作流程域

### TC-WP-001 工作流程列表

| 项目 | 内容 |
|------|------|
| **Input** | `page: 1, pageSize: 10, type: "", status: ""` |
| **Process** | GET `/api/v1/work-processes?page=1&pageSize=10` |
| **Output** | `{ data: [], pagination: { total: 0 } }` 或 `[{ id: "wp1", title: "8月入职办理-测试员工", type: "ONBOARDING", status: "DRAFT", createdAt: "2026-08-01" }]` |

### TC-WP-002 创建工作流程

| 项目 | 内容 |
|------|------|
| **Input** | `{ type: "ONBOARDING", title: "8月入职办理-测试员工", employeeId: "e-new", data: { hireDate: "2026-08-01", department: "生产车间", salary: 8000 } }` |
| **Process** | POST `/api/v1/work-processes` |
| **Output** | HTTP 201，`{ success: true, data: { id: "wp1", title: "8月入职办理-测试员工", type: "ONBOARDING", status: "DRAFT" } }` |

### TC-WP-003 工作流程详情

| 项目 | 内容 |
|------|------|
| **Input** | `id: "wp1"` |
| **Process** | GET `/api/v1/work-processes/wp1` |
| **Output** | `{ id: "wp1", title: "8月入职办理-测试员工", type: "ONBOARDING", status: "DRAFT", data: { hireDate: "2026-08-01", department: "生产车间", salary: 8000 }, steps: [{ step: 1, name: "信息录入", completed: true }, { step: 2, name: "合同签署", completed: false }] }` |

### TC-WP-004 提交工作流程

| 项目 | 内容 |
|------|------|
| **Input** | `id: "wp1"` |
| **Process** | POST `/api/v1/work-processes/wp1/submit` |
| **Output** | HTTP 200，`{ success: true }`。状态变为 `SUBMITTED` |

### TC-WP-005 取消工作流程

| 项目 | 内容 |
|------|------|
| **Input** | `id: "wp1"` |
| **Process** | POST `/api/v1/work-processes/wp1/cancel` |
| **Output** | HTTP 200，`{ success: true }`。状态变为 `CANCELLED` |

### TC-WP-006 删除工作流程

| 项目 | 内容 |
|------|------|
| **Input** | `id: "wp1"` |
| **Process** | DELETE `/api/v1/work-processes/wp1` |
| **Output** | HTTP 200，`{ success: true }`。从列表消失 |

### TC-WP-007 工作流程预览

| 项目 | 内容 |
|------|------|
| **Input** | `id: "wp1"` |
| **Process** | GET `/api/v1/work-processes/wp1/preview` |
| **Output** | `{ preview: { documents: [{ name: "劳动合同", template: "劳动合同模板", variables: { employeeName: "测试员工", department: "生产车间", salary: 8000 } }], steps: [...] } }` |

---

## 12. 特殊状态台账域

### TC-SS-001 特殊状态列表

| 项目 | 内容 |
|------|------|
| **Input** | `page: 1, pageSize: 10, search: "", type: "", status: ""` |
| **Process** | GET `/api/v1/special-statuses?page=1&pageSize=10` |
| **Output** | `{ data: [{ id: "ss1", employeeId: "e4", employeeName: "孙美丽", type: "PREGNANCY", status: "ACTIVE", startDate: "2026-01-01", endDate: "2026-12-31", description: "孕期" }], pagination: { total: 1 } }` |

### TC-SS-002 统计概览

| 项目 | 内容 |
|------|------|
| **Input** | 无 |
| **Process** | GET `/api/v1/special-statuses/stats/overview` |
| **Output** | `{ total: 1, byType: { PREGNANCY: 1, INJURY: 0, ILLNESS: 0, MATERNITY: 0 }, byStatus: { ACTIVE: 1, EXPIRED: 0 } }` |

### TC-SS-003 创建特殊状态

| 项目 | 内容 |
|------|------|
| **Input** | `{ employeeId: "e1", type: "INJURY", startDate: "2026-08-01", endDate: "2026-10-01", description: "工伤休养期" }` |
| **Process** | POST `/api/v1/special-statuses` |
| **Output** | HTTP 201，`{ success: true, data: { id: "ss2", employeeName: "刘大壮", type: "INJURY", status: "ACTIVE" } }` |

### TC-SS-004 更新特殊状态

| 项目 | 内容 |
|------|------|
| **Input** | `id: "ss2"`, `{ endDate: "2026-11-01", description: "工伤休养期延长" }` |
| **Process** | PUT `/api/v1/special-statuses/ss2` |
| **Output** | HTTP 200，`{ success: true }` |

### TC-SS-005 删除特殊状态

| 项目 | 内容 |
|------|------|
| **Input** | `id: "ss2"` |
| **Process** | DELETE `/api/v1/special-statuses/ss2` |
| **Output** | HTTP 200，`{ success: true }` |

---

## 13. 日历与事件域

### TC-CAL-001 月度日历

| 项目 | 内容 |
|------|------|
| **Input** | `month: "2026-08"` |
| **Process** | GET `/api/v1/dashboard/calendar?month=2026-08` |
| **Output** | `{ events: [{ id: "ev1", date: "2026-08-01", type: "RISK_DEADLINE", title: "孙美丽处于孕期/哺乳期，解聘受限 处理截止日", employeeName: "孙美丽" }, { id: "ev2", date: "2026-08-04", type: "RISK_DEADLINE", title: "陈秀英的合同已到期49天未续签 处理截止日", employeeName: "陈秀英" }, { id: "ev3", date: "2026-08-04", type: "RISK_DEADLINE", title: "刘大壮的合同已到期520天未续签 处理截止日", employeeName: "刘大壮" }] }` |

### TC-CAL-002 自定义事件列表

| 项目 | 内容 |
|------|------|
| **Input** | `month: "2026-08"` |
| **Process** | GET `/api/v1/calendar?month=2026-08` |
| **Output** | `[{ id: "ce1", title: "月度全员会议", date: "2026-08-15", type: "MEETING", description: "8月工作总结" }]` 或空数组 |

### TC-CAL-003 创建自定义事件

| 项目 | 内容 |
|------|------|
| **Input** | `{ title: "团队建设活动", date: "2026-08-20", type: "TEAM_BUILDING", description: "秋季团建" }` |
| **Process** | POST `/api/v1/calendar` |
| **Output** | HTTP 201，`{ success: true, data: { id: "ce1", title: "团队建设活动", date: "2026-08-20", type: "TEAM_BUILDING" } }` |

### TC-CAL-004 删除自定义事件

| 项目 | 内容 |
|------|------|
| **Input** | `id: "ce1"` |
| **Process** | DELETE `/api/v1/calendar/ce1` |
| **Output** | HTTP 200，`{ success: true }`。事件从日历消失 |

### TC-CAL-005 日历事件筛选

| 项目 | 内容 |
|------|------|
| **Input** | 筛选类型 `type: "RISK_DEADLINE"` |
| **Process** | 前端筛选日历事件 |
| **Output** | 仅显示风险截止类事件，隐藏其他类型 |

---

## 14. 通知管理域

### TC-NOT-001 通知日志列表

| 项目 | 内容 |
|------|------|
| **Input** | `page: 1, pageSize: 10` |
| **Process** | GET `/api/v1/notifications/logs?page=1&pageSize=10` |
| **Output** | `{ data: [], pagination: { total: 0 } }` 或 `[{ id: "n1", type: "CONTRACT_EXPIRY", channel: "wechat", recipient: "王建国", status: "SENT", sentAt: "2026-08-01T10:00:00Z", content: "您有3名员工合同已到期" }]` |

### TC-NOT-002 通知设置

| 项目 | 内容 |
|------|------|
| **Input** | 无（查看） |
| **Process** | GET `/api/v1/notifications/settings` |
| **Output** | `{ contractExpiryDays: 30, unsignedContractEnabled: true, overtimeAlertEnabled: true, payslipNotificationEnabled: true, channels: { wechat: true, email: false } }` |

### TC-NOT-003 更新通知设置

| 项目 | 内容 |
|------|------|
| **Input** | `{ contractExpiryDays: 60, unsignedContractEnabled: true, overtimeAlertEnabled: false, payslipNotificationEnabled: true, channels: { wechat: true, email: true } }` |
| **Process** | PUT `/api/v1/notifications/settings` |
| **Output** | HTTP 200，`{ success: true }`。页面显示「提前 60 天」 |

### TC-NOT-004 检查合同到期

| 项目 | 内容 |
|------|------|
| **Input** | 无 |
| **Process** | POST `/api/v1/notifications/check-contracts` |
| **Output** | HTTP 200，`{ success: true, data: { checked: 6, alerts: 3 } }`。生成合同到期通知 |

### TC-NOT-005 测试通知发送

| 项目 | 内容 |
|------|------|
| **Input** | `channel: "wechat"` |
| **Process** | POST `/api/v1/notifications/test` `{ channel: "wechat" }` |
| **Output** | HTTP 200，`{ success: true, message: "测试通知已发送" }` |

---

## 15. 系统设置域

### TC-SET-001 企业信息

| 项目 | 内容 |
|------|------|
| **Input** | 无（查看） |
| **Process** | GET `/api/v1/settings/org` |
| **Output** | `{ id: "org1", name: "北京智造科技有限公司", contactName: "王建国", contactPhone: "13800000010", city: "北京", plan: "PRO", payrollFrequency: 1, retirementReminderEnabled: true }` |

### TC-SET-002 更新企业信息

| 项目 | 内容 |
|------|------|
| **Input** | `{ name: "北京智造科技有限公司（更新）", contactName: "王建国", contactPhone: "13800000010", payrollFrequency: 2 }` |
| **Process** | PUT `/api/v1/settings/org` |
| **Output** | HTTP 200，`{ success: true }`。发薪次数更新为「2次（半月一批）」 |

### TC-SET-003 用户列表

| 项目 | 内容 |
|------|------|
| **Input** | 无 |
| **Process** | GET `/api/v1/settings/users` |
| **Output** | `[{ id: "u1", name: "王建国", phone: "13800000010", role: "ADMIN", disabled: false, createdAt: "2026-01-01" }]` |

### TC-SET-004 添加用户

| 项目 | 内容 |
|------|------|
| **Input** | `{ name: "李HR", phone: "13900008888", password: "Hr123456", role: "HR" }` |
| **Process** | POST `/api/v1/settings/users` |
| **Output** | HTTP 201，`{ success: true, data: { id: "u2", name: "李HR", phone: "13900008888", role: "HR" } }` |

### TC-SET-005 更新用户

| 项目 | 内容 |
|------|------|
| **Input** | `id: "u2"`, `{ name: "李人事", role: "HR" }` |
| **Process** | PUT `/api/v1/settings/users/u2` |
| **Output** | HTTP 200，`{ success: true }` |

### TC-SET-006 切换用户禁用状态

| 项目 | 内容 |
|------|------|
| **Input** | `id: "u2"` |
| **Process** | PATCH `/api/v1/settings/users/u2/toggle-disable` |
| **Output** | HTTP 200，`{ success: true, data: { disabled: true } }`。用户被禁用，无法登录 |

### TC-SET-007 用量统计

| 项目 | 内容 |
|------|------|
| **Input** | 无 |
| **Process** | GET `/api/v1/settings/usage` |
| **Output** | `{ plan: "PRO", maxEmployees: 100, currentEmployees: 6, usagePercent: 6, features: { aiConsultation: true, contractReview: true, batchImport: true } }` |

### TC-SET-008 更新套餐

| 项目 | 内容 |
|------|------|
| **Input** | `plan: "ENTERPRISE"` |
| **Process** | PUT `/api/v1/settings/plan` `{ plan: "ENTERPRISE" }` |
| **Output** | HTTP 200，`{ success: true }`。套餐更新为 ENTERPRISE |

### TC-SET-009 退休政策

| 项目 | 内容 |
|------|------|
| **Input** | 无 |
| **Process** | GET `/api/v1/settings/retirement-policy` |
| **Output** | `{ id: "rp1", version: "v1", status: "PENDING_CONFIRMATION", rules: { male: { baseAge: 60, targetAge: 63, stepMonths: 4 }, femaleCadre: { baseAge: 55, targetAge: 58, stepMonths: 4 }, femaleWorker: { baseAge: 50, targetAge: 55, stepMonths: 2 } } }` |

### TC-SET-010 确认退休政策生效

| 项目 | 内容 |
|------|------|
| **Input** | `id: "rp1"` |
| **Process** | POST `/api/v1/settings/retirement-policy/rp1/confirm` |
| **Output** | HTTP 200，`{ success: true }`。状态变为 `ACTIVE` |

---

## 16. 模板管理域

### TC-TPL-001 系统模板列表

| 项目 | 内容 |
|------|------|
| **Input** | `category: ""` 或 `category: "合同"` |
| **Process** | GET `/api/v1/templates` 或 GET `/api/v1/templates?category=合同` |
| **Output** | `[{ id: "t1", name: "固定期限劳动合同模板", category: "合同", variables: ["employeeName", "department", "startDate", "endDate"] }, { id: "t2", name: "解除协议模板", category: "解聘", variables: ["employeeName", "compensation", "lastDay"] }]` |

### TC-TPL-002 系统模板详情

| 项目 | 内容 |
|------|------|
| **Input** | `id: "t1"` |
| **Process** | GET `/api/v1/templates/t1` |
| **Output** | `{ id: "t1", name: "固定期限劳动合同模板", category: "合同", content: "甲方：{{orgName}}\n乙方：{{employeeName}}\n...", variables: [{ key: "employeeName", label: "员工姓名" }, { key: "department", label: "部门" }] }` |

### TC-TPL-003 渲染系统模板

| 项目 | 内容 |
|------|------|
| **Input** | `id: "t1"`, `variables: { orgName: "北京智造科技", employeeName: "测试员工", department: "生产车间", startDate: "2026-08-01", endDate: "2029-07-31" }` |
| **Process** | POST `/api/v1/templates/t1/render` `{ variables: {...} }` |
| **Output** | `{ rendered: "甲方：北京智造科技\n乙方：测试员工\n..." }` |

### TC-TPL-004 企业模板列表

| 项目 | 内容 |
|------|------|
| **Input** | `page: 1, pageSize: 10, category: ""` |
| **Process** | GET `/api/v1/enterprise-templates?page=1&pageSize=10` |
| **Output** | `{ data: [], pagination: { total: 0 } }` 或 `[{ id: "et1", name: "公司入职须知", category: "入职", createdAt: "2026-07-01" }]` |

### TC-TPL-005 创建企业模板

| 项目 | 内容 |
|------|------|
| **Input** | `{ name: "公司入职须知", category: "入职", content: "欢迎加入{{orgName}}...", variables: [{ key: "orgName", label: "企业名称" }] }` |
| **Process** | POST `/api/v1/enterprise-templates` |
| **Output** | HTTP 201，`{ success: true, data: { id: "et1", name: "公司入职须知" } }` |

### TC-TPL-006 更新企业模板

| 项目 | 内容 |
|------|------|
| **Input** | `id: "et1"`, `{ name: "公司入职须知（2026版）", content: "..." }` |
| **Process** | PUT `/api/v1/enterprise-templates/et1` |
| **Output** | HTTP 200，`{ success: true }` |

### TC-TPL-007 删除企业模板

| 项目 | 内容 |
|------|------|
| **Input** | `id: "et1"` |
| **Process** | DELETE `/api/v1/enterprise-templates/et1` |
| **Output** | HTTP 200，`{ success: true }` |

### TC-TPL-008 渲染企业模板

| 项目 | 内容 |
|------|------|
| **Input** | `id: "et1"`, `variables: { orgName: "北京智造科技" }` |
| **Process** | POST `/api/v1/enterprise-templates/et1/render` `{ variables: { orgName: "北京智造科技" } }` |
| **Output** | `{ rendered: "欢迎加入北京智造科技..." }` |

---

## 17. 证据链域

### TC-EVID-001 证据链列表

| 项目 | 内容 |
|------|------|
| **Input** | `page: 1, pageSize: 10, category: ""` |
| **Process** | GET `/api/v1/evidence?page=1&pageSize=10` |
| **Output** | `{ data: [], pagination: { total: 0 } }` 或 `[{ id: "ev1", category: "ONBOARDING", employeeName: "刘大壮", action: "入职登记", hash: "a1b2c3...", timestamp: "2022-03-01T08:00:00Z", verified: true }]` |

### TC-EVID-002 全量验证

| 项目 | 内容 |
|------|------|
| **Input** | 无 |
| **Process** | GET `/api/v1/evidence/verify-all` |
| **Output** | `{ total: 0, verified: 0, failed: 0, details: [] }` 或 `{ total: 15, verified: 14, failed: 1, details: [{ id: "ev1", status: "VERIFIED" }, { id: "ev2", status: "FAILED", reason: "hash mismatch" }] }` |

### TC-EVID-003 按类别筛选

| 项目 | 内容 |
|------|------|
| **Input** | `category: "CONTRACT"` |
| **Process** | GET `/api/v1/evidence?category=CONTRACT` |
| **Output** | `{ data: [{ id: "ev1", category: "CONTRACT", employeeName: "刘大壮", action: "合同签署" }], pagination: { total: 1 } }` |

---

## 18. 公司文件域

### TC-CF-001 文件列表

| 项目 | 内容 |
|------|------|
| **Input** | `fileType: ""` 或 `fileType: "营业执照"` |
| **Process** | GET `/api/v1/company-files` |
| **Output** | `[{ id: "f1", name: "营业执照.pdf", fileType: "营业执照", url: "/uploads/biz-license.pdf", uploadedAt: "2026-01-01" }]` 或空数组 |

### TC-CF-002 添加文件

| 项目 | 内容 |
|------|------|
| **Input** | `{ name: "营业执照.pdf", fileType: "营业执照", url: "/uploads/biz-license.pdf" }` |
| **Process** | POST `/api/v1/company-files` |
| **Output** | HTTP 201，`{ success: true, data: { id: "f1", name: "营业执照.pdf" } }` |

### TC-CF-003 删除文件

| 项目 | 内容 |
|------|------|
| **Input** | `id: "f1"` |
| **Process** | DELETE `/api/v1/company-files/f1` |
| **Output** | HTTP 200，`{ success: true }` |

---

## 19. 审计日志域

### TC-AUD-001 审计日志列表

| 项目 | 内容 |
|------|------|
| **Input** | `page: 1, pageSize: 10, entity: "", dateFrom: "", dateTo: ""` |
| **Process** | GET `/api/v1/audit?page=1&pageSize=10` |
| **Output** | `{ data: [{ id: "al1", entity: "EMPLOYEE", action: "CREATE", operator: "王建国", target: "测试员工", timestamp: "2026-08-01T10:00:00Z", details: "创建员工档案" }], pagination: { total: 1 } }` |

### TC-AUD-002 审计统计

| 项目 | 内容 |
|------|------|
| **Input** | 无 |
| **Process** | GET `/api/v1/audit/stats` |
| **Output** | `{ total: 15, byAction: { CREATE: 6, UPDATE: 5, DELETE: 2, LOGIN: 2 }, byEntity: { EMPLOYEE: 8, PAYROLL: 4, CONTRACT: 3 } }` |

### TC-AUD-003 按实体筛选

| 项目 | 内容 |
|------|------|
| **Input** | `entity: "EMPLOYEE"` |
| **Process** | GET `/api/v1/audit?entity=EMPLOYEE` |
| **Output** | `{ data: [{ id: "al1", entity: "EMPLOYEE", action: "CREATE", operator: "王建国" }], pagination: { total: 8 } }` |

### TC-AUD-004 按日期范围筛选

| 项目 | 内容 |
|------|------|
| **Input** | `dateFrom: "2026-08-01", dateTo: "2026-08-31"` |
| **Process** | GET `/api/v1/audit?dateFrom=2026-08-01&dateTo=2026-08-31` |
| **Output** | `{ data: [...], pagination: { total: 5 } }`。仅显示该日期范围内的日志 |

---

## 20. 薪酬分析仪表盘域

### TC-SAL-001 薪酬仪表盘

| 项目 | 内容 |
|------|------|
| **Input** | `year: 2026` |
| **Process** | GET `/api/v1/salary/dashboard?year=2026` |
| **Output** | `{ year: 2026, monthly: [{ month: "2026-01", totalPay: 53000, avgPay: 8833, headcount: 6 }, ...], departmentSalary: [{ department: "生产车间", avgSalary: 8333 }, { department: "行政部", avgSalary: 11000 }], salaryDistribution: [{ range: "5K-10K", count: 4 }, { range: "10K-15K", count: 2 }], yoyChange: 0 }` |

---

## 21. 平台管理端域

### TC-PLAT-001 平台登录

| 项目 | 内容 |
|------|------|
| **Input** | `phone: "superadmin"`, `password: "xxx"`（SUPER_ADMIN 账号） |
| **Process** | POST `/api/v1/auth/platform-login` |
| **Output** | HTTP 200，`{ success: true, data: { user: { role: "SUPER_ADMIN" }, accessToken: "..." } }`。跳转至 `/platform/dashboard` |

### TC-PLAT-002 平台仪表盘

| 项目 | 内容 |
|------|------|
| **Input** | 已登录 SUPER_ADMIN |
| **Process** | GET `/api/v1/platform/dashboard` |
| **Output** | `{ totalOrgs: 3, totalUsers: 3, totalEmployees: 18, byPlan: { FREE: 1, PRO: 1, ENTERPRISE: 1 }, recentSignups: [...] }` |

### TC-PLAT-003 组织列表

| 项目 | 内容 |
|------|------|
| **Input** | `page: 1, pageSize: 10, search: "", plan: ""` |
| **Process** | GET `/api/v1/platform/orgs?page=1&pageSize=10` |
| **Output** | `{ data: [{ id: "org1", name: "北京智造科技有限公司", plan: "PRO", maxEmployees: 100, currentEmployees: 6, adminName: "王建国", adminPhone: "13800000010", city: "北京", createdAt: "2026-01-01" }, { id: "org2", name: "深圳物流有限公司", plan: "ENTERPRISE", ... }, { id: "org3", name: "杭州科技工作室", plan: "FREE", ... }], pagination: { total: 3 } }` |

### TC-PLAT-004 组织搜索

| 项目 | 内容 |
|------|------|
| **Input** | `search: "北京"` |
| **Process** | GET `/api/v1/platform/orgs?search=北京` |
| **Output** | `{ data: [{ id: "org1", name: "北京智造科技有限公司", plan: "PRO" }], pagination: { total: 1 } }` |

### TC-PLAT-005 组织详情

| 项目 | 内容 |
|------|------|
| **Input** | `id: "org1"` |
| **Process** | GET `/api/v1/platform/orgs/org1` |
| **Output** | `{ id: "org1", name: "北京智造科技有限公司", plan: "PRO", maxEmployees: 100, currentEmployees: 6, adminName: "王建国", adminPhone: "13800000010", city: "北京", contactName: "王建国", contactPhone: "13800000010", payrollFrequency: 1, retirementReminderEnabled: true, socialConfig: { city: "北京", baseMin: 6326, baseMax: 33891 } }` |

### TC-PLAT-006 创建组织

| 项目 | 内容 |
|------|------|
| **Input** | `{ name: "测试新企业", contactName: "测试管理员", contactPhone: "13900007777", adminPhone: "13900007777", adminName: "测试管理员", city: "上海", plan: "PRO", maxEmployees: 50, payrollFrequency: 1 }` |
| **Process** | POST `/api/v1/platform/orgs` |
| **Output** | HTTP 201，`{ success: true, data: { id: "org-new", name: "测试新企业" } }` |

### TC-PLAT-007 更新组织

| 项目 | 内容 |
|------|------|
| **Input** | `id: "org1"`, `{ name: "北京智造科技有限公司（更新）", plan: "ENTERPRISE", maxEmployees: 200 }` |
| **Process** | PUT `/api/v1/platform/orgs/org1` |
| **Output** | HTTP 200，`{ success: true }` |

### TC-PLAT-008 更新组织管理员

| 项目 | 内容 |
|------|------|
| **Input** | `id: "org1"`, `{ adminName: "王建国", adminPhone: "13800000010", password: "NewPass123" }` |
| **Process** | PUT `/api/v1/platform/orgs/org1/admin` |
| **Output** | HTTP 200，`{ success: true }` |

### TC-PLAT-009 删除组织

| 项目 | 内容 |
|------|------|
| **Input** | `id: "org-new"` |
| **Process** | DELETE `/api/v1/platform/orgs/org-new` |
| **Output** | HTTP 200，`{ success: true }` |

### TC-PLAT-010 平台用户列表

| 项目 | 内容 |
|------|------|
| **Input** | `page: 1, pageSize: 10, search: "", orgId: ""` |
| **Process** | GET `/api/v1/platform/users?page=1&pageSize=10` |
| **Output** | `{ data: [{ id: "u1", name: "王建国", phone: "13800000010", role: "ADMIN", orgName: "北京智造科技有限公司", disabled: false }, { id: "u2", name: "李明华", phone: "13800000020", role: "ADMIN", orgName: "深圳物流有限公司" }], pagination: { total: 3 } }` |

### TC-PLAT-011 切换用户状态

| 项目 | 内容 |
|------|------|
| **Input** | `id: "u2"` |
| **Process** | PUT `/api/v1/platform/users/u2/toggle` |
| **Output** | HTTP 200，`{ success: true, data: { disabled: true } }` |

---

## 22. 员工端 Portal 域

### TC-PORTAL-001 员工端登录（密码）

| 项目 | 内容 |
|------|------|
| **Input** | `phone: "13900001001"`, `password: "xxx"`（员工密码） |
| **Process** | POST `/api/v1/portal/login` `{ phone: "13900001001", password: "xxx" }` |
| **Output** | HTTP 200，`{ success: true, data: { employee: { id: "e1", name: "刘大壮", department: "生产车间" }, token: "portal-token-xxx" } }`。localStorage 保存 portalToken 和 portalEmployee |

### TC-PORTAL-002 员工端登录（验证码）

| 项目 | 内容 |
|------|------|
| **Input** | 1. `phone: "13900001001"` → 2. `phone: "13900001001", code: "123456"` |
| **Process** | 1. POST `/api/v1/portal/send-code` `{ phone: "13900001001" }`；2. POST `/api/v1/portal/verify-code` `{ phone: "13900001001", code: "123456" }` |
| **Output** | 第一步 HTTP 200 `{ success: true, message: "验证码已发送" }`；第二步 HTTP 200 `{ success: true, data: { employee: {...}, token: "xxx" } }` |

### TC-PORTAL-003 自动登录（Token）

| 项目 | 内容 |
|------|------|
| **Input** | `token: "auto-login-token-xxx"` |
| **Process** | GET `/api/v1/portal/auto-login?token=auto-login-token-xxx` |
| **Output** | HTTP 200，`{ success: true, data: { employee: {...}, token: "xxx" } }`。自动登录并跳转至 `/portal/home` |

### TC-PORTAL-004 首页概览

| 项目 | 内容 |
|------|------|
| **Input** | 已登录员工端 |
| **Process** | GET `/api/v1/portal/home/overview` |
| **Output** | `{ employee: { name: "刘大壮", department: "生产车间", hireDate: "2022-03-01" }, latestPayslip: { month: "2026-07", totalPay: 8500 }, contractStatus: "EXPIRED", unreadPolicies: 0 }` |

### TC-PORTAL-005 工资条

| 项目 | 内容 |
|------|------|
| **Input** | `month: "2026-07"` |
| **Process** | GET `/api/v1/portal/payslip?month=2026-07` |
| **Output** | `{ month: "2026-07", baseSalary: 8500, overtimePay: 0, allowance: 0, bonus: 0, socialEmp: 892.5, housingEmp: 850, tax: 540.75, netPay: 6217.75, confirmed: false }` |

### TC-PORTAL-006 工资条历史

| 项目 | 内容 |
|------|------|
| **Input** | 无 |
| **Process** | GET `/api/v1/portal/payslip/history` |
| **Output** | `[{ id: "ps1", month: "2026-07", netPay: 6217.75, confirmed: false }, { id: "ps2", month: "2026-06", netPay: 6217.75, confirmed: true }]` |

### TC-PORTAL-007 确认工资条

| 项目 | 内容 |
|------|------|
| **Input** | `id: "ps1"` |
| **Process** | POST `/api/v1/portal/payslip/ps1/confirm` |
| **Output** | HTTP 200，`{ success: true }`。工资条状态变为 `CONFIRMED` |

### TC-PORTAL-008 我的合同

| 项目 | 内容 |
|------|------|
| **Input** | 无 |
| **Process** | GET `/api/v1/portal/contract` |
| **Output** | `{ contract: { id: "c1", type: "FIXED", startDate: "2022-03-01", endDate: "2025-02-27", status: "EXPIRED", monthlySalary: 8500 } }` 或 `{ contract: null }` |

### TC-PORTAL-009 合同确认（发送验证码）

| 项目 | 内容 |
|------|------|
| **Input** | `token: "contract-confirm-token-xxx"` |
| **Process** | POST `/api/v1/portal/contract-confirm/send-code` `{ token: "contract-confirm-token-xxx" }` |
| **Output** | HTTP 200，`{ success: true, message: "验证码已发送至手机" }` |

### TC-PORTAL-010 合同确认（提交）

| 项目 | 内容 |
|------|------|
| **Input** | `token: "contract-confirm-token-xxx"`, `verifyCode: "123456"` |
| **Process** | POST `/api/v1/portal/contract-confirm` `{ token: "xxx", agreed: true, verifyCode: "123456" }` |
| **Output** | HTTP 200，`{ success: true, message: "合同确认成功" }` |

### TC-PORTAL-011 我的考勤

| 项目 | 内容 |
|------|------|
| **Input** | `month: "2026-08"` |
| **Process** | GET `/api/v1/portal/attendance?month=2026-08` |
| **Output** | `{ month: "2026-08", records: [{ date: "2026-08-01", checkIn: "08:50", checkOut: "18:10", status: "NORMAL" }], summary: { normalDays: 22, lateTimes: 0, overtimeHours: 0 } }` |

### TC-PORTAL-012 制度列表

| 项目 | 内容 |
|------|------|
| **Input** | 无 |
| **Process** | GET `/api/v1/portal/policies` |
| **Output** | `[{ id: "p1", title: "员工考勤管理制度", category: "考勤", read: false, publishedAt: "2026-07-01" }]` 或空数组 |

### TC-PORTAL-013 制度详情

| 项目 | 内容 |
|------|------|
| **Input** | `id: "p1"` |
| **Process** | GET `/api/v1/portal/policies/p1` |
| **Output** | `{ id: "p1", title: "员工考勤管理制度", content: "第一章 总则...", publishedAt: "2026-07-01" }` |

### TC-PORTAL-014 制度阅读确认

| 项目 | 内容 |
|------|------|
| **Input** | `id: "p1"` |
| **Process** | POST `/api/v1/portal/policies/p1/read` |
| **Output** | HTTP 200，`{ success: true }`。制度标记为已读 |

### TC-PORTAL-015 入职信息

| 项目 | 内容 |
|------|------|
| **Input** | `token: "onboarding-token-xxx"` |
| **Process** | GET `/api/v1/portal/onboarding/onboarding-token-xxx` |
| **Output** | `{ token: "xxx", orgName: "北京智造科技有限公司", position: "生产车间工人", expectedHireDate: "2026-08-01", requirements: ["身份证复印件", "学历证明", "体检报告"] }` |

### TC-PORTAL-016 入职提交

| 项目 | 内容 |
|------|------|
| **Input** | `{ token: "onboarding-token-xxx", name: "张三", gender: "男", idCard: "110101199001011001", phone: "13900009999", bank: "工商银行", account: "6222020100019999", emergencyContact: "张父", emergencyPhone: "13800009998", address: "北京市朝阳区测试路1号" }` |
| **Process** | POST `/api/v1/portal/onboarding` |
| **Output** | HTTP 200，`{ success: true, message: "入职信息提交成功" }` |

### TC-PORTAL-017 入职文件上传

| 项目 | 内容 |
|------|------|
| **Input** | `token: "onboarding-token-xxx"`, `FormData { file: id-card.jpg }` |
| **Process** | POST `/api/v1/portal/onboarding/onboarding-token-xxx/upload` (multipart/form-data) |
| **Output** | HTTP 200，`{ success: true, data: { url: "/uploads/onboarding/id-card.jpg" } }` |

### TC-PORTAL-018 入职进度

| 项目 | 内容 |
|------|------|
| **Input** | 无（已登录员工端） |
| **Process** | GET `/api/v1/portal/onboarding/progress` |
| **Output** | `{ steps: [{ step: 1, name: "信息填写", completed: true }, { step: 2, name: "文件上传", completed: true }, { step: 3, name: "HR审核", completed: false }], currentStep: 3, status: "PENDING" }` |

### TC-PORTAL-019 离职申请状态

| 项目 | 内容 |
|------|------|
| **Input** | 无 |
| **Process** | GET `/api/v1/portal/resignation/status` |
| **Output** | `[]` 或 `[{ id: "rg1", reason: "个人发展", status: "PENDING", submittedAt: "2026-08-01" }]` |

### TC-PORTAL-020 提交离职申请

| 项目 | 内容 |
|------|------|
| **Input** | `{ reason: "个人发展", expectedLastDay: "2026-09-01", description: "感谢公司培养" }` |
| **Process** | POST `/api/v1/portal/resignation/submit` |
| **Output** | HTTP 201，`{ success: true, data: { id: "rg1", status: "PENDING" } }` |

### TC-PORTAL-021 撤回离职申请

| 项目 | 内容 |
|------|------|
| **Input** | `id: "rg1"` |
| **Process** | POST `/api/v1/portal/resignation/rg1/withdraw` |
| **Output** | HTTP 200，`{ success: true }`。状态变为 `WITHDRAWN` |

### TC-PORTAL-022 重发合同确认链接

| 项目 | 内容 |
|------|------|
| **Input** | `contractId: "c1"`（管理端操作） |
| **Process** | POST `/api/v1/portal/contract-confirm/resend` `{ contractId: "c1" }` |
| **Output** | HTTP 200，`{ success: true, message: "合同确认链接已重新发送" }` |

### TC-PORTAL-023 生成自动登录令牌

| 项目 | 内容 |
|------|------|
| **Input** | `employeeId: "e1"`（管理端操作） |
| **Process** | POST `/api/v1/portal/auto-login-token` `{ employeeId: "e1" }` |
| **Output** | HTTP 200，`{ success: true, data: { token: "auto-login-xxx", url: "/portal/auto-login?token=auto-login-xxx" } }` |

---

## 23. 数据导入导出域

### TC-IMP-001 员工批量导入

| 项目 | 内容 |
|------|------|
| **Input** | `FormData { file: employees.xlsx }` |
| **Process** | POST `/api/v1/import/employees` (multipart/form-data) |
| **Output** | HTTP 200，`{ success: true, data: { total: 10, success: 9, failed: 1, errors: [{ row: 5, message: "身份证号格式不正确" }] } }` |

### TC-IMP-002 考勤批量导入

| 项目 | 内容 |
|------|------|
| **Input** | `FormData { file: attendance.xlsx, month: "2026-08" }` |
| **Process** | POST `/api/v1/import/attendance` (multipart/form-data) |
| **Output** | HTTP 200，`{ success: true, data: { total: 120, success: 118, failed: 2, errors: [{ row: 15, message: "员工不存在" }] } }` |

### TC-IMP-003 加班费批量导入

| 项目 | 内容 |
|------|------|
| **Input** | `items: [{ employeeId: "e1", month: "2026-08", weekdayHours: 10, weekendHours: 8 }]` |
| **Process** | POST `/api/v1/payroll/overtime/batch` `{ items: [...] }` |
| **Output** | HTTP 200，`{ success: true, data: { imported: 1 } }` |

### TC-EXP-001 花名册导出

| 项目 | 内容 |
|------|------|
| **Input** | `status: "ACTIVE", department: ""` |
| **Process** | GET `/api/v1/export/roster?status=ACTIVE`（触发文件下载） |
| **Output** | HTTP 200，Content-Type: `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`，下载 `花名册_2026-08-01.xlsx`，包含 6 条员工记录 |

### TC-EXP-002 工资条导出

| 项目 | 内容 |
|------|------|
| **Input** | `batchId: "b1"` |
| **Process** | GET `/api/v1/export/payslip?batchId=b1` |
| **Output** | HTTP 200，下载 `工资条_2026-08.xlsx`，包含 6 条工资条明细 |

### TC-EXP-003 解聘记录导出

| 项目 | 内容 |
|------|------|
| **Input** | `status: ""` |
| **Process** | GET `/api/v1/export/termination` |
| **Output** | HTTP 200，下载 `解聘记录_2026-08-01.xlsx` |

### TC-EXP-004 考勤月报导出

| 项目 | 内容 |
|------|------|
| **Input** | `month: "2026-08"` |
| **Process** | GET `/api/v1/export/attendance?month=2026-08` |
| **Output** | HTTP 200，下载 `考勤月报_2026-08.xlsx` |

---

## 24. 全局搜索与命令面板域

### TC-SEARCH-001 全局搜索

| 项目 | 内容 |
|------|------|
| **Input** | `q: "刘大壮"` |
| **Process** | GET `/api/v1/search?q=刘大壮` |
| **Output** | `{ employees: [{ id: "e1", name: "刘大壮", department: "生产车间", type: "EMPLOYEE" }], contracts: [], policies: [] }` |

### TC-SEARCH-002 命令面板

| 项目 | 内容 |
|------|------|
| **Input** | 已登录，按下 `Cmd+K`（macOS）或 `Ctrl+K`（Windows） |
| **Process** | 触发 CommandPalette 打开 |
| **Output** | 弹出命令面板浮层，输入「花名册」可快速跳转至 `/roster`，输入「薪酬」可跳转至 `/money` |

### TC-SEARCH-003 搜索无结果

| 项目 | 内容 |
|------|------|
| **Input** | `q: "不存在的员工xyz"` |
| **Process** | GET `/api/v1/search?q=不存在的员工xyz` |
| **Output** | `{ employees: [], contracts: [], policies: [] }`。页面显示「未找到相关结果」 |

---

## 附录：测试数据速查

| 角色 | 手机号 | 密码 | 说明 |
|------|--------|------|------|
| 管理员（北京·PRO） | `13800000010` | `12345678` | 王建国，6 名员工 |
| 管理员（深圳·ENTERPRISE） | `13800000020` | `12345678` | 李明华，7 名员工 |
| 管理员（杭州·FREE） | `13800000030` | `12345678` | 赵雪梅，3 名员工 |
| 员工（刘大壮） | `13900001001` | 见 seed | 生产车间 |
| 员工（孙美丽） | `13900001004` | 见 seed | 行政部，孕期 |

| 员工 | 部门 | 月薪 | 合同状态 | 特殊状态 |
|------|------|------|----------|----------|
| 刘大壮 | 生产车间 | 8,500 | 已过期(520天) | - |
| 陈秀英 | 生产车间 | 7,500 | 已过期(49天) | - |
| 赵铁柱 | 生产车间 | 9,000 | 正常(无固定期) | - |
| 孙美丽 | 行政部 | 11,000 | 已过期(336天) | 孕期 |
| 周大伟 | 生产车间 | 7,000 | 正常 | - |
| 吴小红 | 质检部 | 9,500 | 正常 | - |
