@meridianjs/meridian 0.1.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 (170) hide show
  1. package/dist/api/admin/issues/[id]/activities/route.d.ts +3 -0
  2. package/dist/api/admin/issues/[id]/activities/route.d.ts.map +1 -0
  3. package/dist/api/admin/issues/[id]/activities/route.js +7 -0
  4. package/dist/api/admin/issues/[id]/activities/route.js.map +1 -0
  5. package/dist/api/admin/issues/[id]/attachments/[attachmentId]/route.d.ts +3 -0
  6. package/dist/api/admin/issues/[id]/attachments/[attachmentId]/route.d.ts.map +1 -0
  7. package/dist/api/admin/issues/[id]/attachments/[attachmentId]/route.js +11 -0
  8. package/dist/api/admin/issues/[id]/attachments/[attachmentId]/route.js.map +1 -0
  9. package/dist/api/admin/issues/[id]/attachments/route.d.ts +4 -0
  10. package/dist/api/admin/issues/[id]/attachments/route.d.ts.map +1 -0
  11. package/dist/api/admin/issues/[id]/attachments/route.js +40 -0
  12. package/dist/api/admin/issues/[id]/attachments/route.js.map +1 -0
  13. package/dist/api/admin/issues/[id]/comments/route.d.ts +4 -0
  14. package/dist/api/admin/issues/[id]/comments/route.d.ts.map +1 -0
  15. package/dist/api/admin/issues/[id]/comments/route.js +20 -0
  16. package/dist/api/admin/issues/[id]/comments/route.js.map +1 -0
  17. package/dist/api/admin/issues/[id]/route.d.ts +5 -0
  18. package/dist/api/admin/issues/[id]/route.d.ts.map +1 -0
  19. package/dist/api/admin/issues/[id]/route.js +70 -0
  20. package/dist/api/admin/issues/[id]/route.js.map +1 -0
  21. package/dist/api/admin/issues/[id]/time-logs/[logId]/route.d.ts +3 -0
  22. package/dist/api/admin/issues/[id]/time-logs/[logId]/route.d.ts.map +1 -0
  23. package/dist/api/admin/issues/[id]/time-logs/[logId]/route.js +6 -0
  24. package/dist/api/admin/issues/[id]/time-logs/[logId]/route.js.map +1 -0
  25. package/dist/api/admin/issues/[id]/time-logs/route.d.ts +4 -0
  26. package/dist/api/admin/issues/[id]/time-logs/route.d.ts.map +1 -0
  27. package/dist/api/admin/issues/[id]/time-logs/route.js +26 -0
  28. package/dist/api/admin/issues/[id]/time-logs/route.js.map +1 -0
  29. package/dist/api/admin/issues/[id]/time-logs/timer/route.d.ts +4 -0
  30. package/dist/api/admin/issues/[id]/time-logs/timer/route.d.ts.map +1 -0
  31. package/dist/api/admin/issues/[id]/time-logs/timer/route.js +26 -0
  32. package/dist/api/admin/issues/[id]/time-logs/timer/route.js.map +1 -0
  33. package/dist/api/admin/issues/route.d.ts +4 -0
  34. package/dist/api/admin/issues/route.d.ts.map +1 -0
  35. package/dist/api/admin/issues/route.js +48 -0
  36. package/dist/api/admin/issues/route.js.map +1 -0
  37. package/dist/api/admin/notifications/[id]/read/route.d.ts +3 -0
  38. package/dist/api/admin/notifications/[id]/read/route.d.ts.map +1 -0
  39. package/dist/api/admin/notifications/[id]/read/route.js +6 -0
  40. package/dist/api/admin/notifications/[id]/read/route.js.map +1 -0
  41. package/dist/api/admin/notifications/read-all/route.d.ts +3 -0
  42. package/dist/api/admin/notifications/read-all/route.d.ts.map +1 -0
  43. package/dist/api/admin/notifications/read-all/route.js +11 -0
  44. package/dist/api/admin/notifications/read-all/route.js.map +1 -0
  45. package/dist/api/admin/notifications/route.d.ts +3 -0
  46. package/dist/api/admin/notifications/route.d.ts.map +1 -0
  47. package/dist/api/admin/notifications/route.js +14 -0
  48. package/dist/api/admin/notifications/route.js.map +1 -0
  49. package/dist/api/admin/projects/[id]/route.d.ts +5 -0
  50. package/dist/api/admin/projects/[id]/route.d.ts.map +1 -0
  51. package/dist/api/admin/projects/[id]/route.js +36 -0
  52. package/dist/api/admin/projects/[id]/route.js.map +1 -0
  53. package/dist/api/admin/projects/[id]/statuses/[statusId]/route.d.ts +4 -0
  54. package/dist/api/admin/projects/[id]/statuses/[statusId]/route.d.ts.map +1 -0
  55. package/dist/api/admin/projects/[id]/statuses/[statusId]/route.js +24 -0
  56. package/dist/api/admin/projects/[id]/statuses/[statusId]/route.js.map +1 -0
  57. package/dist/api/admin/projects/[id]/statuses/reorder/route.d.ts +3 -0
  58. package/dist/api/admin/projects/[id]/statuses/reorder/route.d.ts.map +1 -0
  59. package/dist/api/admin/projects/[id]/statuses/reorder/route.js +11 -0
  60. package/dist/api/admin/projects/[id]/statuses/reorder/route.js.map +1 -0
  61. package/dist/api/admin/projects/[id]/statuses/route.d.ts +4 -0
  62. package/dist/api/admin/projects/[id]/statuses/route.d.ts.map +1 -0
  63. package/dist/api/admin/projects/[id]/statuses/route.js +23 -0
  64. package/dist/api/admin/projects/[id]/statuses/route.js.map +1 -0
  65. package/dist/api/admin/projects/[id]/task-lists/route.d.ts +4 -0
  66. package/dist/api/admin/projects/[id]/task-lists/route.d.ts.map +1 -0
  67. package/dist/api/admin/projects/[id]/task-lists/route.js +18 -0
  68. package/dist/api/admin/projects/[id]/task-lists/route.js.map +1 -0
  69. package/dist/api/admin/projects/by-identifier/[identifier]/route.d.ts +3 -0
  70. package/dist/api/admin/projects/by-identifier/[identifier]/route.d.ts.map +1 -0
  71. package/dist/api/admin/projects/by-identifier/[identifier]/route.js +15 -0
  72. package/dist/api/admin/projects/by-identifier/[identifier]/route.js.map +1 -0
  73. package/dist/api/admin/projects/check-identifier/[identifier]/route.d.ts +3 -0
  74. package/dist/api/admin/projects/check-identifier/[identifier]/route.d.ts.map +1 -0
  75. package/dist/api/admin/projects/check-identifier/[identifier]/route.js +11 -0
  76. package/dist/api/admin/projects/check-identifier/[identifier]/route.js.map +1 -0
  77. package/dist/api/admin/projects/route.d.ts +4 -0
  78. package/dist/api/admin/projects/route.d.ts.map +1 -0
  79. package/dist/api/admin/projects/route.js +35 -0
  80. package/dist/api/admin/projects/route.js.map +1 -0
  81. package/dist/api/admin/projects/suggest-identifier/route.d.ts +3 -0
  82. package/dist/api/admin/projects/suggest-identifier/route.d.ts.map +1 -0
  83. package/dist/api/admin/projects/suggest-identifier/route.js +7 -0
  84. package/dist/api/admin/projects/suggest-identifier/route.js.map +1 -0
  85. package/dist/api/admin/sprints/[id]/route.d.ts +5 -0
  86. package/dist/api/admin/sprints/[id]/route.d.ts.map +1 -0
  87. package/dist/api/admin/sprints/[id]/route.js +41 -0
  88. package/dist/api/admin/sprints/[id]/route.js.map +1 -0
  89. package/dist/api/admin/sprints/route.d.ts +4 -0
  90. package/dist/api/admin/sprints/route.d.ts.map +1 -0
  91. package/dist/api/admin/sprints/route.js +25 -0
  92. package/dist/api/admin/sprints/route.js.map +1 -0
  93. package/dist/api/admin/task-lists/[id]/route.d.ts +4 -0
  94. package/dist/api/admin/task-lists/[id]/route.d.ts.map +1 -0
  95. package/dist/api/admin/task-lists/[id]/route.js +12 -0
  96. package/dist/api/admin/task-lists/[id]/route.js.map +1 -0
  97. package/dist/api/admin/users/route.d.ts +3 -0
  98. package/dist/api/admin/users/route.d.ts.map +1 -0
  99. package/dist/api/admin/users/route.js +9 -0
  100. package/dist/api/admin/users/route.js.map +1 -0
  101. package/dist/api/admin/workspaces/route.d.ts +4 -0
  102. package/dist/api/admin/workspaces/route.d.ts.map +1 -0
  103. package/dist/api/admin/workspaces/route.js +19 -0
  104. package/dist/api/admin/workspaces/route.js.map +1 -0
  105. package/dist/api/auth/login/route.d.ts +3 -0
  106. package/dist/api/auth/login/route.d.ts.map +1 -0
  107. package/dist/api/auth/login/route.js +16 -0
  108. package/dist/api/auth/login/route.js.map +1 -0
  109. package/dist/api/auth/register/route.d.ts +3 -0
  110. package/dist/api/auth/register/route.d.ts.map +1 -0
  111. package/dist/api/auth/register/route.js +18 -0
  112. package/dist/api/auth/register/route.js.map +1 -0
  113. package/dist/index.d.ts +9 -0
  114. package/dist/index.d.ts.map +1 -0
  115. package/dist/index.js +12 -0
  116. package/dist/index.js.map +1 -0
  117. package/dist/links/issue-project.d.ts +3 -0
  118. package/dist/links/issue-project.d.ts.map +1 -0
  119. package/dist/links/issue-project.js +5 -0
  120. package/dist/links/issue-project.js.map +1 -0
  121. package/dist/links/issue-sprint.d.ts +3 -0
  122. package/dist/links/issue-sprint.d.ts.map +1 -0
  123. package/dist/links/issue-sprint.js +5 -0
  124. package/dist/links/issue-sprint.js.map +1 -0
  125. package/dist/links/project-workspace.d.ts +3 -0
  126. package/dist/links/project-workspace.d.ts.map +1 -0
  127. package/dist/links/project-workspace.js +5 -0
  128. package/dist/links/project-workspace.js.map +1 -0
  129. package/dist/package.json +1 -0
  130. package/dist/subscribers/comment-created.d.ts +10 -0
  131. package/dist/subscribers/comment-created.d.ts.map +1 -0
  132. package/dist/subscribers/comment-created.js +25 -0
  133. package/dist/subscribers/comment-created.js.map +1 -0
  134. package/dist/subscribers/issue-assigned.d.ts +11 -0
  135. package/dist/subscribers/issue-assigned.d.ts.map +1 -0
  136. package/dist/subscribers/issue-assigned.js +15 -0
  137. package/dist/subscribers/issue-assigned.js.map +1 -0
  138. package/dist/subscribers/issue-created.d.ts +13 -0
  139. package/dist/subscribers/issue-created.d.ts.map +1 -0
  140. package/dist/subscribers/issue-created.js +17 -0
  141. package/dist/subscribers/issue-created.js.map +1 -0
  142. package/dist/utils/upload.d.ts +8 -0
  143. package/dist/utils/upload.d.ts.map +1 -0
  144. package/dist/utils/upload.js +22 -0
  145. package/dist/utils/upload.js.map +1 -0
  146. package/dist/workflows/assign-issue.d.ts +7 -0
  147. package/dist/workflows/assign-issue.d.ts.map +1 -0
  148. package/dist/workflows/assign-issue.js +39 -0
  149. package/dist/workflows/assign-issue.js.map +1 -0
  150. package/dist/workflows/complete-sprint.d.ts +7 -0
  151. package/dist/workflows/complete-sprint.d.ts.map +1 -0
  152. package/dist/workflows/complete-sprint.js +43 -0
  153. package/dist/workflows/complete-sprint.js.map +1 -0
  154. package/dist/workflows/create-issue.d.ts +19 -0
  155. package/dist/workflows/create-issue.d.ts.map +1 -0
  156. package/dist/workflows/create-issue.js +41 -0
  157. package/dist/workflows/create-issue.js.map +1 -0
  158. package/dist/workflows/create-project.d.ts +21 -0
  159. package/dist/workflows/create-project.d.ts.map +1 -0
  160. package/dist/workflows/create-project.js +80 -0
  161. package/dist/workflows/create-project.js.map +1 -0
  162. package/dist/workflows/emit-event.d.ts +3 -0
  163. package/dist/workflows/emit-event.d.ts.map +1 -0
  164. package/dist/workflows/emit-event.js +6 -0
  165. package/dist/workflows/emit-event.js.map +1 -0
  166. package/dist/workflows/update-issue-status.d.ts +7 -0
  167. package/dist/workflows/update-issue-status.d.ts.map +1 -0
  168. package/dist/workflows/update-issue-status.js +38 -0
  169. package/dist/workflows/update-issue-status.js.map +1 -0
  170. package/package.json +46 -0
