@oneuptime/common 10.4.3 → 10.4.5

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.
@@ -91,7 +91,17 @@ export class Service extends DatabaseService<Model> {
91
91
  );
92
92
  }
93
93
 
94
+ /*
95
+ * If the project has its own default Twilio config, OneUptime does not
96
+ * charge the project's Call/SMS balance, so the low-balance check does not apply.
97
+ */
98
+ const projectTwilioConfig: TwilioConfig | undefined =
99
+ await ProjectCallSMSConfigService.getProjectDefaultTwilioConfig(
100
+ createBy.data.projectId!,
101
+ );
102
+
94
103
  if (
104
+ !projectTwilioConfig &&
95
105
  (project.smsOrCallCurrentBalanceInUSDCents as number) <= 100 &&
96
106
  IsBillingEnabled
97
107
  ) {
@@ -161,7 +171,17 @@ export class Service extends DatabaseService<Model> {
161
171
  );
162
172
  }
163
173
 
174
+ /*
175
+ * If the project has its own default Twilio config, OneUptime does not
176
+ * charge the project's Call/SMS balance, so the low-balance check does not apply.
177
+ */
178
+ const projectTwilioConfig: TwilioConfig | undefined =
179
+ await ProjectCallSMSConfigService.getProjectDefaultTwilioConfig(
180
+ item.projectId!,
181
+ );
182
+
164
183
  if (
184
+ !projectTwilioConfig &&
165
185
  (project.smsOrCallCurrentBalanceInUSDCents as number) <= 100 &&
166
186
  IsBillingEnabled
167
187
  ) {
@@ -3,8 +3,10 @@ import CreateBy from "../Types/Database/CreateBy";
3
3
  import { OnCreate } from "../Types/Database/Hooks";
4
4
  import logger from "../Utils/Logger";
5
5
  import DatabaseService from "./DatabaseService";
6
+ import ProjectCallSMSConfigService from "./ProjectCallSMSConfigService";
6
7
  import ProjectService from "./ProjectService";
7
8
  import SmsService from "./SmsService";
9
+ import TwilioConfig from "../../Types/CallAndSMS/TwilioConfig";
8
10
  import BadDataException from "../../Types/Exception/BadDataException";
9
11
  import ObjectID from "../../Types/ObjectID";
10
12
  import Text from "../../Types/Text";
@@ -48,7 +50,17 @@ export class Service extends DatabaseService<Model> {
48
50
  );
49
51
  }
50
52
 
53
+ /*
54
+ * If the project has its own default Twilio config, OneUptime does not
55
+ * charge the project's SMS balance, so the low-balance check does not apply.
56
+ */
57
+ const projectTwilioConfig: TwilioConfig | undefined =
58
+ await ProjectCallSMSConfigService.getProjectDefaultTwilioConfig(
59
+ createBy.data.projectId!,
60
+ );
61
+
51
62
  if (
63
+ !projectTwilioConfig &&
52
64
  (project.smsOrCallCurrentBalanceInUSDCents as number) <= 100 &&
53
65
  IsBillingEnabled
54
66
  ) {
@@ -141,7 +153,17 @@ export class Service extends DatabaseService<Model> {
141
153
  );
142
154
  }
143
155
 
156
+ /*
157
+ * If the project has its own default Twilio config, OneUptime does not
158
+ * charge the project's SMS balance, so the low-balance check does not apply.
159
+ */
160
+ const projectTwilioConfig: TwilioConfig | undefined =
161
+ await ProjectCallSMSConfigService.getProjectDefaultTwilioConfig(
162
+ item.projectId!,
163
+ );
164
+
144
165
  if (
166
+ !projectTwilioConfig &&
145
167
  (project.smsOrCallCurrentBalanceInUSDCents as number) <= 100 &&
146
168
  IsBillingEnabled
147
169
  ) {
@@ -90,7 +90,17 @@ export class Service extends DatabaseService<Model> {
90
90
  );
91
91
  }
92
92
 
93
+ /*
94
+ * If the project has its own default Twilio config, OneUptime does not
95
+ * charge the project's SMS balance, so the low-balance check does not apply.
96
+ */
97
+ const projectTwilioConfig: TwilioConfig | undefined =
98
+ await ProjectCallSMSConfigService.getProjectDefaultTwilioConfig(
99
+ createBy.data.projectId!,
100
+ );
101
+
93
102
  if (
103
+ !projectTwilioConfig &&
94
104
  (project.smsOrCallCurrentBalanceInUSDCents as number) <= 100 &&
95
105
  IsBillingEnabled
96
106
  ) {
@@ -161,7 +171,17 @@ export class Service extends DatabaseService<Model> {
161
171
  );
162
172
  }
