@qq33357486/oh-my-task 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +315 -0
  3. package/dist/api/middleware/auth.d.ts +26 -0
  4. package/dist/api/middleware/auth.d.ts.map +1 -0
  5. package/dist/api/middleware/auth.js +90 -0
  6. package/dist/api/middleware/auth.js.map +1 -0
  7. package/dist/api/middleware/captcha.d.ts +6 -0
  8. package/dist/api/middleware/captcha.d.ts.map +1 -0
  9. package/dist/api/middleware/captcha.js +47 -0
  10. package/dist/api/middleware/captcha.js.map +1 -0
  11. package/dist/api/middleware/ownerCheck.d.ts +22 -0
  12. package/dist/api/middleware/ownerCheck.d.ts.map +1 -0
  13. package/dist/api/middleware/ownerCheck.js +138 -0
  14. package/dist/api/middleware/ownerCheck.js.map +1 -0
  15. package/dist/api/routes/auth.d.ts +8 -0
  16. package/dist/api/routes/auth.d.ts.map +1 -0
  17. package/dist/api/routes/auth.js +136 -0
  18. package/dist/api/routes/auth.js.map +1 -0
  19. package/dist/api/routes/config.d.ts +3 -0
  20. package/dist/api/routes/config.d.ts.map +1 -0
  21. package/dist/api/routes/config.js +26 -0
  22. package/dist/api/routes/config.js.map +1 -0
  23. package/dist/api/routes/projects.d.ts +3 -0
  24. package/dist/api/routes/projects.d.ts.map +1 -0
  25. package/dist/api/routes/projects.js +54 -0
  26. package/dist/api/routes/projects.js.map +1 -0
  27. package/dist/api/routes/schedule.d.ts +3 -0
  28. package/dist/api/routes/schedule.d.ts.map +1 -0
  29. package/dist/api/routes/schedule.js +92 -0
  30. package/dist/api/routes/schedule.js.map +1 -0
  31. package/dist/api/routes/sops.d.ts +3 -0
  32. package/dist/api/routes/sops.d.ts.map +1 -0
  33. package/dist/api/routes/sops.js +155 -0
  34. package/dist/api/routes/sops.js.map +1 -0
  35. package/dist/api/routes/tasks.d.ts +3 -0
  36. package/dist/api/routes/tasks.d.ts.map +1 -0
  37. package/dist/api/routes/tasks.js +218 -0
  38. package/dist/api/routes/tasks.js.map +1 -0
  39. package/dist/api/routes/tokens.d.ts +3 -0
  40. package/dist/api/routes/tokens.d.ts.map +1 -0
  41. package/dist/api/routes/tokens.js +77 -0
  42. package/dist/api/routes/tokens.js.map +1 -0
  43. package/dist/api/routes/users.d.ts +3 -0
  44. package/dist/api/routes/users.d.ts.map +1 -0
  45. package/dist/api/routes/users.js +94 -0
  46. package/dist/api/routes/users.js.map +1 -0
  47. package/dist/api/routes/versions.d.ts +3 -0
  48. package/dist/api/routes/versions.d.ts.map +1 -0
  49. package/dist/api/routes/versions.js +156 -0
  50. package/dist/api/routes/versions.js.map +1 -0
  51. package/dist/api/server.d.ts +4 -0
  52. package/dist/api/server.d.ts.map +1 -0
  53. package/dist/api/server.js +70 -0
  54. package/dist/api/server.js.map +1 -0
  55. package/dist/db/connection.d.ts +15 -0
  56. package/dist/db/connection.d.ts.map +1 -0
  57. package/dist/db/connection.js +158 -0
  58. package/dist/db/connection.js.map +1 -0
  59. package/dist/db/init.d.ts +2 -0
  60. package/dist/db/init.d.ts.map +1 -0
  61. package/dist/db/init.js +5 -0
  62. package/dist/db/init.js.map +1 -0
  63. package/dist/index.d.ts +2 -0
  64. package/dist/index.d.ts.map +1 -0
  65. package/dist/index.js +4 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/mcp/server.d.ts +2 -0
  68. package/dist/mcp/server.d.ts.map +1 -0
  69. package/dist/mcp/server.js +146 -0
  70. package/dist/mcp/server.js.map +1 -0
  71. package/dist/mcp/tools/activate-task.d.ts +10 -0
  72. package/dist/mcp/tools/activate-task.d.ts.map +1 -0
  73. package/dist/mcp/tools/activate-task.js +52 -0
  74. package/dist/mcp/tools/activate-task.js.map +1 -0
  75. package/dist/mcp/tools/add-task-note.d.ts +10 -0
  76. package/dist/mcp/tools/add-task-note.d.ts.map +1 -0
  77. package/dist/mcp/tools/add-task-note.js +46 -0
  78. package/dist/mcp/tools/add-task-note.js.map +1 -0
  79. package/dist/mcp/tools/approve-task.d.ts +10 -0
  80. package/dist/mcp/tools/approve-task.d.ts.map +1 -0
  81. package/dist/mcp/tools/approve-task.js +59 -0
  82. package/dist/mcp/tools/approve-task.js.map +1 -0
  83. package/dist/mcp/tools/archive-version.d.ts +10 -0
  84. package/dist/mcp/tools/archive-version.d.ts.map +1 -0
  85. package/dist/mcp/tools/archive-version.js +57 -0
  86. package/dist/mcp/tools/archive-version.js.map +1 -0
  87. package/dist/mcp/tools/assign-task.d.ts +10 -0
  88. package/dist/mcp/tools/assign-task.d.ts.map +1 -0
  89. package/dist/mcp/tools/assign-task.js +53 -0
  90. package/dist/mcp/tools/assign-task.js.map +1 -0
  91. package/dist/mcp/tools/complete-task.d.ts +10 -0
  92. package/dist/mcp/tools/complete-task.d.ts.map +1 -0
  93. package/dist/mcp/tools/complete-task.js +46 -0
  94. package/dist/mcp/tools/complete-task.js.map +1 -0
  95. package/dist/mcp/tools/create-sop.d.ts +10 -0
  96. package/dist/mcp/tools/create-sop.d.ts.map +1 -0
  97. package/dist/mcp/tools/create-sop.js +90 -0
  98. package/dist/mcp/tools/create-sop.js.map +1 -0
  99. package/dist/mcp/tools/create-task.d.ts +10 -0
  100. package/dist/mcp/tools/create-task.d.ts.map +1 -0
  101. package/dist/mcp/tools/create-task.js +138 -0
  102. package/dist/mcp/tools/create-task.js.map +1 -0
  103. package/dist/mcp/tools/create-version.d.ts +10 -0
  104. package/dist/mcp/tools/create-version.d.ts.map +1 -0
  105. package/dist/mcp/tools/create-version.js +86 -0
  106. package/dist/mcp/tools/create-version.js.map +1 -0
  107. package/dist/mcp/tools/delete-task.d.ts +10 -0
  108. package/dist/mcp/tools/delete-task.d.ts.map +1 -0
  109. package/dist/mcp/tools/delete-task.js +34 -0
  110. package/dist/mcp/tools/delete-task.js.map +1 -0
  111. package/dist/mcp/tools/get-my-tasks.d.ts +10 -0
  112. package/dist/mcp/tools/get-my-tasks.d.ts.map +1 -0
  113. package/dist/mcp/tools/get-my-tasks.js +88 -0
  114. package/dist/mcp/tools/get-my-tasks.js.map +1 -0
  115. package/dist/mcp/tools/get-next-task.d.ts +10 -0
  116. package/dist/mcp/tools/get-next-task.d.ts.map +1 -0
  117. package/dist/mcp/tools/get-next-task.js +84 -0
  118. package/dist/mcp/tools/get-next-task.js.map +1 -0
  119. package/dist/mcp/tools/get-sop.d.ts +10 -0
  120. package/dist/mcp/tools/get-sop.d.ts.map +1 -0
  121. package/dist/mcp/tools/get-sop.js +67 -0
  122. package/dist/mcp/tools/get-sop.js.map +1 -0
  123. package/dist/mcp/tools/get-task-context.d.ts +10 -0
  124. package/dist/mcp/tools/get-task-context.d.ts.map +1 -0
  125. package/dist/mcp/tools/get-task-context.js +114 -0
  126. package/dist/mcp/tools/get-task-context.js.map +1 -0
  127. package/dist/mcp/tools/get-task.d.ts +10 -0
  128. package/dist/mcp/tools/get-task.d.ts.map +1 -0
  129. package/dist/mcp/tools/get-task.js +61 -0
  130. package/dist/mcp/tools/get-task.js.map +1 -0
  131. package/dist/mcp/tools/helpers.d.ts +10 -0
  132. package/dist/mcp/tools/helpers.d.ts.map +1 -0
  133. package/dist/mcp/tools/helpers.js +17 -0
  134. package/dist/mcp/tools/helpers.js.map +1 -0
  135. package/dist/mcp/tools/init-project.d.ts +12 -0
  136. package/dist/mcp/tools/init-project.d.ts.map +1 -0
  137. package/dist/mcp/tools/init-project.js +162 -0
  138. package/dist/mcp/tools/init-project.js.map +1 -0
  139. package/dist/mcp/tools/list-sops.d.ts +10 -0
  140. package/dist/mcp/tools/list-sops.d.ts.map +1 -0
  141. package/dist/mcp/tools/list-sops.js +57 -0
  142. package/dist/mcp/tools/list-sops.js.map +1 -0
  143. package/dist/mcp/tools/list-tasks.d.ts +10 -0
  144. package/dist/mcp/tools/list-tasks.d.ts.map +1 -0
  145. package/dist/mcp/tools/list-tasks.js +96 -0
  146. package/dist/mcp/tools/list-tasks.js.map +1 -0
  147. package/dist/mcp/tools/list-versions.d.ts +10 -0
  148. package/dist/mcp/tools/list-versions.d.ts.map +1 -0
  149. package/dist/mcp/tools/list-versions.js +76 -0
  150. package/dist/mcp/tools/list-versions.js.map +1 -0
  151. package/dist/mcp/tools/reject-task.d.ts +10 -0
  152. package/dist/mcp/tools/reject-task.d.ts.map +1 -0
  153. package/dist/mcp/tools/reject-task.js +63 -0
  154. package/dist/mcp/tools/reject-task.js.map +1 -0
  155. package/dist/mcp/tools/reschedule.d.ts +17 -0
  156. package/dist/mcp/tools/reschedule.d.ts.map +1 -0
  157. package/dist/mcp/tools/reschedule.js +107 -0
  158. package/dist/mcp/tools/reschedule.js.map +1 -0
  159. package/dist/mcp/tools/start-task.d.ts +10 -0
  160. package/dist/mcp/tools/start-task.d.ts.map +1 -0
  161. package/dist/mcp/tools/start-task.js +42 -0
  162. package/dist/mcp/tools/start-task.js.map +1 -0
  163. package/dist/mcp/tools/submit-for-review.d.ts +10 -0
  164. package/dist/mcp/tools/submit-for-review.d.ts.map +1 -0
  165. package/dist/mcp/tools/submit-for-review.js +64 -0
  166. package/dist/mcp/tools/submit-for-review.js.map +1 -0
  167. package/dist/mcp/tools/update-sop.d.ts +10 -0
  168. package/dist/mcp/tools/update-sop.d.ts.map +1 -0
  169. package/dist/mcp/tools/update-sop.js +113 -0
  170. package/dist/mcp/tools/update-sop.js.map +1 -0
  171. package/dist/mcp/tools/update-task-doc.d.ts +10 -0
  172. package/dist/mcp/tools/update-task-doc.d.ts.map +1 -0
  173. package/dist/mcp/tools/update-task-doc.js +70 -0
  174. package/dist/mcp/tools/update-task-doc.js.map +1 -0
  175. package/dist/mcp/tools/update-task.d.ts +10 -0
  176. package/dist/mcp/tools/update-task.d.ts.map +1 -0
  177. package/dist/mcp/tools/update-task.js +106 -0
  178. package/dist/mcp/tools/update-task.js.map +1 -0
  179. package/dist/mcp/tools/utils/config.d.ts +35 -0
  180. package/dist/mcp/tools/utils/config.d.ts.map +1 -0
  181. package/dist/mcp/tools/utils/config.js +81 -0
  182. package/dist/mcp/tools/utils/config.js.map +1 -0
  183. package/dist/services/config.service.d.ts +6 -0
  184. package/dist/services/config.service.d.ts.map +1 -0
  185. package/dist/services/config.service.js +48 -0
  186. package/dist/services/config.service.js.map +1 -0
  187. package/dist/services/project.service.d.ts +29 -0
  188. package/dist/services/project.service.d.ts.map +1 -0
  189. package/dist/services/project.service.js +111 -0
  190. package/dist/services/project.service.js.map +1 -0
  191. package/dist/services/schedule.service.d.ts +104 -0
  192. package/dist/services/schedule.service.d.ts.map +1 -0
  193. package/dist/services/schedule.service.js +362 -0
  194. package/dist/services/schedule.service.js.map +1 -0
  195. package/dist/services/session.service.d.ts +5 -0
  196. package/dist/services/session.service.d.ts.map +1 -0
  197. package/dist/services/session.service.js +30 -0
  198. package/dist/services/session.service.js.map +1 -0
  199. package/dist/services/sop.service.d.ts +53 -0
  200. package/dist/services/sop.service.d.ts.map +1 -0
  201. package/dist/services/sop.service.js +275 -0
  202. package/dist/services/sop.service.js.map +1 -0
  203. package/dist/services/task.service.d.ts +62 -0
  204. package/dist/services/task.service.d.ts.map +1 -0
  205. package/dist/services/task.service.js +546 -0
  206. package/dist/services/task.service.js.map +1 -0
  207. package/dist/services/token.service.d.ts +37 -0
  208. package/dist/services/token.service.d.ts.map +1 -0
  209. package/dist/services/token.service.js +99 -0
  210. package/dist/services/token.service.js.map +1 -0
  211. package/dist/services/user.service.d.ts +95 -0
  212. package/dist/services/user.service.d.ts.map +1 -0
  213. package/dist/services/user.service.js +275 -0
  214. package/dist/services/user.service.js.map +1 -0
  215. package/dist/services/version.service.d.ts +70 -0
  216. package/dist/services/version.service.d.ts.map +1 -0
  217. package/dist/services/version.service.js +225 -0
  218. package/dist/services/version.service.js.map +1 -0
  219. package/dist/types/index.d.ts +207 -0
  220. package/dist/types/index.d.ts.map +1 -0
  221. package/dist/types/index.js +2 -0
  222. package/dist/types/index.js.map +1 -0
  223. package/dist/utils/password.d.ts +16 -0
  224. package/dist/utils/password.d.ts.map +1 -0
  225. package/dist/utils/password.js +37 -0
  226. package/dist/utils/password.js.map +1 -0
  227. package/dist/utils/validation.d.ts +13 -0
  228. package/dist/utils/validation.d.ts.map +1 -0
  229. package/dist/utils/validation.js +20 -0
  230. package/dist/utils/validation.js.map +1 -0
  231. package/package.json +65 -0
  232. package/src/db/schema.sql +162 -0
