agkan 2.14.3 → 3.0.1
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/README.ja.md +62 -238
- package/README.md +48 -241
- package/dist/board/boardFavicon.d.ts +2 -0
- package/dist/board/boardFavicon.d.ts.map +1 -0
- package/dist/board/boardFavicon.js +5 -0
- package/dist/board/boardFavicon.js.map +1 -0
- package/dist/board/boardRenderer.d.ts +22 -6
- package/dist/board/boardRenderer.d.ts.map +1 -1
- package/dist/board/boardRenderer.js +67 -26
- package/dist/board/boardRenderer.js.map +1 -1
- package/dist/board/boardRoutes.d.ts +4 -2
- package/dist/board/boardRoutes.d.ts.map +1 -1
- package/dist/board/boardRoutes.js +140 -13
- package/dist/board/boardRoutes.js.map +1 -1
- package/dist/board/boardStyles.d.ts +1 -1
- package/dist/board/boardStyles.d.ts.map +1 -1
- package/dist/board/boardStyles.js +62 -8
- package/dist/board/boardStyles.js.map +1 -1
- package/dist/board/client/board.js +1007 -29
- package/dist/board/server.d.ts +3 -2
- package/dist/board/server.d.ts.map +1 -1
- package/dist/board/server.js +9 -7
- package/dist/board/server.js.map +1 -1
- package/dist/cli/commands/agent-guide.d.ts.map +1 -1
- package/dist/cli/commands/agent-guide.js +6 -0
- package/dist/cli/commands/agent-guide.js.map +1 -1
- package/dist/cli/commands/board.d.ts.map +1 -1
- package/dist/cli/commands/board.js +202 -15
- package/dist/cli/commands/board.js.map +1 -1
- package/dist/cli/commands/ps.d.ts +7 -0
- package/dist/cli/commands/ps.d.ts.map +1 -0
- package/dist/cli/commands/ps.js +83 -0
- package/dist/cli/commands/ps.js.map +1 -0
- package/dist/cli/commands/tag/add.d.ts.map +1 -1
- package/dist/cli/commands/tag/add.js +10 -11
- package/dist/cli/commands/tag/add.js.map +1 -1
- package/dist/cli/commands/tag/attach.d.ts.map +1 -1
- package/dist/cli/commands/tag/attach.js +10 -11
- package/dist/cli/commands/tag/attach.js.map +1 -1
- package/dist/cli/commands/tag/rename.d.ts.map +1 -1
- package/dist/cli/commands/tag/rename.js +10 -11
- package/dist/cli/commands/tag/rename.js.map +1 -1
- package/dist/cli/commands/task/add.js +1 -1
- package/dist/cli/commands/task/add.js.map +1 -1
- package/dist/cli/commands/task/copy.d.ts +6 -0
- package/dist/cli/commands/task/copy.d.ts.map +1 -0
- package/dist/cli/commands/task/copy.js +118 -0
- package/dist/cli/commands/task/copy.js.map +1 -0
- package/dist/cli/commands/task/list.d.ts.map +1 -1
- package/dist/cli/commands/task/list.js +37 -17
- package/dist/cli/commands/task/list.js.map +1 -1
- package/dist/cli/commands/task/update-parent.d.ts.map +1 -1
- package/dist/cli/commands/task/update-parent.js +10 -11
- package/dist/cli/commands/task/update-parent.js.map +1 -1
- package/dist/cli/index.js +6 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/utils/board-daemon.d.ts +7 -0
- package/dist/cli/utils/board-daemon.d.ts.map +1 -0
- package/dist/cli/utils/board-daemon.js +83 -0
- package/dist/cli/utils/board-daemon.js.map +1 -0
- package/dist/db/adapters/sqlite-storage-backend.d.ts +27 -0
- package/dist/db/adapters/sqlite-storage-backend.d.ts.map +1 -0
- package/dist/db/adapters/sqlite-storage-backend.js +498 -0
- package/dist/db/adapters/sqlite-storage-backend.js.map +1 -0
- package/dist/db/connection.d.ts +19 -0
- package/dist/db/connection.d.ts.map +1 -1
- package/dist/db/connection.js +37 -2
- package/dist/db/connection.js.map +1 -1
- package/dist/db/migrations/20260328000000_initial_schema.d.ts +3 -0
- package/dist/db/migrations/20260328000000_initial_schema.d.ts.map +1 -0
- package/dist/db/migrations/20260328000000_initial_schema.js +218 -0
- package/dist/db/migrations/20260328000000_initial_schema.js.map +1 -0
- package/dist/db/migrations/20260329000000_add_session_id_to_task_run_logs.d.ts +3 -0
- package/dist/db/migrations/20260329000000_add_session_id_to_task_run_logs.d.ts.map +1 -0
- package/dist/db/migrations/20260329000000_add_session_id_to_task_run_logs.js +7 -0
- package/dist/db/migrations/20260329000000_add_session_id_to_task_run_logs.js.map +1 -0
- package/dist/db/migrations/index.d.ts +4 -0
- package/dist/db/migrations/index.d.ts.map +1 -0
- package/dist/db/migrations/index.js +18 -0
- package/dist/db/migrations/index.js.map +1 -0
- package/dist/db/migrations/types.d.ts +17 -0
- package/dist/db/migrations/types.d.ts.map +1 -0
- package/dist/{board/client → db/migrations}/types.js +0 -1
- package/dist/db/migrations/types.js.map +1 -0
- package/dist/db/reset.d.ts.map +1 -1
- package/dist/db/reset.js +8 -3
- package/dist/db/reset.js.map +1 -1
- package/dist/db/schema.d.ts +4 -4
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +22 -207
- package/dist/db/schema.js.map +1 -1
- package/dist/db/types/repository.d.ts +226 -0
- package/dist/db/types/repository.d.ts.map +1 -0
- package/dist/db/types/repository.js +15 -0
- package/dist/db/types/repository.js.map +1 -0
- package/dist/errors.d.ts +27 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +51 -0
- package/dist/errors.js.map +1 -0
- package/dist/models/Task.d.ts +2 -0
- package/dist/models/Task.d.ts.map +1 -1
- package/dist/services/ClaudeProcessService.d.ts +100 -0
- package/dist/services/ClaudeProcessService.d.ts.map +1 -0
- package/dist/services/ClaudeProcessService.js +279 -0
- package/dist/services/ClaudeProcessService.js.map +1 -0
- package/dist/services/CommentService.d.ts +3 -3
- package/dist/services/CommentService.d.ts.map +1 -1
- package/dist/services/CommentService.js +13 -72
- package/dist/services/CommentService.js.map +1 -1
- package/dist/services/ExportImportService.d.ts +3 -3
- package/dist/services/ExportImportService.d.ts.map +1 -1
- package/dist/services/ExportImportService.js +29 -31
- package/dist/services/ExportImportService.js.map +1 -1
- package/dist/services/MetadataService.d.ts +3 -3
- package/dist/services/MetadataService.d.ts.map +1 -1
- package/dist/services/MetadataService.js +9 -69
- package/dist/services/MetadataService.js.map +1 -1
- package/dist/services/ProcessService.d.ts +54 -0
- package/dist/services/ProcessService.d.ts.map +1 -0
- package/dist/services/ProcessService.js +147 -0
- package/dist/services/ProcessService.js.map +1 -0
- package/dist/services/TagService.d.ts +3 -3
- package/dist/services/TagService.d.ts.map +1 -1
- package/dist/services/TagService.js +16 -41
- package/dist/services/TagService.js.map +1 -1
- package/dist/services/TaskBlockService.d.ts +3 -3
- package/dist/services/TaskBlockService.d.ts.map +1 -1
- package/dist/services/TaskBlockService.js +14 -40
- package/dist/services/TaskBlockService.js.map +1 -1
- package/dist/services/TaskService.d.ts +5 -23
- package/dist/services/TaskService.d.ts.map +1 -1
- package/dist/services/TaskService.js +57 -191
- package/dist/services/TaskService.js.map +1 -1
- package/dist/services/TaskTagService.d.ts +3 -3
- package/dist/services/TaskTagService.d.ts.map +1 -1
- package/dist/services/TaskTagService.js +23 -86
- package/dist/services/TaskTagService.js.map +1 -1
- package/dist/services/TmuxService.d.ts +2 -0
- package/dist/services/TmuxService.d.ts.map +1 -0
- package/dist/services/TmuxService.js +7 -0
- package/dist/services/TmuxService.js.map +1 -0
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +3 -1
- package/dist/services/index.js.map +1 -1
- package/dist/utils/logger.d.ts +7 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +18 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +12 -5
- package/dist/board/client/addTaskModal.d.ts +0 -2
- package/dist/board/client/addTaskModal.d.ts.map +0 -1
- package/dist/board/client/addTaskModal.js +0 -64
- package/dist/board/client/addTaskModal.js.map +0 -1
- package/dist/board/client/autoScroll.d.ts +0 -4
- package/dist/board/client/autoScroll.d.ts.map +0 -1
- package/dist/board/client/autoScroll.js +0 -59
- package/dist/board/client/autoScroll.js.map +0 -1
- package/dist/board/client/boardPolling.d.ts +0 -15
- package/dist/board/client/boardPolling.d.ts.map +0 -1
- package/dist/board/client/boardPolling.js +0 -144
- package/dist/board/client/boardPolling.js.map +0 -1
- package/dist/board/client/burgerMenu.d.ts +0 -2
- package/dist/board/client/burgerMenu.d.ts.map +0 -1
- package/dist/board/client/burgerMenu.js +0 -80
- package/dist/board/client/burgerMenu.js.map +0 -1
- package/dist/board/client/contextMenu.d.ts +0 -2
- package/dist/board/client/contextMenu.d.ts.map +0 -1
- package/dist/board/client/contextMenu.js +0 -52
- package/dist/board/client/contextMenu.js.map +0 -1
- package/dist/board/client/detailPanel.d.ts +0 -8
- package/dist/board/client/detailPanel.d.ts.map +0 -1
- package/dist/board/client/detailPanel.js +0 -565
- package/dist/board/client/detailPanel.js.map +0 -1
- package/dist/board/client/dragDrop.d.ts +0 -6
- package/dist/board/client/dragDrop.d.ts.map +0 -1
- package/dist/board/client/dragDrop.js +0 -82
- package/dist/board/client/dragDrop.js.map +0 -1
- package/dist/board/client/filters.d.ts +0 -6
- package/dist/board/client/filters.d.ts.map +0 -1
- package/dist/board/client/filters.js +0 -167
- package/dist/board/client/filters.js.map +0 -1
- package/dist/board/client/main.d.ts +0 -2
- package/dist/board/client/main.d.ts.map +0 -1
- package/dist/board/client/main.js +0 -20
- package/dist/board/client/main.js.map +0 -1
- package/dist/board/client/tags.d.ts +0 -6
- package/dist/board/client/tags.d.ts.map +0 -1
- package/dist/board/client/tags.js +0 -198
- package/dist/board/client/tags.js.map +0 -1
- package/dist/board/client/types.d.ts +0 -48
- package/dist/board/client/types.d.ts.map +0 -1
- package/dist/board/client/types.js.map +0 -1
- package/dist/board/client/utils.d.ts +0 -4
- package/dist/board/client/utils.d.ts.map +0 -1
- package/dist/board/client/utils.js +0 -44
- package/dist/board/client/utils.js.map +0 -1
|
@@ -3,14 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.TagService = void 0;
|
|
4
4
|
const connection_1 = require("../db/connection");
|
|
5
5
|
const input_validators_1 = require("../utils/input-validators");
|
|
6
|
+
const errors_1 = require("../errors");
|
|
6
7
|
/**
|
|
7
8
|
* Tag Service
|
|
8
9
|
* Manages creation, retrieval, update, and deletion of tags
|
|
9
10
|
*/
|
|
10
11
|
class TagService {
|
|
11
|
-
|
|
12
|
-
constructor(
|
|
13
|
-
this.
|
|
12
|
+
backend;
|
|
13
|
+
constructor(backend) {
|
|
14
|
+
this.backend = backend ?? (0, connection_1.getStorageBackend)();
|
|
14
15
|
}
|
|
15
16
|
/**
|
|
16
17
|
* Create a new tag
|
|
@@ -19,25 +20,18 @@ class TagService {
|
|
|
19
20
|
* @throws Error if tag name already exists
|
|
20
21
|
*/
|
|
21
22
|
createTag(input) {
|
|
22
|
-
const db = this.db;
|
|
23
23
|
// Validate input fields
|
|
24
24
|
const validationErrors = (0, input_validators_1.validateTagInput)(input);
|
|
25
25
|
if (validationErrors.length > 0) {
|
|
26
|
-
throw new
|
|
26
|
+
throw new errors_1.ValidationError(validationErrors[0].message);
|
|
27
27
|
}
|
|
28
28
|
// Check for duplicate tag names
|
|
29
29
|
const existingTag = this.getTagByName(input.name);
|
|
30
30
|
if (existingTag) {
|
|
31
|
-
throw new
|
|
31
|
+
throw new errors_1.ConflictError(`Tag with name "${input.name}" already exists`);
|
|
32
32
|
}
|
|
33
33
|
const now = new Date().toISOString();
|
|
34
|
-
|
|
35
|
-
INSERT INTO tags (name, created_at)
|
|
36
|
-
VALUES (?, ?)
|
|
37
|
-
`);
|
|
38
|
-
const result = stmt.run(input.name, now);
|
|
39
|
-
const getStmt = db.prepare('SELECT * FROM tags WHERE id = ?');
|
|
40
|
-
return getStmt.get(result.lastInsertRowid);
|
|
34
|
+
return this.backend.tags.create({ name: input.name, created_at: now });
|
|
41
35
|
}
|
|
42
36
|
/**
|
|
43
37
|
* Get tag by ID
|
|
@@ -45,10 +39,7 @@ class TagService {
|
|
|
45
39
|
* @returns Tag object or null if not found
|
|
46
40
|
*/
|
|
47
41
|
getTag(id) {
|
|
48
|
-
|
|
49
|
-
const stmt = db.prepare('SELECT * FROM tags WHERE id = ?');
|
|
50
|
-
const result = stmt.get(id);
|
|
51
|
-
return result ? result : null;
|
|
42
|
+
return this.backend.tags.findById(id);
|
|
52
43
|
}
|
|
53
44
|
/**
|
|
54
45
|
* Get tag by name
|
|
@@ -56,20 +47,14 @@ class TagService {
|
|
|
56
47
|
* @returns Tag object or null if not found
|
|
57
48
|
*/
|
|
58
49
|
getTagByName(name) {
|
|
59
|
-
|
|
60
|
-
const stmt = db.prepare('SELECT * FROM tags WHERE name = ?');
|
|
61
|
-
const result = stmt.get(name);
|
|
62
|
-
return result ? result : null;
|
|
50
|
+
return this.backend.tags.findByName(name);
|
|
63
51
|
}
|
|
64
52
|
/**
|
|
65
53
|
* List all tags
|
|
66
54
|
* @returns Array of tags sorted by creation date in descending order
|
|
67
55
|
*/
|
|
68
56
|
listTags() {
|
|
69
|
-
|
|
70
|
-
const stmt = db.prepare('SELECT * FROM tags ORDER BY created_at DESC, id DESC');
|
|
71
|
-
const results = stmt.all();
|
|
72
|
-
return results;
|
|
57
|
+
return this.backend.tags.findAll();
|
|
73
58
|
}
|
|
74
59
|
/**
|
|
75
60
|
* Update tag
|
|
@@ -79,7 +64,6 @@ class TagService {
|
|
|
79
64
|
* @throws Error if tag name already exists
|
|
80
65
|
*/
|
|
81
66
|
updateTag(id, input) {
|
|
82
|
-
const db = this.db;
|
|
83
67
|
// Verify that tag exists
|
|
84
68
|
const existingTag = this.getTag(id);
|
|
85
69
|
if (!existingTag) {
|
|
@@ -88,29 +72,23 @@ class TagService {
|
|
|
88
72
|
// Validate name if being updated
|
|
89
73
|
if (input.name !== undefined) {
|
|
90
74
|
if (!input.name || input.name.trim().length === 0) {
|
|
91
|
-
throw new
|
|
75
|
+
throw new errors_1.ValidationError('Name is required');
|
|
92
76
|
}
|
|
93
77
|
if (input.name.length > 50) {
|
|
94
|
-
throw new
|
|
78
|
+
throw new errors_1.ValidationError('Name must not exceed 50 characters');
|
|
95
79
|
}
|
|
96
80
|
if (/^\d+$/.test(input.name.trim())) {
|
|
97
|
-
throw new
|
|
81
|
+
throw new errors_1.ValidationError('Tag name cannot be purely numeric');
|
|
98
82
|
}
|
|
99
83
|
}
|
|
100
84
|
// Check for duplicate tag name if changing the name
|
|
101
85
|
if (input.name !== undefined && input.name !== existingTag.name) {
|
|
102
86
|
const duplicateTag = this.getTagByName(input.name);
|
|
103
87
|
if (duplicateTag) {
|
|
104
|
-
throw new
|
|
88
|
+
throw new errors_1.ConflictError(`Tag with name "${input.name}" already exists`);
|
|
105
89
|
}
|
|
106
90
|
}
|
|
107
|
-
|
|
108
|
-
UPDATE tags
|
|
109
|
-
SET name = COALESCE(?, name)
|
|
110
|
-
WHERE id = ?
|
|
111
|
-
`);
|
|
112
|
-
stmt.run(input.name ?? null, id);
|
|
113
|
-
return this.getTag(id);
|
|
91
|
+
return this.backend.tags.update(id, input);
|
|
114
92
|
}
|
|
115
93
|
/**
|
|
116
94
|
* Delete tag
|
|
@@ -118,10 +96,7 @@ class TagService {
|
|
|
118
96
|
* @returns True if deletion succeeded, false if tag not found
|
|
119
97
|
*/
|
|
120
98
|
deleteTag(id) {
|
|
121
|
-
|
|
122
|
-
const stmt = db.prepare('DELETE FROM tags WHERE id = ?');
|
|
123
|
-
const result = stmt.run(id);
|
|
124
|
-
return result.changes > 0;
|
|
99
|
+
return this.backend.tags.delete(id);
|
|
125
100
|
}
|
|
126
101
|
}
|
|
127
102
|
exports.TagService = TagService;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TagService.js","sourceRoot":"","sources":["../../src/services/TagService.ts"],"names":[],"mappings":";;;AACA,
|
|
1
|
+
{"version":3,"file":"TagService.js","sourceRoot":"","sources":["../../src/services/TagService.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { TaskBlock, CreateTaskBlockInput } from '../models';
|
|
2
2
|
import { TaskService } from './TaskService';
|
|
3
|
-
import {
|
|
3
|
+
import { StorageBackend } from '../db/types/repository';
|
|
4
4
|
/**
|
|
5
5
|
* Task Block Service
|
|
6
6
|
* Manages blocking relationships between tasks
|
|
7
7
|
*/
|
|
8
8
|
export declare class TaskBlockService {
|
|
9
|
-
private
|
|
9
|
+
private backend;
|
|
10
10
|
private taskService;
|
|
11
|
-
constructor(
|
|
11
|
+
constructor(backend?: StorageBackend, taskService?: TaskService);
|
|
12
12
|
/**
|
|
13
13
|
* Add a blocking relationship between tasks
|
|
14
14
|
* @param input - Creation input for the blocking relationship
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskBlockService.d.ts","sourceRoot":"","sources":["../../src/services/TaskBlockService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAE5D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"TaskBlockService.d.ts","sourceRoot":"","sources":["../../src/services/TaskBlockService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAE5D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAGxD;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,WAAW,CAAc;gBAErB,OAAO,CAAC,EAAE,cAAc,EAAE,WAAW,CAAC,EAAE,WAAW;IAK/D;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,oBAAoB,GAAG,SAAS;IA4BhD;;;;;OAKG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAI1D;;;;;OAKG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE;IAI9C;;;;;OAKG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE;IAI9C;;;;OAIG;IACH,YAAY,IAAI,KAAK,CAAC;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE,CAAC;IAI3E;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;CAiB9B"}
|
|
@@ -3,16 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.TaskBlockService = void 0;
|
|
4
4
|
const connection_1 = require("../db/connection");
|
|
5
5
|
const TaskService_1 = require("./TaskService");
|
|
6
|
+
const errors_1 = require("../errors");
|
|
6
7
|
/**
|
|
7
8
|
* Task Block Service
|
|
8
9
|
* Manages blocking relationships between tasks
|
|
9
10
|
*/
|
|
10
11
|
class TaskBlockService {
|
|
11
|
-
|
|
12
|
+
backend;
|
|
12
13
|
taskService;
|
|
13
|
-
constructor(
|
|
14
|
-
this.
|
|
15
|
-
this.taskService = taskService
|
|
14
|
+
constructor(backend, taskService) {
|
|
15
|
+
this.backend = backend ?? (0, connection_1.getStorageBackend)();
|
|
16
|
+
this.taskService = taskService ?? new TaskService_1.TaskService(this.backend);
|
|
16
17
|
}
|
|
17
18
|
/**
|
|
18
19
|
* Add a blocking relationship between tasks
|
|
@@ -21,32 +22,25 @@ class TaskBlockService {
|
|
|
21
22
|
* @throws Error if tasks do not exist, self-reference is detected, or circular reference would be created
|
|
22
23
|
*/
|
|
23
24
|
addBlock(input) {
|
|
24
|
-
const db = this.db;
|
|
25
25
|
// Check for self-reference: prevent a task from blocking itself
|
|
26
26
|
if (input.blocker_task_id === input.blocked_task_id) {
|
|
27
|
-
throw new
|
|
27
|
+
throw new errors_1.ConflictError('Task cannot block itself');
|
|
28
28
|
}
|
|
29
29
|
// Verify both tasks exist in the database
|
|
30
30
|
const blockerTask = this.taskService.getTask(input.blocker_task_id);
|
|
31
31
|
if (!blockerTask) {
|
|
32
|
-
throw new
|
|
32
|
+
throw new errors_1.NotFoundError(`Blocker task with id ${input.blocker_task_id} does not exist`);
|
|
33
33
|
}
|
|
34
34
|
const blockedTask = this.taskService.getTask(input.blocked_task_id);
|
|
35
35
|
if (!blockedTask) {
|
|
36
|
-
throw new
|
|
36
|
+
throw new errors_1.NotFoundError(`Blocked task with id ${input.blocked_task_id} does not exist`);
|
|
37
37
|
}
|
|
38
38
|
// Check for circular reference: ensure new blocking relationship doesn't create a cycle
|
|
39
39
|
if (this.wouldCreateBlockCycle(input.blocker_task_id, input.blocked_task_id)) {
|
|
40
|
-
throw new
|
|
40
|
+
throw new errors_1.ConflictError(`Cannot create block relationship: would create circular dependency between tasks ${input.blocker_task_id} and ${input.blocked_task_id}`);
|
|
41
41
|
}
|
|
42
42
|
const now = new Date().toISOString();
|
|
43
|
-
|
|
44
|
-
INSERT INTO task_blocks (blocker_task_id, blocked_task_id, created_at)
|
|
45
|
-
VALUES (?, ?, ?)
|
|
46
|
-
`);
|
|
47
|
-
const result = stmt.run(input.blocker_task_id, input.blocked_task_id, now);
|
|
48
|
-
const getStmt = db.prepare('SELECT * FROM task_blocks WHERE id = ?');
|
|
49
|
-
return getStmt.get(result.lastInsertRowid);
|
|
43
|
+
return this.backend.blocks.create({ ...input, created_at: now });
|
|
50
44
|
}
|
|
51
45
|
/**
|
|
52
46
|
* Remove a blocking relationship between tasks
|
|
@@ -55,13 +49,7 @@ class TaskBlockService {
|
|
|
55
49
|
* @returns True if removal was successful, false if relationship was not found
|
|
56
50
|
*/
|
|
57
51
|
removeBlock(blockerId, blockedId) {
|
|
58
|
-
|
|
59
|
-
const stmt = db.prepare(`
|
|
60
|
-
DELETE FROM task_blocks
|
|
61
|
-
WHERE blocker_task_id = ? AND blocked_task_id = ?
|
|
62
|
-
`);
|
|
63
|
-
const result = stmt.run(blockerId, blockedId);
|
|
64
|
-
return result.changes > 0;
|
|
52
|
+
return this.backend.blocks.delete(blockerId, blockedId);
|
|
65
53
|
}
|
|
66
54
|
/**
|
|
67
55
|
* Get IDs of tasks blocked by the specified task
|
|
@@ -70,13 +58,7 @@ class TaskBlockService {
|
|
|
70
58
|
* @returns Array of IDs for tasks blocked by this task
|
|
71
59
|
*/
|
|
72
60
|
getBlockedTaskIds(blockerId) {
|
|
73
|
-
|
|
74
|
-
const stmt = db.prepare(`
|
|
75
|
-
SELECT blocked_task_id FROM task_blocks
|
|
76
|
-
WHERE blocker_task_id = ?
|
|
77
|
-
`);
|
|
78
|
-
const results = stmt.all(blockerId);
|
|
79
|
-
return results.map((row) => row.blocked_task_id);
|
|
61
|
+
return this.backend.blocks.findBlockedTaskIds(blockerId);
|
|
80
62
|
}
|
|
81
63
|
/**
|
|
82
64
|
* Get IDs of tasks blocking the specified task
|
|
@@ -85,13 +67,7 @@ class TaskBlockService {
|
|
|
85
67
|
* @returns Array of IDs for blocking tasks
|
|
86
68
|
*/
|
|
87
69
|
getBlockerTaskIds(blockedId) {
|
|
88
|
-
|
|
89
|
-
const stmt = db.prepare(`
|
|
90
|
-
SELECT blocker_task_id FROM task_blocks
|
|
91
|
-
WHERE blocked_task_id = ?
|
|
92
|
-
`);
|
|
93
|
-
const results = stmt.all(blockedId);
|
|
94
|
-
return results.map((row) => row.blocker_task_id);
|
|
70
|
+
return this.backend.blocks.findBlockerTaskIds(blockedId);
|
|
95
71
|
}
|
|
96
72
|
/**
|
|
97
73
|
* Get all blocking relationships
|
|
@@ -99,9 +75,7 @@ class TaskBlockService {
|
|
|
99
75
|
* @returns Array of all blocking relationships
|
|
100
76
|
*/
|
|
101
77
|
getAllBlocks() {
|
|
102
|
-
|
|
103
|
-
const stmt = db.prepare('SELECT blocker_task_id, blocked_task_id FROM task_blocks');
|
|
104
|
-
return stmt.all();
|
|
78
|
+
return this.backend.blocks.findAll();
|
|
105
79
|
}
|
|
106
80
|
/**
|
|
107
81
|
* Check for circular references in blocking relationships (private method)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskBlockService.js","sourceRoot":"","sources":["../../src/services/TaskBlockService.ts"],"names":[],"mappings":";;;AACA,
|
|
1
|
+
{"version":3,"file":"TaskBlockService.js","sourceRoot":"","sources":["../../src/services/TaskBlockService.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Task, CreateTaskInput, UpdateTaskInput, TaskStatus } from '../models';
|
|
2
|
-
import {
|
|
2
|
+
import { StorageBackend } from '../db/types/repository';
|
|
3
3
|
/** Allowed sort fields for task listing */
|
|
4
4
|
export declare const ALLOWED_SORT_FIELDS: readonly ["id", "title", "status", "created_at", "updated_at", "priority"];
|
|
5
5
|
export type SortField = (typeof ALLOWED_SORT_FIELDS)[number];
|
|
@@ -9,10 +9,12 @@ export type SortOrder = 'asc' | 'desc';
|
|
|
9
9
|
* Provides CRUD operations for tasks
|
|
10
10
|
*/
|
|
11
11
|
export declare class TaskService {
|
|
12
|
-
private
|
|
13
|
-
constructor(
|
|
12
|
+
private backend;
|
|
13
|
+
constructor(backend?: StorageBackend);
|
|
14
14
|
/**
|
|
15
15
|
* Create a new task
|
|
16
|
+
* If `tagIds` is provided, the task creation and tag attachments are wrapped
|
|
17
|
+
* in a single transaction to prevent orphaned tasks when tag attachment fails.
|
|
16
18
|
* @param input - Task creation input
|
|
17
19
|
* @returns Created task
|
|
18
20
|
*/
|
|
@@ -23,19 +25,6 @@ export declare class TaskService {
|
|
|
23
25
|
* @returns Task, or null if not found
|
|
24
26
|
*/
|
|
25
27
|
getTask(id: number): Task | null;
|
|
26
|
-
/**
|
|
27
|
-
* Build the base SELECT query and initial params for listTasks.
|
|
28
|
-
* Uses a JOIN when tag IDs are specified.
|
|
29
|
-
*/
|
|
30
|
-
private buildListBaseQuery;
|
|
31
|
-
/**
|
|
32
|
-
* Append filter conditions (status, author, assignees, priority) to query and params.
|
|
33
|
-
*/
|
|
34
|
-
private applyListFilters;
|
|
35
|
-
/**
|
|
36
|
-
* Append ORDER BY clause to query for listTasks.
|
|
37
|
-
*/
|
|
38
|
-
private applyListOrder;
|
|
39
28
|
/**
|
|
40
29
|
* Get task list
|
|
41
30
|
* @param filters - Filter criteria (status, author, tagIds)
|
|
@@ -51,13 +40,6 @@ export declare class TaskService {
|
|
|
51
40
|
priority?: string | string[];
|
|
52
41
|
search?: string;
|
|
53
42
|
}, sort?: SortField, order?: SortOrder): Task[];
|
|
54
|
-
/**
|
|
55
|
-
* Build dynamic UPDATE query for task fields
|
|
56
|
-
* @param input - Update content
|
|
57
|
-
* @param id - Task ID (appended as last param for WHERE clause)
|
|
58
|
-
* @returns Object with sql string and params array
|
|
59
|
-
*/
|
|
60
|
-
private buildUpdateQuery;
|
|
61
43
|
/**
|
|
62
44
|
* Update task
|
|
63
45
|
* @param id - Task ID
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskService.d.ts","sourceRoot":"","sources":["../../src/services/TaskService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAI/E,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"TaskService.d.ts","sourceRoot":"","sources":["../../src/services/TaskService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAI/E,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAGxD,2CAA2C;AAC3C,eAAO,MAAM,mBAAmB,4EAA6E,CAAC;AAC9G,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,CAAC;AAEvC;;;GAGG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAiB;gBAEpB,OAAO,CAAC,EAAE,cAAc;IAIpC;;;;;;OAMG;IACH,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IA2CxC;;;;OAIG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIhC;;;;;;OAMG;IACH,SAAS,CACP,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,UAAU,GAAG,UAAU,EAAE,CAAC;QACnC,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,EACD,IAAI,CAAC,EAAE,SAAS,EAChB,KAAK,CAAC,EAAE,SAAS,GAChB,IAAI,EAAE;IAkBT;;;;;OAKG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,IAAI,GAAG,IAAI;IA4B3D;;;;OAIG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAQ/B;;;OAGG;IACH,oBAAoB,IAAI,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC;IAIlD;;;;;;OAMG;IACH,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,GAAE,UAAU,EAAuB,EAAE,MAAM,GAAE,OAAe,GAAG,IAAI,EAAE;IAclH;;;;;;OAMG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,GAAE,OAAe,EAAE,QAAQ,CAAC,EAAE,UAAU,EAAE,GAAG,IAAI,EAAE;IAiB1F;;;;OAIG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE;IAIvC;;;;OAIG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAQ1C;;;;OAIG;IACH,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE;IAwB5C;;;;OAIG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;CAuBzC"}
|