okr.js
3.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/**
* OKR API — Objective - Key Result 目标管理路由
*
* 旧路径 /api/goals/* 已在 index.js / agent-server.js 注册为向后兼容别名。
*
* GET /api/okr → 列出所有目标
* POST /api/okr → 创建新目标
* GET /api/okr/:objectiveId → 获取完整 OKR 树
* PUT /api/okr/:objectiveId → 更新目标元数据
* POST /api/okr/:objectiveId/nodes → 添加节点
* GET /api/okr/:objectiveId/nodes/:nodeId → 获取节点 + 上下文
* PUT /api/okr/:objectiveId/nodes/:nodeId → 更新节点状态
* GET /api/okr/:objectiveId/progress → 获取进度统计
*
* 参考: docs/architecture-v5.md 第二章
*/
const { Router } = require('express');
const { OkrService } = require('../services/okr-service');
const router = Router();
const okr = new OkrService();
// ── 列出所有目标 ──
router.get('/', (req, res) => {
res.json(okr.list());
});
// ── 创建新目标 ──
router.post('/', (req, res) => {
try {
const { title, description, owner } = req.body;
if (!title || !owner) {
return res.status(400).json({ error: 'title and owner are required' });
}
const objective = okr.create({ title, description, owner });
res.status(201).json(objective);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// ── 获取完整 OKR 树 ──
router.get('/:objectiveId', (req, res) => {
const objective = okr.get(req.params.objectiveId);
if (!objective) return res.status(404).json({ error: 'Objective not found' });
res.json(objective);
});
// ── 更新目标元数据 ──
router.put('/:objectiveId', (req, res) => {
const result = okr.updateObjective(req.params.objectiveId, req.body);
if (!result) return res.status(404).json({ error: 'Objective not found' });
res.json(result);
});
// ── 添加节点 ──
router.post('/:objectiveId/nodes', (req, res) => {
try {
const { parentNodeId, title, owner, priority } = req.body;
if (!title || !owner) {
return res.status(400).json({ error: 'title and owner are required' });
}
const result = okr.addNode(req.params.objectiveId, parentNodeId || null, {
title, owner, priority,
});
if (!result) return res.status(404).json({ error: 'Objective not found' });
res.status(201).json({ nodeId: result.nodeId, node: result.objective.nodes[result.nodeId] });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// ── 获取节点 + 上下文 ──
router.get('/:objectiveId/nodes/:nodeId', (req, res) => {
const node = okr.getNode(req.params.objectiveId, req.params.nodeId);
if (!node) return res.status(404).json({ error: 'Node not found' });
res.json(node);
});
// ── 更新节点状态 ──
router.put('/:objectiveId/nodes/:nodeId', (req, res) => {
const result = okr.updateNode(req.params.objectiveId, req.params.nodeId, req.body);
if (!result) return res.status(404).json({ error: 'Node not found' });
res.json({ nodeId: result.nodeId, node: result.node });
});
// ── 获取进度 ──
router.get('/:objectiveId/progress', (req, res) => {
const progress = okr.getProgress(req.params.objectiveId);
if (!progress) return res.status(404).json({ error: 'Objective not found' });
res.json(progress);
});
module.exports = router;