@oneuptime/common 9.2.11 → 9.2.14

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 (193) hide show
  1. package/Models/DatabaseModels/AlertInternalNote.ts +29 -0
  2. package/Models/DatabaseModels/IncidentInternalNote.ts +29 -0
  3. package/Models/DatabaseModels/IncidentPublicNote.ts +29 -0
  4. package/Models/DatabaseModels/Index.ts +3 -11
  5. package/Models/DatabaseModels/{CopilotPullRequest.ts → LlmProvider.ts} +243 -248
  6. package/Models/DatabaseModels/ScheduledMaintenanceInternalNote.ts +29 -0
  7. package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +29 -0
  8. package/Server/API/LlmProviderAPI.ts +57 -0
  9. package/Server/API/MicrosoftTeamsAPI.ts +2 -146
  10. package/Server/API/SlackAPI.ts +105 -0
  11. package/Server/API/StatusPageAPI.ts +6 -0
  12. package/Server/Infrastructure/Postgres/SchemaMigrations/1765477339178-MigrationName.ts +71 -0
  13. package/Server/Infrastructure/Postgres/SchemaMigrations/1765540325149-MigrationName.ts +45 -0
  14. package/Server/Infrastructure/Postgres/SchemaMigrations/1765540549739-MigrationName.ts +61 -0
  15. package/Server/Infrastructure/Postgres/SchemaMigrations/1765544010078-MigrationName.ts +35 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  17. package/Server/Middleware/SlackAuthorization.ts +4 -1
  18. package/Server/Services/AlertInternalNoteService.ts +26 -0
  19. package/Server/Services/IncidentInternalNoteService.ts +26 -0
  20. package/Server/Services/IncidentPublicNoteService.ts +26 -0
  21. package/Server/Services/Index.ts +2 -11
  22. package/Server/Services/LlmProviderService.ts +100 -0
  23. package/Server/Services/ScheduledMaintenanceInternalNoteService.ts +26 -0
  24. package/Server/Services/ScheduledMaintenancePublicNoteService.ts +26 -0
  25. package/Server/Services/StatusPageService.ts +3 -0
  26. package/Server/Utils/Express.ts +1 -0
  27. package/Server/Utils/StartServer.ts +5 -0
  28. package/Server/Utils/StatusPageResource.ts +89 -0
  29. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +96 -55
  30. package/Server/Utils/Workspace/Slack/Actions/ActionTypes.ts +16 -0
  31. package/Server/Utils/Workspace/Slack/Actions/Alert.ts +184 -1
  32. package/Server/Utils/Workspace/Slack/Actions/Incident.ts +224 -1
  33. package/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.ts +232 -1
  34. package/Server/Utils/Workspace/Slack/Slack.ts +113 -0
  35. package/Server/Utils/Workspace/Slack/app-manifest.json +13 -2
  36. package/Tests/Server/Utils/StatusPageResource.test.ts +161 -0
  37. package/Types/Icon/IconProp.ts +1 -0
  38. package/Types/LLM/Index.ts +4 -0
  39. package/Types/LLM/LlmType.ts +7 -0
  40. package/Types/Monitor/MonitorStep.ts +14 -0
  41. package/Types/Permission.ts +38 -113
  42. package/UI/Components/Icon/Icon.tsx +8 -0
  43. package/UI/Components/Link/Link.tsx +5 -1
  44. package/build/dist/Models/DatabaseModels/AlertInternalNote.js +30 -0
  45. package/build/dist/Models/DatabaseModels/AlertInternalNote.js.map +1 -1
  46. package/build/dist/Models/DatabaseModels/IncidentInternalNote.js +30 -0
  47. package/build/dist/Models/DatabaseModels/IncidentInternalNote.js.map +1 -1
  48. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +30 -0
  49. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
  50. package/build/dist/Models/DatabaseModels/Index.js +2 -10
  51. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  52. package/build/dist/Models/DatabaseModels/{CopilotPullRequest.js → LlmProvider.js} +263 -255
  53. package/build/dist/Models/DatabaseModels/LlmProvider.js.map +1 -0
  54. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceInternalNote.js +30 -0
  55. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceInternalNote.js.map +1 -1
  56. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +30 -0
  57. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
  58. package/build/dist/Server/API/LlmProviderAPI.js +36 -0
  59. package/build/dist/Server/API/LlmProviderAPI.js.map +1 -0
  60. package/build/dist/Server/API/MicrosoftTeamsAPI.js +2 -91
  61. package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
  62. package/build/dist/Server/API/SlackAPI.js +74 -0
  63. package/build/dist/Server/API/SlackAPI.js.map +1 -1
  64. package/build/dist/Server/API/StatusPageAPI.js +6 -0
  65. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  66. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1765477339178-MigrationName.js +30 -0
  67. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1765477339178-MigrationName.js.map +1 -0
  68. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1765540325149-MigrationName.js +22 -0
  69. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1765540325149-MigrationName.js.map +1 -0
  70. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1765540549739-MigrationName.js +39 -0
  71. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1765540549739-MigrationName.js.map +1 -0
  72. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1765544010078-MigrationName.js +18 -0
  73. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1765544010078-MigrationName.js.map +1 -0
  74. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  75. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  76. package/build/dist/Server/Middleware/SlackAuthorization.js +4 -1
  77. package/build/dist/Server/Middleware/SlackAuthorization.js.map +1 -1
  78. package/build/dist/Server/Services/AlertInternalNoteService.js +24 -0
  79. package/build/dist/Server/Services/AlertInternalNoteService.js.map +1 -1
  80. package/build/dist/Server/Services/IncidentInternalNoteService.js +24 -0
  81. package/build/dist/Server/Services/IncidentInternalNoteService.js.map +1 -1
  82. package/build/dist/Server/Services/IncidentPublicNoteService.js +24 -0
  83. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  84. package/build/dist/Server/Services/Index.js +2 -10
  85. package/build/dist/Server/Services/Index.js.map +1 -1
  86. package/build/dist/Server/Services/LlmProviderService.js +85 -0
  87. package/build/dist/Server/Services/LlmProviderService.js.map +1 -0
  88. package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js +24 -0
  89. package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js.map +1 -1
  90. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +24 -0
  91. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
  92. package/build/dist/Server/Services/StatusPageService.js +3 -0
  93. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  94. package/build/dist/Server/Utils/Express.js.map +1 -1
  95. package/build/dist/Server/Utils/StartServer.js +5 -0
  96. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  97. package/build/dist/Server/Utils/StatusPageResource.js +68 -0
  98. package/build/dist/Server/Utils/StatusPageResource.js.map +1 -0
  99. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +73 -42
  100. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  101. package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js +13 -0
  102. package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js.map +1 -1
  103. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js +143 -1
  104. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js.map +1 -1
  105. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js +173 -1
  106. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js.map +1 -1
  107. package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js +173 -1
  108. package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js.map +1 -1
  109. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +92 -0
  110. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  111. package/build/dist/Server/Utils/Workspace/Slack/app-manifest.json +12 -2
  112. package/build/dist/Tests/Server/Utils/StatusPageResource.test.js +122 -0
  113. package/build/dist/Tests/Server/Utils/StatusPageResource.test.js.map +1 -0
  114. package/build/dist/Types/Icon/IconProp.js +1 -0
  115. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  116. package/build/dist/Types/LLM/Index.js +4 -0
  117. package/build/dist/Types/LLM/Index.js.map +1 -0
  118. package/build/dist/Types/LLM/LlmType.js +8 -0
  119. package/build/dist/Types/LLM/LlmType.js.map +1 -0
  120. package/build/dist/Types/Monitor/MonitorStep.js +10 -0
  121. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  122. package/build/dist/Types/Permission.js +32 -97
  123. package/build/dist/Types/Permission.js.map +1 -1
  124. package/build/dist/UI/Components/Icon/Icon.js +3 -0
  125. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  126. package/build/dist/UI/Components/Link/Link.js +4 -1
  127. package/build/dist/UI/Components/Link/Link.js.map +1 -1
  128. package/package.json +5 -1
  129. package/Models/DatabaseModels/CopilotAction.ts +0 -772
  130. package/Models/DatabaseModels/CopilotActionTypePriority.ts +0 -340
  131. package/Models/DatabaseModels/CopilotCodeRepository.ts +0 -637
  132. package/Models/DatabaseModels/ServiceCopilotCodeRepository.ts +0 -544
  133. package/Server/API/CopilotActionAPI.ts +0 -418
  134. package/Server/API/CopilotCodeRepositoryAPI.ts +0 -127
  135. package/Server/API/CopilotPullRequestAPI.ts +0 -243
  136. package/Server/Docs/CodeRepository.md +0 -43
  137. package/Server/Middleware/CodeRepositoryAuthorization.ts +0 -50
  138. package/Server/Services/CopilotActionService.ts +0 -10
  139. package/Server/Services/CopilotActionTypePriorityService.ts +0 -67
  140. package/Server/Services/CopilotCodeRepositoryService.ts +0 -62
  141. package/Server/Services/CopilotPullRequestService.ts +0 -10
  142. package/Server/Services/ServiceCopilotCodeRepositoryService.ts +0 -10
  143. package/Types/Copilot/CopilotActionProps/DirectoryActionProp.ts +0 -3
  144. package/Types/Copilot/CopilotActionProps/ExceptionActionProp.ts +0 -4
  145. package/Types/Copilot/CopilotActionProps/FileActionProp.ts +0 -7
  146. package/Types/Copilot/CopilotActionProps/FunctionActionProp.ts +0 -5
  147. package/Types/Copilot/CopilotActionProps/Index.ts +0 -96
  148. package/Types/Copilot/CopilotActionProps/SpanActionProp.ts +0 -4
  149. package/Types/Copilot/CopilotActionStatus.ts +0 -114
  150. package/Types/Copilot/CopilotActionType.ts +0 -212
  151. package/build/dist/Models/DatabaseModels/CopilotAction.js +0 -793
  152. package/build/dist/Models/DatabaseModels/CopilotAction.js.map +0 -1
  153. package/build/dist/Models/DatabaseModels/CopilotActionTypePriority.js +0 -358
  154. package/build/dist/Models/DatabaseModels/CopilotActionTypePriority.js.map +0 -1
  155. package/build/dist/Models/DatabaseModels/CopilotCodeRepository.js +0 -656
  156. package/build/dist/Models/DatabaseModels/CopilotCodeRepository.js.map +0 -1
  157. package/build/dist/Models/DatabaseModels/CopilotPullRequest.js.map +0 -1
  158. package/build/dist/Models/DatabaseModels/ServiceCopilotCodeRepository.js +0 -561
  159. package/build/dist/Models/DatabaseModels/ServiceCopilotCodeRepository.js.map +0 -1
  160. package/build/dist/Server/API/CopilotActionAPI.js +0 -295
  161. package/build/dist/Server/API/CopilotActionAPI.js.map +0 -1
  162. package/build/dist/Server/API/CopilotCodeRepositoryAPI.js +0 -91
  163. package/build/dist/Server/API/CopilotCodeRepositoryAPI.js.map +0 -1
  164. package/build/dist/Server/API/CopilotPullRequestAPI.js +0 -166
  165. package/build/dist/Server/API/CopilotPullRequestAPI.js.map +0 -1
  166. package/build/dist/Server/Middleware/CodeRepositoryAuthorization.js +0 -48
  167. package/build/dist/Server/Middleware/CodeRepositoryAuthorization.js.map +0 -1
  168. package/build/dist/Server/Services/CopilotActionService.js +0 -9
  169. package/build/dist/Server/Services/CopilotActionService.js.map +0 -1
  170. package/build/dist/Server/Services/CopilotActionTypePriorityService.js +0 -61
  171. package/build/dist/Server/Services/CopilotActionTypePriorityService.js.map +0 -1
  172. package/build/dist/Server/Services/CopilotCodeRepositoryService.js +0 -61
  173. package/build/dist/Server/Services/CopilotCodeRepositoryService.js.map +0 -1
  174. package/build/dist/Server/Services/CopilotPullRequestService.js +0 -9
  175. package/build/dist/Server/Services/CopilotPullRequestService.js.map +0 -1
  176. package/build/dist/Server/Services/ServiceCopilotCodeRepositoryService.js +0 -9
  177. package/build/dist/Server/Services/ServiceCopilotCodeRepositoryService.js.map +0 -1
  178. package/build/dist/Types/Copilot/CopilotActionProps/DirectoryActionProp.js +0 -2
  179. package/build/dist/Types/Copilot/CopilotActionProps/DirectoryActionProp.js.map +0 -1
  180. package/build/dist/Types/Copilot/CopilotActionProps/ExceptionActionProp.js +0 -2
  181. package/build/dist/Types/Copilot/CopilotActionProps/ExceptionActionProp.js.map +0 -1
  182. package/build/dist/Types/Copilot/CopilotActionProps/FileActionProp.js +0 -2
  183. package/build/dist/Types/Copilot/CopilotActionProps/FileActionProp.js.map +0 -1
  184. package/build/dist/Types/Copilot/CopilotActionProps/FunctionActionProp.js +0 -2
  185. package/build/dist/Types/Copilot/CopilotActionProps/FunctionActionProp.js.map +0 -1
  186. package/build/dist/Types/Copilot/CopilotActionProps/Index.js +0 -64
  187. package/build/dist/Types/Copilot/CopilotActionProps/Index.js.map +0 -1
  188. package/build/dist/Types/Copilot/CopilotActionProps/SpanActionProp.js +0 -2
  189. package/build/dist/Types/Copilot/CopilotActionProps/SpanActionProp.js.map +0 -1
  190. package/build/dist/Types/Copilot/CopilotActionStatus.js +0 -96
  191. package/build/dist/Types/Copilot/CopilotActionStatus.js.map +0 -1
  192. package/build/dist/Types/Copilot/CopilotActionType.js +0 -175
  193. package/build/dist/Types/Copilot/CopilotActionType.js.map +0 -1