163
173
 
174
+ /*
175
+ * If the project has its own default Twilio config, OneUptime does not
176
+ * charge the project's SMS balance, so the low-balance check does not apply.
177
+ */
178
+ const projectTwilioConfig: TwilioConfig | undefined =
179
+ await ProjectCallSMSConfigService.getProjectDefaultTwilioConfig(
180
+ item.projectId!,
181
+ );
182
+
164
183
  if (
184
+ !projectTwilioConfig &&
165
185
  (project.smsOrCallCurrentBalanceInUSDCents as number) <= 100 &&
166
186
  IsBillingEnabled
167
187
  ) {
@@ -1,4 +1,5 @@
1
1
  import ObjectID from "../../ObjectID";
2
+ import DashboardChartType from "../Chart/ChartType";
2
3
  import DashboardComponentType from "../DashboardComponentType";
3
4
  import BaseComponent from "./DashboardBaseComponent";
4
5
 
@@ -21,5 +22,6 @@ export default interface DashboardHostMetricChartComponent
21
22
  description?: string | undefined;
22
23
  metricKind?: HostMetricKind | undefined;
23
24
  hostIdentifier?: string | undefined;
25
+ chartType?: DashboardChartType | undefined;
24
26
  };
25
27
  }
@@ -11,6 +11,7 @@ import IncidentMetricType from "../Incident/IncidentMetricType";
11
11
  import MonitorMetricType from "../Monitor/MonitorMetricType";
12
12
  import MetricDashboardMetricType from "../Metrics/MetricDashboardMetricType";
13
13
  import { DashboardValueTrendDirection } from "./DashboardComponents/DashboardValueComponent";
14
+ import { HostMetricKind } from "./DashboardComponents/DashboardHostMetricChartComponent";
14
15
 
