@sprintdock/backend 0.4.2

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 (107) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/README.md +252 -0
  3. package/SERVER.md +25 -0
  4. package/dist/index.d.ts +1536 -0
  5. package/dist/index.js +4103 -0
  6. package/drizzle/0000_fresh_roxanne_simpson.sql +51 -0
  7. package/drizzle/0001_sprint_markdown_content.sql +1 -0
  8. package/drizzle/0002_task_touched_files.sql +8 -0
  9. package/drizzle/meta/0000_snapshot.json +372 -0
  10. package/drizzle/meta/0001_snapshot.json +379 -0
  11. package/drizzle/meta/_journal.json +27 -0
  12. package/drizzle.config.ts +14 -0
  13. package/package.json +40 -0
  14. package/src/application/container.ts +44 -0
  15. package/src/application/dto/plan-sprint-analytics.dto.ts +30 -0
  16. package/src/application/plan.service.ts +123 -0
  17. package/src/application/sprint.service.ts +118 -0
  18. package/src/application/task.service.ts +389 -0
  19. package/src/db/connection.ts +25 -0
  20. package/src/db/migrator.ts +46 -0
  21. package/src/db/schema/index.ts +14 -0
  22. package/src/db/schema/plans.ts +18 -0
  23. package/src/db/schema/relations.ts +36 -0
  24. package/src/db/schema/sprints.ts +33 -0
  25. package/src/db/schema/tasks.ts +62 -0
  26. package/src/domain/entities/index.ts +30 -0
  27. package/src/domain/entities/plan.entity.ts +33 -0
  28. package/src/domain/entities/sprint.entity.ts +44 -0
  29. package/src/domain/entities/task.entity.ts +80 -0
  30. package/src/domain/repositories/index.ts +9 -0
  31. package/src/domain/repositories/plan.repository.ts +21 -0
  32. package/src/domain/repositories/sprint.repository.ts +19 -0
  33. package/src/domain/repositories/task.repository.ts +35 -0
  34. package/src/domain/services/index.ts +9 -0
  35. package/src/domain/services/plan-domain.service.ts +44 -0
  36. package/src/domain/services/sprint-domain.service.ts +44 -0
  37. package/src/domain/services/task-domain.service.ts +136 -0
  38. package/src/errors/backend-errors.ts +75 -0
  39. package/src/http/app-factory.ts +55 -0
  40. package/src/http/controllers/health.controller.ts +33 -0
  41. package/src/http/controllers/plan.controller.ts +153 -0
  42. package/src/http/controllers/sprint.controller.ts +111 -0
  43. package/src/http/controllers/task.controller.ts +158 -0
  44. package/src/http/express-augmentation.d.ts +20 -0
  45. package/src/http/middleware/cors.ts +41 -0
  46. package/src/http/middleware/error-handler.ts +50 -0
  47. package/src/http/middleware/request-id.ts +28 -0
  48. package/src/http/middleware/validate.ts +54 -0
  49. package/src/http/routes/v1/index.ts +39 -0
  50. package/src/http/routes/v1/plan.routes.ts +51 -0
  51. package/src/http/routes/v1/schemas.ts +175 -0
  52. package/src/http/routes/v1/sprint.routes.ts +49 -0
  53. package/src/http/routes/v1/task.routes.ts +64 -0
  54. package/src/index.ts +34 -0
  55. package/src/infrastructure/observability/audit-log.ts +34 -0
  56. package/src/infrastructure/observability/request-correlation.ts +20 -0
  57. package/src/infrastructure/repositories/drizzle/drizzle-plan.repository.ts +138 -0
  58. package/src/infrastructure/repositories/drizzle/drizzle-sprint.repository.ts +137 -0
  59. package/src/infrastructure/repositories/drizzle/drizzle-task.repository.ts +403 -0
  60. package/src/infrastructure/repositories/drizzle/index.ts +16 -0
  61. package/src/infrastructure/repositories/drizzle/row-mappers.ts +106 -0
  62. package/src/infrastructure/repositories/drizzle/sqlite-db.ts +13 -0
  63. package/src/infrastructure/repositories/repository-factory.ts +54 -0
  64. package/src/infrastructure/security/auth-context.ts +35 -0
  65. package/src/infrastructure/security/input-guard.ts +21 -0
  66. package/src/infrastructure/security/rate-limiter.ts +65 -0
  67. package/src/mcp/bootstrap-sprintdock-sqlite.ts +45 -0
  68. package/src/mcp/mcp-query-helpers.ts +89 -0
  69. package/src/mcp/mcp-text-formatters.ts +204 -0
  70. package/src/mcp/mcp-tool-error.ts +24 -0
  71. package/src/mcp/plugins/context-tools.plugin.ts +107 -0
  72. package/src/mcp/plugins/default-plugins.ts +23 -0
  73. package/src/mcp/plugins/index.ts +21 -0
  74. package/src/mcp/plugins/mcp-tool-kit.ts +90 -0
  75. package/src/mcp/plugins/plan-tools.plugin.ts +426 -0
  76. package/src/mcp/plugins/sprint-tools.plugin.ts +396 -0
  77. package/src/mcp/plugins/task-tools.plugin.ts +528 -0
  78. package/src/mcp/plugins/task-workflow.plugin.ts +275 -0
  79. package/src/mcp/plugins/types.ts +45 -0
  80. package/src/mcp/register-sprintdock-mcp-tools.ts +50 -0
  81. package/src/mcp/sprintdock-mcp-capabilities.ts +14 -0
  82. package/src/mcp/sprintdock-mcp-runtime.ts +119 -0
  83. package/src/mcp/tool-guard.ts +58 -0
  84. package/src/mcp/transports/http-app-factory.ts +31 -0
  85. package/src/mcp/transports/http-entry.ts +27 -0
  86. package/src/mcp/transports/stdio-entry.ts +17 -0
  87. package/tests/application/container.test.ts +36 -0
  88. package/tests/application/plan.service.test.ts +114 -0
  89. package/tests/application/sprint.service.test.ts +138 -0
  90. package/tests/application/task.service.test.ts +325 -0
  91. package/tests/db/test-db.test.ts +112 -0
  92. package/tests/domain/plan-domain.service.test.ts +44 -0
  93. package/tests/domain/sprint-domain.service.test.ts +38 -0
  94. package/tests/domain/task-domain.service.test.ts +105 -0
  95. package/tests/errors/backend-errors.test.ts +44 -0
  96. package/tests/helpers/test-db.ts +43 -0
  97. package/tests/http/error-handler.test.ts +37 -0
  98. package/tests/http/plan.routes.test.ts +128 -0
  99. package/tests/http/sprint.routes.test.ts +72 -0
  100. package/tests/http/task.routes.test.ts +130 -0
  101. package/tests/http/test-app.ts +17 -0
  102. package/tests/infrastructure/drizzle-plan.repository.test.ts +62 -0
  103. package/tests/infrastructure/drizzle-sprint.repository.test.ts +49 -0
  104. package/tests/infrastructure/drizzle-task.repository.test.ts +132 -0
  105. package/tests/mcp/mcp-text-formatters.test.ts +246 -0
  106. package/tests/mcp/register-sprintdock-mcp-tools.test.ts +207 -0
  107. package/tsconfig.json +9 -0
