- API.md 新增第 4 节:升级/动作/列表/关系/通知与 6xxx 错误码 - ROADMAP 补 M2 全部条目与 DOD,验收用例加自验与回流两条 - DEVELOPMENT 记两条新坑:PowerShell 批量改写会毁中文、npm.ps1 被执行策略拦 - README 状态表把工单从待做改成已通,测试数 57
This commit is contained in:
+81
-2
@@ -1,4 +1,4 @@
|
||||
# 接口约定(M0–M1 已实现)
|
||||
# 接口约定(M0–M2 已实现)
|
||||
|
||||
> 只写**已经在跑**的接口。写完没验证的东西不进这份文档。
|
||||
> 前缀 `/api/v1`。所有响应都是同一个信封,**HTTP 200 不代表业务成功**。
|
||||
@@ -222,7 +222,86 @@ canceled→ todo (恢复)
|
||||
|
||||
---
|
||||
|
||||
## 4. 健康与版本
|
||||
## 4. 工单 `/workspaces/{ws_id}`
|
||||
|
||||
工单**不是**另一张表里的另一种东西,它是一条 `kind='ticket'` 的 item 加一行 `ticket_ext`。
|
||||
所以详情仍然走 `GET /items/{item_id}`,响应里多一个 `ticket` 字段。
|
||||
|
||||
### 4.1 `POST /items/{item_id}/promote`(任务升级成工单)
|
||||
|
||||
```json
|
||||
{ "assignee_id": "uuid", "title": "可选覆盖", "body_md": "可选补充",
|
||||
"due_at": "2026-10-30T10:00:00+08:00", "priority": 2, "version": 3 }
|
||||
```
|
||||
|
||||
返回 `{ "task": {...}, "ticket": {...} }`。
|
||||
|
||||
- 原任务**留在原地**变成 `blocked`,不搬数据——时间线完整保留。
|
||||
- 一个任务只能升级一次,重复升级 → `6002`。
|
||||
- `assignee_id` 必须是工作区内 `active` 成员,否则 `1001`。
|
||||
- 传 `version` 走乐观锁,`4009` 表示任务刚被别人改过。
|
||||
- 被指派人立刻收到 `ticket_assigned` 通知。
|
||||
|
||||
### 4.2 工单动作
|
||||
|
||||
| 方法 | 路径 | 谁可以 | 前置状态 → 结果 |
|
||||
|---|---|---|---|
|
||||
| POST | `/items/{item_id}/ticket/accept` | 办理人 / admin+ | open → accepted |
|
||||
| POST | `/items/{item_id}/ticket/start` | 办理人 / admin+ | accepted → in_progress |
|
||||
| POST | `/items/{item_id}/ticket/submit` | 办理人 / admin+ | in_progress → pending_verify |
|
||||
| POST | `/items/{item_id}/ticket/verify` | **需求人** / admin+ | pending_verify → done / in_progress |
|
||||
| POST | `/items/{item_id}/ticket/reassign` | 需求人 / admin+ | 任意未完成 → open(清空受理时间) |
|
||||
| POST | `/items/{item_id}/ticket/cancel` | 需求人 / 办理人 / admin+ | 未完成 → canceled |
|
||||
|
||||
`verify` 的请求体:`{ "approve": true, "note": "可选说明", "resolution_md": "验收结论" }`。
|
||||
|
||||
- 驳回时 `approve=false`,回到 `in_progress`(不是 `open`——人还在做,不必重新认领),`reject_count` 加一。
|
||||
- **办理人不能验收自己的工单**,否则 `6004`。这是唯一一条"就算 owner 也不通融"的规则之外的角色限制。
|
||||
- `resolution_md` 是 M3 知识草稿的原料,尽量写。
|
||||
- 前置状态不对 → `6003`,`details` 同时给 `allowed`(当前状态还能去哪)与 `allowed_from`(该动作要求的前置状态)。
|
||||
|
||||
### 4.3 工单列表 `GET /tickets`
|
||||
|
||||
| 参数 | 说明 |
|
||||
|---|---|
|
||||
| `role` | `assigned`(派给我的,默认)/ `requested`(我发起的)/ `all` |
|
||||
| `status` | 可重复,如 `?status=open&status=accepted` |
|
||||
| `limit` / `cursor` | 与任务列表一致 |
|
||||
|
||||
### 4.4 事项关系 `GET|POST /items/{item_id}/links`
|
||||
|
||||
```json
|
||||
{ "to_item_id": "uuid", "link_type": "parent" }
|
||||
```
|
||||
|
||||
`GET` 返回 `{ "children": [...], "parents": [...], "related": [...] }`。
|
||||
`link_type` 只有 `parent` / `related`,**方向是 from 是 to 的子项**;自环 `5005`、重复挂 `5005`、对方不存在 `5004`、跨租户 `5001`。
|
||||
|
||||
### 4.5 通知 `/workspaces/{ws_id}/notifications`
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
|---|---|---|
|
||||
| GET | `/notifications?unread_only=true` | 我的通知,新的在前 |
|
||||
| GET | `/notifications/unread-count` | `{ "unread": 3 }`,轮询用 |
|
||||
| POST | `/notifications/{id}/read` | 标一条 |
|
||||
| POST | `/notifications/read-all` | 全标已读 |
|
||||
|
||||
`kind`:`ticket_assigned` / `ticket_submitted` / `ticket_approved` / `ticket_rejected` / `task_unblocked`。
|
||||
通知只发给当事人,同工作区里其他人看不到——这是"协同"与"广播"的区别。
|
||||
|
||||
### 4.6 工单的错误码
|
||||
|
||||
| 码 | HTTP | 含义 |
|
||||
|---|---|---|
|
||||
| 6001 | 404 | 工单不存在,或不是工单 |
|
||||
| 6002 | 409 | 这个任务已经升级过了 |
|
||||
| 6003 | 409 | 当前状态不允许这个动作 |
|
||||
| 6004 | 403 | 你没有权限做这个动作(例如自验) |
|
||||
| 6005 | 404 | 通知不存在,或不是你的 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 健康与版本
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
|---|---|---|
|
||||
|
||||
Reference in New Issue
Block a user