登录页UI及长时间未操作锁定逻辑优化

This commit is contained in:
Cheng Zhou
2026-03-10 10:10:58 +08:00
parent 7936c55f3f
commit 4c98147f3e
12 changed files with 2225 additions and 470 deletions
@@ -0,0 +1,152 @@
# CTMS 企业级 UI 改造设计方案(第一阶段)
## 1. 目标与边界
### 1.1 North Star1-2 周)
将 CTMS 从“功能可用”升级为“管理层一眼认可的企业级系统”,聚焦:
1. 视觉统一:10 个核心页面采用同一套视觉语言。
2. 信息层级清晰:标题、指标、风险、操作区一眼分层。
3. 专业可信:克制、高密度但不混乱、细节一致。
### 1.2 In Scope(第一阶段)
1. 全局壳层:侧边栏、顶栏、面包屑、页面头、卡片容器。
2. 设计基础:色彩/字体/间距/圆角/阴影/状态色 token 统一。
3. 高曝光 10 页:
- `/project/overview`
- `/project/milestones`
- `/subjects`
- `/risk-issues/sae`
- `/risk-issues/pd`
- `/risk-issues/monitoring-visits`
- `/fees/contracts`
- `/fees/special`
- `/file-versions`
- `/admin/projects/:projectId`
4. 轻交互:筛选区、表格工具栏、主次按钮层级、空态/加载态统一。
### 1.3 Out of Scope(第一阶段不做)
1. 业务流程重构和权限逻辑改动。
2. 新增复杂图表引擎或大规模前端架构迁移。
3. 全量页面一次性翻新。
## 2. 视觉方向与设计系统基线
### 2.1 视觉方向
**Executive Clinical Minimalism(管理层临床极简)**
关键词:克制、秩序、可信、少而精。
避免:花哨渐变、互联网运营感、过度装饰。
### 2.2 品牌识别锚点
1. 深海军蓝 + 冷灰主色体系,传达管理层报告感。
2. 高对比标题 + 低饱和数据面,强化信息主次。
3. 统一壳层卡片语言,确保跨页面一致识别。
### 2.3 最小设计系统(MDS
1. Tokens
- Color`brand / text / bg / border / status`
- Type`Display(标题) + UI(正文)` 双字体体系
- Space8pt 网格(`4/8/12/16/24/32`
- Radius/Shadow:统一 3 档,页面禁止自定义分叉
2. 组件皮肤(Element Plus 主题化)
- Button(主/次/危险/幽灵)
- Input/Select/DatePicker
- Table(表头、行高、hover、密度)
- Card/Section Header/Tag
3. 交互规则
- 页面主按钮固定在右上主操作区
- 筛选条统一(左筛选、右动作)
- 表格区统一“工具栏-表格-分页”三段结构
### 2.4 第一阶段质量门槛
1. 10 页视觉一致性 >= 90%。
2. 不出现第三套颜色、第三套圆角、第三套按钮风格。
3. 1366 桌面与 iPad 宽度保持结构稳定。
## 3. 优先级与里程碑
### 3.1 优先级
#### P0(必须完成)
1. 全局壳层统一:`Layout.vue + main.css + unified-page.css`
2. 10 个核心页面统一改造(见 In Scope)。
3. 统一状态体系:加载态、空态、错误态、禁用态、风险高亮态。
#### P1(有余量时)
1. `/workbench` 视觉升级。
2. 表单页统一(新建/编辑页头、分组、主次按钮)。
3. 克制型关键动效(入场/hover)。
#### P2(后续阶段)
1. 全模块扩展(知识库、启动授权细分页)。
2. 深度交互优化(跨页筛选记忆、快捷操作)。
3. 主题扩展(暗色/品牌变体,按需)。
### 3.2 两周里程碑
#### M1(第 1-3 天):视觉基线锁定
1. 冻结 tokens(颜色/字体/间距/阴影/圆角)。
2. 产出 3 类样板页(概览、列表、详情)。
3. 评审后锁定不可随意改动项。
#### M2(第 4-7 天):高曝光页面落地(第一批)
1. 完成 P0 页面中的 6 页。
2. 统一页面头、筛选条、表格工具栏、分页区。
3. 首轮一致性巡检与收敛。
#### M3(第 8-10 天):P0 收敛(第二批)
1. 完成剩余 4 页。
2. 统一空态/加载态/错误态。
3. 窄屏最小可用适配。
#### M4(第 11-14 天):验收与打磨
1. 演示路径串联:概览 -> 风险 -> 进度 -> 费用。
2. 视觉一致性检查(目标 >= 90%)。
3. 性能与可访问性快速校验并修复阻断项。
## 4. 执行架构与风险控制
### 4.1 双轨并行执行
1. 轨道 A20%):Design System 底座
- 固化 token、组件皮肤、壳层规范。
2. 轨道 B80%):核心页面改造
- 严格按 P0 页面推进,仅做视觉 + 轻交互。
### 4.2 工作机制
1. 每日节奏:样板页 -> 批量套用 -> 巡检收敛。
2. 每 2 天一次统一性评审(跨页面对齐)。
3. 决策优先级:统一性 > 局部美化。
### 4.3 主要风险与控制
1. 风格分叉
- 控制:样式入口收敛到全局 token 与统一壳层 class。
2. 时间被细节吞没
- 控制:先结构统一,后细节打磨;P1 不挤占 P0。
3. 观感升级但管理层不买账
- 控制:围绕高管路径做演示脚本。
4. 样式改动引入回归
- 控制:每页改造后执行关键路径 smoke(筛选/跳转/分页/导出)。
## 5. 第一阶段验收清单
1. 统一性:10 页通过同一套视觉检查项。
2. 观感:15 分钟演示无明显风格跳变与信息噪声。
3. 可用性:主操作、筛选、列表关系明确。
4. 稳定性:桌面与窄屏无结构破坏。
5. 风险控制:无新增业务逻辑缺陷。
## 6. 决策结论
1. 采用“Design System 20% + 页面改造 80%”双轨并行。
2. 第一阶段严格完成 P0;P1 仅在余量下执行。
3. 下一步进入实施计划拆解(writing-plans)。
@@ -0,0 +1,465 @@
# CTMS Enterprise UI Refresh Implementation Plan
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**Goal:** Deliver a management-grade, visually unified CTMS UI across 10 core pages in 1-2 weeks, without changing business logic.
**Architecture:** Use a dual-track rollout: (A) minimal design-system hardening (tokens + shell + shared states), then (B) apply the same UI contract across prioritized pages. All page work must consume centralized CSS variables and shared shell patterns; page-local visual forks are disallowed.
**Tech Stack:** Vue 3, TypeScript, Vite, Element Plus, CSS variables
---
Skills to apply during execution: `@test-driven-development`, `@frontend-design`, `@verification-before-completion`, `@requesting-code-review`.
### Task 1: Add UI Contract Guardrails (Automated Checks)
**Files:**
- Create: `frontend/scripts/verify-ui-contract.mjs`
- Modify: `frontend/package.json`
- Test: `frontend/scripts/verify-ui-contract.mjs`
**Step 1: Write the failing test**
Create `frontend/scripts/verify-ui-contract.mjs`:
```js
import { readFileSync } from "node:fs";
const main = readFileSync("src/styles/main.css", "utf8");
const unified = readFileSync("src/styles/unified-page.css", "utf8");
const requiredMainTokens = [
"--ctms-primary",
"--ctms-text-main",
"--ctms-bg-base",
"--ctms-radius",
"--ctms-shadow"
];
const requiredUnifiedTokens = [
"--unified-shell-bg",
"--unified-shell-radius",
".unified-action-bar",
".unified-section"
];
const missing = [
...requiredMainTokens.filter((t) => !main.includes(t)),
...requiredUnifiedTokens.filter((t) => !unified.includes(t))
];
if (missing.length) {
console.error("UI contract check failed. Missing:", missing.join(", "));
process.exit(1);
}
console.log("UI contract check passed");
```
**Step 2: Run test to verify it fails**
Run: `cd frontend && node scripts/verify-ui-contract.mjs`
Expected: FAIL (`ENOENT` for script file before creation, then missing-token failures until Task 2/3 done)
**Step 3: Write minimal implementation**
Update `frontend/package.json` scripts:
```json
{
"scripts": {
"ui:contract": "node scripts/verify-ui-contract.mjs"
}
}
```
**Step 4: Run test to verify it passes**
Run: `cd frontend && npm run ui:contract`
Expected: PASS with `UI contract check passed` after Tasks 2/3 complete.
**Step 5: Commit**
```bash
git add frontend/scripts/verify-ui-contract.mjs frontend/package.json
git commit -m "chore(ui): add enterprise ui contract checks"
```
### Task 2: Harden Global Design Tokens (Single Source of Truth)
**Files:**
- Modify: `frontend/src/styles/main.css`
- Test: `frontend/scripts/verify-ui-contract.mjs`
**Step 1: Write the failing test**
Add new required tokens into `requiredMainTokens` in `verify-ui-contract.mjs`:
```js
"--ctms-brand-900",
"--ctms-brand-700",
"--ctms-neutral-100",
"--ctms-neutral-300",
"--ctms-focus-ring"
```
**Step 2: Run test to verify it fails**
Run: `cd frontend && npm run ui:contract`
Expected: FAIL listing the newly required tokens as missing.
**Step 3: Write minimal implementation**
In `frontend/src/styles/main.css`, define enterprise tokens in `:root`:
```css
:root {
--ctms-brand-900: #13243a;
--ctms-brand-700: #24496f;
--ctms-neutral-100: #f5f7fa;
--ctms-neutral-300: #d5dce5;
--ctms-focus-ring: 0 0 0 3px rgba(36, 73, 111, 0.2);
}
```
**Step 4: Run test to verify it passes**
Run: `cd frontend && npm run ui:contract`
Expected: PASS for these tokens.
**Step 5: Commit**
```bash
git add frontend/src/styles/main.css frontend/scripts/verify-ui-contract.mjs
git commit -m "feat(ui): add enterprise token baseline"
```
### Task 3: Standardize Shell Layout & Page Container Contract
**Files:**
- Modify: `frontend/src/styles/unified-page.css`
- Modify: `frontend/src/components/Layout.vue`
- Test: `frontend/scripts/verify-ui-contract.mjs`
**Step 1: Write the failing test**
Extend `requiredUnifiedTokens` with:
```js
".ctms-page-shell",
".ctms-page-header-row",
".ctms-page-content-grid"
```
**Step 2: Run test to verify it fails**
Run: `cd frontend && npm run ui:contract`
Expected: FAIL showing missing shell classes.
**Step 3: Write minimal implementation**
Add shell classes in `unified-page.css`:
```css
.ctms-page-shell { padding: 16px 20px 20px; }
.ctms-page-header-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.ctms-page-content-grid { display: grid; gap: 12px; }
```
In `Layout.vue`, ensure routed views are wrapped by a stable shell root class.
**Step 4: Run test to verify it passes**
Run: `cd frontend && npm run ui:contract && npm run type-check`
Expected: PASS.
**Step 5: Commit**
```bash
git add frontend/src/styles/unified-page.css frontend/src/components/Layout.vue frontend/scripts/verify-ui-contract.mjs
git commit -m "feat(ui): enforce shared page shell contract"
```
### Task 4: Create Shared List-Page Visual Pattern
**Files:**
- Modify: `frontend/src/views/ia/ProjectMilestones.vue`
- Modify: `frontend/src/views/ia/SubjectManagement.vue`
- Modify: `frontend/src/views/ia/RiskIssueSae.vue`
- Modify: `frontend/src/views/ia/RiskIssuePd.vue`
- Modify: `frontend/src/views/ia/RiskIssueMonitoringVisits.vue`
- Test: `frontend/src/views/ia/*.vue`
**Step 1: Write the failing test**
In `verify-ui-contract.mjs`, add per-page checks that each target file includes:
```js
"ctms-page-shell",
"unified-action-bar",
"ctms-table-card"
```
**Step 2: Run test to verify it fails**
Run: `cd frontend && npm run ui:contract`
Expected: FAIL on one or more target views.
**Step 3: Write minimal implementation**
Refactor each page template to the same structure:
```vue
<div class="ctms-page-shell">
<section class="unified-action-bar">...</section>
<section class="unified-shell ctms-table-card">...</section>
</div>
```
**Step 4: Run test to verify it passes**
Run: `cd frontend && npm run ui:contract && npm run type-check`
Expected: PASS.
**Step 5: Commit**
```bash
git add frontend/src/views/ia/ProjectMilestones.vue frontend/src/views/ia/SubjectManagement.vue frontend/src/views/ia/RiskIssueSae.vue frontend/src/views/ia/RiskIssuePd.vue frontend/src/views/ia/RiskIssueMonitoringVisits.vue frontend/scripts/verify-ui-contract.mjs
git commit -m "feat(ui): unify list-page enterprise visual pattern"
```
### Task 5: Upgrade Executive Dashboard Surfaces
**Files:**
- Modify: `frontend/src/views/ia/ProjectOverview.vue`
- Modify: `frontend/src/components/KpiCard.vue`
- Modify: `frontend/src/styles/unified-page.css`
- Test: `frontend/src/views/ia/ProjectOverview.vue`
**Step 1: Write the failing test**
Add checks requiring overview page contains:
```js
"ctms-page-shell",
"kpi",
"unified-section"
```
**Step 2: Run test to verify it fails**
Run: `cd frontend && npm run ui:contract`
Expected: FAIL until overview/kpi structure is aligned.
**Step 3: Write minimal implementation**
- Ensure KPI cards use unified spacing, title scale, value prominence.
- Add deterministic class contract to KPI root:
```vue
<article class="kpi-card kpi-enterprise">...</article>
```
- Add style rules in `unified-page.css` for KPI rhythm and hierarchy.
**Step 4: Run test to verify it passes**
Run: `cd frontend && npm run ui:contract && npm run type-check`
Expected: PASS.
**Step 5: Commit**
```bash
git add frontend/src/views/ia/ProjectOverview.vue frontend/src/components/KpiCard.vue frontend/src/styles/unified-page.css frontend/scripts/verify-ui-contract.mjs
git commit -m "feat(ui): elevate project overview for executive readout"
```
### Task 6: Standardize Finance & File Management Pages
**Files:**
- Modify: `frontend/src/views/fees/ContractFees.vue`
- Modify: `frontend/src/views/fees/SpecialExpenses.vue`
- Modify: `frontend/src/views/ia/FileVersionManagement.vue`
- Test: `frontend/src/views/fees/*.vue`, `frontend/src/views/ia/FileVersionManagement.vue`
**Step 1: Write the failing test**
Require common classes in target pages:
```js
"ctms-page-shell",
"unified-action-bar",
"unified-shell"
```
**Step 2: Run test to verify it fails**
Run: `cd frontend && npm run ui:contract`
Expected: FAIL for non-conforming pages.
**Step 3: Write minimal implementation**
Refactor templates to shared contract and align action hierarchy:
- Primary action right-aligned.
- Secondary actions grouped.
- Filter and table blocks separated by unified sections.
**Step 4: Run test to verify it passes**
Run: `cd frontend && npm run ui:contract && npm run type-check`
Expected: PASS.
**Step 5: Commit**
```bash
git add frontend/src/views/fees/ContractFees.vue frontend/src/views/fees/SpecialExpenses.vue frontend/src/views/ia/FileVersionManagement.vue frontend/scripts/verify-ui-contract.mjs
git commit -m "feat(ui): unify finance and file management surfaces"
```
### Task 7: Standardize Admin High-Visibility Project Page
**Files:**
- Modify: `frontend/src/views/admin/ProjectDetail.vue`
- Modify: `frontend/src/styles/unified-page.css`
- Test: `frontend/src/views/admin/ProjectDetail.vue`
**Step 1: Write the failing test**
Add contract checks for `ProjectDetail.vue` requiring:
```js
"ctms-page-shell",
"unified-action-bar",
"unified-section"
```
**Step 2: Run test to verify it fails**
Run: `cd frontend && npm run ui:contract`
Expected: FAIL until shell contract is applied.
**Step 3: Write minimal implementation**
- Normalize section titles, spacing, card treatment.
- Remove page-specific visual overrides that conflict with token system.
- Keep business fields and logic unchanged.
**Step 4: Run test to verify it passes**
Run: `cd frontend && npm run ui:contract && npm run type-check`
Expected: PASS.
**Step 5: Commit**
```bash
git add frontend/src/views/admin/ProjectDetail.vue frontend/src/styles/unified-page.css frontend/scripts/verify-ui-contract.mjs
git commit -m "feat(ui): align admin project detail with enterprise system"
```
### Task 8: Unify Loading / Empty / Error States
**Files:**
- Modify: `frontend/src/components/StateLoading.vue`
- Modify: `frontend/src/components/StateEmpty.vue`
- Modify: `frontend/src/components/StateError.vue`
- Modify: `frontend/src/styles/main.css`
- Test: `frontend/src/components/State*.vue`
**Step 1: Write the failing test**
Add checks requiring all three state components include:
```js
"ctms-state",
"ctms-state-title",
"ctms-state-desc"
```
**Step 2: Run test to verify it fails**
Run: `cd frontend && npm run ui:contract`
Expected: FAIL for missing class contract.
**Step 3: Write minimal implementation**
Refactor each component to common structure:
```vue
<section class="ctms-state">
<h3 class="ctms-state-title">...</h3>
<p class="ctms-state-desc">...</p>
</section>
```
Add shared state styles in `main.css`.
**Step 4: Run test to verify it passes**
Run: `cd frontend && npm run ui:contract && npm run type-check`
Expected: PASS.
**Step 5: Commit**
```bash
git add frontend/src/components/StateLoading.vue frontend/src/components/StateEmpty.vue frontend/src/components/StateError.vue frontend/src/styles/main.css frontend/scripts/verify-ui-contract.mjs
git commit -m "feat(ui): unify loading empty error states"
```
### Task 9: Verification, Demo Path, and Release Gate
**Files:**
- Create: `docs/ui/enterprise-ui-acceptance-checklist.md`
- Modify: `docs/release-checklist.md`
- Test: manual smoke + build checks
**Step 1: Write the failing test**
Create acceptance checklist with explicit pass/fail items. Mark all as pending initially.
```md
- [ ] Overview and milestones visual consistency
- [ ] Risk pages visual consistency
- [ ] Finance pages visual consistency
- [ ] File/admin detail visual consistency
- [ ] Desktop and iPad width checks
- [ ] Management demo path continuity
```
**Step 2: Run test to verify it fails**
Run: `cd frontend && npm run type-check && npm run build`
Expected: PASS technically, but acceptance checklist remains FAIL/PENDING.
**Step 3: Write minimal implementation**
- Execute manual smoke on target routes.
- Update checklist to PASS with reviewer/date notes.
- Add release gating notes to `docs/release-checklist.md`.
**Step 4: Run test to verify it passes**
Run: `cd frontend && npm run ui:contract && npm run type-check && npm run build`
Expected: PASS for all commands and checklist completed.
**Step 5: Commit**
```bash
git add docs/ui/enterprise-ui-acceptance-checklist.md docs/release-checklist.md
git commit -m "docs(ui): add enterprise refresh acceptance and release gates"
```
## Milestone Mapping
1. **M1 (Day 1-3):** Tasks 1-3 + sample page alignment.
2. **M2 (Day 4-7):** Tasks 4-5 (first 6 core pages).
3. **M3 (Day 8-10):** Tasks 6-8 (remaining 4 pages + states).
4. **M4 (Day 11-14):** Task 9 + demo rehearsal + release gate.
## Definition of Done
1. `npm run ui:contract` passes.
2. `npm run type-check` passes.
3. `npm run build` passes.
4. Acceptance checklist fully marked PASS with reviewer/date.
5. No business logic behavior regressions in smoke path.
@@ -0,0 +1,97 @@
# 研发项目进展监测系统(rd-monitor)设计文档
## 1. 目标与范围
- 基于现有 CTMS 的界面/组件经验,建设一个完全独立的研发项目进展监测系统。
- 新系统独立前后端、独立数据库、独立鉴权与权限体系。
- 首期仅实现 PDF《项目进度概览 v2》中的核心功能:概览展示、进度录入、历史变更、导出、项目隐藏规则。
## 2. 系统边界
- 独立仓库:`rd-monitor`
- 技术栈:Vue3 + Element Plus + FastAPI + SQLAlchemy + Alembic + PostgreSQL
- 与 CTMS 关系:仅复用可迁移的组件/样式实现,不依赖 CTMS API 与 CTMS 数据表。
## 3. 数据模型
### 3.1 users
- `id`
- `username`
- `email`
- `password_hash`
- `role` (`ADMIN`/`PM`/`VIEWER`)
- `is_active`
- `created_at`
### 3.2 projects
- `id`
- `project_code`(如 HP-001
- `project_name`
- `regulatory_path`
- `status``ACTIVE`/`APPROVED`/`TERMINATED`
- `created_at`
### 3.3 stage_templates
- `id`
- `stage_key`
- `stage_name`
- `order_no`
- `regulatory_paths`JSON 数组;空表示通用)
- `is_active`
### 3.4 project_stages
- `id`
- `project_id`
- `stage_template_id`
- `order_no`
- `planned_start_date`
- `planned_end_date`
- `actual_finish_date`
- `actual_finish_flag``DONE`/`NOT_APPLICABLE`/`PENDING`
- `adjust_reason`
- `remark`
- `updated_at`
### 3.5 project_stage_change_logs
- `id`
- `project_stage_id`
- `changed_by`
- `before_json`
- `after_json`
- `comment`
- `created_at`
## 4. 状态规则(按 PDF
- `已完成``actual_finish_flag = DONE``actual_finish_date` 有值。
- `未进行``actual_finish_flag = NOT_APPLICABLE`(“此阶段不开展”)。
- `正进行`:当前阶段未完成/未进行,且上一阶段状态为 `已完成`
- `未开始`:其余情况。
- 概览显示日期:使用 `planned_end_date`
- 项目隐藏:`APPROVED``TERMINATED` 不在概览列表中显示。
## 5. 页面与交互
- 登录页(JWT
- 概览页:按项目展示阶段节点、计划完成日期、状态图例
- 录入页:项目阶段表格编辑,支持“此阶段不开展”
- 历史页:阶段变更历史时间线/表格
- 导出:授权用户导出 CSV
## 6. 权限模型
- `ADMIN`:用户/项目/模板管理 + 全部导出
- `PM`:项目进度录入、历史查看、导出
- `VIEWER`:只读(概览、历史)
## 7. API(首期)
- `POST /api/v1/auth/login`
- `GET /api/v1/auth/me`
- `GET /api/v1/projects`
- `POST /api/v1/projects`ADMIN
- `GET /api/v1/stage-templates`
- `POST /api/v1/stage-templates`ADMIN
- `GET /api/v1/projects/{id}/stages`
- `PATCH /api/v1/projects/{id}/stages/{stageId}`PM/ADMIN
- `GET /api/v1/projects/{id}/stages/history`
- `GET /api/v1/projects/stages/export?format=csv`PM/ADMIN
## 8. 验收标准
- 状态计算规则与 PDF 一致
- 录入保存会生成历史记录
- 导出字段与录入字段一致
- `APPROVED/TERMINATED` 项目不在概览展示
@@ -0,0 +1,137 @@
# rd-monitor Implementation Plan
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**Goal:** 搭建独立仓库 `rd-monitor`,实现研发项目进展监测 MVP(独立鉴权、项目阶段录入、状态计算、历史留痕、CSV 导出、前端可用界面)。
**Architecture:** 后端采用 FastAPI + SQLAlchemy + PostgreSQL,提供鉴权、项目阶段、历史、导出 API;前端采用 Vue3 + Element Plus,提供登录、概览、录入、历史页面。通过 Docker Compose 启动前后端与独立 PostgreSQL。
**Tech Stack:** Vue3, Vite, Element Plus, FastAPI, SQLAlchemy, Alembic, PostgreSQL, JWT, Pytest
---
### Task 1: 初始化仓库结构与运行骨架
**Files:**
- Create: `/Users/zcc/MyCTMS/rd-monitor/README.md`
- Create: `/Users/zcc/MyCTMS/rd-monitor/docker-compose.yml`
- Create: `/Users/zcc/MyCTMS/rd-monitor/backend/requirements.txt`
- Create: `/Users/zcc/MyCTMS/rd-monitor/backend/.env.example`
- Create: `/Users/zcc/MyCTMS/rd-monitor/frontend/package.json`
- Create: `/Users/zcc/MyCTMS/rd-monitor/frontend/vite.config.ts`
**Step 1: Write the failing test**
- 编写后端 smoke 测试,断言 `/healthz` 返回 200(此时接口不存在,应失败)。
**Step 2: Run test to verify it fails**
- Run: `cd /Users/zcc/MyCTMS/rd-monitor/backend && pytest -q`
- Expected: FAIL(缺少 app 或路由)。
**Step 3: Write minimal implementation**
- 建立 FastAPI app 与 `/healthz` 路由,补全基础依赖与 compose。
**Step 4: Run test to verify it passes**
- Run: `cd /Users/zcc/MyCTMS/rd-monitor/backend && pytest -q`
- Expected: PASS。
**Step 5: Commit**
- `git add ... && git commit -m "chore: bootstrap rd-monitor skeleton"`
### Task 2: 实现后端核心领域模型与状态计算
**Files:**
- Create: `/Users/zcc/MyCTMS/rd-monitor/backend/app/models/*.py`
- Create: `/Users/zcc/MyCTMS/rd-monitor/backend/app/services/progress.py`
- Test: `/Users/zcc/MyCTMS/rd-monitor/backend/tests/test_progress_status.py`
**Step 1: Write the failing test**
- 用测试覆盖阶段状态计算(已完成/未进行/正进行/未开始)与项目过滤规则。
**Step 2: Run test to verify it fails**
- Run: `pytest tests/test_progress_status.py -q`
- Expected: FAIL。
**Step 3: Write minimal implementation**
- 实现状态计算函数与项目过滤函数。
**Step 4: Run test to verify it passes**
- Run: `pytest tests/test_progress_status.py -q`
- Expected: PASS。
**Step 5: Commit**
- `git commit -m "feat: add progress status domain rules"`
### Task 3: 实现鉴权、项目阶段 API、历史记录与导出
**Files:**
- Create/Modify: `/Users/zcc/MyCTMS/rd-monitor/backend/app/api/*.py`
- Create/Modify: `/Users/zcc/MyCTMS/rd-monitor/backend/app/schemas/*.py`
- Create/Modify: `/Users/zcc/MyCTMS/rd-monitor/backend/app/core/security.py`
- Test: `/Users/zcc/MyCTMS/rd-monitor/backend/tests/test_stage_api.py`
**Step 1: Write the failing test**
- 测试登录、查询项目阶段、更新阶段后历史新增、导出 CSV、权限拦截。
**Step 2: Run test to verify it fails**
- Run: `pytest tests/test_stage_api.py -q`
- Expected: FAIL。
**Step 3: Write minimal implementation**
- 完成相关 API 与依赖。
**Step 4: Run test to verify it passes**
- Run: `pytest tests/test_stage_api.py -q`
- Expected: PASS。
**Step 5: Commit**
- `git commit -m "feat: implement progress APIs with auth history and export"`
### Task 4: 实现前端登录、概览、录入、历史页面
**Files:**
- Create: `/Users/zcc/MyCTMS/rd-monitor/frontend/src/views/*.vue`
- Create: `/Users/zcc/MyCTMS/rd-monitor/frontend/src/router/index.ts`
- Create: `/Users/zcc/MyCTMS/rd-monitor/frontend/src/api/*.ts`
- Create: `/Users/zcc/MyCTMS/rd-monitor/frontend/src/components/*.vue`
**Step 1: Write the failing test**
- 首期用类型检查/构建作为回归保护,先运行应失败(页面未实现)。
**Step 2: Run test to verify it fails**
- Run: `cd /Users/zcc/MyCTMS/rd-monitor/frontend && npm run build`
- Expected: FAIL。
**Step 3: Write minimal implementation**
- 实现可登录、可浏览项目阶段、可编辑阶段、可看历史、可导出。
**Step 4: Run test to verify it passes**
- Run: `npm run build`
- Expected: PASS。
**Step 5: Commit**
- `git commit -m "feat: add frontend pages for monitoring workflow"`
### Task 5: 联调与最终验证
**Files:**
- Modify: `/Users/zcc/MyCTMS/rd-monitor/README.md`
**Step 1: Write the failing test**
- 先运行端到端 smoke(未配置好前应失败)。
**Step 2: Run test to verify it fails**
- Run: `docker compose up --build -d && curl -f http://localhost:8010/healthz`
- Expected: 初次 FAIL 或服务未就绪。
**Step 3: Write minimal implementation**
- 修正配置/环境变量/文档。
**Step 4: Run test to verify it passes**
- Run: `docker compose up --build -d`
- Run: `curl -f http://localhost:8010/healthz`
- Run: `cd backend && pytest -q`
- Run: `cd frontend && npm run build`
- Expected: 全部 PASS。
**Step 5: Commit**
- `git commit -m "docs: finalize rd-monitor setup and verification"`