@@ -0,0 +1,51 @@
1
+ CREATE TABLE `plans` (
2
+ `id` text PRIMARY KEY NOT NULL,
3
+ `slug` text NOT NULL,
4
+ `title` text NOT NULL,
5
+ `description` text,
6
+ `markdown_content` text,
7
+ `status` text NOT NULL,
8
+ `is_active` integer DEFAULT false NOT NULL,
9
+ `created_at` text NOT NULL,
10
+ `updated_at` text NOT NULL
11
+ );
12
+ --> statement-breakpoint
13
+ CREATE UNIQUE INDEX `plans_slug_unique` ON `plans` (`slug`);--> statement-breakpoint
14
+ CREATE TABLE `sprints` (
15
+ `id` text PRIMARY KEY NOT NULL,
16
+ `slug` text NOT NULL,
17
+ `plan_id` text NOT NULL,
18
+ `name` text NOT NULL,
19
+ `goal` text NOT NULL,
20
+ `status` text NOT NULL,
21
+ `order` integer DEFAULT 0 NOT NULL,
22
+ `start_date` text,
23
+ `end_date` text,
24
+ `created_at` text NOT NULL,
25
+ `updated_at` text NOT NULL,
26
+ FOREIGN KEY (`plan_id`) REFERENCES `plans`(`id`) ON UPDATE no action ON DELETE cascade
27
+ );
28
+ --> statement-breakpoint
29
+ CREATE UNIQUE INDEX `sprints_plan_id_slug_unique` ON `sprints` (`plan_id`,`slug`);--> statement-breakpoint
30
+ CREATE TABLE `task_dependencies` (
31
+ `task_id` text NOT NULL,
32
+ `depends_on_task_id` text NOT NULL,
33
+ PRIMARY KEY(`task_id`, `depends_on_task_id`),
34
+ FOREIGN KEY (`task_id`) REFERENCES `tasks`(`id`) ON UPDATE no action ON DELETE cascade,
35
+ FOREIGN KEY (`depends_on_task_id`) REFERENCES `tasks`(`id`) ON UPDATE no action ON DELETE cascade
36
+ );
37
+ --> statement-breakpoint
38
+ CREATE TABLE `tasks` (
39
+ `id` text PRIMARY KEY NOT NULL,
40
+ `sprint_id` text NOT NULL,
41
+ `title` text NOT NULL,
42
+ `description` text,
43
+ `status` text NOT NULL,
44
+ `priority` text NOT NULL,
45
+ `order` integer DEFAULT 0 NOT NULL,
46
+ `assignee` text,
47
+ `tags` text,
48
+ `created_at` text NOT NULL,
49
+ `updated_at` text NOT NULL,
50
+ FOREIGN KEY (`sprint_id`) REFERENCES `sprints`(`id`) ON UPDATE no action ON DELETE cascade
51
+ );
@@ -0,0 +1 @@
1
+ ALTER TABLE `sprints` ADD `markdown_content` text;
@@ -0,0 +1,8 @@
1
+ CREATE TABLE `task_touched_files` (
2
+ `id` text PRIMARY KEY NOT NULL,
3
+ `task_id` text NOT NULL,
4
+ `path` text NOT NULL,
5
+ `file_type` text NOT NULL,
6
+ UNIQUE(`task_id`,`path`),
7
+ FOREIGN KEY (`task_id`) REFERENCES `tasks`(`id`) ON UPDATE no action ON DELETE cascade
8
+ );
@@ -0,0 +1,372 @@
1
+ {
2
+ "version": "6",
3
+ "dialect": "sqlite",
4
+ "id": "83aff8bf-5357-4a7d-a572-042fd77858fb",
5
+ "prevId": "00000000-0000-0000-0000-000000000000",
6
+ "tables": {
7
+ "plans": {
8
+ "name": "plans",
9
+ "columns": {
10
+ "id": {
11
+ "name": "id",
12
+ "type": "text",
13
+ "primaryKey": true,
14
+ "notNull": true,
15
+ "autoincrement": false
16
+ },
17
+ "slug": {
18
+ "name": "slug",
19
+ "type": "text",
20
+ "primaryKey": false,
21
+ "notNull": true,
22
+ "autoincrement": false
23
+ },
24
+ "title": {
25
+ "name": "title",
26
+ "type": "text",
27
+ "primaryKey": false,
28
+ "notNull": true,
29
+ "autoincrement": false
30
+ },
31
+ "description": {
32
+ "name": "description",
33
+ "type": "text",
34
+ "primaryKey": false,
35
+ "notNull": false,
36
+ "autoincrement": false
37
+ },
38
+ "markdown_content": {
39
+ "name": "markdown_content",
40
+ "type": "text",
41
+ "primaryKey": false,
42
+ "notNull": false,
43
+ "autoincrement": false
44
+ },
45
+ "status": {
46
+ "name": "status",
47
+ "type": "text",
48
+ "primaryKey": false,
49
+ "notNull": true,
50
+ "autoincrement": false
51
+ },
52
+ "is_active": {
53
+ "name": "is_active",
54
+ "type": "integer",
55
+ "primaryKey": false,
56
+ "notNull": true,
57
+ "autoincrement": false,
58
+ "default": false
59
+ },
60
+ "created_at": {
61
+ "name": "created_at",
62
+ "type": "text",
63
+ "primaryKey": false,
64
+ "notNull": true,
65
+ "autoincrement": false
66
+ },
67
+ "updated_at": {
68
+ "name": "updated_at",
69
+ "type": "text",
70
+ "primaryKey": false,
71
+ "notNull": true,
72
+ "autoincrement": false
73
+ }
74
+ },
75
+ "indexes": {
76
+ "plans_slug_unique": {
77
+ "name": "plans_slug_unique",
78
+ "columns": [
79
+ "slug"
80
+ ],
81
+ "isUnique": true
82
+ }
83
+ },
84
+ "foreignKeys": {},
85
+ "compositePrimaryKeys": {},
86
+ "uniqueConstraints": {},
87
+ "checkConstraints": {}
88
+ },
89
+ "sprints": {
90
+ "name": "sprints",
91
+ "columns": {
92
+ "id": {
93
+ "name": "id",
94
+ "type": "text",
95
+ "primaryKey": true,
96
+ "notNull": true,
97
+ "autoincrement": false
98
+ },
99
+ "slug": {
100
+ "name": "slug",
101
+ "type": "text",
102
+ "primaryKey": false,
103
+ "notNull": true,
104
+ "autoincrement": false
105
+ },
106
+ "plan_id": {
107
+ "name": "plan_id",
108
+ "type": "text",
109
+ "primaryKey": false,
110
+ "notNull": true,
111
+ "autoincrement": false
112
+ },
113
+ "name": {
114
+ "name": "name",
115
+ "type": "text",
116
+ "primaryKey": false,
117
+ "notNull": true,
118
+ "autoincrement": false
119
+ },
120
+ "goal": {
121
+ "name": "goal",
122
+ "type": "text",
123
+ "primaryKey": false,
124
+ "notNull": true,
125
+ "autoincrement": false
126
+ },
127
+ "status": {
128
+ "name": "status",
129
+ "type": "text",
130
+ "primaryKey": false,
131
+ "notNull": true,
132
+ "autoincrement": false
133
+ },
134
+ "order": {
135
+ "name": "order",
136
+ "type": "integer",
137
+ "primaryKey": false,
138
+ "notNull": true,
139
+ "autoincrement": false,
140
+ "default": 0
141
+ },
142
+ "start_date": {
143
+ "name": "start_date",
144
+ "type": "text",
145
+ "primaryKey": false,
146
+ "notNull": false,
147
+ "autoincrement": false
148
+ },
149
+ "end_date": {
150
+ "name": "end_date",
151
+ "type": "text",
152
+ "primaryKey": false,
153
+ "notNull": false,
154
+ "autoincrement": false
155
+ },
156
+ "created_at": {
157
+ "name": "created_at",
158
+ "type": "text",
159
+ "primaryKey": false,
160
+ "notNull": true,
161
+ "autoincrement": false
162
+ },
163
+ "updated_at": {
164
+ "name": "updated_at",
165
+ "type": "text",
166
+ "primaryKey": false,
167
+ "notNull": true,
168
+ "autoincrement": false
169
+ }
170
+ },
171
+ "indexes": {
172
+ "sprints_plan_id_slug_unique": {
173
+ "name": "sprints_plan_id_slug_unique",
174
+ "columns": [
175
+ "plan_id",
176
+ "slug"
177
+ ],
178
+ "isUnique": true
179
+ }
180
+ },
181
+ "foreignKeys": {
182
+ "sprints_plan_id_plans_id_fk": {
183
+ "name": "sprints_plan_id_plans_id_fk",
184
+ "tableFrom": "sprints",
185
+ "tableTo": "plans",
186
+ "columnsFrom": [
187
+ "plan_id"
188
+ ],
189
+ "columnsTo": [
190
+ "id"
191
+ ],
192
+ "onDelete": "cascade",
193
+ "onUpdate": "no action"
194
+ }
195
+ },
196
+ "compositePrimaryKeys": {},
197
+ "uniqueConstraints": {},
198
+ "checkConstraints": {}
199
+ },
200
+ "task_dependencies": {
201
+ "name": "task_dependencies",
202
+ "columns": {
203
+ "task_id": {
204
+ "name": "task_id",
205
+ "type": "text",
206
+ "primaryKey": false,
207
+ "notNull": true,
208
+ "autoincrement": false
209
+ },
210
+ "depends_on_task_id": {
211
+ "name": "depends_on_task_id",
212
+ "type": "text",
213
+ "primaryKey": false,
214
+ "notNull": true,
215
+ "autoincrement": false
216
+ }
217
+ },
218
+ "indexes": {},
219
+ "foreignKeys": {
220
+ "task_dependencies_task_id_tasks_id_fk": {
221
+ "name": "task_dependencies_task_id_tasks_id_fk",
222
+ "tableFrom": "task_dependencies",
223
+ "tableTo": "tasks",
224
+ "columnsFrom": [
225
+ "task_id"
226
+ ],
227
+ "columnsTo": [
228
+ "id"
229
+ ],
230
+ "onDelete": "cascade",
231
+ "onUpdate": "no action"
232
+ },
233
+ "task_dependencies_depends_on_task_id_tasks_id_fk": {
234
+ "name": "task_dependencies_depends_on_task_id_tasks_id_fk",
235
+ "tableFrom": "task_dependencies",
236
+ "tableTo": "tasks",
237
+ "columnsFrom": [
238
+ "depends_on_task_id"
239
+ ],
240
+ "columnsTo": [
241
+ "id"
242
+ ],
243
+ "onDelete": "cascade",
244
+ "onUpdate": "no action"
245
+ }
246
+ },
247
+ "compositePrimaryKeys": {
248
+ "task_dependencies_task_id_depends_on_task_id_pk": {
249
+ "columns": [
250
+ "task_id",
251
+ "depends_on_task_id"
252
+ ],
253
+ "name": "task_dependencies_task_id_depends_on_task_id_pk"
254
+ }
255
+ },
256
+ "uniqueConstraints": {},
257
+ "checkConstraints": {}
258
+ },
259
+ "tasks": {
260
+ "name": "tasks",
261
+ "columns": {
262
+ "id": {
263
+ "name": "id",
264
+ "type": "text",
265
+ "primaryKey": true,
266
+ "notNull": true,
267
+ "autoincrement": false
268
+ },
269
+ "sprint_id": {
270
+ "name": "sprint_id",
271
+ "type": "text",
272
+ "primaryKey": false,
273
+ "notNull": true,
274
+ "autoincrement": false
275
+ },
276
+ "title": {
277
+ "name": "title",
278
+ "type": "text",
279
+ "primaryKey": false,
280
+ "notNull": true,
281
+ "autoincrement": false
282
+ },
283
+ "description": {
284
+ "name": "description",
285
+ "type": "text",
286
+ "primaryKey": false,
287
+ "notNull": false,
288
+ "autoincrement": false
289
+ },
290
+ "status": {
291
+ "name": "status",
292
+ "type": "text",
293
+ "primaryKey": false,
294
+ "notNull": true,
295
+ "autoincrement": false
296
+ },
297
+ "priority": {
298
+ "name": "priority",
299
+ "type": "text",
300
+ "primaryKey": false,
301
+ "notNull": true,
302
+ "autoincrement": false
303
+ },
304
+ "order": {
305
+ "name": "order",
306
+ "type": "integer",
307
+ "primaryKey": false,
308
+ "notNull": true,
309
+ "autoincrement": false,
310
+ "default": 0
311
+ },
312
+ "assignee": {
313
+ "name": "assignee",
314
+ "type": "text",
315
+ "primaryKey": false,
316
+ "notNull": false,
317
+ "autoincrement": false
318
+ },
319
+ "tags": {
320
+ "name": "tags",
321
+ "type": "text",
322
+ "primaryKey": false,
323
+ "notNull": false,
324
+ "autoincrement": false
325
+ },
326
+ "created_at": {
327
+ "name": "created_at",
328
+ "type": "text",
329
+ "primaryKey": false,
330
+ "notNull": true,
331
+ "autoincrement": false
332
+ },
333
+ "updated_at": {
334
+ "name": "updated_at",
335
+ "type": "text",
336
+ "primaryKey": false,
337
+ "notNull": true,
338
+ "autoincrement": false
339
+ }
340
+ },
341
+ "indexes": {},
342
+ "foreignKeys": {
343
+ "tasks_sprint_id_sprints_id_fk": {
344
+ "name": "tasks_sprint_id_sprints_id_fk",
345
+ "tableFrom": "tasks",
346
+ "tableTo": "sprints",
347
+ "columnsFrom": [
348
+ "sprint_id"
349
+ ],
350
+ "columnsTo": [
351
+ "id"
352
+ ],
353
+ "onDelete": "cascade",
354
+ "onUpdate": "no action"
355
+ }
356
+ },
357
+ "compositePrimaryKeys": {},
358
+ "uniqueConstraints": {},
359
+ "checkConstraints": {}
360
+ }
361
+ },
362
+ "views": {},
363
+ "enums": {},
364
+ "_meta": {
365
+ "schemas": {},
366
+ "tables": {},
367
+ "columns": {}
368
+ },
369
+ "internal": {
370
+ "indexes": {}
371
+ }
372
+ }