@oneuptime/common 9.5.3 → 9.5.4

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 (149) hide show
  1. package/Models/DatabaseModels/Alert.ts +27 -0
  2. package/Models/DatabaseModels/AlertEpisode.ts +26 -0
  3. package/Models/DatabaseModels/Incident.ts +27 -0
  4. package/Models/DatabaseModels/IncidentEpisode.ts +26 -0
  5. package/Models/DatabaseModels/Project.ts +250 -0
  6. package/Models/DatabaseModels/ScheduledMaintenance.ts +27 -0
  7. package/Server/Infrastructure/Postgres/SchemaMigrations/1770237245070-MigrationName.ts +57 -0
  8. package/Server/Infrastructure/Postgres/SchemaMigrations/1770407024682-MigrationName.ts +83 -0
  9. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
  10. package/Server/Services/AlertEpisodeMemberService.ts +6 -3
  11. package/Server/Services/AlertEpisodeService.ts +45 -97
  12. package/Server/Services/AlertEpisodeStateTimelineService.ts +4 -2
  13. package/Server/Services/AlertInternalNoteService.ts +5 -2
  14. package/Server/Services/AlertOwnerTeamService.ts +10 -4
  15. package/Server/Services/AlertOwnerUserService.ts +10 -4
  16. package/Server/Services/AlertService.ts +24 -38
  17. package/Server/Services/AlertStateTimelineService.ts +6 -3
  18. package/Server/Services/DatabaseService.ts +12 -0
  19. package/Server/Services/IncidentEpisodeMemberService.ts +8 -4
  20. package/Server/Services/IncidentEpisodePublicNoteService.ts +9 -6
  21. package/Server/Services/IncidentEpisodeService.ts +65 -117
  22. package/Server/Services/IncidentEpisodeStateTimelineService.ts +4 -2
  23. package/Server/Services/IncidentInternalNoteService.ts +10 -5
  24. package/Server/Services/IncidentMemberService.ts +20 -10
  25. package/Server/Services/IncidentOwnerTeamService.ts +20 -10
  26. package/Server/Services/IncidentOwnerUserService.ts +20 -10
  27. package/Server/Services/IncidentPublicNoteService.ts +10 -5
  28. package/Server/Services/IncidentService.ts +34 -110
  29. package/Server/Services/IncidentStateTimelineService.ts +11 -6
  30. package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +61 -39
  31. package/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.ts +31 -19
  32. package/Server/Services/ProjectService.ts +227 -0
  33. package/Server/Services/ScheduledMaintenanceInternalNoteService.ts +9 -6
  34. package/Server/Services/ScheduledMaintenancePublicNoteService.ts +9 -6
  35. package/Server/Services/ScheduledMaintenanceService.ts +27 -39
  36. package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +8 -6
  37. package/Server/Services/UserNotificationRuleService.ts +32 -21
  38. package/Server/Utils/AI/IncidentEpisodeAIContextBuilder.ts +4 -2
  39. package/Server/Utils/Browser.ts +28 -20
  40. package/Server/Utils/Monitor/MonitorAlert.ts +5 -0
  41. package/Server/Utils/Monitor/MonitorIncident.ts +7 -0
  42. package/Server/Utils/PushNotificationUtil.ts +69 -26
  43. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +8 -4
  44. package/Server/Utils/Workspace/Slack/Actions/Alert.ts +20 -8
  45. package/Server/Utils/Workspace/Slack/Actions/Incident.ts +42 -22
  46. package/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.ts +23 -17
  47. package/Server/Utils/Workspace/WorkspaceMessages/Alert.ts +1 -0
  48. package/Server/Utils/Workspace/WorkspaceMessages/Incident.ts +1 -0
  49. package/Server/Utils/Workspace/WorkspaceMessages/ScheduledMaintenance.ts +1 -0
  50. package/Types/Monitor/MonitorEvaluationSummary.ts +2 -0
  51. package/Utils/Analytics.ts +11 -0
  52. package/build/dist/Models/DatabaseModels/Alert.js +29 -0
  53. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  54. package/build/dist/Models/DatabaseModels/AlertEpisode.js +28 -0
  55. package/build/dist/Models/DatabaseModels/AlertEpisode.js.map +1 -1
  56. package/build/dist/Models/DatabaseModels/Incident.js +29 -0
  57. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  58. package/build/dist/Models/DatabaseModels/IncidentEpisode.js +28 -0
  59. package/build/dist/Models/DatabaseModels/IncidentEpisode.js.map +1 -1
  60. package/build/dist/Models/DatabaseModels/Project.js +265 -0
  61. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  62. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +28 -0
  63. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  64. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770237245070-MigrationName.js +27 -0
  65. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770237245070-MigrationName.js.map +1 -0
  66. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770407024682-MigrationName.js +34 -0
  67. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1770407024682-MigrationName.js.map +1 -0
  68. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
  69. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  70. package/build/dist/Server/Services/AlertEpisodeMemberService.js +6 -3
  71. package/build/dist/Server/Services/AlertEpisodeMemberService.js.map +1 -1
  72. package/build/dist/Server/Services/AlertEpisodeService.js +33 -90
  73. package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -1
  74. package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js +3 -2
  75. package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js.map +1 -1
  76. package/build/dist/Server/Services/AlertInternalNoteService.js +2 -2
  77. package/build/dist/Server/Services/AlertInternalNoteService.js.map +1 -1
  78. package/build/dist/Server/Services/AlertOwnerTeamService.js +4 -4
  79. package/build/dist/Server/Services/AlertOwnerTeamService.js.map +1 -1
  80. package/build/dist/Server/Services/AlertOwnerUserService.js +4 -4
  81. package/build/dist/Server/Services/AlertOwnerUserService.js.map +1 -1
  82. package/build/dist/Server/Services/AlertService.js +16 -34
  83. package/build/dist/Server/Services/AlertService.js.map +1 -1
  84. package/build/dist/Server/Services/AlertStateTimelineService.js +3 -3
  85. package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -1
  86. package/build/dist/Server/Services/DatabaseService.js +9 -0
  87. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  88. package/build/dist/Server/Services/IncidentEpisodeMemberService.js +8 -4
  89. package/build/dist/Server/Services/IncidentEpisodeMemberService.js.map +1 -1
  90. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +4 -3
  91. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
  92. package/build/dist/Server/Services/IncidentEpisodeService.js +46 -103
  93. package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
  94. package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js +3 -2
  95. package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js.map +1 -1
  96. package/build/dist/Server/Services/IncidentInternalNoteService.js +4 -2
  97. package/build/dist/Server/Services/IncidentInternalNoteService.js.map +1 -1
  98. package/build/dist/Server/Services/IncidentMemberService.js +8 -4
  99. package/build/dist/Server/Services/IncidentMemberService.js.map +1 -1
  100. package/build/dist/Server/Services/IncidentOwnerTeamService.js +8 -4
  101. package/build/dist/Server/Services/IncidentOwnerTeamService.js.map +1 -1
  102. package/build/dist/Server/Services/IncidentOwnerUserService.js +8 -4
  103. package/build/dist/Server/Services/IncidentOwnerUserService.js.map +1 -1
  104. package/build/dist/Server/Services/IncidentPublicNoteService.js +4 -2
  105. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  106. package/build/dist/Server/Services/IncidentService.js +24 -94
  107. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  108. package/build/dist/Server/Services/IncidentStateTimelineService.js +5 -3
  109. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  110. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +20 -16
  111. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
  112. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js +10 -8
  113. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js.map +1 -1
  114. package/build/dist/Server/Services/ProjectService.js +207 -0
  115. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  116. package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js +4 -3
  117. package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js.map +1 -1
  118. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +4 -3
  119. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
  120. package/build/dist/Server/Services/ScheduledMaintenanceService.js +16 -37
  121. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  122. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +3 -3
  123. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
  124. package/build/dist/Server/Services/UserNotificationRuleService.js +33 -25
  125. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  126. package/build/dist/Server/Utils/AI/IncidentEpisodeAIContextBuilder.js +4 -2
  127. package/build/dist/Server/Utils/AI/IncidentEpisodeAIContextBuilder.js.map +1 -1
  128. package/build/dist/Server/Utils/Browser.js +19 -12
  129. package/build/dist/Server/Utils/Browser.js.map +1 -1
  130. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +4 -0
  131. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  132. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +4 -0
  133. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  134. package/build/dist/Server/Utils/PushNotificationUtil.js +36 -28
  135. package/build/dist/Server/Utils/PushNotificationUtil.js.map +1 -1
  136. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +8 -4
  137. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  138. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js +8 -8
  139. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js.map +1 -1
  140. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js +18 -10
  141. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js.map +1 -1
  142. package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js +8 -8
  143. package/build/dist/Server/Utils/Workspace/Slack/Actions/ScheduledMaintenance.js.map +1 -1
  144. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Alert.js.map +1 -1
  145. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Incident.js.map +1 -1
  146. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/ScheduledMaintenance.js.map +1 -1
  147. package/build/dist/Utils/Analytics.js +5 -0
  148. package/build/dist/Utils/Analytics.js.map +1 -1
  149. package/package.json +1 -1
