@undefineds.co/xpod 0.3.31 → 0.3.33
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/chatkit/pod-store.d.ts +3 -0
- package/dist/api/chatkit/pod-store.js +93 -59
- package/dist/api/chatkit/pod-store.js.map +1 -1
- package/dist/api/chatkit/schema.d.ts +5 -6
- 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/matrix/PodMatrixStore.js +26 -21
- package/dist/api/matrix/PodMatrixStore.js.map +1 -1
- package/dist/api/runs/InngestRunExecutionBackend.d.ts +2 -2
- package/dist/api/runs/schema.d.ts +5 -7
- package/dist/api/runs/store.js +6 -4
- package/dist/api/runs/store.js.map +1 -1
- package/dist/api/runtime.js +3 -3
- package/dist/api/runtime.js.map +1 -1
- package/dist/api/tasks/InngestTaskScheduler.d.ts +4 -4
- package/dist/api/tasks/schema.d.ts +17 -13
- package/dist/api/tasks/schema.js +7 -2
- package/dist/api/tasks/schema.js.map +1 -1
- package/dist/api/tasks/store.js +1 -2
- package/dist/api/tasks/store.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/http/search/SearchHttpHandler.js +2 -2
- package/dist/http/search/SearchHttpHandler.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/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 +134 -41
- 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/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/vector/VectorIndexingListener.js +2 -2
- package/dist/storage/vector/VectorIndexingListener.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/node_modules/@undefineds.co/drizzle-solid/dist/core/exact-records.d.ts +21 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/exact-records.d.ts.map +1 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/exact-records.js +85 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/exact-records.js.map +1 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/default-id-template.d.ts +10 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/default-id-template.d.ts.map +1 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/default-id-template.js +365 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/default-id-template.js.map +1 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/index.d.ts +1 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/index.d.ts.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/index.js +3 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/index.js.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/insert-query-builder.d.ts.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/insert-query-builder.js +5 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/insert-query-builder.js.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/repository.d.ts +2 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/repository.d.ts.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/repository.js +2 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/repository.js.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-reference.d.ts +18 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-reference.d.ts.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-reference.js +234 -10
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-reference.js.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/pod-table.d.ts +13 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/pod-table.d.ts.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/pod-table.js +19 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/pod-table.js.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/exact-records.d.ts +21 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/exact-records.d.ts.map +1 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/exact-records.js +78 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/exact-records.js.map +1 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/default-id-template.d.ts +10 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/default-id-template.d.ts.map +1 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/default-id-template.js +362 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/default-id-template.js.map +1 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/index.d.ts +1 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/index.d.ts.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/index.js +1 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/index.js.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/insert-query-builder.d.ts.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/insert-query-builder.js +5 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/insert-query-builder.js.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/repository.d.ts +2 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/repository.d.ts.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/repository.js +1 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/repository.js.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-reference.d.ts +18 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-reference.d.ts.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-reference.js +225 -10
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-reference.js.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/pod-table.d.ts +13 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/pod-table.d.ts.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/pod-table.js +19 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/pod-table.js.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/index.d.ts +5 -4
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/index.d.ts.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/index.js +4 -3
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/index.js.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/index.d.ts +5 -4
- package/node_modules/@undefineds.co/drizzle-solid/dist/index.d.ts.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/index.js +20 -3
- package/node_modules/@undefineds.co/drizzle-solid/dist/index.js.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/package.json +1 -1
- package/package.json +3 -3
- 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
|
@@ -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"]}
|