@@ -0,0 +1,155 @@
1
+ import { Router } from 'express';
2
+ import * as sopService from '../../services/sop.service.js';
3
+ import * as projectService from '../../services/project.service.js';
4
+ const router = Router();
5
+ // 获取项目的路径(从请求体、查询参数或请求头)
6
+ function getProjectPath(req) {
7
+ // 从请求体获取
8
+ if (req.body.project_path) {
9
+ return req.body.project_path;
10
+ }
11
+ // 从查询参数获取
12
+ if (req.query.project_path) {
13
+ return req.query.project_path;
14
+ }
15
+ // 从请求头获取
16
+ if (req.headers['x-project-path']) {
17
+ return req.headers['x-project-path'];
18
+ }
19
+ return null;
20
+ }
21
+ // GET /api/sops - 获取 SOP 列表
22
+ router.get('/', (req, res) => {
23
+ const projectId = req.query.project_id;
24
+ const projectPath = getProjectPath(req);
25
+ const userId = req.auth?.user?.id;
26
+ const isAdmin = req.auth?.user?.role === 'admin';
27
+ if (!projectId) {
28
+ res.status(400).json({ success: false, error: 'project_id 不能为空' });
29
+ return;
30
+ }
31
+ if (!projectPath) {
32
+ res.status(400).json({ success: false, error: 'project_path 不能为空(可通过 body、query 或 x-project-path header)' });
33
+ return;
34
+ }
35
+ // 验证项目归属
36
+ if (!isAdmin) {
37
+ const hasAccess = projectService.checkProjectOwnership(projectId, userId);
38
+ if (!hasAccess) {
39
+ res.status(404).json({ success: false, error: '项目不存在' });
40
+ return;
41
+ }
42
+ }
43
+ const sops = sopService.listSOPs(projectId, projectPath, isAdmin ? undefined : userId);
44
+ res.json({ success: true, data: sops });
45
+ });
46
+ // GET /api/sops/:id - 获取 SOP 详情
47
+ router.get('/:id', (req, res) => {
48
+ const projectPath = getProjectPath(req);
49
+ const userId = req.auth?.user?.id;
50
+ const isAdmin = req.auth?.user?.role === 'admin';
51
+ if (!projectPath) {
52
+ res.status(400).json({ success: false, error: 'project_path 不能为空' });
53
+ return;
54
+ }
55
+ const sop = sopService.getSOPById(req.params.id, projectPath, isAdmin ? undefined : userId);
56
+ if (!sop) {
57
+ res.status(404).json({ success: false, error: 'SOP 不存在' });
58
+ return;
59
+ }
60
+ res.json({ success: true, data: sop });
61
+ });
62
+ // POST /api/sops - 创建 SOP
63
+ router.post('/', (req, res) => {
64
+ const { project_id, project_path, name, description, rules, workflow, required, forbidden, experience } = req.body;
65
+ const userId = req.auth.user.id;
66
+ const isAdmin = req.auth.user.role === 'admin';
67
+ if (!project_id) {
68
+ res.status(400).json({ success: false, error: 'project_id 不能为空' });
69
+ return;
70
+ }
71
+ if (!project_path) {
72
+ res.status(400).json({ success: false, error: 'project_path 不能为空' });
73
+ return;
74
+ }
75
+ if (!name) {
76
+ res.status(400).json({ success: false, error: 'name 不能为空' });
77
+ return;
78
+ }
79
+ // 验证项目归属
80
+ if (!isAdmin) {
81
+ const hasAccess = projectService.checkProjectOwnership(project_id, userId);
82
+ if (!hasAccess) {
83
+ res.status(404).json({ success: false, error: '项目不存在' });
84
+ return;
85
+ }
86
+ }
87
+ const params = {
88
+ project_id,
89
+ project_path,
90
+ name,
91
+ description,
92
+ rules,
93
+ workflow,
94
+ required,
95
+ forbidden,
96
+ experience,
97
+ };
98
+ const sop = sopService.createSOP(params);
99
+ res.status(201).json({ success: true, data: sop });
100
+ });
101
+ // PUT /api/sops/:id - 更新 SOP
102
+ router.put('/:id', (req, res) => {
103
+ const { name, description, rules, workflow, required, forbidden, experience, append_experience, project_path } = req.body;
104
+ const userId = req.auth.user.id;
105
+ const isAdmin = req.auth.user.role === 'admin';
106
+ if (!project_path) {
107
+ res.status(400).json({ success: false, error: 'project_path 不能为空' });
108
+ return;
109
+ }
110
+ const params = {
111
+ name,
112
+ description,
113
+ rules,
114
+ workflow,
115
+ required,
116
+ forbidden,
117
+ experience,
118
+ append_experience,
119
+ };
120
+ const sop = sopService.updateSOP(req.params.id, params, project_path);
121
+ if (!sop) {
122
+ res.status(404).json({ success: false, error: 'SOP 不存在' });
123
+ return;
124
+ }
125
+ res.json({ success: true, data: sop });
126
+ });
127
+ // DELETE /api/sops/:id - 删除 SOP
128
+ router.delete('/:id', (req, res) => {
129
+ const projectPath = req.query.project_path || req.body.project_path;
130
+ const userId = req.auth.user.id;
131
+ const isAdmin = req.auth.user.role === 'admin';
132
+ if (!projectPath) {
133
+ res.status(400).json({ success: false, error: 'project_path 不能为空' });
134
+ return;
135
+ }
136
+ // 验证归属
137
+ const sop = sopService.getSOPById(req.params.id, projectPath, isAdmin ? undefined : userId);
138
+ if (!sop) {
139
+ res.status(404).json({ success: false, error: 'SOP 不存在' });
140
+ return;
141
+ }
142
+ const success = sopService.deleteSOP(req.params.id, projectPath);
143
+ if (!success) {
144
+ res.status(404).json({ success: false, error: 'SOP 不存在' });
145
+ return;
146
+ }
147
+ res.json({ success: true, message: 'SOP 已删除' });
148
+ });
149
+ // GET /api/sops/:id/usage - 获取 SOP 使用统计
150
+ router.get('/:id/usage', (req, res) => {
151
+ const count = sopService.getSOPUsageCount(req.params.id);
152
+ res.json({ success: true, data: { usage_count: count } });
153
+ });
154
+ export default router;
155
+ //# sourceMappingURL=sops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sops.js","sourceRoot":"","sources":["../../../src/api/routes/sops.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
3
+ //# sourceMappingURL=tasks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../../src/api/routes/tasks.ts"],"names":[],"mappings":"AAKA,QAAA,MAAM,MAAM,4CAAW,CAAC;AA+PxB,eAAe,MAAM,CAAC"}
@@ -0,0 +1,218 @@
1
+ import { Router } from 'express';
2
+ import * as taskService from '../../services/task.service.js';
3
+ import * as projectService from '../../services/project.service.js';
4
+ const router = Router();
5
+ // GET /api/tasks - 获取任务列表
6
+ router.get('/', (req, res) => {
7
+ const userId = req.auth?.user?.id;
8
+ const isAdmin = req.auth?.user?.role === 'admin';
9
+ const params = {
10
+ project_id: req.query.project_id,
11
+ version_id: req.query.version_id === 'null' ? null : req.query.version_id,
12
+ parent_id: req.query.parent_id === 'null' ? null : req.query.parent_id,
13
+ status: req.query.status,
14
+ assignee_id: req.query.assignee_id,
15
+ };
16
+ // 验证项目归属
17
+ if (params.project_id && !isAdmin) {
18
+ const hasAccess = projectService.checkProjectOwnership(params.project_id, userId);
19
+ if (!hasAccess) {
20
+ res.status(404).json({ success: false, error: '项目不存在' });
21
+ return;
22
+ }
23
+ }
24
+ const tasks = taskService.listTasks(params, isAdmin ? undefined : userId);
25
+ res.json({ success: true, data: tasks });
26
+ });
27
+ // PUT /api/tasks/reorder - 重新排序任务 (must be before /:id)
28
+ router.put('/reorder', (req, res) => {
29
+ const { task_ids, parent_id } = req.body;
30
+ if (!task_ids || !Array.isArray(task_ids)) {
31
+ res.status(400).json({ success: false, error: 'task_ids 必须是数组' });
32
+ return;
33
+ }
34
+ taskService.reorderTasks(task_ids, parent_id ?? null);
35
+ res.json({ success: true, message: '任务排序已更新' });
36
+ });
37
+ // GET /api/tasks/:id - 获取任务详情(含子任务树)
38
+ router.get('/:id', (req, res) => {
39
+ const userId = req.auth?.user?.id;
40
+ const isAdmin = req.auth?.user?.role === 'admin';
41
+ const task = taskService.getTaskWithChildren(req.params.id, isAdmin ? undefined : userId);
42
+ if (!task) {
43
+ res.status(404).json({ success: false, error: '任务不存在' });
44
+ return;
45
+ }
46
+ res.json({ success: true, data: task });
47
+ });
48
+ // POST /api/tasks - 创建任务
49
+ router.post('/', (req, res) => {
50
+ const { project_id, version_id, parent_id, title, description, assignee_id, estimated_days, start_date, due_date } = req.body;
51
+ const userId = req.auth.user.id;
52
+ const isAdmin = req.auth.user.role === 'admin';
53
+ if (!project_id) {
54
+ res.status(400).json({ success: false, error: 'project_id 不能为空' });
55
+ return;
56
+ }
57
+ if (!title) {
58
+ res.status(400).json({ success: false, error: 'title 不能为空' });
59
+ return;
60
+ }
61
+ // 验证项目归属
62
+ if (!isAdmin) {
63
+ const hasAccess = projectService.checkProjectOwnership(project_id, userId);
64
+ if (!hasAccess) {
65
+ res.status(404).json({ success: false, error: '项目不存在' });
66
+ return;
67
+ }
68
+ }
69
+ const params = {
70
+ project_id,
71
+ version_id,
72
+ parent_id,
73
+ title,
74
+ description,
75
+ assignee_id,
76
+ estimated_days,
77
+ start_date,
78
+ due_date,
79
+ };
80
+ const task = taskService.createTask(params, userId);
81
+ res.status(201).json({ success: true, data: task });
82
+ });
83
+ // PUT /api/tasks/:id - 更新任务
84
+ router.put('/:id', (req, res) => {
85
+ const { title, description, status, assignee_id, estimated_days, start_date, due_date, version_id, reason, sop_id } = req.body;
86
+ const userId = req.auth.user.id;
87
+ const isAdmin = req.auth.user.role === 'admin';
88
+ const params = {
89
+ title,
90
+ description,
91
+ status,
92
+ assignee_id,
93
+ estimated_days,
94
+ start_date,
95
+ due_date,
96
+ version_id,
97
+ reason
98
+ };
99
+ // 如果传入了 sop_id,单独处理
100
+ if (sop_id !== undefined) {
101
+ taskService.setTaskSOP(req.params.id, sop_id, userId);
102
+ }
103
+ const task = taskService.updateTask(req.params.id, params, userId);
104
+ if (!task) {
105
+ res.status(404).json({ success: false, error: '任务不存在' });
106
+ return;
107
+ }
108
+ res.json({ success: true, data: task });
109
+ });
110
+ // POST /api/tasks/:id/activate - 激活任务
111
+ router.post('/:id/activate', (req, res) => {
112
+ const { sop_id } = req.body;
113
+ const userId = req.auth.user.id;
114
+ const isAdmin = req.auth.user.role === 'admin';
115
+ const task = taskService.activateTask(req.params.id, sop_id ?? undefined, userId);
116
+ if (!task) {
117
+ res.status(404).json({ success: false, error: '任务不存在' });
118
+ return;
119
+ }
120
+ res.json({ success: true, data: task });
121
+ });
122
+ // POST /api/tasks/:id/complete - 完成任务
123
+ router.post('/:id/complete', (req, res) => {
124
+ const userId = req.auth.user.id;
125
+ const task = taskService.completeTask(req.params.id, userId);
126
+ if (!task) {
127
+ res.status(404).json({ success: false, error: '任务不存在' });
128
+ return;
129
+ }
130
+ res.json({ success: true, data: task });
131
+ });
132
+ // DELETE /api/tasks/:id - 删除任务(软删除)
133
+ router.delete('/:id', (req, res) => {
134
+ const userId = req.auth.user.id;
135
+ const isAdmin = req.auth.user.role === 'admin';
136
+ const task = taskService.getTaskById(req.params.id, isAdmin ? undefined : userId);
137
+ if (!task) {
138
+ res.status(404).json({ success: false, error: '任务不存在' });
139
+ return;
140
+ }
141
+ const success = taskService.deleteTask(req.params.id, userId);
142
+ if (!success) {
143
+ res.status(404).json({ success: false, error: '任务不存在' });
144
+ return;
145
+ }
146
+ res.json({ success: true, message: '任务已删除' });
147
+ });
148
+ // GET /api/tasks/:id/history - 获取任务历史
149
+ router.get('/:id/history', (req, res) => {
150
+ const userId = req.auth.user.id;
151
+ const isAdmin = req.auth.user.role === 'admin';
152
+ const task = taskService.getTaskById(req.params.id, isAdmin ? undefined : userId);
153
+ if (!task) {
154
+ res.status(404).json({ success: false, error: '任务不存在' });
155
+ return;
156
+ }
157
+ const history = taskService.getTaskHistory(req.params.id);
158
+ res.json({ success: true, data: history });
159
+ });
160
+ // POST /api/tasks/:id/history - 添加任务备注
161
+ router.post('/:id/history', (req, res) => {
162
+ const { note } = req.body;
163
+ if (!note) {
164
+ res.status(400).json({ success: false, error: 'note 不能为空' });
165
+ return;
166
+ }
167
+ const userId = req.auth.user.id;
168
+ const isAdmin = req.auth.user.role === 'admin';
169
+ const task = taskService.getTaskById(req.params.id, isAdmin ? undefined : userId);
170
+ if (!task) {
171
+ res.status(404).json({ success: false, error: '任务不存在' });
172
+ return;
173
+ }
174
+ const history = taskService.addTaskNote(req.params.id, note, userId);
175
+ res.status(201).json({ success: true, data: history });
176
+ });
177
+ // GET /api/tasks/:id/context - 获取任务完整上下文(用于断点续传)
178
+ router.get('/:id/context', (req, res) => {
179
+ const historyLimit = parseInt(req.query.history_limit) || 5;
180
+ const userId = req.auth.user.id;
181
+ const isAdmin = req.auth.user.role === 'admin';
182
+ const context = taskService.getTaskContext(req.params.id, historyLimit);
183
+ if (!context) {
184
+ res.status(404).json({ success: false, error: '任务不存在' });
185
+ return;
186
+ }
187
+ // 验证归属
188
+ if (!isAdmin) {
189
+ const task = taskService.getTaskById(req.params.id, userId);
190
+ if (!task) {
191
+ res.status(404).json({ success: false, error: '任务不存在' });
192
+ return;
193
+ }
194
+ }
195
+ res.json({ success: true, data: context });
196
+ });
197
+ // PUT /api/tasks/:id/doc - 更新任务阶段文档
198
+ router.put('/:id/doc', (req, res) => {
199
+ const { doc_type, content, append } = req.body;
200
+ const userId = req.auth.user.id;
201
+ const isAdmin = req.auth.user.role === 'admin';
202
+ if (!doc_type || !['requirement', 'design', 'status'].includes(doc_type)) {
203
+ res.status(400).json({ success: false, error: 'doc_type 必须是: requirement, design, status' });
204
+ return;
205
+ }
206
+ if (content === undefined || content === null) {
207
+ res.status(400).json({ success: false, error: 'content 不能为空' });
208
+ return;
209
+ }
210
+ const task = taskService.updateTaskDoc(req.params.id, doc_type, content, append ?? false, userId);
211
+ if (!task) {
212
+ res.status(404).json({ success: false, error: '任务不存在' });
213
+ return;
214
+ }
215
+ res.json({ success: true, data: task });
216
+ });
217
+ export default router;
218
+ //# sourceMappingURL=tasks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../../src/api/routes/tasks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
3
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../../src/api/routes/tokens.ts"],"names":[],"mappings":"AAQA,QAAA,MAAM,MAAM,4CAAW,CAAC;AAsFxB,eAAe,MAAM,CAAC"}
@@ -0,0 +1,77 @@
1
+ import { Router } from 'express';
2
+ import { createToken, listTokens, deleteToken } from '../../services/token.service.js';
3
+ import { authMiddleware } from '../middleware/auth.js';
4
+ const router = Router();
5
+ // 所有路由需要认证
6
+ router.use(authMiddleware);
7
+ /**
8
+ * GET /api/tokens
9
+ * 列出当前用户的所有 Token
10
+ */
11
+ router.get('/', (req, res) => {
12
+ if (!req.auth?.user) {
13
+ res.status(401).json({ success: false, error: '未登录' });
14
+ return;
15
+ }
16
+ const tokens = listTokens(req.auth.user.id);
17
+ res.json({
18
+ success: true,
19
+ data: { tokens }
20
+ });
21
+ });
22
+ /**
23
+ * POST /api/tokens
24
+ * 创建新 Token
25
+ */
26
+ router.post('/', (req, res) => {
27
+ if (!req.auth?.user) {
28
+ res.status(401).json({ success: false, error: '未登录' });
29
+ return;
30
+ }
31
+ const { name } = req.body;
32
+ if (!name || typeof name !== 'string') {
33
+ res.status(400).json({ success: false, error: 'Token 名称不能为空' });
34
+ return;
35
+ }
36
+ try {
37
+ const token = createToken({
38
+ user_id: req.auth.user.id,
39
+ name
40
+ });
41
+ res.status(201).json({
42
+ success: true,
43
+ data: {
44
+ token: {
45
+ id: token.id,
46
+ name: token.name,
47
+ created_at: token.created_at
48
+ },
49
+ plain_token: token.plain_token
50
+ },
51
+ message: 'Token 已创建,请立即保存!关闭后将无法再次查看完整 Token。'
52
+ });
53
+ }
54
+ catch (error) {
55
+ const message = error instanceof Error ? error.message : '创建 Token 失败';
56
+ res.status(400).json({ success: false, error: message });
57
+ }
58
+ });
59
+ /**
60
+ * DELETE /api/tokens/:id
61
+ * 删除 Token
62
+ */
63
+ router.delete('/:id', (req, res) => {
64
+ if (!req.auth?.user) {
65
+ res.status(401).json({ success: false, error: '未登录' });
66
+ return;
67
+ }
68
+ const { id } = req.params;
69
+ const deleted = deleteToken(id, req.auth.user.id);
70
+ if (!deleted) {
71
+ res.status(404).json({ success: false, error: 'Token 不存在' });
72
+ return;
73
+ }
74
+ res.json({ success: true, message: 'Token 已删除' });
75
+ });
76
+ export default router;
77
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../../src/api/routes/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqB,MAAM,SAAS,CAAC;AACpD,OAAO,EACL,WAAW,EACX,UAAU,EACV,WAAW,EACZ,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;AAExB,WAAW;AACX,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AAE3B;;;GAGG;AACH,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;IAC9C,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;QACpB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAE5C,GAAG,CAAC,IAAI,CAAC;QACP,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,EAAE,MAAM,EAAE;KACjB,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;IAC/C,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;QACpB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;IAE1B,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QAChE,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,WAAW,CAAC;YACxB,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACzB,IAAI;SACL,CAAC,CAAC;QAEH,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,IAAI;YACb,IAAI,EAAE;gBACJ,KAAK,EAAE;oBACL,EAAE,EAAE,KAAK,CAAC,EAAE;oBACZ,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,UAAU,EAAE,KAAK,CAAC,UAAU;iBAC7B;gBACD,WAAW,EAAE,KAAK,CAAC,WAAW;aAC/B;YACD,OAAO,EAAE,qCAAqC;SAC/C,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC;QACvE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;IACpD,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;QACpB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IAED,MAAM,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC;IAE1B,MAAM,OAAO,GAAG,WAAW,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAElD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QAC7D,OAAO;IACT,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;AACpD,CAAC,CAAC,CAAC;AAEH,eAAe,MAAM,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
3
+ //# sourceMappingURL=users.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../../src/api/routes/users.ts"],"names":[],"mappings":"AAKA,QAAA,MAAM,MAAM,4CAAW,CAAC;AAgGxB,eAAe,MAAM,CAAC"}
@@ -0,0 +1,94 @@
1
+ import { Router } from 'express';
2
+ import { adminOnly } from '../middleware/auth.js';
3
+ import * as userService from '../../services/user.service.js';
4
+ const router = Router();
5
+ router.get('/', adminOnly, (req, res) => {
6
+ const page = parseInt(req.query.page) || 1;
7
+ const pageSize = parseInt(req.query.page_size) || 10;
8
+ const { users, total } = userService.getAllUsers(page, pageSize);
9
+ const publicUsers = users.map(u => userService.toPublicUser(u));
10
+ res.json({
11
+ success: true,
12
+ data: {
13
+ users: publicUsers,
14
+ pagination: {
15
+ page,
16
+ page_size: pageSize,
17
+ total,
18
+ total_pages: Math.ceil(total / pageSize)
19
+ }
20
+ }
21
+ });
22
+ });
23
+ router.get('/me', (req, res) => {
24
+ res.json({ success: true, data: { user: req.auth.user } });
25
+ });
26
+ router.get('/:id', adminOnly, (req, res) => {
27
+ const user = userService.getUserById(req.params.id);
28
+ if (!user) {
29
+ res.status(404).json({ success: false, error: 'User not found' });
30
+ return;
31
+ }
32
+ res.json({ success: true, data: userService.toPublicUser(user) });
33
+ });
34
+ router.post('/', adminOnly, async (req, res) => {
35
+ try {
36
+ const { name, email, password, role } = req.body;
37
+ if (!name || !email || !password) {
38
+ res.status(400).json({ success: false, error: 'Name, email and password are required' });
39
+ return;
40
+ }
41
+ const user = await userService.createUserByAdmin({ name, email, password, role });
42
+ res.status(201).json({ success: true, data: userService.toPublicUser(user) });
43
+ }
44
+ catch (error) {
45
+ const message = error instanceof Error ? error.message : 'Failed to create user';
46
+ res.status(400).json({ success: false, error: message });
47
+ }
48
+ });
49
+ router.put('/:id', adminOnly, (req, res) => {
50
+ const { name, role, email, password } = req.body;
51
+ const user = userService.updateUser(req.params.id, { name, role });
52
+ if (!user) {
53
+ res.status(404).json({ success: false, error: 'User not found' });
54
+ return;
55
+ }
56
+ res.json({ success: true, data: userService.toPublicUser(user) });
57
+ });
58
+ router.delete('/:id', adminOnly, (req, res) => {
59
+ if (req.params.id === 'admin-001') {
60
+ res.status(400).json({ success: false, error: 'Cannot delete the default admin user' });
61
+ return;
62
+ }
63
+ const success = userService.deleteUser(req.params.id);
64
+ if (!success) {
65
+ res.status(404).json({ success: false, error: 'User not found' });
66
+ return;
67
+ }
68
+ res.json({ success: true, message: 'User deleted' });
69
+ });
70
+ router.post('/:id/regenerate-key', adminOnly, (req, res) => {
71
+ const user = userService.regenerateApiKey(req.params.id);
72
+ if (!user) {
73
+ res.status(404).json({ success: false, error: 'User not found' });
74
+ return;
75
+ }
76
+ res.json({ success: true, data: userService.toPublicUser(user) });
77
+ });
78
+ router.post('/:id/reset-password', adminOnly, async (req, res) => {
79
+ try {
80
+ const { new_password } = req.body;
81
+ if (!new_password) {
82
+ res.status(400).json({ success: false, error: 'New password is required' });
83
+ return;
84
+ }
85
+ await userService.forceChangePassword(req.params.id, new_password);
86
+ res.json({ success: true, message: 'Password reset successfully' });
87
+ }
88
+ catch (error) {
89
+ const message = error instanceof Error ? error.message : 'Failed to reset password';
90
+ res.status(400).json({ success: false, error: message });
91
+ }
92
+ });
93
+ export default router;
94
+ //# sourceMappingURL=users.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"users.js","sourceRoot":"","sources":["../../../src/api/routes/users.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
3
+ //# sourceMappingURL=versions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"versions.d.ts","sourceRoot":"","sources":["../../../src/api/routes/versions.ts"],"names":[],"mappings":"AAKA,QAAA,MAAM,MAAM,4CAAW,CAAC;AAiLxB,eAAe,MAAM,CAAC"}