@@ -424,4 +424,33 @@ export default class ScheduledMaintenanceInternalNote extends BaseModel {
424
424
  default: false,
425
425
  })
426
426
  public isOwnerNotified?: boolean = undefined;
427
+
428
+ @ColumnAccessControl({
429
+ create: [
430
+ Permission.ProjectOwner,
431
+ Permission.ProjectAdmin,
432
+ Permission.ProjectMember,
433
+ Permission.CreateScheduledMaintenanceInternalNote,
434
+ ],
435
+ read: [
436
+ Permission.ProjectOwner,
437
+ Permission.ProjectAdmin,
438
+ Permission.ProjectMember,
439
+ Permission.ReadScheduledMaintenanceInternalNote,
440
+ ],
441
+ update: [],
442
+ })
443
+ @Index()
444
+ @TableColumn({
445
+ type: TableColumnType.LongText,
446
+ title: "Posted from Slack Message ID",
447
+ description:
448
+ "Unique identifier for the Slack message this note was created from (channel_id:message_ts). Used to prevent duplicate notes when multiple users react to the same message.",
449
+ required: false,
450
+ })
451
+ @Column({
452
+ type: ColumnType.LongText,
453
+ nullable: true,
454
+ })
455
+ public postedFromSlackMessageId?: string = undefined;
427
456
  }