@@ -1084,6 +1084,33 @@ export default class Alert extends BaseModel {
1084
1084
  })
1085
1085
  public alertNumber?: number = undefined;
1086
1086
 
1087
+ @ColumnAccessControl({
1088
+ create: [],
1089
+ read: [
1090
+ Permission.ProjectOwner,
1091
+ Permission.ProjectAdmin,
1092
+ Permission.ProjectMember,
1093
+ Permission.ReadAlert,
1094
+ Permission.ReadAllProjectResources,
1095
+ ],
1096
+ update: [],
1097
+ })
1098
+ @TableColumn({
1099
+ isDefaultValueColumn: false,
1100
+ required: false,
1101
+ type: TableColumnType.ShortText,
1102
+ title: "Alert Number With Prefix",
1103
+ description: "Alert number with prefix (e.g., 'ALT-42' or '#42')",
1104
+ computed: true,
1105
+ canReadOnRelationQuery: true,
1106
+ })
1107
+ @Column({
1108
+ type: ColumnType.ShortText,
1109
+ length: ColumnLength.ShortText,
1110
+ nullable: true,
1111
+ })
1112
+ public alertNumberWithPrefix?: string = undefined;
1113
+
1087
1114
  @ColumnAccessControl({
1088
1115
  create: [],
1089
1116
  read: [],
@@ -260,6 +260,32 @@ export default class AlertEpisode extends BaseModel {
260
260
  })
261
261
  public episodeNumber?: number = undefined;
262
262
 
263
+ @ColumnAccessControl({
264
+ create: [],
265
+ read: [
266
+ Permission.ProjectOwner,
267
+ Permission.ProjectAdmin,
268
+ Permission.ProjectMember,
269
+ Permission.ReadAlertEpisode,
270
+ Permission.ReadAllProjectResources,
271
+ ],
272
+ update: [],
273
+ })
274
+ @TableColumn({
275
+ isDefaultValueColumn: false,
276
+ required: false,
277
+ type: TableColumnType.ShortText,
278
+ title: "Episode Number With Prefix",
279
+ description: "Episode number with prefix (e.g., 'AE-42' or '#42')",
280
+ computed: true,
281
+ })
282
+ @Column({
283
+ type: ColumnType.ShortText,
284
+ length: ColumnLength.ShortText,
285
+ nullable: true,
286
+ })
287
+ public episodeNumberWithPrefix?: string = undefined;
288
+
263
289
  @ColumnAccessControl({
264
290
  create: [
265
291
  Permission.ProjectOwner,
@@ -1512,6 +1512,33 @@ export default class Incident extends BaseModel {
1512
1512
  })
1513
1513
  public incidentNumber?: number = undefined;
1514
1514
 
1515
+ @ColumnAccessControl({
1516
+ create: [],
1517
+ read: [
1518
+ Permission.ProjectOwner,
1519
+ Permission.ProjectAdmin,
1520
+ Permission.ProjectMember,
1521
+ Permission.ReadProjectIncident,
1522
+ Permission.ReadAllProjectResources,
1523
+ ],
1524
+ update: [],
1525
+ })
1526
+ @TableColumn({
1527
+ isDefaultValueColumn: false,
1528
+ required: false,
1529
+ type: TableColumnType.ShortText,
1530
+ title: "Incident Number With Prefix",
1531
+ description: "Incident number with prefix (e.g., 'INC-42' or '#42')",
1532
+ computed: true,
1533
+ canReadOnRelationQuery: true,
1534
+ })
1535
+ @Column({
1536
+ type: ColumnType.ShortText,
1537
+ length: ColumnLength.ShortText,
1538
+ nullable: true,
1539
+ })
1540
+ public incidentNumberWithPrefix?: string = undefined;
1541
+
1515
1542
  @ColumnAccessControl({
1516
1543
  create: [],
1517
1544
  read: [],
@@ -259,6 +259,32 @@ export default class IncidentEpisode extends BaseModel {
259
259
  })
260
260
  public episodeNumber?: number = undefined;
261
261
 
262
+ @ColumnAccessControl({
263
+ create: [],
264
+ read: [
265
+ Permission.ProjectOwner,
266
+ Permission.ProjectAdmin,
267
+ Permission.ProjectMember,
268
+ Permission.ReadIncidentEpisode,
269
+ Permission.ReadAllProjectResources,
270
+ ],
271
+ update: [],
272
+ })
273
+ @TableColumn({
274
+ isDefaultValueColumn: false,
275
+ required: false,
276
+ type: TableColumnType.ShortText,
277
+ title: "Episode Number With Prefix",
278
+ description: "Episode number with prefix (e.g., 'IE-42' or '#42')",
279
+ computed: true,
280
+ })
281
+ @Column({
282
+ type: ColumnType.ShortText,
283
+ length: ColumnLength.ShortText,
284
+ nullable: true,
285
+ })
286
+ public episodeNumberWithPrefix?: string = undefined;
287
+
262
288
  @ColumnAccessControl({
263
289
  create: [
264
290
  Permission.ProjectOwner,
@@ -718,6 +718,256 @@ export default class Project extends TenantModel {
718
718
  })
719
719
  public currentActiveMonitorsCount?: number = undefined;
720
720
 
721
+ @ColumnAccessControl({
722
+ create: [],
723
+ read: [],
724
+ update: [],
725
+ })
726
+ @TableColumn({
727
+ type: TableColumnType.Number,
728
+ isDefaultValueColumn: true,
729
+ required: true,
730
+ hideColumnInDocumentation: true,
731
+ computed: true,
732
+ })
733
+ @Column({
734
+ type: ColumnType.Number,
735
+ nullable: false,
736
+ unique: false,
737
+ default: 0,
738
+ })
739
+ public incidentCounter?: number = undefined;
740
+
741
+ @ColumnAccessControl({
742
+ create: [],
743
+ read: [],
744
+ update: [],
745
+ })
746
+ @TableColumn({
747
+ type: TableColumnType.Number,
748
+ isDefaultValueColumn: true,
749
+ required: true,
750
+ hideColumnInDocumentation: true,
751
+ computed: true,
752
+ })
753
+ @Column({
754
+ type: ColumnType.Number,
755
+ nullable: false,
756
+ unique: false,
757
+ default: 0,
758
+ })
759
+ public alertCounter?: number = undefined;
760
+
761
+ @ColumnAccessControl({
762
+ create: [],
763
+ read: [],
764
+ update: [],
765
+ })
766
+ @TableColumn({
767
+ type: TableColumnType.Number,
768
+ isDefaultValueColumn: true,
769
+ required: true,
770
+ hideColumnInDocumentation: true,
771
+ computed: true,
772
+ })
773
+ @Column({
774
+ type: ColumnType.Number,
775
+ nullable: false,
776
+ unique: false,
777
+ default: 0,
778
+ })
779
+ public scheduledMaintenanceCounter?: number = undefined;
780
+
781
+ @ColumnAccessControl({
782
+ create: [],
783
+ read: [],
784
+ update: [],
785
+ })
786
+ @TableColumn({
787
+ type: TableColumnType.Number,
788
+ isDefaultValueColumn: true,
789
+ required: true,
790
+ hideColumnInDocumentation: true,
791
+ computed: true,
792
+ })
793
+ @Column({
794
+ type: ColumnType.Number,
795
+ nullable: false,
796
+ unique: false,
797
+ default: 0,
798
+ })
799
+ public incidentEpisodeCounter?: number = undefined;
800
+
801
+ @ColumnAccessControl({
802
+ create: [],
803
+ read: [],
804
+ update: [],
805
+ })
806
+ @TableColumn({
807
+ type: TableColumnType.Number,
808
+ isDefaultValueColumn: true,
809
+ required: true,
810
+ hideColumnInDocumentation: true,
811
+ computed: true,
812
+ })
813
+ @Column({
814
+ type: ColumnType.Number,
815
+ nullable: false,
816
+ unique: false,
817
+ default: 0,
818
+ })
819
+ public alertEpisodeCounter?: number = undefined;
820
+
821
+ @ColumnAccessControl({
822
+ create: [Permission.User],
823
+ read: [
824
+ Permission.ProjectOwner,
825
+ Permission.ProjectAdmin,
826
+ Permission.ProjectMember,
827
+ Permission.ReadProject,
828
+ Permission.UnAuthorizedSsoUser,
829
+ Permission.ReadAllProjectResources,
830
+ ],
831
+ update: [
832
+ Permission.ProjectOwner,
833
+ Permission.ProjectAdmin,
834
+ Permission.EditProject,
835
+ ],
836
+ })
837
+ @TableColumn({
838
+ type: TableColumnType.ShortText,
839
+ required: false,
840
+ title: "Incident Number Prefix",
841
+ description:
842
+ "Custom prefix for incident numbers (e.g., 'INC-'). If empty, '#' is used.",
843
+ })
844
+ @Column({
845
+ type: ColumnType.ShortText,
846
+ length: ColumnLength.ShortText,
847
+ nullable: true,
848
+ })
849
+ public incidentNumberPrefix?: string = undefined;
850
+
851
+ @ColumnAccessControl({
852
+ create: [Permission.User],
853
+ read: [
854
+ Permission.ProjectOwner,
855
+ Permission.ProjectAdmin,
856
+ Permission.ProjectMember,
857
+ Permission.ReadProject,
858
+ Permission.UnAuthorizedSsoUser,
859
+ Permission.ReadAllProjectResources,
860
+ ],
861
+ update: [
862
+ Permission.ProjectOwner,
863
+ Permission.ProjectAdmin,
864
+ Permission.EditProject,
865
+ ],
866
+ })
867
+ @TableColumn({
868
+ type: TableColumnType.ShortText,
869
+ required: false,
870
+ title: "Alert Number Prefix",
871
+ description:
872
+ "Custom prefix for alert numbers (e.g., 'ALT-'). If empty, '#' is used.",
873
+ })
874
+ @Column({
875
+ type: ColumnType.ShortText,
876
+ length: ColumnLength.ShortText,
877
+ nullable: true,
878
+ })
879
+ public alertNumberPrefix?: string = undefined;
880
+
881
+ @ColumnAccessControl({
882
+ create: [Permission.User],
883
+ read: [
884
+ Permission.ProjectOwner,
885
+ Permission.ProjectAdmin,
886
+ Permission.ProjectMember,
887
+ Permission.ReadProject,
888
+ Permission.UnAuthorizedSsoUser,
889
+ Permission.ReadAllProjectResources,
890
+ ],
891
+ update: [
892
+ Permission.ProjectOwner,
893
+ Permission.ProjectAdmin,
894
+ Permission.EditProject,
895
+ ],
896
+ })
897
+ @TableColumn({
898
+ type: TableColumnType.ShortText,
899
+ required: false,
900
+ title: "Scheduled Maintenance Number Prefix",
901
+ description:
902
+ "Custom prefix for scheduled maintenance numbers (e.g., 'SM-'). If empty, '#' is used.",
903
+ })
904
+ @Column({
905
+ type: ColumnType.ShortText,
906
+ length: ColumnLength.ShortText,
907
+ nullable: true,
908
+ })
909
+ public scheduledMaintenanceNumberPrefix?: string = undefined;
910
+
911
+ @ColumnAccessControl({
912
+ create: [Permission.User],
913
+ read: [
914
+ Permission.ProjectOwner,
915
+ Permission.ProjectAdmin,
916
+ Permission.ProjectMember,
917
+ Permission.ReadProject,
918
+ Permission.UnAuthorizedSsoUser,
919
+ Permission.ReadAllProjectResources,
920
+ ],
921
+ update: [
922
+ Permission.ProjectOwner,
923
+ Permission.ProjectAdmin,
924
+ Permission.EditProject,
925
+ ],
926
+ })
927
+ @TableColumn({
928
+ type: TableColumnType.ShortText,
929
+ required: false,
930
+ title: "Incident Episode Number Prefix",
931
+ description:
932
+ "Custom prefix for incident episode numbers (e.g., 'IE-'). If empty, '#' is used.",
933
+ })
934
+ @Column({
935
+ type: ColumnType.ShortText,
936
+ length: ColumnLength.ShortText,
937
+ nullable: true,
938
+ })
939
+ public incidentEpisodeNumberPrefix?: string = undefined;
940
+
941
+ @ColumnAccessControl({
942
+ create: [Permission.User],
943
+ read: [
944
+ Permission.ProjectOwner,
945
+ Permission.ProjectAdmin,
946
+ Permission.ProjectMember,
947
+ Permission.ReadProject,
948
+ Permission.UnAuthorizedSsoUser,
949
+ Permission.ReadAllProjectResources,
950
+ ],
951
+ update: [
952
+ Permission.ProjectOwner,
953
+ Permission.ProjectAdmin,
954
+ Permission.EditProject,
955
+ ],
956
+ })
957
+ @TableColumn({
958
+ type: TableColumnType.ShortText,
959
+ required: false,
960
+ title: "Alert Episode Number Prefix",
961
+ description:
962
+ "Custom prefix for alert episode numbers (e.g., 'AE-'). If empty, '#' is used.",
963
+ })
964
+ @Column({
965
+ type: ColumnType.ShortText,
966
+ length: ColumnLength.ShortText,
967
+ nullable: true,
968
+ })
969
+ public alertEpisodeNumberPrefix?: string = undefined;
970
+
721
971
  @ColumnAccessControl({
722
972
  create: [],
723
973
  read: [
@@ -1073,6 +1073,33 @@ export default class ScheduledMaintenance extends BaseModel {
1073
1073
  })
1074
1074
  public scheduledMaintenanceNumber?: number = undefined;
1075
1075
 
1076
+ @ColumnAccessControl({
1077
+ create: [],
1078
+ read: [
1079
+ Permission.ProjectOwner,
1080
+ Permission.ProjectAdmin,
1081
+ Permission.ProjectMember,
1082
+ Permission.ReadProjectScheduledMaintenance,
1083
+ Permission.ReadAllProjectResources,
1084
+ ],
1085
+ update: [],
1086
+ })
1087
+ @TableColumn({
1088
+ isDefaultValueColumn: false,
1089
+ required: false,
1090
+ type: TableColumnType.ShortText,
1091
+ title: "Scheduled Maintenance Number With Prefix",
1092
+ description:
1093
+ "Scheduled maintenance number with prefix (e.g., 'SM-42' or '#42')",
1094
+ computed: true,
1095
+ })
1096
+ @Column({
1097
+ type: ColumnType.ShortText,
1098
+ length: ColumnLength.ShortText,
1099
+ nullable: true,
1100
+ })
1101
+ public scheduledMaintenanceNumberWithPrefix?: string = undefined;
1102
+
1076
1103
  @ColumnAccessControl({
1077
1104
  create: [],
1078
1105
  read: [],
@@ -0,0 +1,57 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class MigrationName1770237245070 implements MigrationInterface {
4
+ public name = "MigrationName1770237245070";
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ // Add counter columns with default 0
8
+ await queryRunner.query(
9
+ `ALTER TABLE "Project" ADD "incidentCounter" integer NOT NULL DEFAULT '0'`,
10
+ );
11
+ await queryRunner.query(
12
+ `ALTER TABLE "Project" ADD "alertCounter" integer NOT NULL DEFAULT '0'`,
13
+ );
14
+ await queryRunner.query(
15
+ `ALTER TABLE "Project" ADD "scheduledMaintenanceCounter" integer NOT NULL DEFAULT '0'`,
16
+ );
17
+ await queryRunner.query(
18
+ `ALTER TABLE "Project" ADD "incidentEpisodeCounter" integer NOT NULL DEFAULT '0'`,
19
+ );
20
+ await queryRunner.query(
21
+ `ALTER TABLE "Project" ADD "alertEpisodeCounter" integer NOT NULL DEFAULT '0'`,
22
+ );
23
+
24
+ // Backfill from MAX of each entity table (including soft-deleted rows)
25
+ await queryRunner.query(
26
+ `UPDATE "Project" SET "incidentCounter" = COALESCE((SELECT MAX("incidentNumber") FROM "Incident" WHERE "Incident"."projectId" = "Project"."_id"), 0)`,
27
+ );
28
+ await queryRunner.query(
29
+ `UPDATE "Project" SET "alertCounter" = COALESCE((SELECT MAX("alertNumber") FROM "Alert" WHERE "Alert"."projectId" = "Project"."_id"), 0)`,
30
+ );
31
+ await queryRunner.query(
32
+ `UPDATE "Project" SET "scheduledMaintenanceCounter" = COALESCE((SELECT MAX("scheduledMaintenanceNumber") FROM "ScheduledMaintenance" WHERE "ScheduledMaintenance"."projectId" = "Project"."_id"), 0)`,
33
+ );
34
+ await queryRunner.query(
35
+ `UPDATE "Project" SET "incidentEpisodeCounter" = COALESCE((SELECT MAX("episodeNumber") FROM "IncidentEpisode" WHERE "IncidentEpisode"."projectId" = "Project"."_id"), 0)`,
36
+ );
37
+ await queryRunner.query(
38
+ `UPDATE "Project" SET "alertEpisodeCounter" = COALESCE((SELECT MAX("episodeNumber") FROM "AlertEpisode" WHERE "AlertEpisode"."projectId" = "Project"."_id"), 0)`,
39
+ );
40
+ }
41
+
42
+ public async down(queryRunner: QueryRunner): Promise<void> {
43
+ await queryRunner.query(
44
+ `ALTER TABLE "Project" DROP COLUMN "alertEpisodeCounter"`,
45
+ );
46
+ await queryRunner.query(
47
+ `ALTER TABLE "Project" DROP COLUMN "incidentEpisodeCounter"`,
48
+ );
49
+ await queryRunner.query(
50
+ `ALTER TABLE "Project" DROP COLUMN "scheduledMaintenanceCounter"`,
51
+ );
52
+ await queryRunner.query(`ALTER TABLE "Project" DROP COLUMN "alertCounter"`);
53
+ await queryRunner.query(
54
+ `ALTER TABLE "Project" DROP COLUMN "incidentCounter"`,
55
+ );
56
+ }
57
+ }
@@ -0,0 +1,83 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class MigrationName1770407024682 implements MigrationInterface {
4
+ public name = "MigrationName1770407024682";
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(
8
+ `ALTER TABLE "Project" ADD "incidentNumberPrefix" character varying(100)`,
9
+ );
10
+ await queryRunner.query(
11
+ `ALTER TABLE "Project" ADD "alertNumberPrefix" character varying(100)`,
12
+ );
13
+ await queryRunner.query(
14
+ `ALTER TABLE "Project" ADD "scheduledMaintenanceNumberPrefix" character varying(100)`,
15
+ );
16
+ await queryRunner.query(
17
+ `ALTER TABLE "Project" ADD "incidentEpisodeNumberPrefix" character varying(100)`,
18
+ );
19
+ await queryRunner.query(
20
+ `ALTER TABLE "Project" ADD "alertEpisodeNumberPrefix" character varying(100)`,
21
+ );
22
+ await queryRunner.query(
23
+ `ALTER TABLE "IncidentEpisode" ADD "episodeNumberWithPrefix" character varying(100)`,
24
+ );
25
+ await queryRunner.query(
26
+ `ALTER TABLE "Incident" ADD "incidentNumberWithPrefix" character varying(100)`,
27
+ );
28
+ await queryRunner.query(
29
+ `ALTER TABLE "AlertEpisode" ADD "episodeNumberWithPrefix" character varying(100)`,
30
+ );
31
+ await queryRunner.query(
32
+ `ALTER TABLE "Alert" ADD "alertNumberWithPrefix" character varying(100)`,
33
+ );
34
+ await queryRunner.query(
35
+ `ALTER TABLE "ScheduledMaintenance" ADD "scheduledMaintenanceNumberWithPrefix" character varying(100)`,
36
+ );
37
+ await queryRunner.query(
38
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type":"Recurring","value":{"intervalType":"Day","intervalCount":{"_type":"PositiveNumber","value":1}}}'`,
39
+ );
40
+ await queryRunner.query(
41
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type":"RestrictionTimes","value":{"restictionType":"None","dayRestrictionTimes":null,"weeklyRestrictionTimes":[]}}'`,
42
+ );
43
+ }
44
+
45
+ public async down(queryRunner: QueryRunner): Promise<void> {
46
+ await queryRunner.query(
47
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type": "RestrictionTimes", "value": {"restictionType": "None", "dayRestrictionTimes": null, "weeklyRestrictionTimes": []}}'`,
48
+ );
49
+ await queryRunner.query(
50
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type": "Recurring", "value": {"intervalType": "Day", "intervalCount": {"_type": "PositiveNumber", "value": 1}}}'`,
51
+ );
52
+ await queryRunner.query(
53
+ `ALTER TABLE "ScheduledMaintenance" DROP COLUMN "scheduledMaintenanceNumberWithPrefix"`,
54
+ );
55
+ await queryRunner.query(
56
+ `ALTER TABLE "Alert" DROP COLUMN "alertNumberWithPrefix"`,
57
+ );
58
+ await queryRunner.query(
59
+ `ALTER TABLE "AlertEpisode" DROP COLUMN "episodeNumberWithPrefix"`,
60
+ );
61
+ await queryRunner.query(
62
+ `ALTER TABLE "Incident" DROP COLUMN "incidentNumberWithPrefix"`,
63
+ );
64
+ await queryRunner.query(
65
+ `ALTER TABLE "IncidentEpisode" DROP COLUMN "episodeNumberWithPrefix"`,
66
+ );
67
+ await queryRunner.query(
68
+ `ALTER TABLE "Project" DROP COLUMN "alertEpisodeNumberPrefix"`,
69
+ );
70
+ await queryRunner.query(
71
+ `ALTER TABLE "Project" DROP COLUMN "incidentEpisodeNumberPrefix"`,
72
+ );
73
+ await queryRunner.query(
74
+ `ALTER TABLE "Project" DROP COLUMN "scheduledMaintenanceNumberPrefix"`,
75
+ );
76
+ await queryRunner.query(
77
+ `ALTER TABLE "Project" DROP COLUMN "alertNumberPrefix"`,
78
+ );
79
+ await queryRunner.query(
80
+ `ALTER TABLE "Project" DROP COLUMN "incidentNumberPrefix"`,
81
+ );
82
+ }
83
+ }
@@ -251,6 +251,8 @@ import { MigrationName1769802715014 } from "./1769802715014-MigrationName";
251
251
  import { MigrationName1770054293299 } from "./1770054293299-MigrationName";
252
252
  import { MigrationName1770232207959 } from "./1770232207959-MigrationName";
253
253
  import { MigrationName1770237245069 } from "./1770237245069-MigrationName";
254
+ import { MigrationName1770237245070 } from "./1770237245070-MigrationName";
255
+ import { MigrationName1770407024682 } from "./1770407024682-MigrationName";
254
256
 
255
257
  export default [
256
258
  InitialMigration,
@@ -506,4 +508,6 @@ export default [
506
508
  MigrationName1770054293299,
507
509
  MigrationName1770232207959,
508
510
  MigrationName1770237245069,
511
+ MigrationName1770237245070,
512
+ MigrationName1770407024682,
509
513
  ];
@@ -120,6 +120,7 @@ export class Service extends DatabaseService<Model> {
120
120
  id: createdItem.alertId,
121
121
  select: {
122
122
  alertNumber: true,
123
+ alertNumberWithPrefix: true,
123
124
  title: true,
124
125
  },
125
126
  props: {
@@ -132,6 +133,7 @@ export class Service extends DatabaseService<Model> {
132
133
  id: createdItem.alertEpisodeId,
133
134
  select: {
134
135
  episodeNumber: true,
136
+ episodeNumberWithPrefix: true,
135
137
  title: true,
136
138
  },
137
139
  props: {
@@ -145,7 +147,7 @@ export class Service extends DatabaseService<Model> {
145
147
  projectId: createdItem.projectId,
146
148
  alertEpisodeFeedEventType: AlertEpisodeFeedEventType.AlertAdded,
147
149
  displayColor: Yellow500,
148
- feedInfoInMarkdown: `**Alert #${alert?.alertNumber || "N/A"}** added to episode: ${alert?.title || "No title"}`,
150
+ feedInfoInMarkdown: `**Alert ${alert?.alertNumberWithPrefix || "#" + (alert?.alertNumber || "N/A")}** added to episode: ${alert?.title || "No title"}`,
149
151
  userId: createdItem.addedByUserId || undefined,
150
152
  });
151
153
 
@@ -155,7 +157,7 @@ export class Service extends DatabaseService<Model> {
155
157
  projectId: createdItem.projectId,
156
158
  alertFeedEventType: AlertFeedEventType.AddedToEpisode,
157
159
  displayColor: Yellow500,
158
- feedInfoInMarkdown: `Added to **Episode #${episode?.episodeNumber || "N/A"}**: ${episode?.title || "No title"}`,
160
+ feedInfoInMarkdown: `Added to **Episode ${episode?.episodeNumberWithPrefix || "#" + (episode?.episodeNumber || "N/A")}**: ${episode?.title || "No title"}`,
159
161
  userId: createdItem.addedByUserId || undefined,
160
162
  });
161
163
 
@@ -228,6 +230,7 @@ export class Service extends DatabaseService<Model> {
228
230
  id: member.alertEpisodeId,
229
231
  select: {
230
232
  episodeNumber: true,
233
+ episodeNumberWithPrefix: true,
231
234
  title: true,
232
235
  },
233
236
  props: {
@@ -250,7 +253,7 @@ export class Service extends DatabaseService<Model> {
250
253
  projectId: member.projectId,
251
254
  alertFeedEventType: AlertFeedEventType.RemovedFromEpisode,
252
255
  displayColor: Green500,
253
- feedInfoInMarkdown: `Removed from **Episode #${episode?.episodeNumber || "N/A"}**: ${episode?.title || "No title"}`,
256
+ feedInfoInMarkdown: `Removed from **Episode ${episode?.episodeNumberWithPrefix || "#" + (episode?.episodeNumber || "N/A")}**: ${episode?.title || "No title"}`,
254
257
  });
255
258
  }
256
259
  }