# 加班/版本/项目模块小幅调整设计

## Context

针对已上线的加班记录、版本列表、项目列表、全局日期校验做一组明确的小幅调整。所有需求点边界已通过澄清确认，方案直接，无需架构层面权衡。

## 决策摘要

| 项 | 决策 |
|---|---|
| 加班"已提交"定义 | 创建即提交，所有记录不可编辑只可删除 |
| "创建日期"取值 | `OvertimeRecord.createdAt`（表单提交日期） |
| 加班人字段 | 默认回显 `useAuthStore` 当前用户 + `disabled` 不可改 |
| 版本列表移除范围 | 顶部 9 个状态 tab + 表格"状态"列 |
| 项目页"未达 100%"取值 | 整体进度（与版本页同源算法） < 100% |
| 日期校验提示 | 提交时验证 + 表单项下方红色文案 |

## 1. 加班记录模块（`apps/web/app/overtime/page.tsx`）

**字段调整**：
- `OvertimeModal` 加 `useAuthStore` 引用，初始化 `person = useAuthStore(s => s.user?.name) ?? ''`
- 加班人 input 加 `disabled` + 灰底（`bg-zinc-50`）
- 编辑时仍以 record 的 `person` 为准（虽然这条路径会被移除）

**列表表头**：
- 在"备注"列前插入"创建日期"列
- 单元格读 `r.createdAt`，已是 `YYYY-MM-DD` 格式直接显示

**编辑功能移除**：
- 删除：`editing` state、`handleEdit` 函数、表格"编辑"按钮、`OvertimeModal` 的 `initial` 编辑分支（保留 `initial: null` 用于校验空表单状态，或直接简化签名移除 initial）
- `handleCreate` 简化为 `setShowModal(true)`
- `OvertimeModal` props 删除 `initial`，简化为新建专用

**日期校验**：
- 提交时检查 `endTime > startTime`，失败设 `formError = '结束时间必须晚于开始时间'`
- 在结束时间 input 下方显示红色文案 `<p className="text-[11px] text-red-500 mt-1">{formError}</p>`

## 2. 全局日期校验

**通用错误提示组件**：新增 `apps/web/components/FieldError.tsx`

```tsx
interface Props { message?: string }
export function FieldError({ message }: Props) {
  if (!message) return null;
  return <p className="mt-1 text-[11px] text-red-500">{message}</p>;
}
```

**应用范围**（提交时校验，下方红色文案）：

- `apps/web/app/overtime/page.tsx` — OvertimeModal 结束时间下方
- `apps/web/components/version/PlanTab.tsx` — 计划开始/结束日期对（按现有结构定位）
- `apps/web/components/dev-task/DevTaskCreateModal.tsx` — 已有 `startBeforeEnd` 校验，统一改为用 `<FieldError>` 显示在预计截止下方
- `apps/web/components/dev-task/DevTaskDetailDrawer.tsx` — 详情抽屉编辑（如有日期对编辑）

**跳过**：
- `apps/web/app/versions/page.tsx` 的 NewVersionModal 仅有截止日期，无开始
- `apps/web/components/dev-task/WorklogPanel.tsx` 仅单 date 字段

## 3. 版本列表（`apps/web/app/versions/page.tsx`）

**移除**：
- `STATUS_TABS` 常量（line 39-50）
- 顶部状态 tab JSX 块（line 275-281）
- 表头"状态"列（line 346）
- 表格"状态"单元格（line 419-424）
- `statusFilter` state 和过滤分支（保留 search/projectFilter/priorityFilter 三个）

**保留**：项目筛选下拉、优先级筛选下拉、搜索框

**整体进度** 列保留——它本身就反映状态信息。

## 4. 项目页（`apps/web/app/projects/page.tsx`）

**计算 versionProgressMap**：
- `ProjectsPage` 加同款 `versionProgressMap` useMemo（与 versions/page.tsx line 141-212 同源算法）
- 需要 import `useVersionPlanStore`、`useDevTaskStore`、`useTestCaseStore`、`useRequirementStore`、`STATUS_PROGRESS`、`getEstimateHours`
- 抽出公共函数 `apps/web/lib/version-progress.ts`：

```ts
export function calcVersionProgress(
  versionId: string,
  plans: VersionPlan[],
  requirements: Requirement[],
  devTasks: DevTask[],
  testCases: TestCase[],
): number;

export function buildVersionProgressMap(
  versions: VersionWithContext[],
  plans, requirements, devTasks, testCases,
): Record<string, number>;
```

把 versions/page.tsx 现有逻辑替换为调用这个工具，避免两份。

**ProjectRow 改动**：
- 接收 `versionProgressMap: Record<string, number>` prop
- `activeVersions = filter(v => (versionProgressMap[v.id] ?? 0) < 100)`
- `releasedCount` 改为 `completedCount = filter(v => (versionProgressMap[v.id] ?? 0) >= 100)`
- "+N 已发布"改为"+N 已完成"

**Legend 调整**：
- 现有图例 `开发中 / 规划中 / 已发布` 颜色与版本状态绑定，VersionChip 也是。继续保留 chip 内部颜色逻辑，仅过滤维度变了。Legend 文案保持不变（这是 chip 颜色含义说明）。

## 数据流

```
overview / requirements / plans / devTasks / testCases
   │
   └── lib/version-progress.ts
         │
         ├── buildVersionProgressMap(versions, ...)
         │     └── Record<versionId, percent>
         │
         ├── versions/page.tsx 整体进度列
         └── projects/page.tsx ProjectRow 过滤未完成版本
```

## 实施清单

新增：
- `apps/web/components/FieldError.tsx`
- `apps/web/lib/version-progress.ts`

修改：
- `apps/web/app/overtime/page.tsx`（加班人禁用 + 创建日期列 + 移除编辑 + 日期校验）
- `apps/web/components/version/PlanTab.tsx`（日期校验）
- `apps/web/components/dev-task/DevTaskCreateModal.tsx`（统一校验文案样式）
- `apps/web/components/dev-task/DevTaskDetailDrawer.tsx`（如有日期对编辑则加校验）
- `apps/web/app/versions/page.tsx`（移除状态 tab/列 + 改用 version-progress.ts）
- `apps/web/app/projects/page.tsx`（加 progressMap + 改 ProjectRow 过滤口径）

## 验证

1. `pnpm type-check` 0 错误
2. `pnpm build` 14 个页面成功
3. 加班记录：新建表单加班人为当前登录用户名且不可改；列表有"创建日期"列；任何记录无"编辑"按钮，仅"删除"
4. 加班/计划/开发任务表单：截止 < 开始时提交，下方显示红色文案，不能提交
5. 版本列表：顶部无状态 tab；表头无状态列；只有项目+优先级两个下拉
6. 项目列表：每行显示进度未达 100% 的版本 chip，已完成数量在末尾"+N 已完成"