@@ -556,4 +556,33 @@ export default class ScheduledMaintenancePublicNote extends BaseModel {
556
556
  unique: false,
557
557
  })
558
558
  public postedAt?: Date = undefined;
559
+
560
+ @ColumnAccessControl({
561
+ create: [
562
+ Permission.ProjectOwner,
563
+ Permission.ProjectAdmin,
564
+ Permission.ProjectMember,
565
+ Permission.CreateScheduledMaintenancePublicNote,
566
+ ],
567
+ read: [
568
+ Permission.ProjectOwner,
569
+ Permission.ProjectAdmin,
570
+ Permission.ProjectMember,
571
+ Permission.ReadScheduledMaintenancePublicNote,
572
+ ],
573
+ update: [],
574
+ })
575
+ @Index()
576
+ @TableColumn({
577
+ type: TableColumnType.LongText,
578
+ title: "Posted from Slack Message ID",
579
+ description:
580
+ "Unique identifier for the Slack message this note was created from (channel_id:message_ts). Used to prevent duplicate notes when multiple users react to the same message.",
581
+ required: false,
582
+ })
583
+ @Column({
584
+ type: ColumnType.LongText,
585
+ nullable: true,
586
+ })
587
+ public postedFromSlackMessageId?: string = undefined;
559
588
  }
