@undefineds.co/xpod 0.3.29 → 0.3.32
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/dist/api/auth/AuthContext.d.ts +3 -2
- package/dist/api/auth/AuthContext.js +2 -1
- package/dist/api/auth/AuthContext.js.map +1 -1
- package/dist/api/auth/ClientCredentialsAuthenticator.d.ts +2 -12
- package/dist/api/auth/ClientCredentialsAuthenticator.js +4 -4
- package/dist/api/auth/ClientCredentialsAuthenticator.js.map +1 -1
- package/dist/api/auth/ServiceTokenAuthenticator.d.ts +2 -2
- package/dist/api/auth/ServiceTokenAuthenticator.js.map +1 -1
- package/dist/api/container/business-token.d.ts +1 -1
- package/dist/api/container/business-token.js +5 -1
- package/dist/api/container/business-token.js.map +1 -1
- package/dist/api/container/common.js +14 -10
- package/dist/api/container/common.js.map +1 -1
- package/dist/api/container/routes.js +16 -3
- package/dist/api/container/routes.js.map +1 -1
- package/dist/api/container/types.d.ts +2 -4
- package/dist/api/container/types.js.map +1 -1
- package/dist/api/handlers/ChatHandler.d.ts +1 -1
- package/dist/api/handlers/ChatHandler.js +1 -1
- package/dist/api/handlers/ChatHandler.js.map +1 -1
- package/dist/api/handlers/EdgeNodeSignalHandler.js +3 -1
- package/dist/api/handlers/EdgeNodeSignalHandler.js.map +1 -1
- package/dist/api/handlers/PodManagementHandler.d.ts +2 -0
- package/dist/api/handlers/PodManagementHandler.js +114 -12
- package/dist/api/handlers/PodManagementHandler.js.map +1 -1
- package/dist/api/handlers/ProvisionHandler.d.ts +27 -0
- package/dist/api/handlers/ProvisionHandler.js +339 -32
- package/dist/api/handlers/ProvisionHandler.js.map +1 -1
- package/dist/api/handlers/QuotaHandler.js +0 -12
- package/dist/api/handlers/QuotaHandler.js.map +1 -1
- package/dist/api/handlers/index.d.ts +0 -1
- package/dist/api/handlers/index.js +0 -1
- package/dist/api/handlers/index.js.map +1 -1
- package/dist/api/runtime.js +3 -3
- package/dist/api/runtime.js.map +1 -1
- package/dist/authorization/PodAuthorizationResources.d.ts +1 -0
- package/dist/authorization/PodAuthorizationResources.js +36 -4
- package/dist/authorization/PodAuthorizationResources.js.map +1 -1
- package/dist/components/context.jsonld +12 -0
- package/dist/edge/EdgeNodeAgent.d.ts +1 -1
- package/dist/edge/EdgeNodeAgent.js +1 -1
- package/dist/edge/EdgeNodeAgent.js.map +1 -1
- package/dist/edge/EdgeNodeDnsCoordinator.d.ts +1 -0
- package/dist/edge/EdgeNodeDnsCoordinator.js +9 -3
- package/dist/edge/EdgeNodeDnsCoordinator.js.map +1 -1
- package/dist/edge/EdgeNodeDnsCoordinator.jsonld +4 -0
- package/dist/edge/EdgeNodeHealthProbeService.d.ts +3 -0
- package/dist/edge/EdgeNodeHealthProbeService.js +22 -2
- package/dist/edge/EdgeNodeHealthProbeService.js.map +1 -1
- package/dist/edge/EdgeNodeHealthProbeService.jsonld +12 -0
- package/dist/http/ClusterIngressRouter.js +6 -3
- package/dist/http/ClusterIngressRouter.js.map +1 -1
- package/dist/http/ClusterWebSocketConfigurator.js +6 -2
- package/dist/http/ClusterWebSocketConfigurator.js.map +1 -1
- package/dist/http/EdgeNodeDirectDebugHttpHandler.d.ts +2 -0
- package/dist/http/EdgeNodeDirectDebugHttpHandler.js +18 -3
- package/dist/http/EdgeNodeDirectDebugHttpHandler.js.map +1 -1
- package/dist/http/EdgeNodeDirectDebugHttpHandler.jsonld +8 -0
- package/dist/http/EdgeNodeProxyHttpHandler.js +6 -2
- package/dist/http/EdgeNodeProxyHttpHandler.js.map +1 -1
- package/dist/http/cluster/PodMigrationHttpHandler.d.ts +2 -2
- package/dist/http/cluster/PodMigrationHttpHandler.js +2 -2
- package/dist/http/cluster/PodMigrationHttpHandler.js.map +1 -1
- package/dist/http/quota/QuotaAdminHttpHandler.js +27 -21
- package/dist/http/quota/QuotaAdminHttpHandler.js.map +1 -1
- package/dist/identity/drizzle/AccountRepository.d.ts +4 -22
- package/dist/identity/drizzle/AccountRepository.js +9 -113
- package/dist/identity/drizzle/AccountRepository.js.map +1 -1
- package/dist/identity/drizzle/AccountRoleRepository.d.ts +5 -5
- package/dist/identity/drizzle/AccountRoleRepository.js +204 -97
- package/dist/identity/drizzle/AccountRoleRepository.js.map +1 -1
- package/dist/identity/drizzle/DdnsRepository.d.ts +5 -20
- package/dist/identity/drizzle/DdnsRepository.js +13 -49
- package/dist/identity/drizzle/DdnsRepository.js.map +1 -1
- package/dist/identity/drizzle/EdgeNodeRepository.d.ts +13 -6
- package/dist/identity/drizzle/EdgeNodeRepository.js +167 -66
- package/dist/identity/drizzle/EdgeNodeRepository.js.map +1 -1
- package/dist/identity/drizzle/PodLookupRepository.d.ts +7 -36
- package/dist/identity/drizzle/PodLookupRepository.js +103 -126
- package/dist/identity/drizzle/PodLookupRepository.js.map +1 -1
- package/dist/identity/drizzle/ServiceTokenRepository.d.ts +13 -1
- package/dist/identity/drizzle/ServiceTokenRepository.js +7 -0
- package/dist/identity/drizzle/ServiceTokenRepository.js.map +1 -1
- package/dist/identity/drizzle/db.d.ts +2 -1
- package/dist/identity/drizzle/db.js +173 -297
- package/dist/identity/drizzle/db.js.map +1 -1
- package/dist/identity/drizzle/schema.pg.d.ts +3 -11
- package/dist/identity/drizzle/schema.pg.js +10 -45
- package/dist/identity/drizzle/schema.pg.js.map +1 -1
- package/dist/identity/drizzle/schema.sqlite.d.ts +88 -531
- package/dist/identity/drizzle/schema.sqlite.js +13 -46
- package/dist/identity/drizzle/schema.sqlite.js.map +1 -1
- package/dist/identity/oidc/ScopedPickWebIdHandler.d.ts +3 -0
- package/dist/identity/oidc/ScopedPickWebIdHandler.js +18 -6
- package/dist/identity/oidc/ScopedPickWebIdHandler.js.map +1 -1
- package/dist/identity/oidc/ScopedPickWebIdHandler.jsonld +22 -0
- package/dist/provision/LocalPodProvisioningService.js +2 -0
- package/dist/provision/LocalPodProvisioningService.js.map +1 -1
- package/dist/provision/ProvisionCodeCodec.js +10 -1
- package/dist/provision/ProvisionCodeCodec.js.map +1 -1
- package/dist/provision/ProvisionPodCreator.d.ts +8 -2
- package/dist/provision/ProvisionPodCreator.js +136 -27
- package/dist/provision/ProvisionPodCreator.js.map +1 -1
- package/dist/provision/ProvisionPodCreator.jsonld +38 -3
- package/dist/quota/DrizzleQuotaService.d.ts +0 -4
- package/dist/quota/DrizzleQuotaService.js +1 -21
- package/dist/quota/DrizzleQuotaService.js.map +1 -1
- package/dist/quota/DrizzleQuotaService.jsonld +0 -16
- package/dist/quota/NoopQuotaService.d.ts +0 -4
- package/dist/quota/NoopQuotaService.js +0 -8
- package/dist/quota/NoopQuotaService.js.map +1 -1
- package/dist/quota/NoopQuotaService.jsonld +0 -16
- package/dist/quota/QuotaService.d.ts +0 -4
- package/dist/quota/QuotaService.js.map +1 -1
- package/dist/quota/QuotaService.jsonld +0 -16
- package/dist/service/EdgeNodeSignalClient.d.ts +0 -2
- package/dist/service/EdgeNodeSignalClient.js +0 -4
- package/dist/service/EdgeNodeSignalClient.js.map +1 -1
- package/dist/service/PodMigrationService.d.ts +2 -2
- package/dist/service/PodMigrationService.js +4 -4
- package/dist/service/PodMigrationService.js.map +1 -1
- package/dist/setup/LocalSetupServiceTokenRepository.d.ts +22 -0
- package/dist/setup/LocalSetupServiceTokenRepository.js +68 -0
- package/dist/setup/LocalSetupServiceTokenRepository.js.map +1 -0
- package/dist/storage/accessors/MixDataAccessor.js.map +1 -1
- package/dist/storage/quota/PerAccountQuotaStrategy.js +2 -2
- package/dist/storage/quota/PerAccountQuotaStrategy.js.map +1 -1
- package/dist/storage/quota/UsageRepository.d.ts +10 -32
- package/dist/storage/quota/UsageRepository.js +84 -281
- package/dist/storage/quota/UsageRepository.js.map +1 -1
- package/dist/storage/rdf/PostgresRdfEngine.d.ts +12 -15
- package/dist/storage/rdf/PostgresRdfEngine.js +1040 -150
- package/dist/storage/rdf/PostgresRdfEngine.js.map +1 -1
- package/dist/storage/rdf/PostgresRdfEngine.jsonld +40 -52
- package/dist/storage/rdf/{RdfLocalQueryEngine.d.ts → RdfQueryExecutor.d.ts} +3 -3
- package/dist/storage/rdf/{RdfLocalQueryEngine.js → RdfQueryExecutor.js} +9 -9
- package/dist/storage/rdf/RdfQueryExecutor.js.map +1 -0
- package/dist/storage/rdf/RdfSparqlAdapter.d.ts +5 -5
- package/dist/storage/rdf/RdfSparqlAdapter.js +27 -27
- package/dist/storage/rdf/RdfSparqlAdapter.js.map +1 -1
- package/dist/storage/rdf/SolidRdfEngine.d.ts +2 -5
- package/dist/storage/rdf/SolidRdfEngine.js +6 -38
- package/dist/storage/rdf/SolidRdfEngine.js.map +1 -1
- package/dist/storage/rdf/SolidRdfEngine.jsonld +0 -12
- package/dist/storage/rdf/SolidRdfSparqlEngine.js.map +1 -1
- package/dist/storage/rdf/index.d.ts +3 -3
- package/dist/storage/rdf/index.js +6 -6
- package/dist/storage/rdf/index.js.map +1 -1
- package/dist/storage/rdf/models-benchmark.d.ts +9 -9
- package/dist/storage/rdf/models-benchmark.js +23 -23
- package/dist/storage/rdf/models-benchmark.js.map +1 -1
- package/dist/storage/rdf/types.d.ts +5 -5
- package/dist/storage/rdf/types.js.map +1 -1
- package/dist/subdomain/SubdomainService.d.ts +1 -1
- package/dist/subdomain/SubdomainService.js +1 -1
- package/dist/subdomain/SubdomainService.js.map +1 -1
- package/dist/subdomain/SubdomainService.jsonld +1 -1
- package/package.json +1 -1
- package/templates/pod/acp/profile/.acr +21 -0
- package/templates/pod/wac/profile/.acl.hbs +18 -0
- package/dist/api/handlers/ApiKeyHandler.d.ts +0 -15
- package/dist/api/handlers/ApiKeyHandler.js +0 -153
- package/dist/api/handlers/ApiKeyHandler.js.map +0 -1
- package/dist/api/store/DrizzleClientCredentialsStore.d.ts +0 -51
- package/dist/api/store/DrizzleClientCredentialsStore.js +0 -115
- package/dist/api/store/DrizzleClientCredentialsStore.js.map +0 -1
- package/dist/storage/rdf/RdfLocalQueryEngine.js.map +0 -1
|
@@ -3,9 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.UsageRepository = void 0;
|
|
4
4
|
const drizzle_orm_1 = require("drizzle-orm");
|
|
5
5
|
const db_1 = require("../../identity/drizzle/db");
|
|
6
|
+
const ACCOUNT_SCOPE = 'account';
|
|
7
|
+
const POD_SCOPE = 'pod';
|
|
6
8
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
+
* Tracks account and pod usage in one table. Account/pod are scopes of the same
|
|
10
|
+
* metric record, not separate data models.
|
|
9
11
|
*/
|
|
10
12
|
class UsageRepository {
|
|
11
13
|
constructor(db) {
|
|
@@ -20,8 +22,8 @@ class UsageRepository {
|
|
|
20
22
|
return;
|
|
21
23
|
}
|
|
22
24
|
await this.db.transaction(async (tx) => {
|
|
23
|
-
await this.
|
|
24
|
-
await this.
|
|
25
|
+
await this.incrementUsageWith(tx, POD_SCOPE, podId, accountId, normalizedStorage, normalizedIngress, normalizedEgress);
|
|
26
|
+
await this.incrementUsageWith(tx, ACCOUNT_SCOPE, accountId, accountId, normalizedStorage, normalizedIngress, normalizedEgress);
|
|
25
27
|
});
|
|
26
28
|
}
|
|
27
29
|
async incrementBandwidth(accountId, podId, ingressDelta, egressDelta) {
|
|
@@ -34,158 +36,94 @@ class UsageRepository {
|
|
|
34
36
|
const owningAccountId = current?.accountId ?? accountId;
|
|
35
37
|
const previousStorage = current?.storageBytes ?? 0;
|
|
36
38
|
const delta = normalized - previousStorage;
|
|
37
|
-
await this.
|
|
39
|
+
await this.upsertUsage(tx, POD_SCOPE, podId, owningAccountId, { storageBytes: normalized });
|
|
38
40
|
if (delta !== 0) {
|
|
39
|
-
await this.
|
|
41
|
+
await this.incrementUsageWith(tx, ACCOUNT_SCOPE, owningAccountId, owningAccountId, delta, 0, 0);
|
|
40
42
|
}
|
|
41
43
|
});
|
|
42
44
|
}
|
|
43
45
|
async setAccountStorage(accountId, storageBytes) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
await this.upsertAccountUsage(tx, accountId, normalized);
|
|
47
|
-
// Adjust pod rows proportionally is undefined behaviour here, so only account-level storage is updated.
|
|
48
|
-
// Pods should be updated independently by their respective setters.
|
|
46
|
+
await this.upsertUsage(this.db, ACCOUNT_SCOPE, accountId, accountId, {
|
|
47
|
+
storageBytes: this.normalizeValue(storageBytes),
|
|
49
48
|
});
|
|
50
49
|
}
|
|
51
50
|
async getAccountUsage(accountId) {
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
ingress: this.schema.accountUsage.ingressBytes,
|
|
55
|
-
egress: this.schema.accountUsage.egressBytes,
|
|
56
|
-
storageLimit: this.schema.accountUsage.storageLimitBytes,
|
|
57
|
-
bandwidthLimit: this.schema.accountUsage.bandwidthLimitBps,
|
|
58
|
-
computeSeconds: this.schema.accountUsage.computeSeconds,
|
|
59
|
-
tokensUsed: this.schema.accountUsage.tokensUsed,
|
|
60
|
-
computeLimitSeconds: this.schema.accountUsage.computeLimitSeconds,
|
|
61
|
-
tokenLimitMonthly: this.schema.accountUsage.tokenLimitMonthly,
|
|
62
|
-
periodStart: this.schema.accountUsage.periodStart,
|
|
63
|
-
}).from(this.schema.accountUsage)
|
|
64
|
-
.where((0, drizzle_orm_1.eq)(this.schema.accountUsage.accountId, accountId));
|
|
65
|
-
if (!result || result.length === 0) {
|
|
66
|
-
return undefined;
|
|
67
|
-
}
|
|
68
|
-
const row = result[0];
|
|
69
|
-
return {
|
|
70
|
-
accountId,
|
|
71
|
-
storageBytes: this.coerceNumber(row.storage),
|
|
72
|
-
ingressBytes: this.coerceNumber(row.ingress),
|
|
73
|
-
egressBytes: this.coerceNumber(row.egress),
|
|
74
|
-
storageLimitBytes: this.coerceNullable(row.storageLimit),
|
|
75
|
-
bandwidthLimitBps: this.coerceNullable(row.bandwidthLimit),
|
|
76
|
-
computeSeconds: this.coerceNumber(row.computeSeconds),
|
|
77
|
-
tokensUsed: this.coerceNumber(row.tokensUsed),
|
|
78
|
-
computeLimitSeconds: this.coerceNullable(row.computeLimitSeconds),
|
|
79
|
-
tokenLimitMonthly: this.coerceNullable(row.tokenLimitMonthly),
|
|
80
|
-
periodStart: this.coerceTimestamp(row.periodStart),
|
|
81
|
-
};
|
|
51
|
+
const row = await this.getUsageRow(this.db, ACCOUNT_SCOPE, accountId);
|
|
52
|
+
return row ? this.toAccountUsage(accountId, row) : undefined;
|
|
82
53
|
}
|
|
83
54
|
async getPodUsage(podId) {
|
|
84
|
-
|
|
85
|
-
accountId: this.schema.podUsage.accountId,
|
|
86
|
-
storage: this.schema.podUsage.storageBytes,
|
|
87
|
-
ingress: this.schema.podUsage.ingressBytes,
|
|
88
|
-
egress: this.schema.podUsage.egressBytes,
|
|
89
|
-
storageLimit: this.schema.podUsage.storageLimitBytes,
|
|
90
|
-
bandwidthLimit: this.schema.podUsage.bandwidthLimitBps,
|
|
91
|
-
computeSeconds: this.schema.podUsage.computeSeconds,
|
|
92
|
-
tokensUsed: this.schema.podUsage.tokensUsed,
|
|
93
|
-
computeLimitSeconds: this.schema.podUsage.computeLimitSeconds,
|
|
94
|
-
tokenLimitMonthly: this.schema.podUsage.tokenLimitMonthly,
|
|
95
|
-
periodStart: this.schema.podUsage.periodStart,
|
|
96
|
-
}).from(this.schema.podUsage)
|
|
97
|
-
.where((0, drizzle_orm_1.eq)(this.schema.podUsage.podId, podId));
|
|
98
|
-
if (!result || result.length === 0) {
|
|
99
|
-
return undefined;
|
|
100
|
-
}
|
|
101
|
-
const row = result[0];
|
|
102
|
-
const accountId = String(row.accountId);
|
|
103
|
-
return {
|
|
104
|
-
podId,
|
|
105
|
-
accountId,
|
|
106
|
-
storageBytes: this.coerceNumber(row.storage),
|
|
107
|
-
ingressBytes: this.coerceNumber(row.ingress),
|
|
108
|
-
egressBytes: this.coerceNumber(row.egress),
|
|
109
|
-
storageLimitBytes: this.coerceNullable(row.storageLimit),
|
|
110
|
-
bandwidthLimitBps: this.coerceNullable(row.bandwidthLimit),
|
|
111
|
-
computeSeconds: this.coerceNumber(row.computeSeconds),
|
|
112
|
-
tokensUsed: this.coerceNumber(row.tokensUsed),
|
|
113
|
-
computeLimitSeconds: this.coerceNullable(row.computeLimitSeconds),
|
|
114
|
-
tokenLimitMonthly: this.coerceNullable(row.tokenLimitMonthly),
|
|
115
|
-
periodStart: this.coerceTimestamp(row.periodStart),
|
|
116
|
-
};
|
|
55
|
+
return this.getPodUsageWith(this.db, podId);
|
|
117
56
|
}
|
|
118
57
|
async setAccountStorageLimit(accountId, limit) {
|
|
119
|
-
await this.
|
|
58
|
+
await this.upsertUsage(this.db, ACCOUNT_SCOPE, accountId, accountId, { storageLimitBytes: limit });
|
|
120
59
|
}
|
|
121
60
|
async setPodStorageLimit(podId, accountId, limit) {
|
|
122
|
-
await this.
|
|
61
|
+
await this.upsertUsage(this.db, POD_SCOPE, podId, accountId, { storageLimitBytes: limit });
|
|
123
62
|
}
|
|
124
63
|
async setAccountBandwidthLimit(accountId, limit) {
|
|
125
|
-
await this.
|
|
64
|
+
await this.upsertUsage(this.db, ACCOUNT_SCOPE, accountId, accountId, { bandwidthLimitBps: limit });
|
|
126
65
|
}
|
|
127
66
|
async setPodBandwidthLimit(podId, accountId, limit) {
|
|
128
|
-
await this.
|
|
67
|
+
await this.upsertUsage(this.db, POD_SCOPE, podId, accountId, { bandwidthLimitBps: limit });
|
|
129
68
|
}
|
|
130
69
|
async setAccountComputeLimit(accountId, limit) {
|
|
131
|
-
await this.
|
|
70
|
+
await this.upsertUsage(this.db, ACCOUNT_SCOPE, accountId, accountId, { computeLimitSeconds: limit });
|
|
132
71
|
}
|
|
133
72
|
async setAccountTokenLimit(accountId, limit) {
|
|
134
|
-
await this.
|
|
73
|
+
await this.upsertUsage(this.db, ACCOUNT_SCOPE, accountId, accountId, { tokenLimitMonthly: limit });
|
|
135
74
|
}
|
|
136
75
|
async setPodComputeLimit(podId, accountId, limit) {
|
|
137
|
-
await this.
|
|
76
|
+
await this.upsertUsage(this.db, POD_SCOPE, podId, accountId, { computeLimitSeconds: limit });
|
|
138
77
|
}
|
|
139
78
|
async setPodTokenLimit(podId, accountId, limit) {
|
|
140
|
-
await this.
|
|
79
|
+
await this.upsertUsage(this.db, POD_SCOPE, podId, accountId, { tokenLimitMonthly: limit });
|
|
141
80
|
}
|
|
142
|
-
/**
|
|
143
|
-
* Increment token usage for an account and pod.
|
|
144
|
-
*/
|
|
145
81
|
async incrementTokenUsage(accountId, podId, tokensDelta) {
|
|
146
82
|
const normalized = this.normalizeDelta(tokensDelta);
|
|
147
83
|
if (normalized === 0) {
|
|
148
84
|
return;
|
|
149
85
|
}
|
|
150
86
|
await this.db.transaction(async (tx) => {
|
|
151
|
-
await this.
|
|
152
|
-
await this.
|
|
87
|
+
await this.incrementTokensWith(tx, POD_SCOPE, podId, accountId, normalized);
|
|
88
|
+
await this.incrementTokensWith(tx, ACCOUNT_SCOPE, accountId, accountId, normalized);
|
|
153
89
|
});
|
|
154
90
|
}
|
|
155
|
-
/**
|
|
156
|
-
* Increment compute usage for an account and pod.
|
|
157
|
-
*/
|
|
158
91
|
async incrementComputeUsage(accountId, podId, secondsDelta) {
|
|
159
92
|
const normalized = this.normalizeDelta(secondsDelta);
|
|
160
93
|
if (normalized === 0) {
|
|
161
94
|
return;
|
|
162
95
|
}
|
|
163
96
|
await this.db.transaction(async (tx) => {
|
|
164
|
-
await this.
|
|
165
|
-
await this.
|
|
97
|
+
await this.incrementComputeWith(tx, POD_SCOPE, podId, accountId, normalized);
|
|
98
|
+
await this.incrementComputeWith(tx, ACCOUNT_SCOPE, accountId, accountId, normalized);
|
|
166
99
|
});
|
|
167
100
|
}
|
|
168
|
-
async
|
|
169
|
-
await
|
|
170
|
-
|
|
171
|
-
accountId,
|
|
172
|
-
storageBytes: 0,
|
|
173
|
-
ingressBytes: 0,
|
|
174
|
-
egressBytes: 0,
|
|
175
|
-
tokensUsed: tokensDelta,
|
|
176
|
-
})
|
|
177
|
-
.onConflictDoUpdate({
|
|
178
|
-
target: this.schema.accountUsage.accountId,
|
|
179
|
-
set: {
|
|
180
|
-
tokensUsed: (0, drizzle_orm_1.sql) `${this.schema.accountUsage.tokensUsed} + ${tokensDelta}`,
|
|
181
|
-
updatedAt: this.now(),
|
|
182
|
-
},
|
|
183
|
-
});
|
|
101
|
+
async getPodUsageWith(client, podId) {
|
|
102
|
+
const row = await this.getUsageRow(client, POD_SCOPE, podId);
|
|
103
|
+
return row ? this.toPodUsage(podId, row) : undefined;
|
|
184
104
|
}
|
|
185
|
-
async
|
|
186
|
-
await client.
|
|
105
|
+
async getUsageRow(client, scopeType, scopeId) {
|
|
106
|
+
const result = await client.select({
|
|
107
|
+
accountId: this.schema.usage.accountId,
|
|
108
|
+
storage: this.schema.usage.storageBytes,
|
|
109
|
+
ingress: this.schema.usage.ingressBytes,
|
|
110
|
+
egress: this.schema.usage.egressBytes,
|
|
111
|
+
storageLimit: this.schema.usage.storageLimitBytes,
|
|
112
|
+
bandwidthLimit: this.schema.usage.bandwidthLimitBps,
|
|
113
|
+
computeSeconds: this.schema.usage.computeSeconds,
|
|
114
|
+
tokensUsed: this.schema.usage.tokensUsed,
|
|
115
|
+
computeLimitSeconds: this.schema.usage.computeLimitSeconds,
|
|
116
|
+
tokenLimitMonthly: this.schema.usage.tokenLimitMonthly,
|
|
117
|
+
periodStart: this.schema.usage.periodStart,
|
|
118
|
+
}).from(this.schema.usage)
|
|
119
|
+
.where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(this.schema.usage.scopeType, scopeType), (0, drizzle_orm_1.eq)(this.schema.usage.scopeId, scopeId)));
|
|
120
|
+
return result?.[0];
|
|
121
|
+
}
|
|
122
|
+
async incrementTokensWith(client, scopeType, scopeId, accountId, tokensDelta) {
|
|
123
|
+
await client.insert(this.schema.usage)
|
|
187
124
|
.values({
|
|
188
|
-
|
|
125
|
+
scopeType,
|
|
126
|
+
scopeId,
|
|
189
127
|
accountId,
|
|
190
128
|
storageBytes: 0,
|
|
191
129
|
ingressBytes: 0,
|
|
@@ -193,35 +131,19 @@ class UsageRepository {
|
|
|
193
131
|
tokensUsed: tokensDelta,
|
|
194
132
|
})
|
|
195
133
|
.onConflictDoUpdate({
|
|
196
|
-
target: this.schema.
|
|
134
|
+
target: [this.schema.usage.scopeType, this.schema.usage.scopeId],
|
|
197
135
|
set: {
|
|
198
|
-
tokensUsed: (0, drizzle_orm_1.sql) `${this.schema.
|
|
136
|
+
tokensUsed: (0, drizzle_orm_1.sql) `${this.schema.usage.tokensUsed} + ${tokensDelta}`,
|
|
199
137
|
accountId,
|
|
200
138
|
updatedAt: this.now(),
|
|
201
139
|
},
|
|
202
140
|
});
|
|
203
141
|
}
|
|
204
|
-
async
|
|
205
|
-
await client.insert(this.schema.
|
|
206
|
-
.values({
|
|
207
|
-
accountId,
|
|
208
|
-
storageBytes: 0,
|
|
209
|
-
ingressBytes: 0,
|
|
210
|
-
egressBytes: 0,
|
|
211
|
-
computeSeconds: secondsDelta,
|
|
212
|
-
})
|
|
213
|
-
.onConflictDoUpdate({
|
|
214
|
-
target: this.schema.accountUsage.accountId,
|
|
215
|
-
set: {
|
|
216
|
-
computeSeconds: (0, drizzle_orm_1.sql) `${this.schema.accountUsage.computeSeconds} + ${secondsDelta}`,
|
|
217
|
-
updatedAt: this.now(),
|
|
218
|
-
},
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
async incrementPodComputeWith(client, accountId, podId, secondsDelta) {
|
|
222
|
-
await client.insert(this.schema.podUsage)
|
|
142
|
+
async incrementComputeWith(client, scopeType, scopeId, accountId, secondsDelta) {
|
|
143
|
+
await client.insert(this.schema.usage)
|
|
223
144
|
.values({
|
|
224
|
-
|
|
145
|
+
scopeType,
|
|
146
|
+
scopeId,
|
|
225
147
|
accountId,
|
|
226
148
|
storageBytes: 0,
|
|
227
149
|
ingressBytes: 0,
|
|
@@ -229,187 +151,76 @@ class UsageRepository {
|
|
|
229
151
|
computeSeconds: secondsDelta,
|
|
230
152
|
})
|
|
231
153
|
.onConflictDoUpdate({
|
|
232
|
-
target: this.schema.
|
|
154
|
+
target: [this.schema.usage.scopeType, this.schema.usage.scopeId],
|
|
233
155
|
set: {
|
|
234
|
-
computeSeconds: (0, drizzle_orm_1.sql) `${this.schema.
|
|
156
|
+
computeSeconds: (0, drizzle_orm_1.sql) `${this.schema.usage.computeSeconds} + ${secondsDelta}`,
|
|
235
157
|
accountId,
|
|
236
158
|
updatedAt: this.now(),
|
|
237
159
|
},
|
|
238
160
|
});
|
|
239
161
|
}
|
|
240
|
-
async
|
|
241
|
-
await client.insert(this.schema.
|
|
162
|
+
async incrementUsageWith(client, scopeType, scopeId, accountId, storageDelta, ingressDelta, egressDelta) {
|
|
163
|
+
await client.insert(this.schema.usage)
|
|
242
164
|
.values({
|
|
165
|
+
scopeType,
|
|
166
|
+
scopeId,
|
|
243
167
|
accountId,
|
|
244
168
|
storageBytes: storageDelta,
|
|
245
169
|
ingressBytes: ingressDelta,
|
|
246
170
|
egressBytes: egressDelta,
|
|
247
171
|
})
|
|
248
172
|
.onConflictDoUpdate({
|
|
249
|
-
target: this.schema.
|
|
173
|
+
target: [this.schema.usage.scopeType, this.schema.usage.scopeId],
|
|
250
174
|
set: {
|
|
251
|
-
storageBytes: (0, drizzle_orm_1.sql) `${this.schema.
|
|
252
|
-
ingressBytes: (0, drizzle_orm_1.sql) `${this.schema.
|
|
253
|
-
egressBytes: (0, drizzle_orm_1.sql) `${this.schema.
|
|
254
|
-
updatedAt: this.now(),
|
|
255
|
-
},
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
async incrementPodUsageWith(client, accountId, podId, storageDelta, ingressDelta, egressDelta) {
|
|
259
|
-
await client.insert(this.schema.podUsage)
|
|
260
|
-
.values({
|
|
261
|
-
podId,
|
|
262
|
-
accountId,
|
|
263
|
-
storageBytes: storageDelta,
|
|
264
|
-
ingressBytes: ingressDelta,
|
|
265
|
-
egressBytes: egressDelta,
|
|
266
|
-
})
|
|
267
|
-
.onConflictDoUpdate({
|
|
268
|
-
target: this.schema.podUsage.podId,
|
|
269
|
-
set: {
|
|
270
|
-
storageBytes: (0, drizzle_orm_1.sql) `${this.schema.podUsage.storageBytes} + ${storageDelta}`,
|
|
271
|
-
ingressBytes: (0, drizzle_orm_1.sql) `${this.schema.podUsage.ingressBytes} + ${ingressDelta}`,
|
|
272
|
-
egressBytes: (0, drizzle_orm_1.sql) `${this.schema.podUsage.egressBytes} + ${egressDelta}`,
|
|
175
|
+
storageBytes: (0, drizzle_orm_1.sql) `${this.schema.usage.storageBytes} + ${storageDelta}`,
|
|
176
|
+
ingressBytes: (0, drizzle_orm_1.sql) `${this.schema.usage.ingressBytes} + ${ingressDelta}`,
|
|
177
|
+
egressBytes: (0, drizzle_orm_1.sql) `${this.schema.usage.egressBytes} + ${egressDelta}`,
|
|
273
178
|
accountId,
|
|
274
179
|
updatedAt: this.now(),
|
|
275
180
|
},
|
|
276
181
|
});
|
|
277
182
|
}
|
|
278
|
-
async
|
|
279
|
-
const storageValue = typeof storageBytes === 'number' ? this.normalizeValue(storageBytes) : undefined;
|
|
280
|
-
const insertValues = {
|
|
281
|
-
accountId,
|
|
282
|
-
storageBytes: storageValue ?? 0,
|
|
283
|
-
ingressBytes: 0,
|
|
284
|
-
egressBytes: 0,
|
|
285
|
-
};
|
|
286
|
-
if (storageLimit !== undefined) {
|
|
287
|
-
insertValues.storageLimitBytes = storageLimit;
|
|
288
|
-
}
|
|
289
|
-
if (bandwidthLimit !== undefined) {
|
|
290
|
-
insertValues.bandwidthLimitBps = bandwidthLimit;
|
|
291
|
-
}
|
|
292
|
-
const updateSet = {
|
|
293
|
-
updatedAt: this.now(),
|
|
294
|
-
};
|
|
295
|
-
if (typeof storageValue === 'number') {
|
|
296
|
-
updateSet.storageBytes = storageValue;
|
|
297
|
-
}
|
|
298
|
-
if (storageLimit !== undefined) {
|
|
299
|
-
updateSet.storageLimitBytes = storageLimit;
|
|
300
|
-
}
|
|
301
|
-
if (bandwidthLimit !== undefined) {
|
|
302
|
-
updateSet.bandwidthLimitBps = bandwidthLimit;
|
|
303
|
-
}
|
|
304
|
-
await client.insert(this.schema.accountUsage)
|
|
305
|
-
.values(insertValues)
|
|
306
|
-
.onConflictDoUpdate({
|
|
307
|
-
target: this.schema.accountUsage.accountId,
|
|
308
|
-
set: updateSet,
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
async upsertPodUsage(client, accountId, podId, storageBytes, storageLimit, bandwidthLimit) {
|
|
312
|
-
const storageValue = typeof storageBytes === 'number' ? this.normalizeValue(storageBytes) : undefined;
|
|
183
|
+
async upsertUsage(client, scopeType, scopeId, accountId, values) {
|
|
313
184
|
const insertValues = {
|
|
314
|
-
|
|
185
|
+
scopeType,
|
|
186
|
+
scopeId,
|
|
315
187
|
accountId,
|
|
316
|
-
storageBytes:
|
|
188
|
+
storageBytes: values.storageBytes ?? 0,
|
|
317
189
|
ingressBytes: 0,
|
|
318
190
|
egressBytes: 0,
|
|
319
191
|
};
|
|
320
|
-
if (storageLimit !== undefined) {
|
|
321
|
-
insertValues.storageLimitBytes = storageLimit;
|
|
322
|
-
}
|
|
323
|
-
if (bandwidthLimit !== undefined) {
|
|
324
|
-
insertValues.bandwidthLimitBps = bandwidthLimit;
|
|
325
|
-
}
|
|
326
192
|
const updateSet = {
|
|
327
193
|
accountId,
|
|
328
194
|
updatedAt: this.now(),
|
|
329
195
|
};
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
}
|
|
336
|
-
if (bandwidthLimit !== undefined) {
|
|
337
|
-
updateSet.bandwidthLimitBps = bandwidthLimit;
|
|
196
|
+
for (const field of ['storageBytes', 'storageLimitBytes', 'bandwidthLimitBps', 'computeLimitSeconds', 'tokenLimitMonthly']) {
|
|
197
|
+
if (values[field] !== undefined) {
|
|
198
|
+
insertValues[field] = values[field];
|
|
199
|
+
updateSet[field] = values[field];
|
|
200
|
+
}
|
|
338
201
|
}
|
|
339
|
-
await client.insert(this.schema.
|
|
202
|
+
await client.insert(this.schema.usage)
|
|
340
203
|
.values(insertValues)
|
|
341
204
|
.onConflictDoUpdate({
|
|
342
|
-
target: this.schema.
|
|
205
|
+
target: [this.schema.usage.scopeType, this.schema.usage.scopeId],
|
|
343
206
|
set: updateSet,
|
|
344
207
|
});
|
|
345
208
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
*/
|
|
349
|
-
async upsertAccountLimit(client, accountId, field, value) {
|
|
350
|
-
const insertValues = {
|
|
209
|
+
toAccountUsage(accountId, row) {
|
|
210
|
+
return {
|
|
351
211
|
accountId,
|
|
352
|
-
|
|
353
|
-
ingressBytes: 0,
|
|
354
|
-
egressBytes: 0,
|
|
355
|
-
[field]: value,
|
|
212
|
+
...this.toUsageMetrics(row),
|
|
356
213
|
};
|
|
357
|
-
await client.insert(this.schema.accountUsage)
|
|
358
|
-
.values(insertValues)
|
|
359
|
-
.onConflictDoUpdate({
|
|
360
|
-
target: this.schema.accountUsage.accountId,
|
|
361
|
-
set: {
|
|
362
|
-
[field]: value,
|
|
363
|
-
updatedAt: this.now(),
|
|
364
|
-
},
|
|
365
|
-
});
|
|
366
214
|
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
*/
|
|
370
|
-
async upsertPodLimit(client, accountId, podId, field, value) {
|
|
371
|
-
const insertValues = {
|
|
215
|
+
toPodUsage(podId, row) {
|
|
216
|
+
return {
|
|
372
217
|
podId,
|
|
373
|
-
accountId,
|
|
374
|
-
|
|
375
|
-
ingressBytes: 0,
|
|
376
|
-
egressBytes: 0,
|
|
377
|
-
[field]: value,
|
|
218
|
+
accountId: String(row.accountId),
|
|
219
|
+
...this.toUsageMetrics(row),
|
|
378
220
|
};
|
|
379
|
-
await client.insert(this.schema.podUsage)
|
|
380
|
-
.values(insertValues)
|
|
381
|
-
.onConflictDoUpdate({
|
|
382
|
-
target: this.schema.podUsage.podId,
|
|
383
|
-
set: {
|
|
384
|
-
accountId,
|
|
385
|
-
[field]: value,
|
|
386
|
-
updatedAt: this.now(),
|
|
387
|
-
},
|
|
388
|
-
});
|
|
389
221
|
}
|
|
390
|
-
|
|
391
|
-
const result = await client.select({
|
|
392
|
-
accountId: this.schema.podUsage.accountId,
|
|
393
|
-
storage: this.schema.podUsage.storageBytes,
|
|
394
|
-
ingress: this.schema.podUsage.ingressBytes,
|
|
395
|
-
egress: this.schema.podUsage.egressBytes,
|
|
396
|
-
storageLimit: this.schema.podUsage.storageLimitBytes,
|
|
397
|
-
bandwidthLimit: this.schema.podUsage.bandwidthLimitBps,
|
|
398
|
-
computeSeconds: this.schema.podUsage.computeSeconds,
|
|
399
|
-
tokensUsed: this.schema.podUsage.tokensUsed,
|
|
400
|
-
computeLimitSeconds: this.schema.podUsage.computeLimitSeconds,
|
|
401
|
-
tokenLimitMonthly: this.schema.podUsage.tokenLimitMonthly,
|
|
402
|
-
periodStart: this.schema.podUsage.periodStart,
|
|
403
|
-
}).from(this.schema.podUsage)
|
|
404
|
-
.where((0, drizzle_orm_1.eq)(this.schema.podUsage.podId, podId));
|
|
405
|
-
if (!result || result.length === 0) {
|
|
406
|
-
return undefined;
|
|
407
|
-
}
|
|
408
|
-
const row = result[0];
|
|
409
|
-
const accountId = String(row.accountId);
|
|
222
|
+
toUsageMetrics(row) {
|
|
410
223
|
return {
|
|
411
|
-
podId,
|
|
412
|
-
accountId,
|
|
413
224
|
storageBytes: this.coerceNumber(row.storage),
|
|
414
225
|
ingressBytes: this.coerceNumber(row.ingress),
|
|
415
226
|
egressBytes: this.coerceNumber(row.egress),
|
|
@@ -451,10 +262,6 @@ class UsageRepository {
|
|
|
451
262
|
}
|
|
452
263
|
return Math.trunc(numeric);
|
|
453
264
|
}
|
|
454
|
-
/**
|
|
455
|
-
* Coerce timestamp value to Unix timestamp (seconds).
|
|
456
|
-
* Handles Date objects (from PG) and numbers (from SQLite).
|
|
457
|
-
*/
|
|
458
265
|
coerceTimestamp(value) {
|
|
459
266
|
if (value === null || value === undefined) {
|
|
460
267
|
return null;
|
|
@@ -467,10 +274,6 @@ class UsageRepository {
|
|
|
467
274
|
}
|
|
468
275
|
return null;
|
|
469
276
|
}
|
|
470
|
-
/**
|
|
471
|
-
* Get the current timestamp in the format expected by the database.
|
|
472
|
-
* PG expects Date objects, SQLite expects Unix timestamps (seconds).
|
|
473
|
-
*/
|
|
474
277
|
now() {
|
|
475
278
|
const timestamp = new Date();
|
|
476
279
|
return (0, db_1.isDatabaseSqlite)(this.db) ? Math.floor(timestamp.getTime() / 1000) : timestamp;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UsageRepository.js","sourceRoot":"","sources":["../../../src/storage/quota/UsageRepository.ts"],"names":[],"mappings":"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","sourcesContent":["import { sql, eq } from 'drizzle-orm';\nimport type { IdentityDatabase } from '../../identity/drizzle/db';\nimport { getSchema, isDatabaseSqlite } from '../../identity/drizzle/db';\nimport type { NodePgTransaction } from 'drizzle-orm/node-postgres/session';\n\ntype DbClient = IdentityDatabase | NodePgTransaction<any, any>;\n\nexport interface AccountUsageRecord {\n accountId: string;\n storageBytes: number;\n ingressBytes: number;\n egressBytes: number;\n storageLimitBytes?: number | null;\n bandwidthLimitBps?: number | null;\n computeSeconds: number;\n tokensUsed: number;\n computeLimitSeconds?: number | null;\n tokenLimitMonthly?: number | null;\n periodStart?: number | null;\n}\n\nexport interface PodUsageRecord extends AccountUsageRecord {\n podId: string;\n}\n\n/**\n * Repository for tracking pod and account usage metrics.\n * Supports both PostgreSQL and SQLite through unified schema abstraction.\n */\nexport class UsageRepository {\n private readonly schema: ReturnType<typeof getSchema>;\n\n public constructor(private readonly db: IdentityDatabase) {\n this.schema = getSchema(db);\n }\n\n public async incrementUsage(accountId: string, podId: string, storageDelta: number, ingressDelta: number, egressDelta: number): Promise<void> {\n const normalizedStorage = this.normalizeDelta(storageDelta);\n const normalizedIngress = this.normalizeDelta(ingressDelta);\n const normalizedEgress = this.normalizeDelta(egressDelta);\n if (normalizedStorage === 0 && normalizedIngress === 0 && normalizedEgress === 0) {\n return;\n }\n await this.db.transaction(async (tx: IdentityDatabase) => {\n await this.incrementPodUsageWith(tx, accountId, podId, normalizedStorage, normalizedIngress, normalizedEgress);\n await this.incrementAccountUsageWith(tx, accountId, normalizedStorage, normalizedIngress, normalizedEgress);\n });\n }\n\n public async incrementBandwidth(accountId: string, podId: string, ingressDelta: number, egressDelta: number): Promise<void> {\n await this.incrementUsage(accountId, podId, 0, ingressDelta, egressDelta);\n }\n\n public async setPodStorage(accountId: string, podId: string, storageBytes: number): Promise<void> {\n const normalized = this.normalizeValue(storageBytes);\n await this.db.transaction(async (tx: IdentityDatabase) => {\n const current = await this.getPodUsageWith(tx, podId);\n const owningAccountId = current?.accountId ?? accountId;\n const previousStorage = current?.storageBytes ?? 0;\n const delta = normalized - previousStorage;\n\n await this.upsertPodUsage(tx, owningAccountId, podId, normalized);\n if (delta !== 0) {\n await this.incrementAccountUsageWith(tx, owningAccountId, delta, 0, 0);\n }\n });\n }\n\n public async setAccountStorage(accountId: string, storageBytes: number): Promise<void> {\n const normalized = this.normalizeValue(storageBytes);\n await this.db.transaction(async (tx: IdentityDatabase) => {\n await this.upsertAccountUsage(tx, accountId, normalized);\n // Adjust pod rows proportionally is undefined behaviour here, so only account-level storage is updated.\n // Pods should be updated independently by their respective setters.\n });\n }\n\n public async getAccountUsage(accountId: string): Promise<AccountUsageRecord | undefined> {\n const result = await this.db.select({\n storage: this.schema.accountUsage.storageBytes,\n ingress: this.schema.accountUsage.ingressBytes,\n egress: this.schema.accountUsage.egressBytes,\n storageLimit: this.schema.accountUsage.storageLimitBytes,\n bandwidthLimit: this.schema.accountUsage.bandwidthLimitBps,\n computeSeconds: this.schema.accountUsage.computeSeconds,\n tokensUsed: this.schema.accountUsage.tokensUsed,\n computeLimitSeconds: this.schema.accountUsage.computeLimitSeconds,\n tokenLimitMonthly: this.schema.accountUsage.tokenLimitMonthly,\n periodStart: this.schema.accountUsage.periodStart,\n }).from(this.schema.accountUsage)\n .where(eq(this.schema.accountUsage.accountId, accountId));\n if (!result || result.length === 0) {\n return undefined;\n }\n const row = result[0];\n return {\n accountId,\n storageBytes: this.coerceNumber(row.storage),\n ingressBytes: this.coerceNumber(row.ingress),\n egressBytes: this.coerceNumber(row.egress),\n storageLimitBytes: this.coerceNullable(row.storageLimit),\n bandwidthLimitBps: this.coerceNullable(row.bandwidthLimit),\n computeSeconds: this.coerceNumber(row.computeSeconds),\n tokensUsed: this.coerceNumber(row.tokensUsed),\n computeLimitSeconds: this.coerceNullable(row.computeLimitSeconds),\n tokenLimitMonthly: this.coerceNullable(row.tokenLimitMonthly),\n periodStart: this.coerceTimestamp(row.periodStart),\n };\n }\n\n public async getPodUsage(podId: string): Promise<PodUsageRecord | undefined> {\n const result = await this.db.select({\n accountId: this.schema.podUsage.accountId,\n storage: this.schema.podUsage.storageBytes,\n ingress: this.schema.podUsage.ingressBytes,\n egress: this.schema.podUsage.egressBytes,\n storageLimit: this.schema.podUsage.storageLimitBytes,\n bandwidthLimit: this.schema.podUsage.bandwidthLimitBps,\n computeSeconds: this.schema.podUsage.computeSeconds,\n tokensUsed: this.schema.podUsage.tokensUsed,\n computeLimitSeconds: this.schema.podUsage.computeLimitSeconds,\n tokenLimitMonthly: this.schema.podUsage.tokenLimitMonthly,\n periodStart: this.schema.podUsage.periodStart,\n }).from(this.schema.podUsage)\n .where(eq(this.schema.podUsage.podId, podId));\n if (!result || result.length === 0) {\n return undefined;\n }\n const row = result[0];\n const accountId = String(row.accountId);\n return {\n podId,\n accountId,\n storageBytes: this.coerceNumber(row.storage),\n ingressBytes: this.coerceNumber(row.ingress),\n egressBytes: this.coerceNumber(row.egress),\n storageLimitBytes: this.coerceNullable(row.storageLimit),\n bandwidthLimitBps: this.coerceNullable(row.bandwidthLimit),\n computeSeconds: this.coerceNumber(row.computeSeconds),\n tokensUsed: this.coerceNumber(row.tokensUsed),\n computeLimitSeconds: this.coerceNullable(row.computeLimitSeconds),\n tokenLimitMonthly: this.coerceNullable(row.tokenLimitMonthly),\n periodStart: this.coerceTimestamp(row.periodStart),\n };\n }\n\n public async setAccountStorageLimit(accountId: string, limit: number | null): Promise<void> {\n await this.upsertAccountUsage(this.db, accountId, undefined, limit, undefined);\n }\n\n public async setPodStorageLimit(podId: string, accountId: string, limit: number | null): Promise<void> {\n await this.upsertPodUsage(this.db, accountId, podId, undefined, limit, undefined);\n }\n\n public async setAccountBandwidthLimit(accountId: string, limit: number | null): Promise<void> {\n await this.upsertAccountUsage(this.db, accountId, undefined, undefined, limit);\n }\n\n public async setPodBandwidthLimit(podId: string, accountId: string, limit: number | null): Promise<void> {\n await this.upsertPodUsage(this.db, accountId, podId, undefined, undefined, limit);\n }\n\n public async setAccountComputeLimit(accountId: string, limit: number | null): Promise<void> {\n await this.upsertAccountLimit(this.db, accountId, 'computeLimitSeconds', limit);\n }\n\n public async setAccountTokenLimit(accountId: string, limit: number | null): Promise<void> {\n await this.upsertAccountLimit(this.db, accountId, 'tokenLimitMonthly', limit);\n }\n\n public async setPodComputeLimit(podId: string, accountId: string, limit: number | null): Promise<void> {\n await this.upsertPodLimit(this.db, accountId, podId, 'computeLimitSeconds', limit);\n }\n\n public async setPodTokenLimit(podId: string, accountId: string, limit: number | null): Promise<void> {\n await this.upsertPodLimit(this.db, accountId, podId, 'tokenLimitMonthly', limit);\n }\n\n /**\n * Increment token usage for an account and pod.\n */\n public async incrementTokenUsage(accountId: string, podId: string, tokensDelta: number): Promise<void> {\n const normalized = this.normalizeDelta(tokensDelta);\n if (normalized === 0) {\n return;\n }\n await this.db.transaction(async (tx: IdentityDatabase) => {\n await this.incrementPodTokensWith(tx, accountId, podId, normalized);\n await this.incrementAccountTokensWith(tx, accountId, normalized);\n });\n }\n\n /**\n * Increment compute usage for an account and pod.\n */\n public async incrementComputeUsage(accountId: string, podId: string, secondsDelta: number): Promise<void> {\n const normalized = this.normalizeDelta(secondsDelta);\n if (normalized === 0) {\n return;\n }\n await this.db.transaction(async (tx: IdentityDatabase) => {\n await this.incrementPodComputeWith(tx, accountId, podId, normalized);\n await this.incrementAccountComputeWith(tx, accountId, normalized);\n });\n }\n\n private async incrementAccountTokensWith(client: DbClient, accountId: string, tokensDelta: number): Promise<void> {\n await client.insert(this.schema.accountUsage)\n .values({\n accountId,\n storageBytes: 0,\n ingressBytes: 0,\n egressBytes: 0,\n tokensUsed: tokensDelta,\n })\n .onConflictDoUpdate({\n target: this.schema.accountUsage.accountId,\n set: {\n tokensUsed: sql`${this.schema.accountUsage.tokensUsed} + ${tokensDelta}`,\n updatedAt: this.now(),\n },\n });\n }\n\n private async incrementPodTokensWith(client: DbClient, accountId: string, podId: string, tokensDelta: number): Promise<void> {\n await client.insert(this.schema.podUsage)\n .values({\n podId,\n accountId,\n storageBytes: 0,\n ingressBytes: 0,\n egressBytes: 0,\n tokensUsed: tokensDelta,\n })\n .onConflictDoUpdate({\n target: this.schema.podUsage.podId,\n set: {\n tokensUsed: sql`${this.schema.podUsage.tokensUsed} + ${tokensDelta}`,\n accountId,\n updatedAt: this.now(),\n },\n });\n }\n\n private async incrementAccountComputeWith(client: DbClient, accountId: string, secondsDelta: number): Promise<void> {\n await client.insert(this.schema.accountUsage)\n .values({\n accountId,\n storageBytes: 0,\n ingressBytes: 0,\n egressBytes: 0,\n computeSeconds: secondsDelta,\n })\n .onConflictDoUpdate({\n target: this.schema.accountUsage.accountId,\n set: {\n computeSeconds: sql`${this.schema.accountUsage.computeSeconds} + ${secondsDelta}`,\n updatedAt: this.now(),\n },\n });\n }\n\n private async incrementPodComputeWith(client: DbClient, accountId: string, podId: string, secondsDelta: number): Promise<void> {\n await client.insert(this.schema.podUsage)\n .values({\n podId,\n accountId,\n storageBytes: 0,\n ingressBytes: 0,\n egressBytes: 0,\n computeSeconds: secondsDelta,\n })\n .onConflictDoUpdate({\n target: this.schema.podUsage.podId,\n set: {\n computeSeconds: sql`${this.schema.podUsage.computeSeconds} + ${secondsDelta}`,\n accountId,\n updatedAt: this.now(),\n },\n });\n }\n\n private async incrementAccountUsageWith(client: DbClient, accountId: string, storageDelta: number, ingressDelta: number, egressDelta: number): Promise<void> {\n await client.insert(this.schema.accountUsage)\n .values({\n accountId,\n storageBytes: storageDelta,\n ingressBytes: ingressDelta,\n egressBytes: egressDelta,\n })\n .onConflictDoUpdate({\n target: this.schema.accountUsage.accountId,\n set: {\n storageBytes: sql`${this.schema.accountUsage.storageBytes} + ${storageDelta}`,\n ingressBytes: sql`${this.schema.accountUsage.ingressBytes} + ${ingressDelta}`,\n egressBytes: sql`${this.schema.accountUsage.egressBytes} + ${egressDelta}`,\n updatedAt: this.now(),\n },\n });\n }\n\n private async incrementPodUsageWith(client: DbClient, accountId: string, podId: string, storageDelta: number, ingressDelta: number, egressDelta: number): Promise<void> {\n await client.insert(this.schema.podUsage)\n .values({\n podId,\n accountId,\n storageBytes: storageDelta,\n ingressBytes: ingressDelta,\n egressBytes: egressDelta,\n })\n .onConflictDoUpdate({\n target: this.schema.podUsage.podId,\n set: {\n storageBytes: sql`${this.schema.podUsage.storageBytes} + ${storageDelta}`,\n ingressBytes: sql`${this.schema.podUsage.ingressBytes} + ${ingressDelta}`,\n egressBytes: sql`${this.schema.podUsage.egressBytes} + ${egressDelta}`,\n accountId,\n updatedAt: this.now(),\n },\n });\n }\n\n private async upsertAccountUsage(client: DbClient, accountId: string, storageBytes?: number, storageLimit?: number | null, bandwidthLimit?: number | null): Promise<void> {\n const storageValue = typeof storageBytes === 'number' ? this.normalizeValue(storageBytes) : undefined;\n const insertValues: Record<string, unknown> = {\n accountId,\n storageBytes: storageValue ?? 0,\n ingressBytes: 0,\n egressBytes: 0,\n };\n if (storageLimit !== undefined) {\n insertValues.storageLimitBytes = storageLimit;\n }\n if (bandwidthLimit !== undefined) {\n insertValues.bandwidthLimitBps = bandwidthLimit;\n }\n const updateSet: Record<string, unknown> = {\n updatedAt: this.now(),\n };\n if (typeof storageValue === 'number') {\n updateSet.storageBytes = storageValue;\n }\n if (storageLimit !== undefined) {\n updateSet.storageLimitBytes = storageLimit;\n }\n if (bandwidthLimit !== undefined) {\n updateSet.bandwidthLimitBps = bandwidthLimit;\n }\n await client.insert(this.schema.accountUsage)\n .values(insertValues)\n .onConflictDoUpdate({\n target: this.schema.accountUsage.accountId,\n set: updateSet,\n });\n }\n\n private async upsertPodUsage(client: DbClient, accountId: string, podId: string, storageBytes?: number, storageLimit?: number | null, bandwidthLimit?: number | null): Promise<void> {\n const storageValue = typeof storageBytes === 'number' ? this.normalizeValue(storageBytes) : undefined;\n const insertValues: Record<string, unknown> = {\n podId,\n accountId,\n storageBytes: storageValue ?? 0,\n ingressBytes: 0,\n egressBytes: 0,\n };\n if (storageLimit !== undefined) {\n insertValues.storageLimitBytes = storageLimit;\n }\n if (bandwidthLimit !== undefined) {\n insertValues.bandwidthLimitBps = bandwidthLimit;\n }\n const updateSet: Record<string, unknown> = {\n accountId,\n updatedAt: this.now(),\n };\n if (typeof storageValue === 'number') {\n updateSet.storageBytes = storageValue;\n }\n if (storageLimit !== undefined) {\n updateSet.storageLimitBytes = storageLimit;\n }\n if (bandwidthLimit !== undefined) {\n updateSet.bandwidthLimitBps = bandwidthLimit;\n }\n await client.insert(this.schema.podUsage)\n .values(insertValues)\n .onConflictDoUpdate({\n target: this.schema.podUsage.podId,\n set: updateSet,\n });\n }\n\n /**\n * Generic account limit setter for compute/token limits.\n */\n private async upsertAccountLimit(client: DbClient, accountId: string, field: 'computeLimitSeconds' | 'tokenLimitMonthly', value: number | null): Promise<void> {\n const insertValues: Record<string, unknown> = {\n accountId,\n storageBytes: 0,\n ingressBytes: 0,\n egressBytes: 0,\n [field]: value,\n };\n await client.insert(this.schema.accountUsage)\n .values(insertValues)\n .onConflictDoUpdate({\n target: this.schema.accountUsage.accountId,\n set: {\n [field]: value,\n updatedAt: this.now(),\n },\n });\n }\n\n /**\n * Generic pod limit setter for compute/token limits.\n */\n private async upsertPodLimit(client: DbClient, accountId: string, podId: string, field: 'computeLimitSeconds' | 'tokenLimitMonthly', value: number | null): Promise<void> {\n const insertValues: Record<string, unknown> = {\n podId,\n accountId,\n storageBytes: 0,\n ingressBytes: 0,\n egressBytes: 0,\n [field]: value,\n };\n await client.insert(this.schema.podUsage)\n .values(insertValues)\n .onConflictDoUpdate({\n target: this.schema.podUsage.podId,\n set: {\n accountId,\n [field]: value,\n updatedAt: this.now(),\n },\n });\n }\n\n private async getPodUsageWith(client: DbClient, podId: string): Promise<PodUsageRecord | undefined> {\n const result = await client.select({\n accountId: this.schema.podUsage.accountId,\n storage: this.schema.podUsage.storageBytes,\n ingress: this.schema.podUsage.ingressBytes,\n egress: this.schema.podUsage.egressBytes,\n storageLimit: this.schema.podUsage.storageLimitBytes,\n bandwidthLimit: this.schema.podUsage.bandwidthLimitBps,\n computeSeconds: this.schema.podUsage.computeSeconds,\n tokensUsed: this.schema.podUsage.tokensUsed,\n computeLimitSeconds: this.schema.podUsage.computeLimitSeconds,\n tokenLimitMonthly: this.schema.podUsage.tokenLimitMonthly,\n periodStart: this.schema.podUsage.periodStart,\n }).from(this.schema.podUsage)\n .where(eq(this.schema.podUsage.podId, podId));\n if (!result || result.length === 0) {\n return undefined;\n }\n const row = result[0];\n const accountId = String(row.accountId);\n return {\n podId,\n accountId,\n storageBytes: this.coerceNumber(row.storage),\n ingressBytes: this.coerceNumber(row.ingress),\n egressBytes: this.coerceNumber(row.egress),\n storageLimitBytes: this.coerceNullable(row.storageLimit),\n bandwidthLimitBps: this.coerceNullable(row.bandwidthLimit),\n computeSeconds: this.coerceNumber(row.computeSeconds),\n tokensUsed: this.coerceNumber(row.tokensUsed),\n computeLimitSeconds: this.coerceNullable(row.computeLimitSeconds),\n tokenLimitMonthly: this.coerceNullable(row.tokenLimitMonthly),\n periodStart: this.coerceTimestamp(row.periodStart),\n };\n }\n\n private normalizeDelta(value: number): number {\n if (!Number.isFinite(value) || value === 0) {\n return 0;\n }\n return Math.trunc(value);\n }\n\n private normalizeValue(value: number): number {\n if (!Number.isFinite(value) || value <= 0) {\n return 0;\n }\n return Math.max(0, Math.trunc(value));\n }\n\n private coerceNumber(value: unknown): number {\n const numeric = Number(value ?? 0);\n return Number.isFinite(numeric) ? numeric : 0;\n }\n\n private coerceNullable(value: unknown): number | null | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (value === null) {\n return null;\n }\n const numeric = Number(value);\n if (!Number.isFinite(numeric)) {\n return null;\n }\n return Math.trunc(numeric);\n }\n\n /**\n * Coerce timestamp value to Unix timestamp (seconds).\n * Handles Date objects (from PG) and numbers (from SQLite).\n */\n private coerceTimestamp(value: unknown): number | null {\n if (value === null || value === undefined) {\n return null;\n }\n if (value instanceof Date) {\n return Math.floor(value.getTime() / 1000);\n }\n if (typeof value === 'number') {\n return value;\n }\n return null;\n }\n\n /**\n * Get the current timestamp in the format expected by the database.\n * PG expects Date objects, SQLite expects Unix timestamps (seconds).\n */\n private now(): Date | number {\n const timestamp = new Date();\n return isDatabaseSqlite(this.db) ? Math.floor(timestamp.getTime() / 1000) : timestamp;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"UsageRepository.js","sourceRoot":"","sources":["../../../src/storage/quota/UsageRepository.ts"],"names":[],"mappings":"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","sourcesContent":["import { sql, eq, and } from 'drizzle-orm';\nimport type { IdentityDatabase } from '../../identity/drizzle/db';\nimport { getSchema, isDatabaseSqlite } from '../../identity/drizzle/db';\nimport type { NodePgTransaction } from 'drizzle-orm/node-postgres/session';\n\ntype DbClient = IdentityDatabase | NodePgTransaction<any, any>;\ntype UsageScopeType = 'account' | 'pod';\n\nconst ACCOUNT_SCOPE: UsageScopeType = 'account';\nconst POD_SCOPE: UsageScopeType = 'pod';\n\nexport interface AccountUsageRecord {\n accountId: string;\n storageBytes: number;\n ingressBytes: number;\n egressBytes: number;\n storageLimitBytes?: number | null;\n bandwidthLimitBps?: number | null;\n computeSeconds: number;\n tokensUsed: number;\n computeLimitSeconds?: number | null;\n tokenLimitMonthly?: number | null;\n periodStart?: number | null;\n}\n\nexport interface PodUsageRecord extends AccountUsageRecord {\n podId: string;\n}\n\n/**\n * Tracks account and pod usage in one table. Account/pod are scopes of the same\n * metric record, not separate data models.\n */\nexport class UsageRepository {\n private readonly schema: ReturnType<typeof getSchema>;\n\n public constructor(private readonly db: IdentityDatabase) {\n this.schema = getSchema(db);\n }\n\n public async incrementUsage(accountId: string, podId: string, storageDelta: number, ingressDelta: number, egressDelta: number): Promise<void> {\n const normalizedStorage = this.normalizeDelta(storageDelta);\n const normalizedIngress = this.normalizeDelta(ingressDelta);\n const normalizedEgress = this.normalizeDelta(egressDelta);\n if (normalizedStorage === 0 && normalizedIngress === 0 && normalizedEgress === 0) {\n return;\n }\n await this.db.transaction(async (tx: IdentityDatabase) => {\n await this.incrementUsageWith(tx, POD_SCOPE, podId, accountId, normalizedStorage, normalizedIngress, normalizedEgress);\n await this.incrementUsageWith(tx, ACCOUNT_SCOPE, accountId, accountId, normalizedStorage, normalizedIngress, normalizedEgress);\n });\n }\n\n public async incrementBandwidth(accountId: string, podId: string, ingressDelta: number, egressDelta: number): Promise<void> {\n await this.incrementUsage(accountId, podId, 0, ingressDelta, egressDelta);\n }\n\n public async setPodStorage(accountId: string, podId: string, storageBytes: number): Promise<void> {\n const normalized = this.normalizeValue(storageBytes);\n await this.db.transaction(async (tx: IdentityDatabase) => {\n const current = await this.getPodUsageWith(tx, podId);\n const owningAccountId = current?.accountId ?? accountId;\n const previousStorage = current?.storageBytes ?? 0;\n const delta = normalized - previousStorage;\n\n await this.upsertUsage(tx, POD_SCOPE, podId, owningAccountId, { storageBytes: normalized });\n if (delta !== 0) {\n await this.incrementUsageWith(tx, ACCOUNT_SCOPE, owningAccountId, owningAccountId, delta, 0, 0);\n }\n });\n }\n\n public async setAccountStorage(accountId: string, storageBytes: number): Promise<void> {\n await this.upsertUsage(this.db, ACCOUNT_SCOPE, accountId, accountId, {\n storageBytes: this.normalizeValue(storageBytes),\n });\n }\n\n public async getAccountUsage(accountId: string): Promise<AccountUsageRecord | undefined> {\n const row = await this.getUsageRow(this.db, ACCOUNT_SCOPE, accountId);\n return row ? this.toAccountUsage(accountId, row) : undefined;\n }\n\n public async getPodUsage(podId: string): Promise<PodUsageRecord | undefined> {\n return this.getPodUsageWith(this.db, podId);\n }\n\n public async setAccountStorageLimit(accountId: string, limit: number | null): Promise<void> {\n await this.upsertUsage(this.db, ACCOUNT_SCOPE, accountId, accountId, { storageLimitBytes: limit });\n }\n\n public async setPodStorageLimit(podId: string, accountId: string, limit: number | null): Promise<void> {\n await this.upsertUsage(this.db, POD_SCOPE, podId, accountId, { storageLimitBytes: limit });\n }\n\n public async setAccountBandwidthLimit(accountId: string, limit: number | null): Promise<void> {\n await this.upsertUsage(this.db, ACCOUNT_SCOPE, accountId, accountId, { bandwidthLimitBps: limit });\n }\n\n public async setPodBandwidthLimit(podId: string, accountId: string, limit: number | null): Promise<void> {\n await this.upsertUsage(this.db, POD_SCOPE, podId, accountId, { bandwidthLimitBps: limit });\n }\n\n public async setAccountComputeLimit(accountId: string, limit: number | null): Promise<void> {\n await this.upsertUsage(this.db, ACCOUNT_SCOPE, accountId, accountId, { computeLimitSeconds: limit });\n }\n\n public async setAccountTokenLimit(accountId: string, limit: number | null): Promise<void> {\n await this.upsertUsage(this.db, ACCOUNT_SCOPE, accountId, accountId, { tokenLimitMonthly: limit });\n }\n\n public async setPodComputeLimit(podId: string, accountId: string, limit: number | null): Promise<void> {\n await this.upsertUsage(this.db, POD_SCOPE, podId, accountId, { computeLimitSeconds: limit });\n }\n\n public async setPodTokenLimit(podId: string, accountId: string, limit: number | null): Promise<void> {\n await this.upsertUsage(this.db, POD_SCOPE, podId, accountId, { tokenLimitMonthly: limit });\n }\n\n public async incrementTokenUsage(accountId: string, podId: string, tokensDelta: number): Promise<void> {\n const normalized = this.normalizeDelta(tokensDelta);\n if (normalized === 0) {\n return;\n }\n await this.db.transaction(async (tx: IdentityDatabase) => {\n await this.incrementTokensWith(tx, POD_SCOPE, podId, accountId, normalized);\n await this.incrementTokensWith(tx, ACCOUNT_SCOPE, accountId, accountId, normalized);\n });\n }\n\n public async incrementComputeUsage(accountId: string, podId: string, secondsDelta: number): Promise<void> {\n const normalized = this.normalizeDelta(secondsDelta);\n if (normalized === 0) {\n return;\n }\n await this.db.transaction(async (tx: IdentityDatabase) => {\n await this.incrementComputeWith(tx, POD_SCOPE, podId, accountId, normalized);\n await this.incrementComputeWith(tx, ACCOUNT_SCOPE, accountId, accountId, normalized);\n });\n }\n\n private async getPodUsageWith(client: DbClient, podId: string): Promise<PodUsageRecord | undefined> {\n const row = await this.getUsageRow(client, POD_SCOPE, podId);\n return row ? this.toPodUsage(podId, row) : undefined;\n }\n\n private async getUsageRow(client: DbClient, scopeType: UsageScopeType, scopeId: string): Promise<Record<string, unknown> | undefined> {\n const result = await client.select({\n accountId: this.schema.usage.accountId,\n storage: this.schema.usage.storageBytes,\n ingress: this.schema.usage.ingressBytes,\n egress: this.schema.usage.egressBytes,\n storageLimit: this.schema.usage.storageLimitBytes,\n bandwidthLimit: this.schema.usage.bandwidthLimitBps,\n computeSeconds: this.schema.usage.computeSeconds,\n tokensUsed: this.schema.usage.tokensUsed,\n computeLimitSeconds: this.schema.usage.computeLimitSeconds,\n tokenLimitMonthly: this.schema.usage.tokenLimitMonthly,\n periodStart: this.schema.usage.periodStart,\n }).from(this.schema.usage)\n .where(and(\n eq(this.schema.usage.scopeType, scopeType),\n eq(this.schema.usage.scopeId, scopeId),\n ));\n return result?.[0];\n }\n\n private async incrementTokensWith(client: DbClient, scopeType: UsageScopeType, scopeId: string, accountId: string, tokensDelta: number): Promise<void> {\n await client.insert(this.schema.usage)\n .values({\n scopeType,\n scopeId,\n accountId,\n storageBytes: 0,\n ingressBytes: 0,\n egressBytes: 0,\n tokensUsed: tokensDelta,\n })\n .onConflictDoUpdate({\n target: [ this.schema.usage.scopeType, this.schema.usage.scopeId ],\n set: {\n tokensUsed: sql`${this.schema.usage.tokensUsed} + ${tokensDelta}`,\n accountId,\n updatedAt: this.now(),\n },\n });\n }\n\n private async incrementComputeWith(client: DbClient, scopeType: UsageScopeType, scopeId: string, accountId: string, secondsDelta: number): Promise<void> {\n await client.insert(this.schema.usage)\n .values({\n scopeType,\n scopeId,\n accountId,\n storageBytes: 0,\n ingressBytes: 0,\n egressBytes: 0,\n computeSeconds: secondsDelta,\n })\n .onConflictDoUpdate({\n target: [ this.schema.usage.scopeType, this.schema.usage.scopeId ],\n set: {\n computeSeconds: sql`${this.schema.usage.computeSeconds} + ${secondsDelta}`,\n accountId,\n updatedAt: this.now(),\n },\n });\n }\n\n private async incrementUsageWith(client: DbClient, scopeType: UsageScopeType, scopeId: string, accountId: string, storageDelta: number, ingressDelta: number, egressDelta: number): Promise<void> {\n await client.insert(this.schema.usage)\n .values({\n scopeType,\n scopeId,\n accountId,\n storageBytes: storageDelta,\n ingressBytes: ingressDelta,\n egressBytes: egressDelta,\n })\n .onConflictDoUpdate({\n target: [ this.schema.usage.scopeType, this.schema.usage.scopeId ],\n set: {\n storageBytes: sql`${this.schema.usage.storageBytes} + ${storageDelta}`,\n ingressBytes: sql`${this.schema.usage.ingressBytes} + ${ingressDelta}`,\n egressBytes: sql`${this.schema.usage.egressBytes} + ${egressDelta}`,\n accountId,\n updatedAt: this.now(),\n },\n });\n }\n\n private async upsertUsage(\n client: DbClient,\n scopeType: UsageScopeType,\n scopeId: string,\n accountId: string,\n values: {\n storageBytes?: number;\n storageLimitBytes?: number | null;\n bandwidthLimitBps?: number | null;\n computeLimitSeconds?: number | null;\n tokenLimitMonthly?: number | null;\n },\n ): Promise<void> {\n const insertValues: Record<string, unknown> = {\n scopeType,\n scopeId,\n accountId,\n storageBytes: values.storageBytes ?? 0,\n ingressBytes: 0,\n egressBytes: 0,\n };\n const updateSet: Record<string, unknown> = {\n accountId,\n updatedAt: this.now(),\n };\n for (const field of [ 'storageBytes', 'storageLimitBytes', 'bandwidthLimitBps', 'computeLimitSeconds', 'tokenLimitMonthly' ] as const) {\n if (values[field] !== undefined) {\n insertValues[field] = values[field];\n updateSet[field] = values[field];\n }\n }\n\n await client.insert(this.schema.usage)\n .values(insertValues)\n .onConflictDoUpdate({\n target: [ this.schema.usage.scopeType, this.schema.usage.scopeId ],\n set: updateSet,\n });\n }\n\n private toAccountUsage(accountId: string, row: Record<string, unknown>): AccountUsageRecord {\n return {\n accountId,\n ...this.toUsageMetrics(row),\n };\n }\n\n private toPodUsage(podId: string, row: Record<string, unknown>): PodUsageRecord {\n return {\n podId,\n accountId: String(row.accountId),\n ...this.toUsageMetrics(row),\n };\n }\n\n private toUsageMetrics(row: Record<string, unknown>): Omit<AccountUsageRecord, 'accountId'> {\n return {\n storageBytes: this.coerceNumber(row.storage),\n ingressBytes: this.coerceNumber(row.ingress),\n egressBytes: this.coerceNumber(row.egress),\n storageLimitBytes: this.coerceNullable(row.storageLimit),\n bandwidthLimitBps: this.coerceNullable(row.bandwidthLimit),\n computeSeconds: this.coerceNumber(row.computeSeconds),\n tokensUsed: this.coerceNumber(row.tokensUsed),\n computeLimitSeconds: this.coerceNullable(row.computeLimitSeconds),\n tokenLimitMonthly: this.coerceNullable(row.tokenLimitMonthly),\n periodStart: this.coerceTimestamp(row.periodStart),\n };\n }\n\n private normalizeDelta(value: number): number {\n if (!Number.isFinite(value) || value === 0) {\n return 0;\n }\n return Math.trunc(value);\n }\n\n private normalizeValue(value: number): number {\n if (!Number.isFinite(value) || value <= 0) {\n return 0;\n }\n return Math.max(0, Math.trunc(value));\n }\n\n private coerceNumber(value: unknown): number {\n const numeric = Number(value ?? 0);\n return Number.isFinite(numeric) ? numeric : 0;\n }\n\n private coerceNullable(value: unknown): number | null | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (value === null) {\n return null;\n }\n const numeric = Number(value);\n if (!Number.isFinite(numeric)) {\n return null;\n }\n return Math.trunc(numeric);\n }\n\n private coerceTimestamp(value: unknown): number | null {\n if (value === null || value === undefined) {\n return null;\n }\n if (value instanceof Date) {\n return Math.floor(value.getTime() / 1000);\n }\n if (typeof value === 'number') {\n return value;\n }\n return null;\n }\n\n private now(): Date | number {\n const timestamp = new Date();\n return isDatabaseSqlite(this.db) ? Math.floor(timestamp.getTime() / 1000) : timestamp;\n }\n}\n"]}
|