15
16
  /*
16
17
  * Trace / Exception / Profiles entries are intentionally not in this
@@ -25,6 +26,7 @@ export enum DashboardTemplateType {
25
26
  Monitor = "Monitor",
26
27
  Incident = "Incident",
27
28
  Kubernetes = "Kubernetes",
29
+ Host = "Host",
28
30
  Metrics = "Metrics",
29
31
  }
30
32
 
@@ -63,6 +65,13 @@ export const DashboardTemplates: Array<DashboardTemplate> = [
63
65
  "Pod/node CPU and memory averages, utilization gauges, live pod and node lists, network I/O, restarts, and cluster logs.",
64
66
  icon: IconProp.Kubernetes,
65
67
  },
68
+ {
69
+ type: DashboardTemplateType.Host,
70
+ name: "Hosts Dashboard",
71
+ description:
72
+ "Per-host CPU, memory, disk and network charts, a live host inventory, CPU utilization gauge, process counts, and recent logs.",
73
+ icon: IconProp.Server,
74
+ },
66
75
  {
67
76
  type: DashboardTemplateType.Metrics,
68
77
  name: "Metrics Dashboard",
@@ -374,6 +383,62 @@ function createKubernetesNodeListComponent(data: {
374
383
  };
375
384
  }
376
385
 
386
+ function createHostListComponent(data: {
387
+ title: string;
388
+ top: number;
389
+ left: number;
390
+ width: number;
391
+ height: number;
392
+ maxRows?: number;
393
+ statusFilter?: string;
394
+ osTypeFilter?: string;
395
+ }): DashboardBaseComponent {
396
+ return {
397
+ _type: ObjectType.DashboardComponent,
398
+ componentType: DashboardComponentType.HostList,
399
+ componentId: ObjectID.generate(),
400
+ topInDashboardUnits: data.top,
401
+ leftInDashboardUnits: data.left,
402
+ widthInDashboardUnits: data.width,
403
+ heightInDashboardUnits: data.height,
404
+ minHeightInDashboardUnits: 3,
405
+ minWidthInDashboardUnits: 6,
406
+ arguments: {
407
+ title: data.title,
408
+ maxRows: data.maxRows ?? 25,
409
+ statusFilter: data.statusFilter,
410
+ osTypeFilter: data.osTypeFilter,
411
+ },
412
+ };
413
+ }
414
+
415
+ function createHostMetricChartComponent(data: {
416
+ title: string;
417
+ description?: string;
418
+ metricKind: HostMetricKind;
419
+ top: number;
420
+ left: number;
421
+ width: number;
422
+ height: number;
423
+ }): DashboardBaseComponent {
424
+ return {
425
+ _type: ObjectType.DashboardComponent,
426
+ componentType: DashboardComponentType.HostMetricChart,
427
+ componentId: ObjectID.generate(),
428
+ topInDashboardUnits: data.top,
429
+ leftInDashboardUnits: data.left,
430
+ widthInDashboardUnits: data.width,
431
+ heightInDashboardUnits: data.height,
432
+ minHeightInDashboardUnits: 3,
433
+ minWidthInDashboardUnits: 6,
434
+ arguments: {
435
+ title: data.title,
436
+ description: data.description,
437
+ metricKind: data.metricKind,
438
+ },
439
+ };
440
+ }
441
+
377
442
  // -- Dashboard configs --
378
443
 
379
444
  function createMonitorDashboardConfig(): DashboardViewConfig {
@@ -1384,6 +1449,229 @@ function createMetricsDashboardConfig(): DashboardViewConfig {
1384
1449
  };
1385
1450
  }
1386
1451
 
1452
+ function createHostDashboardConfig(): DashboardViewConfig {
1453
+ /*
1454
+ * Layout notes:
1455
+ *
1456
+ * - The HostMetricChart widget groups by `host.name` and plots one
1457
+ * series per host (or a single series when filtered to one host).
1458
+ * The OTel host receiver emits `system.cpu.utilization` and
1459
+ * `system.memory.utilization` as [0, 1] ratios, which Value/Gauge
1460
+ * widgets auto-scale to percent at render time (see
1461
+ * splitFormattedValue / isFractionScale).
1462
+ *
1463
+ * - The Value widget for "Avg Memory" uses `system.memory.usage`
1464
+ * (bytes) and is auto-formatted to MB/GB by ValueFormatter, since
1465
+ * `system.memory.utilization` is not always emitted by default OTel
1466
+ * host metrics.
1467
+ *
1468
+ * - Disk and Network I/O Value widgets aggregate the raw byte counters
1469
+ * with Sum. HostMetricChart turns these into per-second rates for
1470
+ * the chart view; the Value tile shows the unrated total so users
1471
+ * reading "Disk I/O" against the time window get an absolute byte
1472
+ * figure rather than a noisy snapshot.
1473
+ */
1474
+ const components: Array<DashboardBaseComponent> = [
1475
+ // Row 0: Title
1476
+ createTextComponent({
1477
+ text: "Hosts Dashboard",
1478
+ top: 0,
1479
+ left: 0,
1480
+ width: 12,
1481
+ height: 1,
1482
+ isBold: true,
1483
+ }),
1484
+
1485
+ // Row 1: Key host metrics
1486
+ createValueComponent({
1487
+ title: "Avg CPU",
1488
+ top: 1,
1489
+ left: 0,
1490
+ width: 3,
1491
+ metricConfig: {
1492
+ metricName: MetricDashboardMetricType.SystemCpuUtilization,
1493
+ aggregationType: MetricsAggregationType.Avg,
1494
+ },
1495
+ trendDirection: DashboardValueTrendDirection.HigherIsWorse,
1496
+ }),
1497
+ createValueComponent({
1498
+ title: "Avg Memory",
1499
+ top: 1,
1500
+ left: 3,
1501
+ width: 3,
1502
+ metricConfig: {
1503
+ metricName: MetricDashboardMetricType.SystemMemoryUsage,
1504
+ aggregationType: MetricsAggregationType.Avg,
1505
+ },
1506
+ trendDirection: DashboardValueTrendDirection.HigherIsWorse,
1507
+ }),
1508
+ createValueComponent({
1509
+ title: "Disk I/O",
1510
+ top: 1,
1511
+ left: 6,
1512
+ width: 3,
1513
+ metricConfig: {
1514
+ metricName: MetricDashboardMetricType.SystemDiskIo,
1515
+ aggregationType: MetricsAggregationType.Sum,
1516
+ },
1517
+ trendDirection: DashboardValueTrendDirection.HigherIsBetter,
1518
+ }),
1519
+ createValueComponent({
1520
+ title: "Network I/O",
1521
+ top: 1,
1522
+ left: 9,
1523
+ width: 3,
1524
+ metricConfig: {
1525
+ metricName: MetricDashboardMetricType.SystemNetworkIo,
1526
+ aggregationType: MetricsAggregationType.Sum,
1527
+ },
1528
+ trendDirection: DashboardValueTrendDirection.HigherIsBetter,
1529
+ }),
1530
+
1531
+ // Row 2-4: Per-host CPU and Memory charts
1532
+ createHostMetricChartComponent({
1533
+ title: "CPU Utilization by Host",
1534
+ metricKind: HostMetricKind.CpuUtilization,
1535
+ top: 2,
1536
+ left: 0,
1537
+ width: 6,
1538
+ height: 3,
1539
+ }),
1540
+ createHostMetricChartComponent({
1541
+ title: "Memory Usage by Host",
1542
+ metricKind: HostMetricKind.MemoryUsage,
1543
+ top: 2,
1544
+ left: 6,
1545
+ width: 6,
1546
+ height: 3,
1547
+ }),
1548
+
1549
+ // Row 5: Section header
1550
+ createTextComponent({
1551
+ text: "Hosts",
1552
+ top: 5,
1553
+ left: 0,
1554
+ width: 12,
1555
+ height: 1,
1556
+ isBold: true,
1557
+ }),
1558
+
1559
+ /*
1560
+ * Row 6-9: Live host inventory. The widget reads the Postgres host
1561
+ * snapshot, so the header shows the true current count and rows
1562
+ * link to per-host detail pages.
1563
+ */
1564
+ createHostListComponent({
1565
+ title: "All Hosts",
1566
+ top: 6,
1567
+ left: 0,
1568
+ width: 12,
1569
+ height: 4,
1570
+ maxRows: 25,
1571
+ }),
1572
+
1573
+ // Row 10: Section header
1574
+ createTextComponent({
1575
+ text: "Resource Health",
1576
+ top: 10,
1577
+ left: 0,
1578
+ width: 12,
1579
+ height: 1,
1580
+ isBold: true,
1581
+ }),
1582
+
1583
+ /*
1584
+ * Row 11-13: CPU gauge (auto-scaled from [0,1] ratio to percent),
1585
+ * alongside the filesystem-usage chart so capacity pressure is
1586
+ * visible per host.
1587
+ */
1588
+ createGaugeComponent({
1589
+ title: "Avg CPU Utilization",
1590
+ top: 11,
1591
+ left: 0,
1592
+ width: 4,
1593
+ height: 3,
1594
+ minValue: 0,
1595
+ maxValue: 100,
1596
+ warningThreshold: 70,
1597
+ criticalThreshold: 90,
1598
+ metricConfig: {
1599
+ metricName: MetricDashboardMetricType.SystemCpuUtilization,
1600
+ aggregationType: MetricsAggregationType.Avg,
1601
+ },
1602
+ }),
1603
+ createHostMetricChartComponent({
1604
+ title: "Filesystem Usage by Host",
1605
+ metricKind: HostMetricKind.Filesystem,
1606
+ top: 11,
1607
+ left: 4,
1608
+ width: 8,
1609
+ height: 3,
1610
+ }),
1611
+
1612
+ // Row 14: Section header
1613
+ createTextComponent({
1614
+ text: "I/O Activity",
1615
+ top: 14,
1616
+ left: 0,
1617
+ width: 12,
1618
+ height: 1,
1619
+ isBold: true,
1620
+ }),
1621
+
1622
+ // Row 15-17: Disk and network I/O rates per host
1623
+ createHostMetricChartComponent({
1624
+ title: "Disk I/O by Host",
1625
+ metricKind: HostMetricKind.DiskIo,
1626
+ top: 15,
1627
+ left: 0,
1628
+ width: 6,
1629
+ height: 3,
1630
+ }),
1631
+ createHostMetricChartComponent({
1632
+ title: "Network I/O by Host",
1633
+ metricKind: HostMetricKind.NetworkIo,
1634
+ top: 15,
1635
+ left: 6,
1636
+ width: 6,
1637
+ height: 3,
1638
+ }),
1639
+
1640
+ // Row 18: Section header
1641
+ createTextComponent({
1642
+ text: "Processes & Logs",
1643
+ top: 18,
1644
+ left: 0,
1645
+ width: 12,
1646
+ height: 1,
1647
+ isBold: true,
1648
+ }),
1649
+
1650
+ // Row 19-21: Process count chart and recent logs
1651
+ createHostMetricChartComponent({
1652
+ title: "Process Count by Host",
1653
+ metricKind: HostMetricKind.ProcessCount,
1654
+ top: 19,
1655
+ left: 0,
1656
+ width: 6,
1657
+ height: 3,
1658
+ }),
1659
+ createLogStreamComponent({
1660
+ title: "Recent Logs",
1661
+ top: 19,
1662
+ left: 6,
1663
+ width: 6,
1664
+ height: 3,
1665
+ }),
1666
+ ];
1667
+
1668
+ return {
1669
+ _type: ObjectType.DashboardViewConfig,
1670
+ components,
1671
+ heightInDashboardUnits: Math.max(DashboardSize.heightInDashboardUnits, 22),
1672
+ };
1673
+ }
1674
+
1387
1675
  export function getTemplateConfig(
1388
1676
  type: DashboardTemplateType,
1389
1677
  ): DashboardViewConfig | null {
@@ -1394,6 +1682,8 @@ export function getTemplateConfig(
1394
1682
  return createIncidentDashboardConfig();
1395
1683
  case DashboardTemplateType.Kubernetes:
1396
1684
  return createKubernetesDashboardConfig();
1685
+ case DashboardTemplateType.Host:
1686
+ return createHostDashboardConfig();
1397
1687
  case DashboardTemplateType.Metrics:
1398
1688
  return createMetricsDashboardConfig();
1399
1689
  case DashboardTemplateType.Blank:
@@ -10,6 +10,7 @@ import {
10
10
  ComponentInputType,
11
11
  } from "../../../Types/Dashboard/DashboardComponents/ComponentArgument";
12
12
  import DashboardComponentType from "../../../Types/Dashboard/DashboardComponentType";
13
+ import DashboardChartType from "../../../Types/Dashboard/Chart/ChartType";
13
14
 
14
15
  const DataSection: ComponentArgumentSection = {
15
16
  name: "Data Source",
@@ -38,6 +39,7 @@ export default class DashboardHostMetricChartComponentUtil extends DashboardBase
38
39
  minWidthInDashboardUnits: 6,
39
40
  arguments: {
40
41
  metricKind: HostMetricKind.CpuUtilization,
42
+ chartType: DashboardChartType.Line,
41
43
  },
42
44
  };
43
45
  }
@@ -80,6 +82,33 @@ export default class DashboardHostMetricChartComponentUtil extends DashboardBase
80
82
  section: DataSection,
81
83
  });