@@ -0,0 +1,57 @@
1
+ import UserMiddleware from "../Middleware/UserAuthorization";
2
+ import LlmProviderService, {
3
+ Service as LlmProviderServiceType,
4
+ } from "../Services/LlmProviderService";
5
+ import {
6
+ ExpressRequest,
7
+ ExpressResponse,
8
+ NextFunction,
9
+ } from "../Utils/Express";
10
+ import Response from "../Utils/Response";
11
+ import BaseAPI from "./BaseAPI";
12
+ import LIMIT_MAX from "../../Types/Database/LimitMax";
13
+ import PositiveNumber from "../../Types/PositiveNumber";
14
+ import LlmProvider from "../../Models/DatabaseModels/LlmProvider";
15
+
16
+ export default class LlmProviderAPI extends BaseAPI<
17
+ LlmProvider,
18
+ LlmProviderServiceType
19
+ > {
20
+ public constructor() {
21
+ super(LlmProvider, LlmProviderService);
22
+
23
+ this.router.post(
24
+ `${new this.entityType().getCrudApiPath()?.toString()}/global-llms`,
25
+ UserMiddleware.getUserMiddleware,
26
+ async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
27
+ try {
28
+ const llmProviders: Array<LlmProvider> =
29
+ await LlmProviderService.findBy({
30
+ query: {
31
+ isGlobalLlm: true,
32
+ },
33
+ select: {
34
+ name: true,
35
+ description: true,
36
+ },
37
+ props: {
38
+ isRoot: true,
39
+ },
40
+ skip: 0,
41
+ limit: LIMIT_MAX,
42
+ });
43
+
44
+ return Response.sendEntityArrayResponse(
45
+ req,
46
+ res,
47
+ llmProviders,
48
+ new PositiveNumber(llmProviders.length),
49
+ LlmProvider,
50
+ );
51
+ } catch (err) {
52
+ next(err);
53
+ }
54
+ },
55
+ );
56
+ }
57
+ }
@@ -473,152 +473,6 @@ export default class MicrosoftTeamsAPI {
473
473
  },
474
474
  );
475
475
 
