164 lines
4.8 KiB
Markdown
164 lines
4.8 KiB
Markdown
# HarborForge — Propose → Feature Story → Milestone 流程
|
||
|
||
> 更新时间:2026-03-18
|
||
> 本文档描述 feature 进入 milestone 的完整流程。
|
||
|
||
---
|
||
|
||
## 1. 流程总览
|
||
|
||
```
|
||
用户创建 Propose 负责人审阅 系统自动生成
|
||
│ │ │
|
||
▼ ▼ ▼
|
||
Propose (open) ──accept──▶ Propose (accepted)
|
||
│ │
|
||
│ ▼
|
||
│ Feature Story Task (pending)
|
||
│ 归属选定 milestone
|
||
│
|
||
──reject──▶ Propose (rejected)
|
||
│
|
||
──reopen──▶ Propose (open) ── 重新审阅 ──▶ ...
|
||
```
|
||
|
||
---
|
||
|
||
## 2. 详细步骤
|
||
|
||
### Step 1:创建 Propose
|
||
|
||
- 用户在 project 下创建 propose
|
||
- 填写 title + description
|
||
- 系统自动生成 `propose_code`(格式:`{proj_code}:P{i:05x}`)
|
||
- 初始状态:`open`
|
||
|
||
### Step 2:审阅
|
||
|
||
- 负责人在 Propose 详情页查看内容
|
||
- `open` 状态下可选操作:
|
||
- **Accept** — 接受并生成 feature task
|
||
- **Reject** — 拒绝(建议填写 reason)
|
||
- Propose 创建者在 `open` 状态下可编辑 title/description
|
||
|
||
### Step 3a:Accept
|
||
|
||
前置条件:
|
||
- 操作者拥有 `propose.accept` 权限
|
||
- 选择一个 `open` 状态的目标 milestone(同 project)
|
||
|
||
系统执行:
|
||
1. Propose status → `accepted`
|
||
2. 在目标 milestone 下自动创建 `story/feature` task
|
||
- 继承 title、description、created_by
|
||
- 默认状态 `pending`
|
||
3. 自动回填 `feat_task_id`(只读字段)
|
||
4. 写入 activity log
|
||
|
||
Accept 后:
|
||
- Propose 详情页显示 "View Generated Task" 跳转按钮
|
||
- Propose 主体不可再编辑
|
||
|
||
### Step 3b:Reject
|
||
|
||
前置条件:
|
||
- 操作者拥有 `propose.reject` 权限
|
||
|
||
系统执行:
|
||
1. Propose status → `rejected`
|
||
2. 写入 reject reason(activity log)
|
||
|
||
Reject 后:
|
||
- Propose 详情页显示 "Reopen" 按钮
|
||
- Propose 主体不可编辑
|
||
|
||
### Step 4:Reopen(可选)
|
||
|
||
前置条件:
|
||
- 操作者拥有 `propose.reopen` 权限
|
||
- Propose 当前状态为 `rejected`
|
||
|
||
系统执行:
|
||
1. Propose status → `open`(复用原 propose,不创建新记录)
|
||
2. 写入 reopen 记录
|
||
|
||
Reopen 后:
|
||
- 可再次编辑 title/description
|
||
- 可再次 accept 或 reject
|
||
|
||
---
|
||
|
||
## 3. Feature Task 生命周期
|
||
|
||
Accept 生成的 feature story task 遵循标准 task 状态机:
|
||
|
||
```
|
||
pending → open → undergoing → completed
|
||
│
|
||
(触发 milestone auto-complete
|
||
仅当该 task 是 release task 时)
|
||
```
|
||
|
||
关键约束:
|
||
- Feature story task **不能**通过通用 create task 页面创建
|
||
- Milestone 进入 `freeze` 后,不再接受新的 feature story
|
||
- Milestone 非 `open` 时,已有 feature story task 的 body 字段锁定
|
||
|
||
---
|
||
|
||
## 4. Milestone 完整生命周期(含 propose)
|
||
|
||
```
|
||
1. 创建 milestone (open)
|
||
2. 通过 propose → accept 添加 feature story tasks
|
||
3. 创建 release maintenance task(通过 milestone endpoint)
|
||
4. Freeze milestone(需有且仅有 1 个 release task)
|
||
5. 满足依赖后 Start milestone → undergoing
|
||
6. Tasks 开始执行(pending → open → undergoing → completed)
|
||
7. Release maintenance task 完成 → milestone 自动 completed
|
||
```
|
||
|
||
---
|
||
|
||
## 5. Propose 编码规则
|
||
|
||
- 格式:`{proj_code}:P{i:05x}`
|
||
- 示例:`HF:P00001`, `HF:P00002`, `HF:P0000a`
|
||
- 每个 project 独立递增
|
||
- 并发安全:数据库 unique 约束保底
|
||
|
||
---
|
||
|
||
## 6. API 端点
|
||
|
||
| 操作 | 方法 | 路径 |
|
||
|---------|--------|--------------------------------------------------|
|
||
| 创建 | POST | `/projects/{pid}/proposes` |
|
||
| 列表 | GET | `/projects/{pid}/proposes` |
|
||
| 详情 | GET | `/projects/{pid}/proposes/{id}` |
|
||
| 编辑 | PATCH | `/projects/{pid}/proposes/{id}` |
|
||
| Accept | POST | `/projects/{pid}/proposes/{id}/actions/accept` |
|
||
| Reject | POST | `/projects/{pid}/proposes/{id}/actions/reject` |
|
||
| Reopen | POST | `/projects/{pid}/proposes/{id}/actions/reopen` |
|
||
|
||
---
|
||
|
||
## 7. CLI 命令
|
||
|
||
```bash
|
||
# 列出 proposes
|
||
harborforge proposes --project <project_id>
|
||
|
||
# 创建 propose
|
||
harborforge propose-create "My Feature Idea" --project <project_id>
|
||
|
||
# Accept(需指定 milestone)
|
||
harborforge propose-accept <propose_id> --project <project_id> --milestone <milestone_id>
|
||
|
||
# Reject(可选 reason)
|
||
harborforge propose-reject <propose_id> --project <project_id> --reason "Not in scope"
|
||
|
||
# Reopen
|
||
harborforge propose-reopen <propose_id> --project <project_id>
|
||
```
|