@oneuptime/common 9.3.22 → 9.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/IncomingCallLog.ts +521 -0
- package/Models/DatabaseModels/IncomingCallLogItem.ts +463 -0
- package/Models/DatabaseModels/IncomingCallPolicy.ts +811 -0
- package/Models/DatabaseModels/IncomingCallPolicyEscalationRule.ts +597 -0
- package/Models/DatabaseModels/Index.ts +18 -0
- package/Models/DatabaseModels/ProjectSCIMLog.ts +422 -0
- package/Models/DatabaseModels/StatusPageDomain.ts +2 -0
- package/Models/DatabaseModels/StatusPageSCIMLog.ts +455 -0
- package/Models/DatabaseModels/User.ts +0 -15
- package/Models/DatabaseModels/UserIncomingCallNumber.ts +296 -0
- package/Server/API/UserIncomingCallNumberAPI.ts +128 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1768583966447-MigrationName.ts +121 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1768825402472-MigrationName.ts +317 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
- package/Server/Services/DatabaseService.ts +23 -1
- package/Server/Services/DomainService.ts +26 -15
- package/Server/Services/IncomingCallLogItemService.ts +10 -0
- package/Server/Services/IncomingCallLogService.ts +10 -0
- package/Server/Services/IncomingCallPolicyEscalationRuleService.ts +267 -0
- package/Server/Services/IncomingCallPolicyService.ts +10 -0
- package/Server/Services/Index.ts +7 -0
- package/Server/Services/MonitorProbeService.ts +96 -1
- package/Server/Services/ProjectSCIMLogService.ts +11 -0
- package/Server/Services/StatusPageSCIMLogService.ts +11 -0
- package/Server/Services/UserCallService.ts +31 -0
- package/Server/Services/UserIncomingCallNumberService.ts +258 -0
- package/Server/Services/UserSmsService.ts +31 -0
- package/Server/Utils/StartServer.ts +5 -0
- package/Types/Call/CallProvider.ts +99 -0
- package/Types/Call/CallProviderType.ts +6 -0
- package/Types/Domain.ts +23 -0
- package/Types/Icon/IconProp.ts +1 -0
- package/Types/IncomingCall/IncomingCallStatus.ts +13 -0
- package/Types/Permission.ts +126 -0
- package/Types/Phone.ts +53 -4
- package/Types/SCIM/SCIMLogStatus.ts +7 -0
- package/UI/Components/Diagram/ConceptCards.tsx +74 -0
- package/UI/Components/Diagram/HorizontalStepChain.tsx +92 -0
- package/UI/Components/Diagram/Index.ts +11 -0
- package/UI/Components/Diagram/NumberedSteps.tsx +77 -0
- package/UI/Components/Diagram/VerticalFlowSteps.tsx +59 -0
- package/UI/Components/Icon/Icon.tsx +10 -0
- package/UI/Components/SimpleLogViewer/SimpleLogViewer.tsx +86 -2
- package/build/dist/Models/DatabaseModels/IncomingCallLog.js +565 -0
- package/build/dist/Models/DatabaseModels/IncomingCallLog.js.map +1 -0
- package/build/dist/Models/DatabaseModels/IncomingCallLogItem.js +497 -0
- package/build/dist/Models/DatabaseModels/IncomingCallLogItem.js.map +1 -0
- package/build/dist/Models/DatabaseModels/IncomingCallPolicy.js +840 -0
- package/build/dist/Models/DatabaseModels/IncomingCallPolicy.js.map +1 -0
- package/build/dist/Models/DatabaseModels/IncomingCallPolicyEscalationRule.js +619 -0
- package/build/dist/Models/DatabaseModels/IncomingCallPolicyEscalationRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Index.js +16 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectSCIMLog.js +455 -0
- package/build/dist/Models/DatabaseModels/ProjectSCIMLog.js.map +1 -0
- package/build/dist/Models/DatabaseModels/StatusPageDomain.js +2 -0
- package/build/dist/Models/DatabaseModels/StatusPageDomain.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageSCIMLog.js +486 -0
- package/build/dist/Models/DatabaseModels/StatusPageSCIMLog.js.map +1 -0
- package/build/dist/Models/DatabaseModels/User.js +0 -16
- package/build/dist/Models/DatabaseModels/User.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js +315 -0
- package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js.map +1 -0
- package/build/dist/Server/API/UserIncomingCallNumberAPI.js +72 -0
- package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1768583966447-MigrationName.js +48 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1768583966447-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1768825402472-MigrationName.js +116 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1768825402472-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +12 -0
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DomainService.js +19 -8
- package/build/dist/Server/Services/DomainService.js.map +1 -1
- package/build/dist/Server/Services/IncomingCallLogItemService.js +9 -0
- package/build/dist/Server/Services/IncomingCallLogItemService.js.map +1 -0
- package/build/dist/Server/Services/IncomingCallLogService.js +9 -0
- package/build/dist/Server/Services/IncomingCallLogService.js.map +1 -0
- package/build/dist/Server/Services/IncomingCallPolicyEscalationRuleService.js +197 -0
- package/build/dist/Server/Services/IncomingCallPolicyEscalationRuleService.js.map +1 -0
- package/build/dist/Server/Services/IncomingCallPolicyService.js +9 -0
- package/build/dist/Server/Services/IncomingCallPolicyService.js.map +1 -0
- package/build/dist/Server/Services/Index.js +6 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MonitorProbeService.js +77 -0
- package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
- package/build/dist/Server/Services/ProjectSCIMLogService.js +10 -0
- package/build/dist/Server/Services/ProjectSCIMLogService.js.map +1 -0
- package/build/dist/Server/Services/StatusPageSCIMLogService.js +10 -0
- package/build/dist/Server/Services/StatusPageSCIMLogService.js.map +1 -0
- package/build/dist/Server/Services/UserCallService.js +21 -0
- package/build/dist/Server/Services/UserCallService.js.map +1 -1
- package/build/dist/Server/Services/UserIncomingCallNumberService.js +225 -0
- package/build/dist/Server/Services/UserIncomingCallNumberService.js.map +1 -0
- package/build/dist/Server/Services/UserSmsService.js +21 -0
- package/build/dist/Server/Services/UserSmsService.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +5 -0
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Types/Call/CallProvider.js +2 -0
- package/build/dist/Types/Call/CallProvider.js.map +1 -0
- package/build/dist/Types/Call/CallProviderType.js +7 -0
- package/build/dist/Types/Call/CallProviderType.js.map +1 -0
- package/build/dist/Types/Domain.js +23 -1
- package/build/dist/Types/Domain.js.map +1 -1
- package/build/dist/Types/Icon/IconProp.js +1 -0
- package/build/dist/Types/Icon/IconProp.js.map +1 -1
- package/build/dist/Types/IncomingCall/IncomingCallStatus.js +14 -0
- package/build/dist/Types/IncomingCall/IncomingCallStatus.js.map +1 -0
- package/build/dist/Types/Permission.js +104 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Phone.js +47 -3
- package/build/dist/Types/Phone.js.map +1 -1
- package/build/dist/Types/SCIM/SCIMLogStatus.js +8 -0
- package/build/dist/Types/SCIM/SCIMLogStatus.js.map +1 -0
- package/build/dist/UI/Components/Diagram/ConceptCards.js +30 -0
- package/build/dist/UI/Components/Diagram/ConceptCards.js.map +1 -0
- package/build/dist/UI/Components/Diagram/HorizontalStepChain.js +30 -0
- package/build/dist/UI/Components/Diagram/HorizontalStepChain.js.map +1 -0
- package/build/dist/UI/Components/Diagram/Index.js +5 -0
- package/build/dist/UI/Components/Diagram/Index.js.map +1 -0
- package/build/dist/UI/Components/Diagram/NumberedSteps.js +18 -0
- package/build/dist/UI/Components/Diagram/NumberedSteps.js.map +1 -0
- package/build/dist/UI/Components/Diagram/VerticalFlowSteps.js +16 -0
- package/build/dist/UI/Components/Diagram/VerticalFlowSteps.js.map +1 -0
- package/build/dist/UI/Components/Icon/Icon.js +4 -0
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/SimpleLogViewer/SimpleLogViewer.js +30 -1
- package/build/dist/UI/Components/SimpleLogViewer/SimpleLogViewer.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import DatabaseService from "./DatabaseService";
|
|
2
|
+
import CreateBy from "../Types/Database/CreateBy";
|
|
3
|
+
import { OnCreate, OnDelete, OnUpdate } from "../Types/Database/Hooks";
|
|
4
|
+
import DeleteBy from "../Types/Database/DeleteBy";
|
|
5
|
+
import UpdateBy from "../Types/Database/UpdateBy";
|
|
6
|
+
import Query from "../Types/Database/Query";
|
|
7
|
+
import QueryHelper from "../Types/Database/QueryHelper";
|
|
8
|
+
import BadDataException from "../../Types/Exception/BadDataException";
|
|
9
|
+
import PositiveNumber from "../../Types/PositiveNumber";
|
|
10
|
+
import ObjectID from "../../Types/ObjectID";
|
|
11
|
+
import SortOrder from "../../Types/BaseDatabase/SortOrder";
|
|
12
|
+
import LIMIT_MAX from "../../Types/Database/LimitMax";
|
|
13
|
+
import IncomingCallPolicyEscalationRule from "../../Models/DatabaseModels/IncomingCallPolicyEscalationRule";
|
|
14
|
+
|
|
15
|
+
export class Service extends DatabaseService<IncomingCallPolicyEscalationRule> {
|
|
16
|
+
public constructor() {
|
|
17
|
+
super(IncomingCallPolicyEscalationRule);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
protected override async onBeforeCreate(
|
|
21
|
+
createBy: CreateBy<IncomingCallPolicyEscalationRule>,
|
|
22
|
+
): Promise<OnCreate<IncomingCallPolicyEscalationRule>> {
|
|
23
|
+
// Validate mutual exclusivity: either userId OR onCallDutyPolicyScheduleId must be set
|
|
24
|
+
const hasUser: boolean = Boolean(createBy.data.userId);
|
|
25
|
+
const hasSchedule: boolean = Boolean(
|
|
26
|
+
createBy.data.onCallDutyPolicyScheduleId,
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
if (!hasUser && !hasSchedule) {
|
|
30
|
+
throw new BadDataException(
|
|
31
|
+
"Either a User or an On-Call Schedule must be specified for the escalation rule",
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (hasUser && hasSchedule) {
|
|
36
|
+
throw new BadDataException(
|
|
37
|
+
"Only one of User or On-Call Schedule can be specified, not both",
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!createBy.data.incomingCallPolicyId) {
|
|
42
|
+
throw new BadDataException("incomingCallPolicyId is required");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Auto-generate order if not provided
|
|
46
|
+
if (!createBy.data.order) {
|
|
47
|
+
const query: Query<IncomingCallPolicyEscalationRule> = {
|
|
48
|
+
incomingCallPolicyId: createBy.data.incomingCallPolicyId,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const count: PositiveNumber = await this.countBy({
|
|
52
|
+
query: query,
|
|
53
|
+
props: {
|
|
54
|
+
isRoot: true,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
createBy.data.order = count.toNumber() + 1;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
await this.rearrangeOrder(
|
|
62
|
+
createBy.data.order,
|
|
63
|
+
createBy.data.incomingCallPolicyId,
|
|
64
|
+
true,
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
createBy,
|
|
69
|
+
carryForward: null,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
protected override async onBeforeDelete(
|
|
74
|
+
deleteBy: DeleteBy<IncomingCallPolicyEscalationRule>,
|
|
75
|
+
): Promise<OnDelete<IncomingCallPolicyEscalationRule>> {
|
|
76
|
+
if (!deleteBy.query._id && !deleteBy.props.isRoot) {
|
|
77
|
+
throw new BadDataException(
|
|
78
|
+
"_id should be present when deleting escalation rule. Please try the delete with objectId",
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
let resource: IncomingCallPolicyEscalationRule | null = null;
|
|
83
|
+
|
|
84
|
+
if (!deleteBy.props.isRoot) {
|
|
85
|
+
resource = await this.findOneBy({
|
|
86
|
+
query: deleteBy.query,
|
|
87
|
+
props: {
|
|
88
|
+
isRoot: true,
|
|
89
|
+
},
|
|
90
|
+
select: {
|
|
91
|
+
order: true,
|
|
92
|
+
incomingCallPolicyId: true,
|
|
93
|
+
projectId: true,
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
if (!resource) {
|
|
98
|
+
throw new BadDataException(
|
|
99
|
+
"IncomingCallPolicyEscalationRule with this id not found",
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
deleteBy,
|
|
106
|
+
carryForward: resource,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
protected override async onDeleteSuccess(
|
|
111
|
+
onDelete: OnDelete<IncomingCallPolicyEscalationRule>,
|
|
112
|
+
_itemIdsBeforeDelete: ObjectID[],
|
|
113
|
+
): Promise<OnDelete<IncomingCallPolicyEscalationRule>> {
|
|
114
|
+
const deleteBy: DeleteBy<IncomingCallPolicyEscalationRule> =
|
|
115
|
+
onDelete.deleteBy;
|
|
116
|
+
const resource: IncomingCallPolicyEscalationRule | null =
|
|
117
|
+
onDelete.carryForward;
|
|
118
|
+
|
|
119
|
+
if (!deleteBy.props.isRoot && resource) {
|
|
120
|
+
if (resource && resource.order && resource.incomingCallPolicyId) {
|
|
121
|
+
await this.rearrangeOrder(
|
|
122
|
+
resource.order,
|
|
123
|
+
resource.incomingCallPolicyId,
|
|
124
|
+
false,
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
deleteBy: deleteBy,
|
|
131
|
+
carryForward: null,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
protected override async onBeforeUpdate(
|
|
136
|
+
updateBy: UpdateBy<IncomingCallPolicyEscalationRule>,
|
|
137
|
+
): Promise<OnUpdate<IncomingCallPolicyEscalationRule>> {
|
|
138
|
+
if (updateBy.data.order && !updateBy.props.isRoot && updateBy.query._id) {
|
|
139
|
+
const resource: IncomingCallPolicyEscalationRule | null =
|
|
140
|
+
await this.findOneBy({
|
|
141
|
+
query: {
|
|
142
|
+
_id: updateBy.query._id!,
|
|
143
|
+
},
|
|
144
|
+
props: {
|
|
145
|
+
isRoot: true,
|
|
146
|
+
},
|
|
147
|
+
select: {
|
|
148
|
+
order: true,
|
|
149
|
+
incomingCallPolicyId: true,
|
|
150
|
+
_id: true,
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const currentOrder: number = resource?.order as number;
|
|
155
|
+
const newOrder: number = updateBy.data.order as number;
|
|
156
|
+
|
|
157
|
+
const resources: Array<IncomingCallPolicyEscalationRule> =
|
|
158
|
+
await this.findBy({
|
|
159
|
+
query: {
|
|
160
|
+
incomingCallPolicyId: resource?.incomingCallPolicyId as ObjectID,
|
|
161
|
+
},
|
|
162
|
+
limit: LIMIT_MAX,
|
|
163
|
+
skip: 0,
|
|
164
|
+
props: {
|
|
165
|
+
isRoot: true,
|
|
166
|
+
},
|
|
167
|
+
select: {
|
|
168
|
+
order: true,
|
|
169
|
+
incomingCallPolicyId: true,
|
|
170
|
+
_id: true,
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
if (currentOrder > newOrder) {
|
|
175
|
+
// moving up.
|
|
176
|
+
for (const resource of resources) {
|
|
177
|
+
if (resource.order! >= newOrder && resource.order! < currentOrder) {
|
|
178
|
+
// increment order.
|
|
179
|
+
await this.updateOneBy({
|
|
180
|
+
query: {
|
|
181
|
+
_id: resource._id!,
|
|
182
|
+
},
|
|
183
|
+
data: {
|
|
184
|
+
order: resource.order! + 1,
|
|
185
|
+
},
|
|
186
|
+
props: {
|
|
187
|
+
isRoot: true,
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (newOrder > currentOrder) {
|
|
195
|
+
// moving down.
|
|
196
|
+
for (const resource of resources) {
|
|
197
|
+
if (resource.order! <= newOrder) {
|
|
198
|
+
// increment order.
|
|
199
|
+
await this.updateOneBy({
|
|
200
|
+
query: {
|
|
201
|
+
_id: resource._id!,
|
|
202
|
+
},
|
|
203
|
+
data: {
|
|
204
|
+
order: resource.order! - 1,
|
|
205
|
+
},
|
|
206
|
+
props: {
|
|
207
|
+
isRoot: true,
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return { updateBy, carryForward: null };
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
private async rearrangeOrder(
|
|
219
|
+
currentOrder: number,
|
|
220
|
+
incomingCallPolicyId: ObjectID,
|
|
221
|
+
increaseOrder: boolean = true,
|
|
222
|
+
): Promise<void> {
|
|
223
|
+
const resources: Array<IncomingCallPolicyEscalationRule> =
|
|
224
|
+
await this.findBy({
|
|
225
|
+
query: {
|
|
226
|
+
order: QueryHelper.greaterThanEqualTo(currentOrder),
|
|
227
|
+
incomingCallPolicyId: incomingCallPolicyId,
|
|
228
|
+
},
|
|
229
|
+
limit: LIMIT_MAX,
|
|
230
|
+
skip: 0,
|
|
231
|
+
props: {
|
|
232
|
+
isRoot: true,
|
|
233
|
+
},
|
|
234
|
+
select: {
|
|
235
|
+
_id: true,
|
|
236
|
+
order: true,
|
|
237
|
+
},
|
|
238
|
+
sort: {
|
|
239
|
+
order: SortOrder.Ascending,
|
|
240
|
+
},
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
let newOrder: number = currentOrder;
|
|
244
|
+
|
|
245
|
+
for (const resource of resources) {
|
|
246
|
+
if (increaseOrder) {
|
|
247
|
+
newOrder = resource.order! + 1;
|
|
248
|
+
} else {
|
|
249
|
+
newOrder = resource.order! - 1;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
await this.updateOneBy({
|
|
253
|
+
query: {
|
|
254
|
+
_id: resource._id!,
|
|
255
|
+
},
|
|
256
|
+
data: {
|
|
257
|
+
order: newOrder,
|
|
258
|
+
},
|
|
259
|
+
props: {
|
|
260
|
+
isRoot: true,
|
|
261
|
+
},
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export default new Service();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import DatabaseService from "./DatabaseService";
|
|
2
|
+
import IncomingCallPolicy from "../../Models/DatabaseModels/IncomingCallPolicy";
|
|
3
|
+
|
|
4
|
+
export class Service extends DatabaseService<IncomingCallPolicy> {
|
|
5
|
+
public constructor() {
|
|
6
|
+
super(IncomingCallPolicy);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default new Service();
|
package/Server/Services/Index.ts
CHANGED
|
@@ -134,6 +134,7 @@ import UserSessionService from "./UserSessionService";
|
|
|
134
134
|
import UserTotpAuthService from "./UserTotpAuthService";
|
|
135
135
|
import UserWebAuthnService from "./UserWebAuthnService";
|
|
136
136
|
import UserSmsService from "./UserSmsService";
|
|
137
|
+
import UserIncomingCallNumberService from "./UserIncomingCallNumberService";
|
|
137
138
|
import UserWhatsAppService from "./UserWhatsAppService";
|
|
138
139
|
import WorkflowLogService from "./WorkflowLogService";
|
|
139
140
|
// Workflows.
|
|
@@ -173,6 +174,8 @@ import OnCallDutyPolicyUserOverrideService from "./OnCallDutyPolicyUserOverrideS
|
|
|
173
174
|
import MonitorLogService from "./MonitorLogService";
|
|
174
175
|
|
|
175
176
|
import OnCallDutyPolicyTimeLogService from "./OnCallDutyPolicyTimeLogService";
|
|
177
|
+
import ProjectSCIMLogService from "./ProjectSCIMLogService";
|
|
178
|
+
import StatusPageSCIMLogService from "./StatusPageSCIMLogService";
|
|
176
179
|
|
|
177
180
|
const services: Array<BaseService> = [
|
|
178
181
|
OnCallDutyPolicyTimeLogService,
|
|
@@ -299,6 +302,7 @@ const services: Array<BaseService> = [
|
|
|
299
302
|
UserOnCallLogService,
|
|
300
303
|
UserOnCallLogTimelineService,
|
|
301
304
|
UserSmsService,
|
|
305
|
+
UserIncomingCallNumberService,
|
|
302
306
|
UserWhatsAppService,
|
|
303
307
|
UserTotpAuthService,
|
|
304
308
|
UserWebAuthnService,
|
|
@@ -355,6 +359,9 @@ const services: Array<BaseService> = [
|
|
|
355
359
|
WorkspaceSettingService,
|
|
356
360
|
WorkspaceNotificationRuleService,
|
|
357
361
|
WorkspaceNotificationLogService,
|
|
362
|
+
|
|
363
|
+
ProjectSCIMLogService,
|
|
364
|
+
StatusPageSCIMLogService,
|
|
358
365
|
];
|
|
359
366
|
|
|
360
367
|
export const AnalyticsServices: Array<
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import ObjectID from "../../Types/ObjectID";
|
|
2
2
|
import CreateBy from "../Types/Database/CreateBy";
|
|
3
3
|
import { OnCreate, OnUpdate } from "../Types/Database/Hooks";
|
|
4
|
-
import DatabaseService from "./DatabaseService";
|
|
4
|
+
import DatabaseService, { EntityManager } from "./DatabaseService";
|
|
5
5
|
import OneUptimeDate from "../../Types/Date";
|
|
6
6
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
7
7
|
import MonitorProbe from "../../Models/DatabaseModels/MonitorProbe";
|
|
@@ -69,6 +69,101 @@ export class Service extends DatabaseService<MonitorProbe> {
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Atomically claims monitor probes for a specific probe instance.
|
|
74
|
+
* Uses PostgreSQL's FOR UPDATE SKIP LOCKED to prevent multiple probe instances
|
|
75
|
+
* from picking up the same monitors simultaneously.
|
|
76
|
+
*
|
|
77
|
+
* @param data - Object containing probeId, limit, and nextPingAt
|
|
78
|
+
* @returns Array of claimed MonitorProbe IDs
|
|
79
|
+
*/
|
|
80
|
+
public async claimMonitorProbesForProbing(data: {
|
|
81
|
+
probeId: ObjectID;
|
|
82
|
+
limit: number;
|
|
83
|
+
}): Promise<Array<ObjectID>> {
|
|
84
|
+
const currentDate: Date = OneUptimeDate.getCurrentDate();
|
|
85
|
+
|
|
86
|
+
/*
|
|
87
|
+
* Use a transaction with FOR UPDATE SKIP LOCKED to atomically claim monitors
|
|
88
|
+
* This prevents multiple probe instances from picking up the same monitors
|
|
89
|
+
*/
|
|
90
|
+
const claimedIds: Array<ObjectID> = await this.executeTransaction(
|
|
91
|
+
async (transactionalEntityManager: EntityManager) => {
|
|
92
|
+
/*
|
|
93
|
+
* First, select and lock the monitor probes that need to be processed
|
|
94
|
+
* FOR UPDATE SKIP LOCKED ensures that:
|
|
95
|
+
* 1. Rows are locked for this transaction
|
|
96
|
+
* 2. Rows already locked by other transactions are skipped
|
|
97
|
+
*/
|
|
98
|
+
const selectQuery: string = `
|
|
99
|
+
SELECT mp."_id"
|
|
100
|
+
FROM "MonitorProbe" mp
|
|
101
|
+
INNER JOIN "Monitor" m ON mp."monitorId" = m."_id"
|
|
102
|
+
INNER JOIN "Project" p ON mp."projectId" = p."_id"
|
|
103
|
+
WHERE mp."probeId" = $1
|
|
104
|
+
AND mp."isEnabled" = true
|
|
105
|
+
AND mp."deletedAt" IS NULL
|
|
106
|
+
AND (mp."nextPingAt" IS NULL OR mp."nextPingAt" <= $2)
|
|
107
|
+
AND m."disableActiveMonitoring" = false
|
|
108
|
+
AND m."disableActiveMonitoringBecauseOfManualIncident" = false
|
|
109
|
+
AND m."disableActiveMonitoringBecauseOfScheduledMaintenanceEvent" = false
|
|
110
|
+
AND m."deletedAt" IS NULL
|
|
111
|
+
AND p."deletedAt" IS NULL
|
|
112
|
+
AND (p."paymentProviderSubscriptionStatus" IS NULL
|
|
113
|
+
OR p."paymentProviderSubscriptionStatus" IN ('active', 'trialing'))
|
|
114
|
+
AND (p."paymentProviderMeteredSubscriptionStatus" IS NULL
|
|
115
|
+
OR p."paymentProviderMeteredSubscriptionStatus" IN ('active', 'trialing'))
|
|
116
|
+
ORDER BY mp."nextPingAt" ASC NULLS FIRST
|
|
117
|
+
LIMIT $3
|
|
118
|
+
FOR UPDATE OF mp SKIP LOCKED
|
|
119
|
+
`;
|
|
120
|
+
|
|
121
|
+
const selectedRows: Array<{ _id: string }> =
|
|
122
|
+
await transactionalEntityManager.query(selectQuery, [
|
|
123
|
+
data.probeId.toString(),
|
|
124
|
+
currentDate,
|
|
125
|
+
data.limit,
|
|
126
|
+
]);
|
|
127
|
+
|
|
128
|
+
if (selectedRows.length === 0) {
|
|
129
|
+
return [];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const ids: Array<string> = selectedRows.map((row: { _id: string }) => {
|
|
133
|
+
return row._id;
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
/*
|
|
137
|
+
* Update the claimed monitors to set nextPingAt to 1 minute from now
|
|
138
|
+
* This is a temporary value; the actual nextPingAt will be calculated
|
|
139
|
+
* based on the monitor's interval after the probe fetches the full details
|
|
140
|
+
*/
|
|
141
|
+
const tempNextPingAt: Date = OneUptimeDate.addRemoveMinutes(
|
|
142
|
+
currentDate,
|
|
143
|
+
1,
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
const updateQuery: string = `
|
|
147
|
+
UPDATE "MonitorProbe"
|
|
148
|
+
SET "lastPingAt" = $1, "nextPingAt" = $2
|
|
149
|
+
WHERE "_id" = ANY($3::uuid[])
|
|
150
|
+
`;
|
|
151
|
+
|
|
152
|
+
await transactionalEntityManager.query(updateQuery, [
|
|
153
|
+
currentDate,
|
|
154
|
+
tempNextPingAt,
|
|
155
|
+
ids,
|
|
156
|
+
]);
|
|
157
|
+
|
|
158
|
+
return ids.map((id: string) => {
|
|
159
|
+
return new ObjectID(id);
|
|
160
|
+
});
|
|
161
|
+
},
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
return claimedIds;
|
|
165
|
+
}
|
|
166
|
+
|
|
72
167
|
protected override async onBeforeCreate(
|
|
73
168
|
createBy: CreateBy<MonitorProbe>,
|
|
74
169
|
): Promise<OnCreate<MonitorProbe>> {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import DatabaseService from "./DatabaseService";
|
|
2
|
+
import Model from "../../Models/DatabaseModels/ProjectSCIMLog";
|
|
3
|
+
|
|
4
|
+
export class Service extends DatabaseService<Model> {
|
|
5
|
+
public constructor() {
|
|
6
|
+
super(Model);
|
|
7
|
+
this.hardDeleteItemsOlderThanInDays("createdAt", 3);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default new Service();
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import DatabaseService from "./DatabaseService";
|
|
2
|
+
import Model from "../../Models/DatabaseModels/StatusPageSCIMLog";
|
|
3
|
+
|
|
4
|
+
export class Service extends DatabaseService<Model> {
|
|
5
|
+
public constructor() {
|
|
6
|
+
super(Model);
|
|
7
|
+
this.hardDeleteItemsOlderThanInDays("createdAt", 3);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default new Service();
|
|
@@ -137,6 +137,37 @@ export class Service extends DatabaseService<Model> {
|
|
|
137
137
|
throw new BadDataException("Phone Number already verified");
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
+
// Check if Call notifications are enabled for this project
|
|
141
|
+
const project: Project | null = await ProjectService.findOneById({
|
|
142
|
+
id: item.projectId!,
|
|
143
|
+
props: {
|
|
144
|
+
isRoot: true,
|
|
145
|
+
},
|
|
146
|
+
select: {
|
|
147
|
+
enableCallNotifications: true,
|
|
148
|
+
smsOrCallCurrentBalanceInUSDCents: true,
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
if (!project) {
|
|
153
|
+
throw new BadDataException("Project not found");
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (!project.enableCallNotifications) {
|
|
157
|
+
throw new BadDataException(
|
|
158
|
+
"Call notifications are disabled for this project. Please enable them in Project Settings > Notification Settings.",
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (
|
|
163
|
+
(project.smsOrCallCurrentBalanceInUSDCents as number) <= 100 &&
|
|
164
|
+
IsBillingEnabled
|
|
165
|
+
) {
|
|
166
|
+
throw new BadDataException(
|
|
167
|
+
"Your SMS balance is low. Please recharge your SMS balance in Project Settings > Notification Settings.",
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
140
171
|
// generate new verification code
|
|
141
172
|
item.verificationCode = Text.generateRandomNumber(6);
|
|
142
173
|
|