@layer-ai/core 2.0.35 → 2.0.37
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.
|
@@ -25,6 +25,8 @@ export declare const db: {
|
|
|
25
25
|
setUserEnforcementType(userId: string, enforcementType: string): Promise<void>;
|
|
26
26
|
resetUserSpending(userId: string): Promise<void>;
|
|
27
27
|
getUsersToResetSpending(): Promise<string[]>;
|
|
28
|
+
resetDailyUsage(): Promise<void>;
|
|
29
|
+
resetMonthlyUsage(): Promise<void>;
|
|
28
30
|
recordSpendingAlert(userId: string): Promise<void>;
|
|
29
31
|
getApiKeyByHash(keyHash: string): Promise<ApiKey | null>;
|
|
30
32
|
createApiKey(userId: string, keyHash: string, keyPrefix: string, name: string): Promise<ApiKey>;
|
|
@@ -92,6 +94,7 @@ export declare const db: {
|
|
|
92
94
|
setGateSpendingPeriod(gateId: string, period: "monthly" | "daily"): Promise<void>;
|
|
93
95
|
trackGateSpending(gateId: string, cost: number): Promise<void>;
|
|
94
96
|
resetGateSpending(gateId: string): Promise<void>;
|
|
97
|
+
getGatesToResetSpending(): Promise<string[]>;
|
|
95
98
|
checkGateSpendingLimit(gateId: string): Promise<{
|
|
96
99
|
allowed: boolean;
|
|
97
100
|
reason?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../../src/lib/db/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAyB,WAAW,EAAE,MAAM,eAAe,CAAC;AAO5F,iBAAS,OAAO,IAAI,EAAE,CAAC,IAAI,CAqB1B;AA0BD,eAAO,MAAM,EAAE;gBAEK,MAAM,WAAW,GAAG,EAAE;0BASZ,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;oBAQnC,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;sBAQ3B,MAAM,gBAAgB,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;0BAQxC,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;4BAU7B,MAAM,GAAG,OAAO,CAAC;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,WAAW,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,oBAAoB,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;+BAexI,MAAM,eAAe,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;kCAOxC,MAAM,QAAQ,MAAM,GAAG,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;0BAexG,MAAM,UAAU,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;iCAO/B,MAAM,SAAS,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;mCAO1C,MAAM,mBAAmB,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;8BAOpD,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;+BAYrB,OAAO,CAAC,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../../src/lib/db/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAyB,WAAW,EAAE,MAAM,eAAe,CAAC;AAO5F,iBAAS,OAAO,IAAI,EAAE,CAAC,IAAI,CAqB1B;AA0BD,eAAO,MAAM,EAAE;gBAEK,MAAM,WAAW,GAAG,EAAE;0BASZ,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;oBAQnC,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;sBAQ3B,MAAM,gBAAgB,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;0BAQxC,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;4BAU7B,MAAM,GAAG,OAAO,CAAC;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,WAAW,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,oBAAoB,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;+BAexI,MAAM,eAAe,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;kCAOxC,MAAM,QAAQ,MAAM,GAAG,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;0BAexG,MAAM,UAAU,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;iCAO/B,MAAM,SAAS,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;mCAO1C,MAAM,mBAAmB,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;8BAOpD,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;+BAYrB,OAAO,CAAC,MAAM,EAAE,CAAC;uBASzB,OAAO,CAAC,IAAI,CAAC;yBAmBX,OAAO,CAAC,IAAI,CAAC;gCAkCN,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;6BAQzB,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;yBAQnC,MAAM,WAAW,MAAM,aAAa,MAAM,QAAQ,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;kCAQjE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;8BAO1B,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;qBAQnC,MAAM,UAAU,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;iCAS7B,MAAM,YAAY,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;+BAQjD,MAAM,UAAU,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;4BAQhD,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;uBAQ7B,MAAM,QAAQ,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;oBAoCpC,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;mBAQ9B,MAAM,QAAQ,GAAG,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;mBA8DxC,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;qBAUvB,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;2BAkBhC,MAAM,YACJ;QACR,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,SAAS,CAAC,EAAE,IAAI,CAAC;QACjB,OAAO,CAAC,EAAE,IAAI,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GACA,OAAO,CAAC,GAAG,EAAE,CAAC;iCAuCkB,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;6BAQhE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;qCAehB,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;2BAQhC,MAAM,YAAY,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;4BAQrD,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;8BASnD,MAAM,YACJ,MAAM,gBACF;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,aACrD,MAAM,GAChB,OAAO,CAAC,WAAW,CAAC;8BAWb,MAAM,YACJ,MAAM,gBACF;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,aACrD,MAAM,GAChB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;8BAWE,MAAM,YAAY,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;oCAQrC,MAAM,YAAY,MAAM,YAAY,OAAO,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;kCAW3E,MAAM,YAAY,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;qCAQzC,MAAM,GAAQ,OAAO,CAAC,WAAW,EAAE,CAAC;8BAahE,MAAM,QACR,OAAO,CAAC,IAAI,CAAC,aACR,MAAM,GAAG,MAAM,kBACV,MAAM,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC;2BA8Ca,MAAM,UAAS,MAAM,GAAQ,OAAO,CAAC,GAAG,EAAE,CAAC;2BAW3C,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC;+BAQxB,MAAM,UAAS,MAAM,GAAS,OAAO,CAAC,GAAG,EAAE,CAAC;8BAcnE,MAAM,UACN,MAAM,GAAG,IAAI,UACb,eAAe,GAAG,aAAa,GAAG,YAAY,GAAG,UAAU,WAC1D,GAAG,GACX,OAAO,CAAC,IAAI,CAAC;2BAQa,MAAM,UAAS,MAAM,GAAQ,OAAO,CAAC,GAAG,EAAE,CAAC;gCAWtC,MAAM,UAAS,MAAM,GAAS,OAAO,CAAC,GAAG,EAAE,CAAC;4BAchD,MAAM,UAAS,MAAM,GAAS,OAAO,CAAC,GAAG,EAAE,CAAC;yBAa/C,MAAM,aAAa,MAAM,UAAU,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;4BAiF7D,MAAM,GAAG,OAAO,CAAC;QAC7C,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,mBAAmB,EAAE,SAAS,GAAG,OAAO,CAAC;QACzC,eAAe,EAAE,MAAM,CAAC;QACxB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,mBAAmB,EAAE,YAAY,GAAG,OAAO,CAAC;QAC5C,cAAc,EAAE,QAAQ,GAAG,WAAW,CAAC;QACvC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;KAC5B,GAAG,IAAI,CAAC;iCAkC0B,MAAM,SAAS,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;uCAStC,MAAM,eAAe,YAAY,GAAG,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;kCAShE,MAAM,UAAU,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;8BASvD,MAAM,QAAQ,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;8BASpC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;+BASrB,OAAO,CAAC,MAAM,EAAE,CAAC;mCAab,MAAM,GAAG,OAAO,CAAC;QACpD,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,eAAe,EAAE,MAAM,CAAC;QACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,WAAW,EAAE,YAAY,GAAG,OAAO,CAAC;KACrC,CAAC;CAgDH,CAAC;AAEF,eAAe,OAAO,CAAC"}
|
package/dist/lib/db/postgres.js
CHANGED
|
@@ -118,6 +118,53 @@ export const db = {
|
|
|
118
118
|
AND status IN ('active', 'over_limit')`);
|
|
119
119
|
return result.rows.map(row => row.id);
|
|
120
120
|
},
|
|
121
|
+
async resetDailyUsage() {
|
|
122
|
+
// Resets at midnight America/Los_Angeles. The job runs hourly so it fires
|
|
123
|
+
// within an hour of PT midnight. We detect "a new PT day has started since
|
|
124
|
+
// last reset" by comparing the PT calendar date of last_daily_reset to today's PT date.
|
|
125
|
+
await getPool().query(`UPDATE users u
|
|
126
|
+
SET daily_requests_used = COALESCE((
|
|
127
|
+
SELECT SUM(ue.request_count)
|
|
128
|
+
FROM usage_events ue
|
|
129
|
+
WHERE ue.user_id = u.id
|
|
130
|
+
AND ue.used_platform_key = true
|
|
131
|
+
AND ue.created_at >= DATE_TRUNC('day', NOW() AT TIME ZONE 'America/Los_Angeles') AT TIME ZONE 'America/Los_Angeles'
|
|
132
|
+
), 0),
|
|
133
|
+
last_daily_reset = NOW()
|
|
134
|
+
WHERE (last_daily_reset AT TIME ZONE 'America/Los_Angeles')::date
|
|
135
|
+
< (NOW() AT TIME ZONE 'America/Los_Angeles')::date`);
|
|
136
|
+
},
|
|
137
|
+
async resetMonthlyUsage() {
|
|
138
|
+
// Resets at midnight PT on the same day-of-month as billing_cycle_start,
|
|
139
|
+
// matching Stripe-style same-day-each-month anchoring.
|
|
140
|
+
// End-of-month: if billing day > days in current month, fires on last day of month.
|
|
141
|
+
await getPool().query(`UPDATE users u
|
|
142
|
+
SET monthly_requests_used = COALESCE((
|
|
143
|
+
SELECT SUM(ue.request_count)
|
|
144
|
+
FROM usage_events ue
|
|
145
|
+
WHERE ue.user_id = u.id
|
|
146
|
+
AND ue.created_at >= u.billing_cycle_start AT TIME ZONE 'America/Los_Angeles'
|
|
147
|
+
), 0),
|
|
148
|
+
monthly_tokens_used = COALESCE((
|
|
149
|
+
SELECT SUM(ue.token_count)
|
|
150
|
+
FROM usage_events ue
|
|
151
|
+
WHERE ue.user_id = u.id
|
|
152
|
+
AND ue.used_platform_key = true
|
|
153
|
+
AND ue.created_at >= u.billing_cycle_start AT TIME ZONE 'America/Los_Angeles'
|
|
154
|
+
), 0),
|
|
155
|
+
billing_cycle_start = (DATE_TRUNC('day', NOW() AT TIME ZONE 'America/Los_Angeles'))::date
|
|
156
|
+
WHERE (
|
|
157
|
+
-- Same day-of-month as original cycle start has passed in PT, and it's been at least 28 days
|
|
158
|
+
EXTRACT(DAY FROM billing_cycle_start) <= EXTRACT(DAY FROM (NOW() AT TIME ZONE 'America/Los_Angeles'))
|
|
159
|
+
AND billing_cycle_start < (NOW() AT TIME ZONE 'America/Los_Angeles')::date - INTERVAL '28 days'
|
|
160
|
+
)
|
|
161
|
+
OR (
|
|
162
|
+
-- End-of-month clamping: billing day doesn't exist this month, fire on last day of month
|
|
163
|
+
EXTRACT(DAY FROM billing_cycle_start) > EXTRACT(DAY FROM DATE_TRUNC('month', NOW() AT TIME ZONE 'America/Los_Angeles') + INTERVAL '1 month' - INTERVAL '1 day')
|
|
164
|
+
AND (NOW() AT TIME ZONE 'America/Los_Angeles')::date = (DATE_TRUNC('month', NOW() AT TIME ZONE 'America/Los_Angeles') + INTERVAL '1 month' - INTERVAL '1 day')::date
|
|
165
|
+
AND billing_cycle_start < (NOW() AT TIME ZONE 'America/Los_Angeles')::date - INTERVAL '28 days'
|
|
166
|
+
)`);
|
|
167
|
+
},
|
|
121
168
|
async recordSpendingAlert(userId) {
|
|
122
169
|
await getPool().query('UPDATE users SET last_spending_alert_sent_at = NOW(), updated_at = NOW() WHERE id = $1', [userId]);
|
|
123
170
|
},
|
|
@@ -563,9 +610,19 @@ export const db = {
|
|
|
563
610
|
},
|
|
564
611
|
async resetGateSpending(gateId) {
|
|
565
612
|
await getPool().query(`UPDATE gates
|
|
566
|
-
SET spending_current = 0, spending_period_start = NOW(), updated_at = NOW()
|
|
613
|
+
SET spending_current = 0, spending_period_start = NOW(), spending_status = 'active', updated_at = NOW()
|
|
567
614
|
WHERE id = $1`, [gateId]);
|
|
568
615
|
},
|
|
616
|
+
async getGatesToResetSpending() {
|
|
617
|
+
const result = await getPool().query(`SELECT id FROM gates
|
|
618
|
+
WHERE spending_limit IS NOT NULL
|
|
619
|
+
AND (
|
|
620
|
+
(spending_limit_period = 'daily' AND spending_period_start < NOW() - INTERVAL '1 day')
|
|
621
|
+
OR
|
|
622
|
+
(spending_limit_period = 'monthly' AND spending_period_start < NOW() - INTERVAL '30 days')
|
|
623
|
+
)`);
|
|
624
|
+
return result.rows.map(row => row.id);
|
|
625
|
+
},
|
|
569
626
|
async checkGateSpendingLimit(gateId) {
|
|
570
627
|
const spending = await this.getGateSpending(gateId);
|
|
571
628
|
if (!spending) {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export declare const spendingJobs: {
|
|
2
2
|
syncSpendingJob(): Promise<void>;
|
|
3
3
|
resetSpendingPeriodsJob(): Promise<void>;
|
|
4
|
+
resetGateSpendingPeriodsJob(): Promise<void>;
|
|
5
|
+
resetUsageCountersJob(): Promise<void>;
|
|
4
6
|
startScheduledJobs(): void;
|
|
5
7
|
};
|
|
6
8
|
//# sourceMappingURL=spending-jobs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spending-jobs.d.ts","sourceRoot":"","sources":["../../src/lib/spending-jobs.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,YAAY;uBACE,OAAO,CAAC,IAAI,CAAC;+BASL,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"spending-jobs.d.ts","sourceRoot":"","sources":["../../src/lib/spending-jobs.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,YAAY;uBACE,OAAO,CAAC,IAAI,CAAC;+BASL,OAAO,CAAC,IAAI,CAAC;mCAwBT,OAAO,CAAC,IAAI,CAAC;6BAuBnB,OAAO,CAAC,IAAI,CAAC;0BAWtB,IAAI;CAqC3B,CAAC"}
|
|
@@ -31,6 +31,36 @@ export const spendingJobs = {
|
|
|
31
31
|
console.error('[Spending Job] Reset failed:', error);
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
|
+
async resetGateSpendingPeriodsJob() {
|
|
35
|
+
console.log('[Spending Job] Checking for gate spending periods to reset...');
|
|
36
|
+
try {
|
|
37
|
+
const gatesToReset = await db.getGatesToResetSpending();
|
|
38
|
+
if (gatesToReset.length === 0) {
|
|
39
|
+
console.log('[Spending Job] No gates need reset');
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
console.log(`[Spending Job] Resetting ${gatesToReset.length} gates`);
|
|
43
|
+
for (const gateId of gatesToReset) {
|
|
44
|
+
await db.resetGateSpending(gateId);
|
|
45
|
+
console.log(`[Spending Job] Reset gate ${gateId}`);
|
|
46
|
+
}
|
|
47
|
+
console.log('[Spending Job] Gate reset complete');
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console.error('[Spending Job] Gate reset failed:', error);
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
async resetUsageCountersJob() {
|
|
54
|
+
console.log('[Spending Job] Checking for usage counters to reset...');
|
|
55
|
+
try {
|
|
56
|
+
await db.resetDailyUsage();
|
|
57
|
+
await db.resetMonthlyUsage();
|
|
58
|
+
console.log('[Spending Job] Usage counters reset complete');
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
console.error('[Spending Job] Usage counter reset failed:', error);
|
|
62
|
+
}
|
|
63
|
+
},
|
|
34
64
|
startScheduledJobs() {
|
|
35
65
|
// Sync Redis to DB every 5 minutes
|
|
36
66
|
setInterval(() => {
|
|
@@ -43,6 +73,12 @@ export const spendingJobs = {
|
|
|
43
73
|
this.resetSpendingPeriodsJob().catch(err => {
|
|
44
74
|
console.error('[Spending Job] Reset interval error:', err);
|
|
45
75
|
});
|
|
76
|
+
this.resetGateSpendingPeriodsJob().catch(err => {
|
|
77
|
+
console.error('[Spending Job] Gate reset interval error:', err);
|
|
78
|
+
});
|
|
79
|
+
this.resetUsageCountersJob().catch(err => {
|
|
80
|
+
console.error('[Spending Job] Usage counter reset interval error:', err);
|
|
81
|
+
});
|
|
46
82
|
}, 60 * 60 * 1000);
|
|
47
83
|
// Run once on startup
|
|
48
84
|
this.syncSpendingJob().catch(err => {
|
|
@@ -51,6 +87,12 @@ export const spendingJobs = {
|
|
|
51
87
|
this.resetSpendingPeriodsJob().catch(err => {
|
|
52
88
|
console.error('[Spending Job] Initial reset error:', err);
|
|
53
89
|
});
|
|
90
|
+
this.resetGateSpendingPeriodsJob().catch(err => {
|
|
91
|
+
console.error('[Spending Job] Initial gate reset error:', err);
|
|
92
|
+
});
|
|
93
|
+
this.resetUsageCountersJob().catch(err => {
|
|
94
|
+
console.error('[Spending Job] Initial usage counter reset error:', err);
|
|
95
|
+
});
|
|
54
96
|
console.log('[Spending Job] Scheduled jobs started');
|
|
55
97
|
},
|
|
56
98
|
};
|