476
- // Endpoint to finalize team selection when multiple teams are available.
477
- router.post(
478
- "/microsoft-teams/select-team",
479
- async (req: ExpressRequest, res: ExpressResponse) => {
480
- try {
481
- const projectIdString: string | undefined = req.body["projectId"];
482
- const userIdString: string | undefined = req.body["userId"];
483
- const teamId: string | undefined = req.body["teamId"];
484
-
485
- if (!projectIdString || !userIdString || !teamId) {
486
- return Response.sendErrorResponse(
487
- req,
488
- res,
489
- new BadRequestException(
490
- "projectId, userId and teamId are required",
491
- ),
492
- );
493
- }
494
-
495
- const projectId: ObjectID = new ObjectID(projectIdString);
496
- const userId: ObjectID = new ObjectID(userIdString);
497
-
498
- // Fetch user auth to get access token and available teams.
499
- const userAuth: WorkspaceUserAuthToken | null =
500
- await WorkspaceUserAuthTokenService.getUserAuth({
501
- projectId: projectId,
502
- userId: userId,
503
- workspaceType: WorkspaceType.MicrosoftTeams,
504
- });
505
-
506
- if (!userAuth) {
507
- return Response.sendErrorResponse(
508
- req,
509
- res,
510
- new BadRequestException(
511
- "User Microsoft Teams auth not found. Please re-authenticate.",
512
- ),
513
- );
514
- }
515
-
516
- const accessToken: string = userAuth.authToken || "";
517
- const miscData: any = userAuth.miscData || {};
518
- const availableTeams: Record<string, MicrosoftTeamsTeam> =
519
- await MicrosoftTeamsUtil.refreshTeams({
520
- projectId: projectId,
521
- });
522
- const matchedTeam: MicrosoftTeamsTeam | undefined = Object.values(
523
- availableTeams,
524
- ).find((t: MicrosoftTeamsTeam) => {
525
- return t.id === teamId;
526
- });
527
-
528
- if (!matchedTeam) {
529
- return Response.sendErrorResponse(
530
- req,
531
- res,
532
- new BadRequestException(
533
- "Selected teamId is not in availableTeams list",
534
- ),
535
- );
536
- }
537
-
538
- // Decode JWT to get tenant ID
539
- const tokenParts: Array<string> = accessToken.split(".");
540
- if (tokenParts.length !== 3) {
541
- return Response.sendErrorResponse(
542
- req,
543
- res,
544
- new BadRequestException("Invalid JWT token"),
545
- );
546
- }
547
- const payload: JSONObject = JSON.parse(
548
- Buffer.from(tokenParts[1]!, "base64").toString("utf-8"),
549
- );
550
- const tenantId: string = payload["tid"] as string;
551
-
552
- if (!tenantId) {
553
- return Response.sendErrorResponse(
554
- req,
555
- res,
556
- new BadRequestException("Tenant ID not found in token"),
557
- );
558
- }
559
-
560
- /*
561
- * Persist project auth now that team is selected.
562
- * IMPORTANT: Do NOT overwrite project-level auth token (admin-consent app token)
563
- * with the user delegated token. Preserve existing project auth token if present.
564
- */
565
- const existingProjectAuth: WorkspaceProjectAuthToken | null =
566
- await WorkspaceProjectAuthTokenService.getProjectAuth({
567
- projectId: projectId,
568
- workspaceType: WorkspaceType.MicrosoftTeams,
569
- });
570
-
571
- const projectAuthTokenToPersist: string =
572
- existingProjectAuth?.authToken || "";
573
-
574
- // Merge miscData while updating team selection details
575
- const mergedProjectMiscData: MicrosoftTeamsMiscData = {
576
- ...(existingProjectAuth?.miscData as any),
577
- tenantId: tenantId,
578
- teamId: teamId,
579
- teamName: matchedTeam.name,
580
- botId: MicrosoftTeamsAppClientId || "",
581
- };
582
-
583
- await WorkspaceProjectAuthTokenService.refreshAuthToken({
584
- projectId: projectId,
585
- workspaceType: WorkspaceType.MicrosoftTeams,
586
- authToken: projectAuthTokenToPersist,
587
- workspaceProjectId: tenantId, // Use tenant ID as the workspace project identifier
588
- miscData: mergedProjectMiscData,
589
- });
590
-
591
- // Update user token to remove availableTeams (cleanup) and store selected team info
592
- await WorkspaceUserAuthTokenService.refreshAuthToken({
593
- projectId: projectId,
594
- userId: userId,
595
- workspaceType: WorkspaceType.MicrosoftTeams,
596
- authToken: accessToken,
597
- workspaceUserId: miscData.userId || "",
598
- miscData: {
599
- userId: miscData.userId,
600
- displayName: miscData.displayName,
601
- email: miscData.email,
602
- teamId: teamId,
603
- teamName: matchedTeam.name,
604
- },
605
- });
606
-
607
- return Response.sendJsonObjectResponse(req, res, {
608
- success: true,
609
- });
610
- } catch (err) {
611
- logger.error("Error selecting Microsoft Teams team: ");
612
- logger.error(err);
613
- return Response.sendErrorResponse(
614
- req,
615
- res,
616
- new BadDataException("Failed to select Microsoft Teams team"),
617
- );
618
- }
619
- },
620
- );
621
-
622
476
  /*
623
477
  * Admin consent - start flow (tenant-wide admin consent)
624
478
  * Uses state in the same format as OAuth: <projectId>:<userId>
@@ -1118,6 +972,7 @@ export default class MicrosoftTeamsAPI {
1118
972
  const availableTeams: Record<string, MicrosoftTeamsTeam> =
1119
973
  await MicrosoftTeamsUtil.refreshTeams({
1120
974
  projectId: projectId,
975
+ ...(databaseProps.userId && { userId: databaseProps.userId }),
1121
976
  });
1122
977
 
1123
978
  return Response.sendJsonObjectResponse(req, res, {
@@ -1151,6 +1006,7 @@ export default class MicrosoftTeamsAPI {
1151
1006
  const availableTeams: Record<string, MicrosoftTeamsTeam> =
1152
1007
  await MicrosoftTeamsUtil.refreshTeams({
1153
1008
  projectId: projectId,
1009
+ ...(databaseProps.userId && { userId: databaseProps.userId }),
1154
1010
  });
1155
1011
 
1156
1012
  return Response.sendJsonObjectResponse(req, res, {
@@ -42,6 +42,10 @@ import UserMiddleware from "../Middleware/UserAuthorization";
42
42
  import CommonAPI from "./CommonAPI";
43
43
  import SlackUtil from "../Utils/Workspace/Slack/Slack";
44
44
  import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
45
+ import {
46
+ PrivateNoteEmojis,
47
+ PublicNoteEmojis,
48
+ } from "../Utils/Workspace/Slack/Actions/ActionTypes";
45
49
 
46
50
  export default class SlackAPI {
47
51
  public getRouter(): ExpressRouter {
@@ -731,6 +735,107 @@ export default class SlackAPI {
731
735
  },
732
736
  );
733
737
 
738
+ // Slack Events API endpoint for handling events like emoji reactions
739
+ router.post(
740
+ "/slack/events",
741
+ SlackAuthorization.isAuthorizedSlackRequest,
742
+ async (req: ExpressRequest, res: ExpressResponse) => {
743
+ logger.debug("Slack Events API Request received");
744
+ logger.debug(req.body);
745
+
746
+ const payload: JSONObject = req.body;
747
+
748
+ // Handle URL verification challenge from Slack
749
+ if (payload["type"] === "url_verification") {
750
+ logger.debug("Slack URL verification challenge received");
751
+ return Response.sendJsonObjectResponse(req, res, {
752
+ challenge: payload["challenge"],
753
+ });
754
+ }
755
+
756
+ // Handle event callbacks
757
+ if (payload["type"] === "event_callback") {
758
+ const event: JSONObject = payload["event"] as JSONObject;
759
+
760
+ if (!event) {
761
+ logger.debug("No event found in payload");
762
+ return Response.sendTextResponse(req, res, "ok");
763
+ }
764
+
765
+ // Handle reaction_added events
766
+ if (event["type"] === "reaction_added") {
767
+ logger.debug("Reaction added event received");
768
+
769
+ /*
770
+ * Respond immediately to Slack to prevent retry
771
+ * Process the event asynchronously
772
+ */
773
+ Response.sendTextResponse(req, res, "ok");
774
+
775
+ const reactionData: {
776
+ teamId: string;
777
+ reaction: string;
778
+ userId: string;
779
+ channelId: string;
780
+ messageTs: string;
781
+ } = {
782
+ teamId: payload["team_id"] as string,
783
+ reaction: event["reaction"] as string,
784
+ userId: event["user"] as string,
785
+ channelId: (event["item"] as JSONObject)?.["channel"] as string,
786
+ messageTs: (event["item"] as JSONObject)?.["ts"] as string,
787
+ };
788
+
789
+ // OPTIMIZATION: Quick check if this is a supported emoji before any DB queries
790
+ const isSupportedEmoji: boolean =
791
+ PrivateNoteEmojis.includes(reactionData.reaction) ||
792
+ PublicNoteEmojis.includes(reactionData.reaction);
793
+
794
+ if (!isSupportedEmoji) {
795
+ logger.debug(
796
+ `Emoji "${reactionData.reaction}" is not supported. Skipping.`,
797
+ );
798
+ return;
799
+ }
800
+
801
+ /*
802
+ * Process emoji reactions for Incidents, Alerts, and Scheduled Maintenance
803
+ * Each handler will silently ignore if the channel is not linked to their resource type
804
+ */
805
+ try {
806
+ await SlackIncidentActions.handleEmojiReaction(reactionData);
807
+ } catch (err) {
808
+ logger.error("Error handling incident emoji reaction:");
809
+ logger.error(err);
810
+ }
811
+
812
+ try {
813
+ await SlackAlertActions.handleEmojiReaction(reactionData);
814
+ } catch (err) {
815
+ logger.error("Error handling alert emoji reaction:");
816
+ logger.error(err);
817
+ }
818
+
819
+ try {
820
+ await SlackScheduledMaintenanceActions.handleEmojiReaction(
821
+ reactionData,
822
+ );
823
+ } catch (err) {
824
+ logger.error(
825
+ "Error handling scheduled maintenance emoji reaction:",
826
+ );
827
+ logger.error(err);
828
+ }
829
+
830
+ return;
831
+ }
832
+ }
833
+
834
+ // For any other event types, just acknowledge
835
+ return Response.sendTextResponse(req, res, "ok");
836
+ },
837
+ );
838
+
734
839
  // options load endpoint.
