Files
ftb-project-management/docs/superpowers/specs/2026-06-16-overtime-versions-projects-tweaks-design.md
Script Generator c2f2fed82c feat: 加班/版本/项目调整 + 角色权限设计
加班记录:
- 加班人默认回显当前用户且不可改
- 列表加创建日期列
- 移除编辑功能(创建即提交,仅可删除)
- 提交时校验结束>开始

版本列表:
- 移除顶部 9 个状态 tab + 表格状态列
- 仅保留搜索、项目、优先级筛选

项目列表:
- 行内显示进度未达 100% 的版本(与版本页同源算法)
- 新增 lib/version-progress.ts 抽出公共进度计算

角色权限:
- RoleItem 加 permissions 字段
- 新建 lib/permissions.ts: 14 组 37 个权限点 + 默认 5 角色映射 + hasPermission
- 角色表单内嵌权限矩阵(主模块 4 件套 + Tab 二档 + Bug Tab 4 档)+ 全选/反选/仅查看快捷
- 新建 components/auth/Guard.tsx: RouteGuard + PermissionGuard + useHasPermission + AccessDenied
- Sidebar 菜单按 view 权限过滤
- 7 个主路由(products/projects/versions/requirements/overtime/admin/members/roles)包 RouteGuard
- 版本详情 Tab 按 view 权限过滤,自动跳转到第一个有权限的 Tab
- 默认未登录/无角色按只读最严格
- 超管 role-admin: ['*'] 通配符,permissions 不可改

通用:
- 新建 components/FieldError.tsx 统一表单错误文案
- PlanTab 提交时校验结束>开始

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-16 19:15:28 +08:00

143 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 加班/版本/项目模块小幅调整设计
## 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 已完成"