82
84
 
85
+ args.push({
86
+ name: "Chart Type",
87
+ description: "How the data will be visualized",
88
+ required: false,
89
+ type: ComponentInputType.Dropdown,
90
+ id: "chartType",
91
+ section: DisplaySection,
92
+ dropdownOptions: [
93
+ {
94
+ label: "Line Chart",
95
+ value: DashboardChartType.Line,
96
+ },
97
+ {
98
+ label: "Bar Chart",
99
+ value: DashboardChartType.Bar,
100
+ },
101
+ {
102
+ label: "Area Chart",
103
+ value: DashboardChartType.Area,
104
+ },
105
+ {
106
+ label: "Stacked Area Chart",
107
+ value: DashboardChartType.StackedArea,
108
+ },
109
+ ],
110
+ });
111
+
83
112
  args.push({
84
113
  name: "Title",
85
114
  description: "Displayed above the chart",
@@ -0,0 +1,98 @@
1
+ import Includes from "../../Types/BaseDatabase/Includes";
2
+ import DashboardVariable, {
3
+ DashboardVariableType,
4
+ } from "../../Types/Dashboard/DashboardVariable";
5
+ import DashboardVariableInterpolation, {
6
+ ResolvedVariableValue,
7
+ } from "./VariableInterpolation";
8
+
9
+ /*
10
+ * Maps a dashboard variable's OpenTelemetry attribute key (e.g.
11
+ * "host.name", "k8s.namespace.name") to the Postgres model column
12
+ * that should be filtered for a given list widget. Each list widget
13
+ * declares the subset of attribute keys it understands.
14
+ */
15
+ export type AttributeToColumnMap = Record<string, string>;
16
+
17
+ /*
18
+ * Applies dashboard variables to a Postgres model query at render time.
19
+ *
20
+ * Companion to `DashboardVariableInterpolation`, which targets OTel
21
+ * attribute filters used by metric/log widgets. Resource list widgets
22
+ * (Host, Kubernetes resources, Docker resources) query the model store
23
+ * by column instead, so this helper translates the variable's bound
24
+ * OTel attribute key into the matching column name before writing the
25
+ * predicate. An empty/unset selection removes any prior filter on that
26
+ * column so the list falls back to its widget-default view.
27
+ */
28
+ export default class DashboardModelQueryInterpolation {
29
+ public static applyToQuery(
30
+ query: Record<string, unknown>,
31
+ variables: Array<DashboardVariable> | undefined,
32
+ attributeToColumn: AttributeToColumnMap,
33
+ ): Record<string, unknown> {
34
+ if (!variables || variables.length === 0) {
35
+ return query;
36
+ }
37
+
38
+ const mappedAttributeKeys: Array<string> = Object.keys(attributeToColumn);
39
+ if (mappedAttributeKeys.length === 0) {
40
+ return query;
41
+ }
42
+
43
+ const relevantVariables: Array<DashboardVariable> = variables.filter(
44
+ (v: DashboardVariable) => {
45
+ return (
46
+ v.type === DashboardVariableType.TelemetryAttribute &&
47
+ Boolean(v.attributeKey) &&
48
+ mappedAttributeKeys.includes(v.attributeKey as string)
49
+ );
50
+ },
51
+ );
52
+
53
+ if (relevantVariables.length === 0) {
54
+ return query;
55
+ }
56
+
57
+ let next: Record<string, unknown> = query;
58
+ let changed: boolean = false;
59
+
60
+ for (const variable of relevantVariables) {
61
+ const column: string = attributeToColumn[
62
+ variable.attributeKey as string
63
+ ] as string;
64
+ const resolved: ResolvedVariableValue | undefined =
65
+ DashboardVariableInterpolation.resolveValue(variable);
66
+
67
+ if (!resolved) {
68
+ if (column in next) {
69
+ if (!changed) {
70
+ next = { ...query };
71
+ changed = true;
72
+ }
73
+ delete next[column];
74
+ }
75
+ continue;
76
+ }
77
+
78
+ if (resolved.multi && resolved.multi.length > 0) {
79
+ if (!changed) {
80
+ next = { ...query };
81
+ changed = true;
82
+ }
83
+ next[column] = new Includes(resolved.multi);
84
+ continue;
85
+ }
86
+
87
+ if (resolved.scalar !== undefined && next[column] !== resolved.scalar) {
88
+ if (!changed) {
89
+ next = { ...query };
90
+ changed = true;
91
+ }
92
+ next[column] = resolved.scalar;
93
+ }
94
+ }
95
+
96
+ return changed ? next : query;
97
+ }
98
+ }
@@ -76,7 +76,13 @@ export class Service extends DatabaseService {
76
76
  if (!project.enableCallNotifications) {
77
77
  throw new BadDataException("Call notifications are disabled for this project. Please enable them in Project Settings > Notification Settings.");
78
78
  }
79
- if (project.smsOrCallCurrentBalanceInUSDCents <= 100 &&
79
+ /*
80
+ * If the project has its own default Twilio config, OneUptime does not
81
+ * charge the project's Call/SMS balance, so the low-balance check does not apply.
82
+ */
83
+ const projectTwilioConfig = await ProjectCallSMSConfigService.getProjectDefaultTwilioConfig(createBy.data.projectId);
84
+ if (!projectTwilioConfig &&
85
+ project.smsOrCallCurrentBalanceInUSDCents <= 100 &&
80
86
  IsBillingEnabled) {
81
87
  throw new BadDataException("Your SMS balance is low. Please recharge your SMS balance in Project Settings > Notification Settings.");
82
88
  }
@@ -124,7 +130,13 @@ export class Service extends DatabaseService {
124
130
  if (!project.enableCallNotifications) {
125
131
  throw new BadDataException("Call notifications are disabled for this project. Please enable them in Project Settings > Notification Settings.");
126
132
  }
127
- if (project.smsOrCallCurrentBalanceInUSDCents <= 100 &&
133
+ /*
134
+ * If the project has its own default Twilio config, OneUptime does not
135
+ * charge the project's Call/SMS balance, so the low-balance check does not apply.
136
+ */
137
+ const projectTwilioConfig = await ProjectCallSMSConfigService.getProjectDefaultTwilioConfig(item.projectId);
138
+ if (!projectTwilioConfig &&
139
+ project.smsOrCallCurrentBalanceInUSDCents <= 100 &&
128
140
  IsBillingEnabled) {
129
141
  throw new BadDataException("Your SMS balance is low. Please recharge your SMS balance in Project Settings > Notification Settings.");
130
142
  }
@@ -1 +1 @@
1
- {"version":3,"file":"UserCallService.js","sourceRoot":"","sources":["../../../../Server/Services/UserCallService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"UserCallService.js","sourceRoot":"","sources":["../../../../Server/Services/UserCallService.ts"],"names":[],"mappings":"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"}