735
840
 
736
841
  router.post(
@@ -2510,6 +2510,9 @@ export default class StatusPageAPI extends BaseAPI<
2510
2510
  },
2511
2511
  select: {
2512
2512
  statusPageGroupId: true,
2513
+ statusPageGroup: {
2514
+ name: true,
2515
+ },
2513
2516
  monitorId: true,
2514
2517
  displayTooltip: true,
2515
2518
  displayDescription: true,
@@ -3631,6 +3634,9 @@ export default class StatusPageAPI extends BaseAPI<
3631
3634
  },
3632
3635
  select: {
3633
3636
  statusPageGroupId: true,
3637
+ statusPageGroup: {
3638
+ name: true,
3639
+ },
3634
3640
  monitorId: true,
3635
3641
  displayTooltip: true,
3636
3642
  displayDescription: true,
@@ -0,0 +1,71 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class MigrationName1765477339178 implements MigrationInterface {
4
+ public name = "MigrationName1765477339178";
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(
8
+ `ALTER TABLE "IncidentInternalNote" ADD "postedFromSlackMessageId" character varying`,
9
+ );
10
+ await queryRunner.query(
11
+ `ALTER TABLE "IncidentPublicNote" ADD "postedFromSlackMessageId" character varying`,
12
+ );
13
+ await queryRunner.query(
14
+ `ALTER TABLE "ScheduledMaintenanceInternalNote" ADD "postedFromSlackMessageId" character varying`,
15
+ );
16
+ await queryRunner.query(
17
+ `ALTER TABLE "ScheduledMaintenancePublicNote" ADD "postedFromSlackMessageId" character varying`,
18
+ );
19
+ await queryRunner.query(
20
+ `ALTER TABLE "AlertInternalNote" ADD "postedFromSlackMessageId" character varying`,
21
+ );
22
+ await queryRunner.query(
23
+ `CREATE INDEX "IDX_6007d639fd6dededbc77393761" ON "IncidentInternalNote" ("postedFromSlackMessageId") `,
24
+ );
25
+ await queryRunner.query(
26
+ `CREATE INDEX "IDX_7ffc0c79197aca5dd604c9b556" ON "IncidentPublicNote" ("postedFromSlackMessageId") `,
27
+ );
28
+ await queryRunner.query(
29
+ `CREATE INDEX "IDX_6dff06e544ac3b99e5ec720508" ON "ScheduledMaintenanceInternalNote" ("postedFromSlackMessageId") `,
30
+ );
31
+ await queryRunner.query(
32
+ `CREATE INDEX "IDX_2131c4ba2b8d8e793dcc3add9e" ON "ScheduledMaintenancePublicNote" ("postedFromSlackMessageId") `,
33
+ );
34
+ await queryRunner.query(
35
+ `CREATE INDEX "IDX_dd2d9bc2dbd669143263ae58c4" ON "AlertInternalNote" ("postedFromSlackMessageId") `,
36
+ );
37
+ }
38
+
39
+ public async down(queryRunner: QueryRunner): Promise<void> {
40
+ await queryRunner.query(
41
+ `DROP INDEX "public"."IDX_dd2d9bc2dbd669143263ae58c4"`,
42
+ );
43
+ await queryRunner.query(
44
+ `DROP INDEX "public"."IDX_2131c4ba2b8d8e793dcc3add9e"`,
45
+ );
46
+ await queryRunner.query(
47
+ `DROP INDEX "public"."IDX_6dff06e544ac3b99e5ec720508"`,
48
+ );
49
+ await queryRunner.query(
50
+ `DROP INDEX "public"."IDX_7ffc0c79197aca5dd604c9b556"`,
51
+ );
52
+ await queryRunner.query(
53
+ `DROP INDEX "public"."IDX_6007d639fd6dededbc77393761"`,
54
+ );
55
+ await queryRunner.query(
56
+ `ALTER TABLE "AlertInternalNote" DROP COLUMN "postedFromSlackMessageId"`,
57
+ );
58
+ await queryRunner.query(
59
+ `ALTER TABLE "ScheduledMaintenancePublicNote" DROP COLUMN "postedFromSlackMessageId"`,
60
+ );
61
+ await queryRunner.query(
62
+ `ALTER TABLE "ScheduledMaintenanceInternalNote" DROP COLUMN "postedFromSlackMessageId"`,
63
+ );
64
+ await queryRunner.query(
65
+ `ALTER TABLE "IncidentPublicNote" DROP COLUMN "postedFromSlackMessageId"`,
66
+ );
67
+ await queryRunner.query(
68
+ `ALTER TABLE "IncidentInternalNote" DROP COLUMN "postedFromSlackMessageId"`,
69
+ );
70
+ }
71
+ }
@@ -0,0 +1,45 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class MigrationName1765540325149 implements MigrationInterface {
4
+ public name = "MigrationName1765540325149";
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(
8
+ `CREATE TABLE "LlmProvider" ("_id" uuid NOT NULL DEFAULT uuid_generate_v4(), "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP WITH TIME ZONE, "version" integer NOT NULL, "name" character varying(50) NOT NULL, "description" character varying, "slug" character varying(100) NOT NULL, "llmType" character varying(100) NOT NULL, "apiKey" character varying, "modelName" character varying(100), "baseUrl" character varying(100), "projectId" uuid, "deletedByUserId" uuid, "createdByUserId" uuid, "isGlobalLlm" boolean NOT NULL DEFAULT false, "isEnabled" boolean NOT NULL DEFAULT true, CONSTRAINT "PK_c057270b82040d0c3f3eb7904d6" PRIMARY KEY ("_id"))`,
9
+ );
10
+ await queryRunner.query(
11
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type":"Recurring","value":{"intervalType":"Day","intervalCount":{"_type":"PositiveNumber","value":1}}}'`,
12
+ );
13
+ await queryRunner.query(
14
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type":"RestrictionTimes","value":{"restictionType":"None","dayRestrictionTimes":null,"weeklyRestrictionTimes":[]}}'`,
15
+ );
16
+ await queryRunner.query(
17
+ `ALTER TABLE "LlmProvider" ADD CONSTRAINT "FK_745a31adc0966cf0444cc321541" FOREIGN KEY ("projectId") REFERENCES "Project"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
18
+ );
19
+ await queryRunner.query(
20
+ `ALTER TABLE "LlmProvider" ADD CONSTRAINT "FK_082f150ef63369af3cd022d3720" FOREIGN KEY ("deletedByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
21
+ );
22
+ await queryRunner.query(
23
+ `ALTER TABLE "LlmProvider" ADD CONSTRAINT "FK_6d1f986fccda177f98ec3549629" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
24
+ );
25
+ }
26
+
27
+ public async down(queryRunner: QueryRunner): Promise<void> {
28
+ await queryRunner.query(
29
+ `ALTER TABLE "LlmProvider" DROP CONSTRAINT "FK_6d1f986fccda177f98ec3549629"`,
30
+ );
31
+ await queryRunner.query(
32
+ `ALTER TABLE "LlmProvider" DROP CONSTRAINT "FK_082f150ef63369af3cd022d3720"`,
33
+ );
34
+ await queryRunner.query(
35
+ `ALTER TABLE "LlmProvider" DROP CONSTRAINT "FK_745a31adc0966cf0444cc321541"`,
36
+ );
37
+ await queryRunner.query(
38
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type": "RestrictionTimes", "value": {"restictionType": "None", "dayRestrictionTimes": null, "weeklyRestrictionTimes": []}}'`,
39
+ );
40
+ await queryRunner.query(
41
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type": "Recurring", "value": {"intervalType": "Day", "intervalCount": {"_type": "PositiveNumber", "value": 1}}}'`,
42
+ );
43
+ await queryRunner.query(`DROP TABLE "LlmProvider"`);
44
+ }
45
+ }
@@ -0,0 +1,61 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class MigrationName1765540549739 implements MigrationInterface {
4
+ public name = "MigrationName1765540549739";
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ /*
8
+ * Delete all Copilot and CodeRepository related tables
9
+ * Drop tables in correct order respecting foreign key constraints
10
+ */
11
+
12
+ // First drop CopilotActionTypePriority (depends on CopilotCodeRepository)
13
+ await queryRunner.query(
14
+ `DROP TABLE IF EXISTS "CopilotActionTypePriority" CASCADE`,
15
+ );
16
+
17
+ // Drop CopilotPullRequest (depends on CopilotCodeRepository, ServiceCopilotCodeRepository)
18
+ await queryRunner.query(
19
+ `DROP TABLE IF EXISTS "CopilotPullRequest" CASCADE`,
20
+ );
21
+
22
+ // Drop CopilotAction (depends on CodeRepository, ServiceRepository)
23
+ await queryRunner.query(`DROP TABLE IF EXISTS "CopilotAction" CASCADE`);
24
+
25
+ // Drop ServiceCopilotCodeRepository (depends on CopilotCodeRepository)
26
+ await queryRunner.query(
27
+ `DROP TABLE IF EXISTS "ServiceCopilotCodeRepository" CASCADE`,
28
+ );
29
+
30
+ // Drop CopilotCodeRepositoryLabel (junction table)
31
+ await queryRunner.query(
32
+ `DROP TABLE IF EXISTS "CopilotCodeRepositoryLabel" CASCADE`,
33
+ );
34
+
35
+ // Drop CopilotCodeRepository
36
+ await queryRunner.query(
37
+ `DROP TABLE IF EXISTS "CopilotCodeRepository" CASCADE`,
38
+ );
39
+
40
+ // Drop ServiceRepository (depends on CodeRepository)
41
+ await queryRunner.query(`DROP TABLE IF EXISTS "ServiceRepository" CASCADE`);
42
+
43
+ // Drop CodeRepositoryLabel (junction table)
44
+ await queryRunner.query(
45
+ `DROP TABLE IF EXISTS "CodeRepositoryLabel" CASCADE`,
46
+ );
47
+
48
+ // Drop CodeRepository
49
+ await queryRunner.query(`DROP TABLE IF EXISTS "CodeRepository" CASCADE`);
50
+ }
51
+
52
+ public async down(_queryRunner: QueryRunner): Promise<void> {
53
+ /*
54
+ * Note: The down migration does not recreate the Copilot and CodeRepository tables
55
+ * as they are being permanently removed from the system.
56
+ * If you need to restore these tables, you would need to run the original migrations
57
+ * that created them (1717955235341, 1718037833516, 1718124277321, 1718879960254,
58
+ * 1720532068612, 1720785305192, 1725291476867).
59
+ */
60
+ }
61
+ }
@@ -0,0 +1,35 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class MigrationName1765544010078 implements MigrationInterface {
4
+ public name = "MigrationName1765544010078";
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(
8
+ `ALTER TABLE "LlmProvider" RENAME COLUMN "isEnabled" TO "isDefault"`,
9
+ );
10
+ await queryRunner.query(
11
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type":"Recurring","value":{"intervalType":"Day","intervalCount":{"_type":"PositiveNumber","value":1}}}'`,
12
+ );
13
+ await queryRunner.query(
14
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type":"RestrictionTimes","value":{"restictionType":"None","dayRestrictionTimes":null,"weeklyRestrictionTimes":[]}}'`,
15
+ );
16
+ await queryRunner.query(
17
+ `ALTER TABLE "LlmProvider" ALTER COLUMN "isDefault" SET DEFAULT false`,
18
+ );
19
+ }
20
+
21
+ public async down(queryRunner: QueryRunner): Promise<void> {
22
+ await queryRunner.query(
23
+ `ALTER TABLE "LlmProvider" ALTER COLUMN "isDefault" SET DEFAULT true`,
24
+ );
25
+ await queryRunner.query(
26
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type": "RestrictionTimes", "value": {"restictionType": "None", "dayRestrictionTimes": null, "weeklyRestrictionTimes": []}}'`,
27
+ );
28
+ await queryRunner.query(
29
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type": "Recurring", "value": {"intervalType": "Day", "intervalCount": {"_type": "PositiveNumber", "value": 1}}}'`,
30
+ );
31
+ await queryRunner.query(
32
+ `ALTER TABLE "LlmProvider" RENAME COLUMN "isDefault" TO "isEnabled"`,
33
+ );
34
+ }
35
+ }
@@ -192,6 +192,10 @@ import { MigrationName1764767371788 } from "./1764767371788-MigrationName";
192
192
  import { MigrationName1764789433216 } from "./1764789433216-MigrationName";
193
193
  import { MigrationName1764850876394 } from "./1764850876394-MigrationName";
194
194
  import { MigrationName1765195603978 } from "./1765195603978-MigrationName";
195
+ import { MigrationName1765477339178 } from "./1765477339178-MigrationName";
196
+ import { MigrationName1765540325149 } from "./1765540325149-MigrationName";
197
+ import { MigrationName1765540549739 } from "./1765540549739-MigrationName";
198
+ import { MigrationName1765544010078 } from "./1765544010078-MigrationName";
195
199
 
196
200
  export default [
197
201
  InitialMigration,
@@ -388,4 +392,8 @@ export default [
388
392
  MigrationName1764789433216,
389
393
  MigrationName1764850876394,
390
394
  MigrationName1765195603978,
395
+ MigrationName1765477339178,
396
+ MigrationName1765540325149,
397
+ MigrationName1765540549739,
398
+ MigrationName1765544010078
391
399
  ];