@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.
- package/LICENSE +21 -0
- package/README.md +315 -0
- package/dist/api/middleware/auth.d.ts +26 -0
- package/dist/api/middleware/auth.d.ts.map +1 -0
- package/dist/api/middleware/auth.js +90 -0
- package/dist/api/middleware/auth.js.map +1 -0
- package/dist/api/middleware/captcha.d.ts +6 -0
- package/dist/api/middleware/captcha.d.ts.map +1 -0
- package/dist/api/middleware/captcha.js +47 -0
- package/dist/api/middleware/captcha.js.map +1 -0
- package/dist/api/middleware/ownerCheck.d.ts +22 -0
- package/dist/api/middleware/ownerCheck.d.ts.map +1 -0
- package/dist/api/middleware/ownerCheck.js +138 -0
- package/dist/api/middleware/ownerCheck.js.map +1 -0
- package/dist/api/routes/auth.d.ts +8 -0
- package/dist/api/routes/auth.d.ts.map +1 -0
- package/dist/api/routes/auth.js +136 -0
- package/dist/api/routes/auth.js.map +1 -0
- package/dist/api/routes/config.d.ts +3 -0
- package/dist/api/routes/config.d.ts.map +1 -0
- package/dist/api/routes/config.js +26 -0
- package/dist/api/routes/config.js.map +1 -0
- package/dist/api/routes/projects.d.ts +3 -0
- package/dist/api/routes/projects.d.ts.map +1 -0
- package/dist/api/routes/projects.js +54 -0
- package/dist/api/routes/projects.js.map +1 -0
- package/dist/api/routes/schedule.d.ts +3 -0
- package/dist/api/routes/schedule.d.ts.map +1 -0
- package/dist/api/routes/schedule.js +92 -0
- package/dist/api/routes/schedule.js.map +1 -0
- package/dist/api/routes/sops.d.ts +3 -0
- package/dist/api/routes/sops.d.ts.map +1 -0
- package/dist/api/routes/sops.js +155 -0
- package/dist/api/routes/sops.js.map +1 -0
- package/dist/api/routes/tasks.d.ts +3 -0
- package/dist/api/routes/tasks.d.ts.map +1 -0
- package/dist/api/routes/tasks.js +218 -0
- package/dist/api/routes/tasks.js.map +1 -0
- package/dist/api/routes/tokens.d.ts +3 -0
- package/dist/api/routes/tokens.d.ts.map +1 -0
- package/dist/api/routes/tokens.js +77 -0
- package/dist/api/routes/tokens.js.map +1 -0
- package/dist/api/routes/users.d.ts +3 -0
- package/dist/api/routes/users.d.ts.map +1 -0
- package/dist/api/routes/users.js +94 -0
- package/dist/api/routes/users.js.map +1 -0
- package/dist/api/routes/versions.d.ts +3 -0
- package/dist/api/routes/versions.d.ts.map +1 -0
- package/dist/api/routes/versions.js +156 -0
- package/dist/api/routes/versions.js.map +1 -0
- package/dist/api/server.d.ts +4 -0
- package/dist/api/server.d.ts.map +1 -0
- package/dist/api/server.js +70 -0
- package/dist/api/server.js.map +1 -0
- package/dist/db/connection.d.ts +15 -0
- package/dist/db/connection.d.ts.map +1 -0
- package/dist/db/connection.js +158 -0
- package/dist/db/connection.js.map +1 -0
- package/dist/db/init.d.ts +2 -0
- package/dist/db/init.d.ts.map +1 -0
- package/dist/db/init.js +5 -0
- package/dist/db/init.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +146 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/activate-task.d.ts +10 -0
- package/dist/mcp/tools/activate-task.d.ts.map +1 -0
- package/dist/mcp/tools/activate-task.js +52 -0
- package/dist/mcp/tools/activate-task.js.map +1 -0
- package/dist/mcp/tools/add-task-note.d.ts +10 -0
- package/dist/mcp/tools/add-task-note.d.ts.map +1 -0
- package/dist/mcp/tools/add-task-note.js +46 -0
- package/dist/mcp/tools/add-task-note.js.map +1 -0
- package/dist/mcp/tools/approve-task.d.ts +10 -0
- package/dist/mcp/tools/approve-task.d.ts.map +1 -0
- package/dist/mcp/tools/approve-task.js +59 -0
- package/dist/mcp/tools/approve-task.js.map +1 -0
- package/dist/mcp/tools/archive-version.d.ts +10 -0
- package/dist/mcp/tools/archive-version.d.ts.map +1 -0
- package/dist/mcp/tools/archive-version.js +57 -0
- package/dist/mcp/tools/archive-version.js.map +1 -0
- package/dist/mcp/tools/assign-task.d.ts +10 -0
- package/dist/mcp/tools/assign-task.d.ts.map +1 -0
- package/dist/mcp/tools/assign-task.js +53 -0
- package/dist/mcp/tools/assign-task.js.map +1 -0
- package/dist/mcp/tools/complete-task.d.ts +10 -0
- package/dist/mcp/tools/complete-task.d.ts.map +1 -0
- package/dist/mcp/tools/complete-task.js +46 -0
- package/dist/mcp/tools/complete-task.js.map +1 -0
- package/dist/mcp/tools/create-sop.d.ts +10 -0
- package/dist/mcp/tools/create-sop.d.ts.map +1 -0
- package/dist/mcp/tools/create-sop.js +90 -0
- package/dist/mcp/tools/create-sop.js.map +1 -0
- package/dist/mcp/tools/create-task.d.ts +10 -0
- package/dist/mcp/tools/create-task.d.ts.map +1 -0
- package/dist/mcp/tools/create-task.js +138 -0
- package/dist/mcp/tools/create-task.js.map +1 -0
- package/dist/mcp/tools/create-version.d.ts +10 -0
- package/dist/mcp/tools/create-version.d.ts.map +1 -0
- package/dist/mcp/tools/create-version.js +86 -0
- package/dist/mcp/tools/create-version.js.map +1 -0
- package/dist/mcp/tools/delete-task.d.ts +10 -0
- package/dist/mcp/tools/delete-task.d.ts.map +1 -0
- package/dist/mcp/tools/delete-task.js +34 -0
- package/dist/mcp/tools/delete-task.js.map +1 -0
- package/dist/mcp/tools/get-my-tasks.d.ts +10 -0
- package/dist/mcp/tools/get-my-tasks.d.ts.map +1 -0
- package/dist/mcp/tools/get-my-tasks.js +88 -0
- package/dist/mcp/tools/get-my-tasks.js.map +1 -0
- package/dist/mcp/tools/get-next-task.d.ts +10 -0
- package/dist/mcp/tools/get-next-task.d.ts.map +1 -0
- package/dist/mcp/tools/get-next-task.js +84 -0
- package/dist/mcp/tools/get-next-task.js.map +1 -0
- package/dist/mcp/tools/get-sop.d.ts +10 -0
- package/dist/mcp/tools/get-sop.d.ts.map +1 -0
- package/dist/mcp/tools/get-sop.js +67 -0
- package/dist/mcp/tools/get-sop.js.map +1 -0
- package/dist/mcp/tools/get-task-context.d.ts +10 -0
- package/dist/mcp/tools/get-task-context.d.ts.map +1 -0
- package/dist/mcp/tools/get-task-context.js +114 -0
- package/dist/mcp/tools/get-task-context.js.map +1 -0
- package/dist/mcp/tools/get-task.d.ts +10 -0
- package/dist/mcp/tools/get-task.d.ts.map +1 -0
- package/dist/mcp/tools/get-task.js +61 -0
- package/dist/mcp/tools/get-task.js.map +1 -0
- package/dist/mcp/tools/helpers.d.ts +10 -0
- package/dist/mcp/tools/helpers.d.ts.map +1 -0
- package/dist/mcp/tools/helpers.js +17 -0
- package/dist/mcp/tools/helpers.js.map +1 -0
- package/dist/mcp/tools/init-project.d.ts +12 -0
- package/dist/mcp/tools/init-project.d.ts.map +1 -0
- package/dist/mcp/tools/init-project.js +162 -0
- package/dist/mcp/tools/init-project.js.map +1 -0
- package/dist/mcp/tools/list-sops.d.ts +10 -0
- package/dist/mcp/tools/list-sops.d.ts.map +1 -0
- package/dist/mcp/tools/list-sops.js +57 -0
- package/dist/mcp/tools/list-sops.js.map +1 -0
- package/dist/mcp/tools/list-tasks.d.ts +10 -0
- package/dist/mcp/tools/list-tasks.d.ts.map +1 -0
- package/dist/mcp/tools/list-tasks.js +96 -0
- package/dist/mcp/tools/list-tasks.js.map +1 -0
- package/dist/mcp/tools/list-versions.d.ts +10 -0
- package/dist/mcp/tools/list-versions.d.ts.map +1 -0
- package/dist/mcp/tools/list-versions.js +76 -0
- package/dist/mcp/tools/list-versions.js.map +1 -0
- package/dist/mcp/tools/reject-task.d.ts +10 -0
- package/dist/mcp/tools/reject-task.d.ts.map +1 -0
- package/dist/mcp/tools/reject-task.js +63 -0
- package/dist/mcp/tools/reject-task.js.map +1 -0
- package/dist/mcp/tools/reschedule.d.ts +17 -0
- package/dist/mcp/tools/reschedule.d.ts.map +1 -0
- package/dist/mcp/tools/reschedule.js +107 -0
- package/dist/mcp/tools/reschedule.js.map +1 -0
- package/dist/mcp/tools/start-task.d.ts +10 -0
- package/dist/mcp/tools/start-task.d.ts.map +1 -0
- package/dist/mcp/tools/start-task.js +42 -0
- package/dist/mcp/tools/start-task.js.map +1 -0
- package/dist/mcp/tools/submit-for-review.d.ts +10 -0
- package/dist/mcp/tools/submit-for-review.d.ts.map +1 -0
- package/dist/mcp/tools/submit-for-review.js +64 -0
- package/dist/mcp/tools/submit-for-review.js.map +1 -0
- package/dist/mcp/tools/update-sop.d.ts +10 -0
- package/dist/mcp/tools/update-sop.d.ts.map +1 -0
- package/dist/mcp/tools/update-sop.js +113 -0
- package/dist/mcp/tools/update-sop.js.map +1 -0
- package/dist/mcp/tools/update-task-doc.d.ts +10 -0
- package/dist/mcp/tools/update-task-doc.d.ts.map +1 -0
- package/dist/mcp/tools/update-task-doc.js +70 -0
- package/dist/mcp/tools/update-task-doc.js.map +1 -0
- package/dist/mcp/tools/update-task.d.ts +10 -0
- package/dist/mcp/tools/update-task.d.ts.map +1 -0
- package/dist/mcp/tools/update-task.js +106 -0
- package/dist/mcp/tools/update-task.js.map +1 -0
- package/dist/mcp/tools/utils/config.d.ts +35 -0
- package/dist/mcp/tools/utils/config.d.ts.map +1 -0
- package/dist/mcp/tools/utils/config.js +81 -0
- package/dist/mcp/tools/utils/config.js.map +1 -0
- package/dist/services/config.service.d.ts +6 -0
- package/dist/services/config.service.d.ts.map +1 -0
- package/dist/services/config.service.js +48 -0
- package/dist/services/config.service.js.map +1 -0
- package/dist/services/project.service.d.ts +29 -0
- package/dist/services/project.service.d.ts.map +1 -0
- package/dist/services/project.service.js +111 -0
- package/dist/services/project.service.js.map +1 -0
- package/dist/services/schedule.service.d.ts +104 -0
- package/dist/services/schedule.service.d.ts.map +1 -0
- package/dist/services/schedule.service.js +362 -0
- package/dist/services/schedule.service.js.map +1 -0
- package/dist/services/session.service.d.ts +5 -0
- package/dist/services/session.service.d.ts.map +1 -0
- package/dist/services/session.service.js +30 -0
- package/dist/services/session.service.js.map +1 -0
- package/dist/services/sop.service.d.ts +53 -0
- package/dist/services/sop.service.d.ts.map +1 -0
- package/dist/services/sop.service.js +275 -0
- package/dist/services/sop.service.js.map +1 -0
- package/dist/services/task.service.d.ts +62 -0
- package/dist/services/task.service.d.ts.map +1 -0
- package/dist/services/task.service.js +546 -0
- package/dist/services/task.service.js.map +1 -0
- package/dist/services/token.service.d.ts +37 -0
- package/dist/services/token.service.d.ts.map +1 -0
- package/dist/services/token.service.js +99 -0
- package/dist/services/token.service.js.map +1 -0
- package/dist/services/user.service.d.ts +95 -0
- package/dist/services/user.service.d.ts.map +1 -0
- package/dist/services/user.service.js +275 -0
- package/dist/services/user.service.js.map +1 -0
- package/dist/services/version.service.d.ts +70 -0
- package/dist/services/version.service.d.ts.map +1 -0
- package/dist/services/version.service.js +225 -0
- package/dist/services/version.service.js.map +1 -0
- package/dist/types/index.d.ts +207 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/password.d.ts +16 -0
- package/dist/utils/password.d.ts.map +1 -0
- package/dist/utils/password.js +37 -0
- package/dist/utils/password.js.map +1 -0
- package/dist/utils/validation.d.ts +13 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +20 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +65 -0
- package/src/db/schema.sql +162 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
2
|
+
import { getDb } from '../db/connection.js';
|
|
3
|
+
import { ensureHolidaysLoaded, formatDate, parseDate, addWorkdaysSync } from './schedule.service.js';
|
|
4
|
+
/**
|
|
5
|
+
* 获取项目的所有版本(验证归属)
|
|
6
|
+
*/
|
|
7
|
+
export function listVersions(projectId, userId) {
|
|
8
|
+
const db = getDb();
|
|
9
|
+
if (userId) {
|
|
10
|
+
// 验证项目归属
|
|
11
|
+
const project = db.prepare(`
|
|
12
|
+
SELECT id FROM projects WHERE id = ? AND owner_id = ?
|
|
13
|
+
`).get(projectId, userId);
|
|
14
|
+
if (!project) {
|
|
15
|
+
return []; // 无权限时返回空数组
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return db.prepare('SELECT * FROM versions WHERE project_id = ? ORDER BY sort_order ASC, created_at ASC').all(projectId);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 根据 ID 获取版本(验证归属)
|
|
22
|
+
*/
|
|
23
|
+
export function getVersionById(id, userId) {
|
|
24
|
+
const db = getDb();
|
|
25
|
+
if (userId) {
|
|
26
|
+
const version = db.prepare(`
|
|
27
|
+
SELECT v.* FROM versions v
|
|
28
|
+
JOIN projects p ON v.project_id = p.id
|
|
29
|
+
WHERE v.id = ? AND p.owner_id = ?
|
|
30
|
+
`).get(id, userId);
|
|
31
|
+
return version || null;
|
|
32
|
+
}
|
|
33
|
+
// 兼容旧逻辑
|
|
34
|
+
const version = db.prepare('SELECT * FROM versions WHERE id = ?').get(id);
|
|
35
|
+
return version || null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* 创建版本(验证归属)
|
|
39
|
+
*/
|
|
40
|
+
export function createVersion(params, userId) {
|
|
41
|
+
const db = getDb();
|
|
42
|
+
// 验证项目归属
|
|
43
|
+
if (userId) {
|
|
44
|
+
const project = db.prepare(`
|
|
45
|
+
SELECT id FROM projects WHERE id = ? AND owner_id = ?
|
|
46
|
+
`).get(params.project_id, userId);
|
|
47
|
+
if (!project) {
|
|
48
|
+
return null; // 无权限
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const id = uuidv4();
|
|
52
|
+
const now = new Date().toISOString();
|
|
53
|
+
// 获取最大 sort_order
|
|
54
|
+
const maxOrder = db.prepare('SELECT MAX(sort_order) as max_order FROM versions WHERE project_id = ?').get(params.project_id);
|
|
55
|
+
const sortOrder = (maxOrder?.max_order ?? -1) + 1;
|
|
56
|
+
db.prepare(`
|
|
57
|
+
INSERT INTO versions (id, project_id, name, description, start_date, due_date, sort_order, created_at, updated_at)
|
|
58
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
59
|
+
`).run(id, params.project_id, params.name, params.description || null, params.start_date || null, params.due_date || null, sortOrder, now, now);
|
|
60
|
+
return getVersionById(id);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* 更新版本(验证归属)
|
|
64
|
+
*/
|
|
65
|
+
export function updateVersion(id, params, userId) {
|
|
66
|
+
const db = getDb();
|
|
67
|
+
const version = getVersionById(id, userId);
|
|
68
|
+
if (!version)
|
|
69
|
+
return null;
|
|
70
|
+
const now = new Date().toISOString();
|
|
71
|
+
const updates = ['updated_at = ?'];
|
|
72
|
+
const values = [now];
|
|
73
|
+
if (params.name !== undefined) {
|
|
74
|
+
updates.push('name = ?');
|
|
75
|
+
values.push(params.name);
|
|
76
|
+
}
|
|
77
|
+
if (params.description !== undefined) {
|
|
78
|
+
updates.push('description = ?');
|
|
79
|
+
values.push(params.description);
|
|
80
|
+
}
|
|
81
|
+
if (params.start_date !== undefined) {
|
|
82
|
+
updates.push('start_date = ?');
|
|
83
|
+
values.push(params.start_date);
|
|
84
|
+
}
|
|
85
|
+
if (params.due_date !== undefined) {
|
|
86
|
+
updates.push('due_date = ?');
|
|
87
|
+
values.push(params.due_date);
|
|
88
|
+
}
|
|
89
|
+
values.push(id);
|
|
90
|
+
db.prepare(`UPDATE versions SET ${updates.join(', ')} WHERE id = ?`).run(...values);
|
|
91
|
+
return getVersionById(id);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* 删除版本(验证归属)
|
|
95
|
+
*/
|
|
96
|
+
export function deleteVersion(id, userId) {
|
|
97
|
+
const db = getDb();
|
|
98
|
+
// 验证归属
|
|
99
|
+
if (userId) {
|
|
100
|
+
const version = db.prepare(`
|
|
101
|
+
SELECT v.id FROM versions v
|
|
102
|
+
JOIN projects p ON v.project_id = p.id
|
|
103
|
+
WHERE v.id = ? AND p.owner_id = ?
|
|
104
|
+
`).get(id, userId);
|
|
105
|
+
if (!version) {
|
|
106
|
+
return false; // 无权限
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// 先将该版本下的任务的 version_id 设为 null
|
|
110
|
+
db.prepare('UPDATE tasks SET version_id = NULL WHERE version_id = ?').run(id);
|
|
111
|
+
const result = db.prepare('DELETE FROM versions WHERE id = ?').run(id);
|
|
112
|
+
return result.changes > 0;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* 重新排序版本
|
|
116
|
+
*/
|
|
117
|
+
export function reorderVersions(versionIds) {
|
|
118
|
+
const db = getDb();
|
|
119
|
+
const now = new Date().toISOString();
|
|
120
|
+
versionIds.forEach((versionId, index) => {
|
|
121
|
+
db.prepare('UPDATE versions SET sort_order = ?, updated_at = ? WHERE id = ?').run(index, now, versionId);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* 锁定版本(标记规划完成,进入执行阶段)
|
|
126
|
+
*/
|
|
127
|
+
export function lockVersion(versionId) {
|
|
128
|
+
const db = getDb();
|
|
129
|
+
const version = getVersionById(versionId);
|
|
130
|
+
if (!version || version.locked_at)
|
|
131
|
+
return version;
|
|
132
|
+
const now = new Date().toISOString();
|
|
133
|
+
db.prepare('UPDATE versions SET locked_at = ?, updated_at = ? WHERE id = ?')
|
|
134
|
+
.run(now, now, versionId);
|
|
135
|
+
return getVersionById(versionId);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* 获取版本统计信息(异步版本,基于工时计算实际预期日期)
|
|
139
|
+
*/
|
|
140
|
+
export async function getVersionStats(versionId) {
|
|
141
|
+
const db = getDb();
|
|
142
|
+
const version = getVersionById(versionId);
|
|
143
|
+
if (!version)
|
|
144
|
+
return null;
|
|
145
|
+
// 递归获取所有任务(含子任务)
|
|
146
|
+
const allTasks = db.prepare(`
|
|
147
|
+
WITH RECURSIVE task_tree AS (
|
|
148
|
+
SELECT id, status, estimated_days, due_date, actual_end, created_at, parent_id, sort_order FROM tasks WHERE version_id = ?
|
|
149
|
+
UNION ALL
|
|
150
|
+
SELECT t.id, t.status, t.estimated_days, t.due_date, t.actual_end, t.created_at, t.parent_id, t.sort_order FROM tasks t
|
|
151
|
+
INNER JOIN task_tree tt ON t.parent_id = tt.id
|
|
152
|
+
)
|
|
153
|
+
SELECT * FROM task_tree
|
|
154
|
+
`).all(versionId);
|
|
155
|
+
const totalTasks = allTasks.length;
|
|
156
|
+
const doneTasks = allTasks.filter(t => t.status === 'done').length;
|
|
157
|
+
const progress = totalTasks > 0 ? Math.round((doneTasks / totalTasks) * 100) : 0;
|
|
158
|
+
// 获取顶层任务(按 sort_order 排序)用于计算实际预期日期
|
|
159
|
+
const topLevelTasks = allTasks
|
|
160
|
+
.filter(t => t.parent_id === null)
|
|
161
|
+
.sort((a, b) => a.sort_order - b.sort_order);
|
|
162
|
+
// 基于工时计算实际预期日期
|
|
163
|
+
let actualDueDate = null;
|
|
164
|
+
if (topLevelTasks.length > 0) {
|
|
165
|
+
// 确定起始日期:使用版本的 start_date,否则使用今天
|
|
166
|
+
const startDateStr = version.start_date || formatDate(new Date());
|
|
167
|
+
let currentDate = parseDate(startDateStr);
|
|
168
|
+
// 预加载节假日数据
|
|
169
|
+
await ensureHolidaysLoaded(currentDate.getFullYear());
|
|
170
|
+
await ensureHolidaysLoaded(currentDate.getFullYear() + 1);
|
|
171
|
+
for (const task of topLevelTasks) {
|
|
172
|
+
// 已完成的任务使用实际结束日期
|
|
173
|
+
if (task.status === 'done' && task.actual_end) {
|
|
174
|
+
const actualEnd = task.actual_end.split('T')[0];
|
|
175
|
+
if (!actualDueDate || actualEnd > actualDueDate) {
|
|
176
|
+
actualDueDate = actualEnd;
|
|
177
|
+
}
|
|
178
|
+
// 下一个任务从实际结束日期后开始
|
|
179
|
+
currentDate = addWorkdaysSync(parseDate(actualEnd), 1);
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
// 未完成的任务计算预期结束日期
|
|
183
|
+
const days = task.estimated_days || 1;
|
|
184
|
+
const endDate = addWorkdaysSync(currentDate, days);
|
|
185
|
+
const endDateStr = formatDate(endDate);
|
|
186
|
+
if (!actualDueDate || endDateStr > actualDueDate) {
|
|
187
|
+
actualDueDate = endDateStr;
|
|
188
|
+
}
|
|
189
|
+
// 下一个任务从当前任务结束后的下一个工作日开始
|
|
190
|
+
currentDate = addWorkdaysSync(endDate, 1);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// 计划交付日期:优先使用版本的 due_date
|
|
194
|
+
const plannedDueDate = version.due_date || null;
|
|
195
|
+
// 计算进度误差(天数):实际预期 - 计划交付
|
|
196
|
+
let deviationDays = 0;
|
|
197
|
+
if (plannedDueDate && actualDueDate) {
|
|
198
|
+
const planned = parseDate(plannedDueDate);
|
|
199
|
+
const actual = parseDate(actualDueDate);
|
|
200
|
+
deviationDays = Math.ceil((actual.getTime() - planned.getTime()) / (1000 * 60 * 60 * 24));
|
|
201
|
+
}
|
|
202
|
+
// 中途新增任务数(锁定后创建的顶层任务)
|
|
203
|
+
let insertedTasks = 0;
|
|
204
|
+
if (version.locked_at) {
|
|
205
|
+
const result = db.prepare(`
|
|
206
|
+
SELECT COUNT(*) as count FROM tasks
|
|
207
|
+
WHERE version_id = ?
|
|
208
|
+
AND parent_id IS NULL
|
|
209
|
+
AND created_at > ?
|
|
210
|
+
`).get(versionId, version.locked_at);
|
|
211
|
+
insertedTasks = result.count;
|
|
212
|
+
}
|
|
213
|
+
return {
|
|
214
|
+
totalTasks,
|
|
215
|
+
doneTasks,
|
|
216
|
+
startDate: version.start_date,
|
|
217
|
+
plannedDueDate,
|
|
218
|
+
actualDueDate,
|
|
219
|
+
delayDays: Math.max(0, deviationDays), // 保持向后兼容
|
|
220
|
+
deviationDays, // 新增:可以是负数(提前)
|
|
221
|
+
insertedTasks,
|
|
222
|
+
progress,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=version.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.service.js","sourceRoot":"","sources":["../../src/services/version.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
export type UserRole = 'admin' | 'member';
|
|
2
|
+
export type TaskStatus = 'planned' | 'in_progress' | 'done';
|
|
3
|
+
export type TaskAction = 'created' | 'updated' | 'status_changed' | 'assigned' | 'noted';
|
|
4
|
+
export interface User {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
email: string | null;
|
|
8
|
+
password_hash: string | null;
|
|
9
|
+
api_key: string | null;
|
|
10
|
+
role: UserRole;
|
|
11
|
+
is_first_login: number;
|
|
12
|
+
reset_token: string | null;
|
|
13
|
+
reset_token_expires: string | null;
|
|
14
|
+
created_at: string;
|
|
15
|
+
updated_at: string;
|
|
16
|
+
}
|
|
17
|
+
export interface UserToken {
|
|
18
|
+
id: string;
|
|
19
|
+
user_id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
token: string;
|
|
22
|
+
last_used_at: string | null;
|
|
23
|
+
created_at: string;
|
|
24
|
+
}
|
|
25
|
+
export interface Project {
|
|
26
|
+
id: string;
|
|
27
|
+
name: string;
|
|
28
|
+
description: string | null;
|
|
29
|
+
owner_id: string | null;
|
|
30
|
+
created_at: string;
|
|
31
|
+
updated_at: string;
|
|
32
|
+
}
|
|
33
|
+
export interface SOP {
|
|
34
|
+
id: string;
|
|
35
|
+
project_id: string;
|
|
36
|
+
name: string;
|
|
37
|
+
description: string | null;
|
|
38
|
+
rules: string;
|
|
39
|
+
workflow: string;
|
|
40
|
+
required: string;
|
|
41
|
+
forbidden: string;
|
|
42
|
+
experience: string;
|
|
43
|
+
created_at: string;
|
|
44
|
+
updated_at: string;
|
|
45
|
+
}
|
|
46
|
+
export interface Version {
|
|
47
|
+
id: string;
|
|
48
|
+
project_id: string;
|
|
49
|
+
name: string;
|
|
50
|
+
description: string | null;
|
|
51
|
+
start_date: string | null;
|
|
52
|
+
due_date: string | null;
|
|
53
|
+
locked_at: string | null;
|
|
54
|
+
archived_at: string | null;
|
|
55
|
+
sort_order: number;
|
|
56
|
+
created_at: string;
|
|
57
|
+
updated_at: string;
|
|
58
|
+
}
|
|
59
|
+
export interface VersionStats {
|
|
60
|
+
totalTasks: number;
|
|
61
|
+
doneTasks: number;
|
|
62
|
+
startDate: string | null;
|
|
63
|
+
plannedDueDate: string | null;
|
|
64
|
+
actualDueDate: string | null;
|
|
65
|
+
delayDays: number;
|
|
66
|
+
deviationDays: number;
|
|
67
|
+
insertedTasks: number;
|
|
68
|
+
progress: number;
|
|
69
|
+
}
|
|
70
|
+
export interface Task {
|
|
71
|
+
id: string;
|
|
72
|
+
project_id: string;
|
|
73
|
+
version_id: string | null;
|
|
74
|
+
parent_id: string | null;
|
|
75
|
+
title: string;
|
|
76
|
+
description: string | null;
|
|
77
|
+
status: TaskStatus;
|
|
78
|
+
assignee_id: string | null;
|
|
79
|
+
estimated_days: number | null;
|
|
80
|
+
start_date: string | null;
|
|
81
|
+
due_date: string | null;
|
|
82
|
+
actual_start: string | null;
|
|
83
|
+
actual_end: string | null;
|
|
84
|
+
sort_order: number;
|
|
85
|
+
dependencies: string | null;
|
|
86
|
+
sop_id: string | null;
|
|
87
|
+
deleted_at: string | null;
|
|
88
|
+
requirement_doc: string | null;
|
|
89
|
+
design_doc: string | null;
|
|
90
|
+
current_status: string | null;
|
|
91
|
+
created_at: string;
|
|
92
|
+
updated_at: string;
|
|
93
|
+
}
|
|
94
|
+
export interface TaskWithChildren extends Task {
|
|
95
|
+
children: TaskWithChildren[];
|
|
96
|
+
assignee?: User | null;
|
|
97
|
+
sop?: SOP | null;
|
|
98
|
+
}
|
|
99
|
+
export interface TaskHistory {
|
|
100
|
+
id: string;
|
|
101
|
+
task_id: string;
|
|
102
|
+
action: TaskAction;
|
|
103
|
+
field: string | null;
|
|
104
|
+
old_value: string | null;
|
|
105
|
+
new_value: string | null;
|
|
106
|
+
reason: string | null;
|
|
107
|
+
changed_by: string | null;
|
|
108
|
+
changed_at: string;
|
|
109
|
+
}
|
|
110
|
+
export interface TaskContext {
|
|
111
|
+
id: string;
|
|
112
|
+
title: string;
|
|
113
|
+
status: TaskStatus;
|
|
114
|
+
assignee: User | null;
|
|
115
|
+
start_date: string | null;
|
|
116
|
+
due_date: string | null;
|
|
117
|
+
estimated_days: number | null;
|
|
118
|
+
actual_start: string | null;
|
|
119
|
+
actual_end: string | null;
|
|
120
|
+
requirement_doc: string | null;
|
|
121
|
+
design_doc: string | null;
|
|
122
|
+
current_status: string | null;
|
|
123
|
+
recent_history: TaskHistory[];
|
|
124
|
+
children_summary: {
|
|
125
|
+
total: number;
|
|
126
|
+
done: number;
|
|
127
|
+
in_progress: number;
|
|
128
|
+
children: Array<{
|
|
129
|
+
id: string;
|
|
130
|
+
title: string;
|
|
131
|
+
status: TaskStatus;
|
|
132
|
+
}>;
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
export type DocType = 'requirement' | 'design' | 'status';
|
|
136
|
+
export interface UpdateTaskDocParams {
|
|
137
|
+
doc_type: DocType;
|
|
138
|
+
content: string;
|
|
139
|
+
append?: boolean;
|
|
140
|
+
}
|
|
141
|
+
export interface Holiday {
|
|
142
|
+
date: string;
|
|
143
|
+
year: number;
|
|
144
|
+
is_workday: number;
|
|
145
|
+
name: string | null;
|
|
146
|
+
}
|
|
147
|
+
export interface ApiResponse<T = unknown> {
|
|
148
|
+
success: boolean;
|
|
149
|
+
data?: T;
|
|
150
|
+
error?: string;
|
|
151
|
+
message?: string;
|
|
152
|
+
}
|
|
153
|
+
export interface CreateTaskParams {
|
|
154
|
+
project_id: string;
|
|
155
|
+
version_id?: string;
|
|
156
|
+
parent_id?: string;
|
|
157
|
+
title: string;
|
|
158
|
+
description?: string;
|
|
159
|
+
assignee_id?: string;
|
|
160
|
+
estimated_days?: number;
|
|
161
|
+
start_date?: string;
|
|
162
|
+
due_date?: string;
|
|
163
|
+
}
|
|
164
|
+
export interface UpdateTaskParams {
|
|
165
|
+
title?: string;
|
|
166
|
+
description?: string;
|
|
167
|
+
status?: TaskStatus;
|
|
168
|
+
assignee_id?: string;
|
|
169
|
+
estimated_days?: number;
|
|
170
|
+
start_date?: string;
|
|
171
|
+
due_date?: string;
|
|
172
|
+
version_id?: string;
|
|
173
|
+
reason?: string;
|
|
174
|
+
}
|
|
175
|
+
export interface ListTasksParams {
|
|
176
|
+
project_id?: string;
|
|
177
|
+
version_id?: string | null;
|
|
178
|
+
parent_id?: string | null;
|
|
179
|
+
status?: TaskStatus;
|
|
180
|
+
assignee_id?: string;
|
|
181
|
+
}
|
|
182
|
+
export interface ProjectConfig {
|
|
183
|
+
project_id?: string;
|
|
184
|
+
project_name?: string;
|
|
185
|
+
project_path: string;
|
|
186
|
+
server_url: string;
|
|
187
|
+
token?: string;
|
|
188
|
+
created_at: string;
|
|
189
|
+
}
|
|
190
|
+
export interface AuthContext {
|
|
191
|
+
user: User;
|
|
192
|
+
}
|
|
193
|
+
export interface SystemConfig {
|
|
194
|
+
key: string;
|
|
195
|
+
value: string;
|
|
196
|
+
description: string | null;
|
|
197
|
+
updated_at: string;
|
|
198
|
+
}
|
|
199
|
+
export interface SystemConfigMap {
|
|
200
|
+
server_url: string;
|
|
201
|
+
smtp_host: string;
|
|
202
|
+
smtp_port: string;
|
|
203
|
+
smtp_user: string;
|
|
204
|
+
smtp_pass: string;
|
|
205
|
+
smtp_from: string;
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 哈希密码
|
|
3
|
+
*/
|
|
4
|
+
export declare function hashPassword(password: string): Promise<string>;
|
|
5
|
+
/**
|
|
6
|
+
* 验证密码
|
|
7
|
+
*/
|
|
8
|
+
export declare function verifyPassword(password: string, hash: string): Promise<boolean>;
|
|
9
|
+
/**
|
|
10
|
+
* 验证密码强度
|
|
11
|
+
*/
|
|
12
|
+
export declare function validatePasswordStrength(password: string): {
|
|
13
|
+
valid: boolean;
|
|
14
|
+
errors: string[];
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=password.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../src/utils/password.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEpE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,CAAC,CAElB;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG;IAC1D,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAoBA"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import bcrypt from 'bcrypt';
|
|
2
|
+
const SALT_ROUNDS = 12;
|
|
3
|
+
/**
|
|
4
|
+
* 哈希密码
|
|
5
|
+
*/
|
|
6
|
+
export async function hashPassword(password) {
|
|
7
|
+
return bcrypt.hash(password, SALT_ROUNDS);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* 验证密码
|
|
11
|
+
*/
|
|
12
|
+
export async function verifyPassword(password, hash) {
|
|
13
|
+
return bcrypt.compare(password, hash);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* 验证密码强度
|
|
17
|
+
*/
|
|
18
|
+
export function validatePasswordStrength(password) {
|
|
19
|
+
const errors = [];
|
|
20
|
+
if (password.length < 8) {
|
|
21
|
+
errors.push('密码至少 8 位');
|
|
22
|
+
}
|
|
23
|
+
if (!/[A-Z]/.test(password)) {
|
|
24
|
+
errors.push('密码需要包含大写字母');
|
|
25
|
+
}
|
|
26
|
+
if (!/[a-z]/.test(password)) {
|
|
27
|
+
errors.push('密码需要包含小写字母');
|
|
28
|
+
}
|
|
29
|
+
if (!/[0-9]/.test(password)) {
|
|
30
|
+
errors.push('密码需要包含数字');
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
valid: errors.length === 0,
|
|
34
|
+
errors
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=password.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password.js","sourceRoot":"","sources":["../../src/utils/password.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,MAAM,WAAW,GAAG,EAAE,CAAC;AAEvB;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,QAAgB,EAChB,IAAY;IAEZ,OAAO,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,QAAgB;IAIvD,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC1B,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5B,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5B,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;QAC1B,MAAM;KACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 验证邮箱格式
|
|
3
|
+
*/
|
|
4
|
+
export declare function validateEmail(email: string): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* 标准化邮箱(小写)
|
|
7
|
+
*/
|
|
8
|
+
export declare function normalizeEmail(email: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* 清理用户输入
|
|
11
|
+
*/
|
|
12
|
+
export declare function sanitizeInput(input: string): string;
|
|
13
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2
|
+
/**
|
|
3
|
+
* 验证邮箱格式
|
|
4
|
+
*/
|
|
5
|
+
export function validateEmail(email) {
|
|
6
|
+
return EMAIL_REGEX.test(email);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* 标准化邮箱(小写)
|
|
10
|
+
*/
|
|
11
|
+
export function normalizeEmail(email) {
|
|
12
|
+
return email.trim().toLowerCase();
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* 清理用户输入
|
|
16
|
+
*/
|
|
17
|
+
export function sanitizeInput(input) {
|
|
18
|
+
return input.trim();
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,GAAG,4BAA4B,CAAC;AAEjD;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@qq33357486/oh-my-task",
|
|
3
|
+
"version": "1.4.0",
|
|
4
|
+
"description": "文档驱动的 AI 编程协作系统 - 通过 MCP 工具管理任务",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"oh-my-task": "dist/mcp/server.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"src/db/schema.sql",
|
|
14
|
+
"README.md",
|
|
15
|
+
"LICENSE"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"dev": "tsx watch src/index.ts",
|
|
19
|
+
"dev:all": "tsx scripts/dev.ts",
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"start": "node dist/index.js",
|
|
22
|
+
"mcp": "tsx src/mcp/server.ts",
|
|
23
|
+
"db:init": "tsx src/db/init.ts",
|
|
24
|
+
"db:clean": "tsx scripts/clean-db.ts",
|
|
25
|
+
"db:migrate-auth": "tsx scripts/migrate-auth.ts",
|
|
26
|
+
"test": "vitest run",
|
|
27
|
+
"test:watch": "vitest",
|
|
28
|
+
"test:coverage": "vitest run --coverage",
|
|
29
|
+
"test:e2e": "playwright test",
|
|
30
|
+
"test:e2e:ui": "playwright test --ui",
|
|
31
|
+
"test:e2e:report": "playwright show-report"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"task-management",
|
|
35
|
+
"mcp",
|
|
36
|
+
"ai-assistant"
|
|
37
|
+
],
|
|
38
|
+
"author": "",
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
42
|
+
"bcrypt": "^6.0.0",
|
|
43
|
+
"better-sqlite3": "^11.0.0",
|
|
44
|
+
"better-sqlite3-session-store": "^0.1.0",
|
|
45
|
+
"cors": "^2.8.5",
|
|
46
|
+
"express": "^4.18.2",
|
|
47
|
+
"express-session": "^1.19.0",
|
|
48
|
+
"uuid": "^9.0.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@playwright/test": "^1.40.0",
|
|
52
|
+
"@types/bcrypt": "^6.0.0",
|
|
53
|
+
"@types/better-sqlite3": "^7.6.8",
|
|
54
|
+
"@types/cors": "^2.8.17",
|
|
55
|
+
"@types/express": "^4.17.21",
|
|
56
|
+
"@types/express-session": "^1.18.2",
|
|
57
|
+
"@types/node": "^20.10.0",
|
|
58
|
+
"@types/supertest": "^6.0.3",
|
|
59
|
+
"@types/uuid": "^9.0.7",
|
|
60
|
+
"supertest": "^7.2.2",
|
|
61
|
+
"tsx": "^4.7.0",
|
|
62
|
+
"typescript": "^5.3.0",
|
|
63
|
+
"vitest": "^3.2.4"
|
|
64
|
+
}
|
|
65
|
+
}
|