@@ -0,0 +1,3 @@
1
+ import type { Response } from "express";
2
+ export declare const GET: (req: any, res: Response) => Promise<void>;
3
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/api/admin/issues/[id]/activities/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvC,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAKhD,CAAA"}
@@ -0,0 +1,7 @@
1
+ export const GET = async (req, res) => {
2
+ const activityService = req.scope.resolve("activityModuleService");
3
+ const activities = await activityService.listActivityForEntity("issue", req.params.id);
4
+ activities.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
5
+ res.json({ activities });
6
+ };
7
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../src/api/admin/issues/[id]/activities/route.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACnD,MAAM,eAAe,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,uBAAuB,CAAQ,CAAA;IACzE,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC,qBAAqB,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IACtF,UAAU,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,CAAM,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;IACxG,GAAG,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC,CAAA;AAC1B,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { Response } from "express";
2
+ export declare const DELETE: (req: any, res: Response) => Promise<void>;
3
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/api/admin/issues/[id]/attachments/[attachmentId]/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAIvC,eAAO,MAAM,MAAM,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAOnD,CAAA"}
@@ -0,0 +1,11 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ export const DELETE = async (req, res) => {
4
+ const issueService = req.scope.resolve("issueModuleService");
5
+ const attachment = await issueService.deleteAttachment(req.params.attachmentId);
6
+ const rootDir = req.scope.resolve("config")?.rootDir ?? process.cwd();
7
+ const filePath = path.join(rootDir, "uploads", "issue-attachments", attachment.filename);
8
+ await fs.unlink(filePath).catch(() => { });
9
+ res.json({ attachment });
10
+ };
11
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../../src/api/admin/issues/[id]/attachments/[attachmentId]/route.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACjC,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACtD,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAQ,CAAA;IACnE,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;IAC/E,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;IACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;IACxF,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IACzC,GAAG,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC,CAAA;AAC1B,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { Response } from "express";
2
+ export declare const GET: (req: any, res: Response) => Promise<void>;
3
+ export declare const POST: (req: any, res: Response) => Promise<void>;
4
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/api/admin/issues/[id]/attachments/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAYvC,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAIhD,CAAA;AAED,eAAO,MAAM,IAAI,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAyBjD,CAAA"}
@@ -0,0 +1,40 @@
1
+ import path from "node:path";
2
+ import { mkdirSync } from "node:fs";
3
+ import { createUpload } from "../../../../../utils/upload.js";
4
+ function getUploadDir(req) {
5
+ const rootDir = req.scope.resolve("config")?.rootDir ?? process.cwd();
6
+ const uploadDir = path.join(rootDir, "uploads", "issue-attachments");
7
+ mkdirSync(uploadDir, { recursive: true });
8
+ return uploadDir;
9
+ }
10
+ export const GET = async (req, res) => {
11
+ const issueService = req.scope.resolve("issueModuleService");
12
+ const attachments = await issueService.listAttachmentsByIssue(req.params.id);
13
+ res.json({ attachments });
14
+ };
15
+ export const POST = async (req, res) => {
16
+ const uploadDir = getUploadDir(req);
17
+ const upload = createUpload(uploadDir);
18
+ await new Promise((resolve, reject) => {
19
+ upload.single("file")(req, res, (err) => err ? reject(err) : resolve());
20
+ });
21
+ if (!req.file) {
22
+ res.status(400).json({ error: { message: "No file uploaded. Use multipart/form-data with field name 'file'." } });
23
+ return;
24
+ }
25
+ const issueService = req.scope.resolve("issueModuleService");
26
+ const issue = await issueService.retrieveIssue(req.params.id).catch(() => null);
27
+ if (!issue) {
28
+ res.status(404).json({ error: { message: "Issue not found." } });
29
+ return;
30
+ }
31
+ const attachment = await issueService.createAttachment({
32
+ issue_id: req.params.id, comment_id: req.body?.comment_id || null,
33
+ filename: req.file.filename, original_name: req.file.originalname,
34
+ mime_type: req.file.mimetype, size: req.file.size,
35
+ url: `/uploads/issue-attachments/${req.file.filename}`,
36
+ uploader_id: req.user?.id ?? "system", workspace_id: issue.workspace_id,
37
+ });
38
+ res.status(201).json({ attachment });
39
+ };
40
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../src/api/admin/issues/[id]/attachments/route.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Response } from "express";
2
+ export declare const GET: (req: any, res: Response) => Promise<void>;
3
+ export declare const POST: (req: any, res: Response) => Promise<void>;
4
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/api/admin/issues/[id]/comments/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvC,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAIhD,CAAA;AAED,eAAO,MAAM,IAAI,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAajD,CAAA"}
@@ -0,0 +1,20 @@
1
+ export const GET = async (req, res) => {
2
+ const issueService = req.scope.resolve("issueModuleService");
3
+ const comments = await issueService.listCommentsByIssue(req.params.id);
4
+ res.json({ comments });
5
+ };
6
+ export const POST = async (req, res) => {
7
+ const issueService = req.scope.resolve("issueModuleService");
8
+ const eventBus = req.scope.resolve("eventBus");
9
+ const { body } = req.body;
10
+ if (!body || typeof body !== "string" || body.trim().length === 0) {
11
+ res.status(400).json({ error: { message: "body is required" } });
12
+ return;
13
+ }
14
+ const comment = await issueService.createComment({
15
+ issue_id: req.params.id, body: body.trim(), author_id: req.user?.id ?? "system",
16
+ });
17
+ eventBus.emit({ name: "comment.created", data: { comment_id: comment.id, issue_id: req.params.id, author_id: comment.author_id } }).catch(() => { });
18
+ res.status(201).json({ comment });
19
+ };
20
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../src/api/admin/issues/[id]/comments/route.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACnD,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAQ,CAAA;IACnE,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IACtE,GAAG,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAA;AACxB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,IAAI,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACpD,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAQ,CAAA;IACnE,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAQ,CAAA;IACrD,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC,IAAI,CAAA;IACzB,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAA;QAChE,OAAM;IACR,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,aAAa,CAAC;QAC/C,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,QAAQ;KAChF,CAAC,CAAA;IACF,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IACnJ,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAA;AACnC,CAAC,CAAA"}
@@ -0,0 +1,5 @@
1
+ import type { Response } from "express";
2
+ export declare const GET: (req: any, res: Response) => Promise<void>;
3
+ export declare const PUT: (req: any, res: Response) => Promise<void>;
4
+ export declare const DELETE: (req: any, res: Response) => Promise<void>;
5
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../src/api/admin/issues/[id]/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAIvC,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAIhD,CAAA;AAED,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAmDhD,CAAA;AAED,eAAO,MAAM,MAAM,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAInD,CAAA"}
@@ -0,0 +1,70 @@
1
+ import { updateIssueStatusWorkflow } from "../../../../workflows/update-issue-status.js";
2
+ import { assignIssueWorkflow } from "../../../../workflows/assign-issue.js";
3
+ export const GET = async (req, res) => {
4
+ const issueService = req.scope.resolve("issueModuleService");
5
+ const issue = await issueService.retrieveIssue(req.params.id);
6
+ res.json({ issue });
7
+ };
8
+ export const PUT = async (req, res) => {
9
+ const issueService = req.scope.resolve("issueModuleService");
10
+ const activityService = req.scope.resolve("activityModuleService");
11
+ const allowed = ["title", "description", "status", "priority", "type",
12
+ "assignee_ids", "parent_id", "sprint_id", "task_list_id", "due_date", "estimate"];
13
+ const updates = {};
14
+ for (const field of allowed) {
15
+ if (req.body[field] !== undefined)
16
+ updates[field] = req.body[field];
17
+ }
18
+ if (updates.due_date)
19
+ updates.due_date = new Date(updates.due_date);
20
+ if (updates.status !== undefined) {
21
+ const { result: issue, errors, transaction_status } = await updateIssueStatusWorkflow(req.scope).run({
22
+ input: { issueId: req.params.id, status: updates.status, actor_id: req.user?.id ?? null },
23
+ });
24
+ if (transaction_status === "reverted") {
25
+ const err = errors[0];
26
+ res.status(err.status ?? 500).json({ error: { message: err.message } });
27
+ return;
28
+ }
29
+ delete updates.status;
30
+ if (Object.keys(updates).length === 0) {
31
+ res.json({ issue });
32
+ return;
33
+ }
34
+ const finalIssue = await issueService.updateIssue(req.params.id, updates);
35
+ res.json({ issue: finalIssue });
36
+ return;
37
+ }
38
+ if ("assignee_ids" in updates) {
39
+ const { result: issue, errors, transaction_status } = await assignIssueWorkflow(req.scope).run({
40
+ input: { issueId: req.params.id, assignee_ids: Array.isArray(updates.assignee_ids) ? updates.assignee_ids : [], actor_id: req.user?.id ?? null },
41
+ });
42
+ if (transaction_status === "reverted") {
43
+ const err = errors[0];
44
+ res.status(err.status ?? 500).json({ error: { message: err.message } });
45
+ return;
46
+ }
47
+ delete updates.assignee_ids;
48
+ if (Object.keys(updates).length === 0) {
49
+ res.json({ issue });
50
+ return;
51
+ }
52
+ const finalIssue = await issueService.updateIssue(req.params.id, updates);
53
+ res.json({ issue: finalIssue });
54
+ return;
55
+ }
56
+ const currentIssue = await issueService.retrieveIssue(req.params.id);
57
+ const issue = await issueService.updateIssue(req.params.id, updates);
58
+ await activityService.recordActivity({
59
+ entity_type: "issue", entity_id: req.params.id,
60
+ actor_id: req.user?.id ?? "system", action: "updated", workspace_id: issue.workspace_id,
61
+ changes: Object.fromEntries(Object.keys(updates).map(k => [k, { from: currentIssue[k], to: updates[k] }])),
62
+ }).catch(() => { });
63
+ res.json({ issue });
64
+ };
65
+ export const DELETE = async (req, res) => {
66
+ const issueService = req.scope.resolve("issueModuleService");
67
+ await issueService.deleteIssue(req.params.id);
68
+ res.status(204).send();
69
+ };
70
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../src/api/admin/issues/[id]/route.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,8CAA8C,CAAA;AACxF,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAA;AAE3E,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACnD,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAQ,CAAA;IACnE,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IAC7D,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;AACrB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACnD,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAQ,CAAA;IACnE,MAAM,eAAe,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,uBAAuB,CAAQ,CAAA;IACzE,MAAM,OAAO,GAAG,CAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM;QACpD,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,UAAU,CAAC,CAAA;IAClG,MAAM,OAAO,GAA4B,EAAE,CAAA;IAC3C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,SAAS;YAAE,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACrE,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ;QAAE,OAAO,CAAC,QAAQ,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,QAAkB,CAAC,CAAA;IAE7E,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,GAAG,MAAM,yBAAyB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC;YACnG,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAgB,EAAE,QAAQ,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,IAAI,EAAE;SACpG,CAAC,CAAA;QACF,IAAI,kBAAkB,KAAK,UAAU,EAAE,CAAC;YACtC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;YACrB,GAAG,CAAC,MAAM,CAAE,GAAW,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;YAChF,OAAM;QACR,CAAC;QACD,OAAO,OAAO,CAAC,MAAM,CAAA;QACrB,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAAC,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YAAC,OAAM;QAAC,CAAC;QACtE,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;QACzE,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAA;QAC/B,OAAM;IACR,CAAC;IAED,IAAI,cAAc,IAAI,OAAO,EAAE,CAAC;QAC9B,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,GAAG,MAAM,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC;YAC7F,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,YAAwB,CAAC,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,IAAI,EAAE;SAC7J,CAAC,CAAA;QACF,IAAI,kBAAkB,KAAK,UAAU,EAAE,CAAC;YACtC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;YACrB,GAAG,CAAC,MAAM,CAAE,GAAW,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;YAChF,OAAM;QACR,CAAC;QACD,OAAO,OAAO,CAAC,YAAY,CAAA;QAC3B,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAAC,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YAAC,OAAM;QAAC,CAAC;QACtE,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;QACzE,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAA;QAC/B,OAAM;IACR,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IACpE,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IACpE,MAAM,eAAe,CAAC,cAAc,CAAC;QACnC,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE;QAC9C,QAAQ,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY;QACvF,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAG,YAAoB,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;KACpH,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IAClB,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;AACrB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACtD,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAQ,CAAA;IACnE,MAAM,YAAY,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IAC7C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;AACxB,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { Response } from "express";
2
+ export declare const DELETE: (req: any, res: Response) => Promise<void>;
3
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/api/admin/issues/[id]/time-logs/[logId]/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvC,eAAO,MAAM,MAAM,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAInD,CAAA"}
@@ -0,0 +1,6 @@
1
+ export const DELETE = async (req, res) => {
2
+ const issueService = req.scope.resolve("issueModuleService");
3
+ const entry = await issueService.deleteTimeLog(req.params.logId);
4
+ res.json({ time_log: entry });
5
+ };
6
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../../src/api/admin/issues/[id]/time-logs/[logId]/route.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACtD,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAQ,CAAA;IACnE,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAChE,GAAG,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAA;AAC/B,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { Response } from "express";
2
+ export declare const GET: (req: any, res: Response) => Promise<void>;
3
+ export declare const POST: (req: any, res: Response) => Promise<void>;
4
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/api/admin/issues/[id]/time-logs/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvC,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAKhD,CAAA;AAED,eAAO,MAAM,IAAI,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAejD,CAAA"}
@@ -0,0 +1,26 @@
1
+ export const GET = async (req, res) => {
2
+ const issueService = req.scope.resolve("issueModuleService");
3
+ const logs = await issueService.listTimeLogsByIssue(req.params.id);
4
+ const total_minutes = logs.reduce((sum, log) => sum + (log.duration_minutes ?? 0), 0);
5
+ res.json({ time_logs: logs, total_minutes });
6
+ };
7
+ export const POST = async (req, res) => {
8
+ const issueService = req.scope.resolve("issueModuleService");
9
+ const { duration_minutes, description, logged_date } = req.body;
10
+ if (typeof duration_minutes !== "number" || duration_minutes <= 0) {
11
+ res.status(400).json({ error: { message: "duration_minutes must be a positive number." } });
12
+ return;
13
+ }
14
+ const issue = await issueService.retrieveIssue(req.params.id).catch(() => null);
15
+ if (!issue) {
16
+ res.status(404).json({ error: { message: "Issue not found." } });
17
+ return;
18
+ }
19
+ const entry = await issueService.createManualTimeLog({
20
+ issue_id: req.params.id, user_id: req.user?.id ?? "system", workspace_id: issue.workspace_id,
21
+ duration_minutes, description: description ?? null,
22
+ logged_date: logged_date ? new Date(logged_date) : undefined,
23
+ });
24
+ res.status(201).json({ time_log: entry });
25
+ };
26
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../src/api/admin/issues/[id]/time-logs/route.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACnD,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAQ,CAAA;IACnE,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IAClE,MAAM,aAAa,GAAI,IAAc,CAAC,MAAM,CAAC,CAAC,GAAW,EAAE,GAAQ,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC7G,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAA;AAC9C,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,IAAI,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACpD,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAQ,CAAA;IACnE,MAAM,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC,IAAI,CAAA;IAC/D,IAAI,OAAO,gBAAgB,KAAK,QAAQ,IAAI,gBAAgB,IAAI,CAAC,EAAE,CAAC;QAClE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,6CAA6C,EAAE,EAAE,CAAC,CAAA;QAC3F,OAAM;IACR,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;IAC/E,IAAI,CAAC,KAAK,EAAE,CAAC;QAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC;QAAC,OAAM;IAAC,CAAC;IACxF,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,mBAAmB,CAAC;QACnD,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,QAAQ,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY;QAC5F,gBAAgB,EAAE,WAAW,EAAE,WAAW,IAAI,IAAI;QAClD,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS;KAC7D,CAAC,CAAA;IACF,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAA;AAC3C,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { Response } from "express";
2
+ export declare const GET: (req: any, res: Response) => Promise<void>;
3
+ export declare const POST: (req: any, res: Response) => Promise<void>;
4
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/api/admin/issues/[id]/time-logs/timer/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvC,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAIhD,CAAA;AAED,eAAO,MAAM,IAAI,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAgBjD,CAAA"}
@@ -0,0 +1,26 @@
1
+ export const GET = async (req, res) => {
2
+ const issueService = req.scope.resolve("issueModuleService");
3
+ const active = await issueService.getActiveTimer(req.params.id, req.user?.id ?? "system");
4
+ res.json({ active_timer: active ?? null });
5
+ };
6
+ export const POST = async (req, res) => {
7
+ const issueService = req.scope.resolve("issueModuleService");
8
+ const { action } = req.body;
9
+ if (action !== "start" && action !== "stop") {
10
+ res.status(400).json({ error: { message: "action must be 'start' or 'stop'." } });
11
+ return;
12
+ }
13
+ if (action === "start") {
14
+ const issue = await issueService.retrieveIssue(req.params.id).catch(() => null);
15
+ if (!issue) {
16
+ res.status(404).json({ error: { message: "Issue not found." } });
17
+ return;
18
+ }
19
+ const entry = await issueService.startTimer(req.params.id, req.user?.id ?? "system", issue.workspace_id);
20
+ res.status(201).json({ time_log: entry });
21
+ return;
22
+ }
23
+ const entry = await issueService.stopTimer(req.params.id, req.user?.id ?? "system");
24
+ res.json({ time_log: entry });
25
+ };
26
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../../src/api/admin/issues/[id]/time-logs/timer/route.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACnD,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAQ,CAAA;IACnE,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,QAAQ,CAAC,CAAA;IACzF,GAAG,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,MAAM,IAAI,IAAI,EAAE,CAAC,CAAA;AAC5C,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,IAAI,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACpD,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAQ,CAAA;IACnE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,IAAI,CAAA;IAC3B,IAAI,MAAM,KAAK,OAAO,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QAC5C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,mCAAmC,EAAE,EAAE,CAAC,CAAA;QACjF,OAAM;IACR,CAAC;IACD,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;QAC/E,IAAI,CAAC,KAAK,EAAE,CAAC;YAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC;YAAC,OAAM;QAAC,CAAC;QACxF,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,CAAA;QACxG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAA;QACzC,OAAM;IACR,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,QAAQ,CAAC,CAAA;IACnF,GAAG,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAA;AAC/B,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { Response } from "express";
2
+ export declare const GET: (req: any, res: Response) => Promise<void>;
3
+ export declare const POST: (req: any, res: Response) => Promise<void>;
4
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../src/api/admin/issues/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAGvC,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAchD,CAAA;AAED,eAAO,MAAM,IAAI,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAwBjD,CAAA"}
@@ -0,0 +1,48 @@
1
+ import { createIssueWorkflow } from "../../../workflows/create-issue.js";
2
+ export const GET = async (req, res) => {
3
+ const issueService = req.scope.resolve("issueModuleService");
4
+ const limit = Math.min(Number(req.query.limit) || 50, 200);
5
+ const offset = Number(req.query.offset) || 0;
6
+ const filters = {};
7
+ if (req.query.project_id)
8
+ filters.project_id = req.query.project_id;
9
+ if (req.query.status)
10
+ filters.status = req.query.status;
11
+ if (req.query.type)
12
+ filters.type = req.query.type;
13
+ if (req.query.sprint_id === "none")
14
+ filters.sprint_id = null;
15
+ else if (req.query.sprint_id)
16
+ filters.sprint_id = req.query.sprint_id;
17
+ if (req.query.task_list_id === "none")
18
+ filters.task_list_id = null;
19
+ else if (req.query.task_list_id)
20
+ filters.task_list_id = req.query.task_list_id;
21
+ const [issues, count] = await issueService.listAndCountIssues(filters, { limit, offset });
22
+ res.json({ issues, count, limit, offset });
23
+ };
24
+ export const POST = async (req, res) => {
25
+ const { title, project_id, workspace_id, description, type, priority, status, assignee_ids, reporter_id, parent_id, due_date, estimate, sprint_id, task_list_id } = req.body;
26
+ if (!title || !project_id || !workspace_id) {
27
+ res.status(400).json({ error: { message: "title, project_id and workspace_id are required" } });
28
+ return;
29
+ }
30
+ const { result: issue, errors, transaction_status } = await createIssueWorkflow(req.scope).run({
31
+ input: {
32
+ title, project_id, workspace_id, description, type, priority, status,
33
+ assignee_ids: Array.isArray(assignee_ids) ? assignee_ids : null,
34
+ reporter_id: reporter_id ?? (req.user?.id ?? null),
35
+ parent_id: parent_id ?? null,
36
+ due_date: due_date ? new Date(due_date) : undefined,
37
+ estimate: estimate ?? null, sprint_id: sprint_id ?? null, task_list_id: task_list_id ?? null,
38
+ actor_id: req.user?.id ?? null,
39
+ },
40
+ });
41
+ if (transaction_status === "reverted") {
42
+ const err = errors[0];
43
+ res.status(err.status ?? 500).json({ error: { message: err.message } });
44
+ return;
45
+ }
46
+ res.status(201).json({ issue });
47
+ };
48
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../src/api/admin/issues/route.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Response } from "express";
2
+ export declare const POST: (req: any, res: Response) => Promise<void>;
3
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/api/admin/notifications/[id]/read/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvC,eAAO,MAAM,IAAI,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAIjD,CAAA"}
@@ -0,0 +1,6 @@
1
+ export const POST = async (req, res) => {
2
+ const notifService = req.scope.resolve("notificationModuleService");
3
+ const notification = await notifService.markAsRead(req.params.id);
4
+ res.json({ notification });
5
+ };
6
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../src/api/admin/notifications/[id]/read/route.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,IAAI,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACpD,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,2BAA2B,CAAQ,CAAA;IAC1E,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IACjE,GAAG,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,CAAC,CAAA;AAC5B,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { Response } from "express";
2
+ export declare const POST: (req: any, res: Response) => Promise<void>;
3
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../src/api/admin/notifications/read-all/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvC,eAAO,MAAM,IAAI,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAMjD,CAAA"}
@@ -0,0 +1,11 @@
1
+ export const POST = async (req, res) => {
2
+ const notifService = req.scope.resolve("notificationModuleService");
3
+ const userId = req.user?.id;
4
+ if (!userId) {
5
+ res.status(401).json({ error: { message: "Unauthorized" } });
6
+ return;
7
+ }
8
+ await notifService.markAllAsRead(userId);
9
+ res.json({ ok: true });
10
+ };
11
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../src/api/admin/notifications/read-all/route.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,IAAI,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACpD,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,2BAA2B,CAAQ,CAAA;IAC1E,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,EAAE,CAAA;IAC3B,IAAI,CAAC,MAAM,EAAE,CAAC;QAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC;QAAC,OAAM;IAAC,CAAC;IACrF,MAAM,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,CAAA;IACxC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;AACxB,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { Response } from "express";
2
+ export declare const GET: (req: any, res: Response) => Promise<void>;
3
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../src/api/admin/notifications/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvC,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAShD,CAAA"}
@@ -0,0 +1,14 @@
1
+ export const GET = async (req, res) => {
2
+ const notifService = req.scope.resolve("notificationModuleService");
3
+ const userId = req.user?.id;
4
+ if (!userId) {
5
+ res.status(401).json({ error: { message: "Unauthorized" } });
6
+ return;
7
+ }
8
+ const limit = Math.min(Number(req.query.limit) || 20, 100);
9
+ const offset = Number(req.query.offset) || 0;
10
+ const unreadOnly = req.query.unread === "true";
11
+ const [notifications, count] = await notifService.listNotificationsForUser(userId, { limit, offset, unreadOnly });
12
+ res.json({ notifications, count, limit, offset });
13
+ };
14
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../src/api/admin/notifications/route.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACnD,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,2BAA2B,CAAQ,CAAA;IAC1E,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,EAAE,CAAA;IAC3B,IAAI,CAAC,MAAM,EAAE,CAAC;QAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC;QAAC,OAAM;IAAC,CAAC;IACrF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAA;IAC1D,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC5C,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAA;IAC9C,MAAM,CAAC,aAAa,EAAE,KAAK,CAAC,GAAG,MAAM,YAAY,CAAC,wBAAwB,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAA;IACjH,GAAG,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;AACnD,CAAC,CAAA"}
@@ -0,0 +1,5 @@
1
+ import type { Response } from "express";
2
+ export declare const GET: (req: any, res: Response) => Promise<void>;
3
+ export declare const PUT: (req: any, res: Response) => Promise<void>;
4
+ export declare const DELETE: (req: any, res: Response) => Promise<void>;
5
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../src/api/admin/projects/[id]/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvC,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAIhD,CAAA;AAED,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAkBhD,CAAA;AAED,eAAO,MAAM,MAAM,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAInD,CAAA"}
@@ -0,0 +1,36 @@
1
+ export const GET = async (req, res) => {
2
+ const projectService = req.scope.resolve("projectModuleService");
3
+ const project = await projectService.retrieveProject(req.params.id);
4
+ res.json({ project });
5
+ };
6
+ export const PUT = async (req, res) => {
7
+ const projectService = req.scope.resolve("projectModuleService");
8
+ const activityService = req.scope.resolve("activityModuleService");
9
+ const { name, description, status, visibility, icon, color } = req.body;
10
+ const updates = {};
11
+ if (name !== undefined)
12
+ updates.name = name;
13
+ if (description !== undefined)
14
+ updates.description = description;
15
+ if (status !== undefined)
16
+ updates.status = status;
17
+ if (visibility !== undefined)
18
+ updates.visibility = visibility;
19
+ if (icon !== undefined)
20
+ updates.icon = icon;
21
+ if (color !== undefined)
22
+ updates.color = color;
23
+ const project = await projectService.updateProject(req.params.id, updates);
24
+ await activityService.recordActivity({
25
+ entity_type: "project", entity_id: req.params.id,
26
+ actor_id: req.user?.id ?? "system", action: "updated", workspace_id: project.workspace_id,
27
+ changes: Object.fromEntries(Object.keys(updates).map(k => [k, { to: updates[k] }])),
28
+ }).catch(() => { });
29
+ res.json({ project });
30
+ };
31
+ export const DELETE = async (req, res) => {
32
+ const projectService = req.scope.resolve("projectModuleService");
33
+ await projectService.deleteProject(req.params.id);
34
+ res.status(204).send();
35
+ };
36
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../src/api/admin/projects/[id]/route.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACnD,MAAM,cAAc,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,sBAAsB,CAAQ,CAAA;IACvE,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IACnE,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAA;AACvB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACnD,MAAM,cAAc,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,sBAAsB,CAAQ,CAAA;IACvE,MAAM,eAAe,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,uBAAuB,CAAQ,CAAA;IACzE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,IAAI,CAAA;IACvE,MAAM,OAAO,GAA4B,EAAE,CAAA;IAC3C,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,CAAC,IAAI,GAAG,IAAI,CAAA;IAC3C,IAAI,WAAW,KAAK,SAAS;QAAE,OAAO,CAAC,WAAW,GAAG,WAAW,CAAA;IAChE,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,CAAC,MAAM,GAAG,MAAM,CAAA;IACjD,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,CAAC,UAAU,GAAG,UAAU,CAAA;IAC7D,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,CAAC,IAAI,GAAG,IAAI,CAAA;IAC3C,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,CAAC,KAAK,GAAG,KAAK,CAAA;IAC9C,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IAC1E,MAAM,eAAe,CAAC,cAAc,CAAC;QACnC,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE;QAChD,QAAQ,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY;QACzF,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;KACpF,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IAClB,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAA;AACvB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACtD,MAAM,cAAc,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,sBAAsB,CAAQ,CAAA;IACvE,MAAM,cAAc,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IACjD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;AACxB,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { Response } from "express";
2
+ export declare const PUT: (req: any, res: Response) => Promise<void>;
3
+ export declare const DELETE: (req: any, res: Response) => Promise<void>;
4
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/api/admin/projects/[id]/statuses/[statusId]/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvC,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAKhD,CAAA;AAED,eAAO,MAAM,MAAM,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAanD,CAAA"}
@@ -0,0 +1,24 @@
1
+ export const PUT = async (req, res) => {
2
+ const { name, color, category } = req.body;
3
+ const svc = req.scope.resolve("projectModuleService");
4
+ const updated = await svc.updateProjectStatus(req.params.statusId, { name, color, category });
5
+ res.json({ status: updated });
6
+ };
7
+ export const DELETE = async (req, res) => {
8
+ const svc = req.scope.resolve("projectModuleService");
9
+ const issueSvc = req.scope.resolve("issueModuleService");
10
+ const statuses = await svc.listStatusesByProject(req.params.id);
11
+ const target = statuses.find((s) => s.id === req.params.statusId);
12
+ if (!target) {
13
+ res.status(404).json({ error: { message: "Status not found" } });
14
+ return;
15
+ }
16
+ const [, count] = await issueSvc.listAndCountIssues({ project_id: req.params.id, status: target.key }, { limit: 1, offset: 0 });
17
+ if (count > 0) {
18
+ res.status(409).json({ error: { message: `Cannot delete status "${target.name}": ${count} issue(s) still use it` } });
19
+ return;
20
+ }
21
+ await svc.deleteProjectStatus(req.params.statusId);
22
+ res.status(204).send();
23
+ };
24
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../../src/api/admin/projects/[id]/statuses/[statusId]/route.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACnD,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC,IAAI,CAAA;IAC1C,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,sBAAsB,CAAQ,CAAA;IAC5D,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAA;IAC7F,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;AAC/B,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACtD,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,sBAAsB,CAAQ,CAAA;IAC5D,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAQ,CAAA;IAC/D,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IAC/D,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IACtE,IAAI,CAAC,MAAM,EAAE,CAAC;QAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC;QAAC,OAAM;IAAC,CAAC;IACzF,MAAM,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,QAAQ,CAAC,kBAAkB,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAA;IAC/H,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,yBAAyB,MAAM,CAAC,IAAI,MAAM,KAAK,wBAAwB,EAAE,EAAE,CAAC,CAAA;QACrH,OAAM;IACR,CAAC;IACD,MAAM,GAAG,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IAClD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;AACxB,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { Response } from "express";
2
+ export declare const POST: (req: any, res: Response) => Promise<void>;
3
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/api/admin/projects/[id]/statuses/reorder/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvC,eAAO,MAAM,IAAI,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBASjD,CAAA"}