@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.
Files changed (218) hide show
  1. package/dist/api/auth/AuthContext.d.ts +3 -2
  2. package/dist/api/auth/AuthContext.js +2 -1
  3. package/dist/api/auth/AuthContext.js.map +1 -1
  4. package/dist/api/auth/ClientCredentialsAuthenticator.d.ts +2 -12
  5. package/dist/api/auth/ClientCredentialsAuthenticator.js +4 -4
  6. package/dist/api/auth/ClientCredentialsAuthenticator.js.map +1 -1
  7. package/dist/api/auth/ServiceTokenAuthenticator.d.ts +2 -2
  8. package/dist/api/auth/ServiceTokenAuthenticator.js.map +1 -1
  9. package/dist/api/chatkit/pod-store.d.ts +3 -0
  10. package/dist/api/chatkit/pod-store.js +93 -59
  11. package/dist/api/chatkit/pod-store.js.map +1 -1
  12. package/dist/api/chatkit/schema.d.ts +5 -6
  13. package/dist/api/container/business-token.d.ts +1 -1
  14. package/dist/api/container/business-token.js +5 -1
  15. package/dist/api/container/business-token.js.map +1 -1
  16. package/dist/api/container/common.js +14 -10
  17. package/dist/api/container/common.js.map +1 -1
  18. package/dist/api/container/routes.js +16 -3
  19. package/dist/api/container/routes.js.map +1 -1
  20. package/dist/api/container/types.d.ts +2 -4
  21. package/dist/api/container/types.js.map +1 -1
  22. package/dist/api/handlers/ChatHandler.d.ts +1 -1
  23. package/dist/api/handlers/ChatHandler.js +1 -1
  24. package/dist/api/handlers/ChatHandler.js.map +1 -1
  25. package/dist/api/handlers/EdgeNodeSignalHandler.js +3 -1
  26. package/dist/api/handlers/EdgeNodeSignalHandler.js.map +1 -1
  27. package/dist/api/handlers/PodManagementHandler.d.ts +2 -0
  28. package/dist/api/handlers/PodManagementHandler.js +114 -12
  29. package/dist/api/handlers/PodManagementHandler.js.map +1 -1
  30. package/dist/api/handlers/ProvisionHandler.d.ts +27 -0
  31. package/dist/api/handlers/ProvisionHandler.js +339 -32
  32. package/dist/api/handlers/ProvisionHandler.js.map +1 -1
  33. package/dist/api/handlers/QuotaHandler.js +0 -12
  34. package/dist/api/handlers/QuotaHandler.js.map +1 -1
  35. package/dist/api/handlers/index.d.ts +0 -1
  36. package/dist/api/handlers/index.js +0 -1
  37. package/dist/api/handlers/index.js.map +1 -1
  38. package/dist/api/matrix/PodMatrixStore.js +26 -21
  39. package/dist/api/matrix/PodMatrixStore.js.map +1 -1
  40. package/dist/api/runs/InngestRunExecutionBackend.d.ts +2 -2
  41. package/dist/api/runs/schema.d.ts +5 -7
  42. package/dist/api/runs/store.js +6 -4
  43. package/dist/api/runs/store.js.map +1 -1
  44. package/dist/api/runtime.js +3 -3
  45. package/dist/api/runtime.js.map +1 -1
  46. package/dist/api/tasks/InngestTaskScheduler.d.ts +4 -4
  47. package/dist/api/tasks/schema.d.ts +17 -13
  48. package/dist/api/tasks/schema.js +7 -2
  49. package/dist/api/tasks/schema.js.map +1 -1
  50. package/dist/api/tasks/store.js +1 -2
  51. package/dist/api/tasks/store.js.map +1 -1
  52. package/dist/components/context.jsonld +12 -0
  53. package/dist/edge/EdgeNodeAgent.d.ts +1 -1
  54. package/dist/edge/EdgeNodeAgent.js +1 -1
  55. package/dist/edge/EdgeNodeAgent.js.map +1 -1
  56. package/dist/edge/EdgeNodeDnsCoordinator.d.ts +1 -0
  57. package/dist/edge/EdgeNodeDnsCoordinator.js +9 -3
  58. package/dist/edge/EdgeNodeDnsCoordinator.js.map +1 -1
  59. package/dist/edge/EdgeNodeDnsCoordinator.jsonld +4 -0
  60. package/dist/edge/EdgeNodeHealthProbeService.d.ts +3 -0
  61. package/dist/edge/EdgeNodeHealthProbeService.js +22 -2
  62. package/dist/edge/EdgeNodeHealthProbeService.js.map +1 -1
  63. package/dist/edge/EdgeNodeHealthProbeService.jsonld +12 -0
  64. package/dist/http/ClusterIngressRouter.js +6 -3
  65. package/dist/http/ClusterIngressRouter.js.map +1 -1
  66. package/dist/http/ClusterWebSocketConfigurator.js +6 -2
  67. package/dist/http/ClusterWebSocketConfigurator.js.map +1 -1
  68. package/dist/http/EdgeNodeDirectDebugHttpHandler.d.ts +2 -0
  69. package/dist/http/EdgeNodeDirectDebugHttpHandler.js +18 -3
  70. package/dist/http/EdgeNodeDirectDebugHttpHandler.js.map +1 -1
  71. package/dist/http/EdgeNodeDirectDebugHttpHandler.jsonld +8 -0
  72. package/dist/http/EdgeNodeProxyHttpHandler.js +6 -2
  73. package/dist/http/EdgeNodeProxyHttpHandler.js.map +1 -1
  74. package/dist/http/cluster/PodMigrationHttpHandler.d.ts +2 -2
  75. package/dist/http/cluster/PodMigrationHttpHandler.js +2 -2
  76. package/dist/http/cluster/PodMigrationHttpHandler.js.map +1 -1
  77. package/dist/http/quota/QuotaAdminHttpHandler.js +27 -21
  78. package/dist/http/quota/QuotaAdminHttpHandler.js.map +1 -1
  79. package/dist/http/search/SearchHttpHandler.js +2 -2
  80. package/dist/http/search/SearchHttpHandler.js.map +1 -1
  81. package/dist/identity/drizzle/AccountRepository.d.ts +4 -22
  82. package/dist/identity/drizzle/AccountRepository.js +9 -113
  83. package/dist/identity/drizzle/AccountRepository.js.map +1 -1
  84. package/dist/identity/drizzle/AccountRoleRepository.d.ts +5 -5
  85. package/dist/identity/drizzle/AccountRoleRepository.js +204 -97
  86. package/dist/identity/drizzle/AccountRoleRepository.js.map +1 -1
  87. package/dist/identity/drizzle/DdnsRepository.d.ts +5 -20
  88. package/dist/identity/drizzle/DdnsRepository.js +13 -49
  89. package/dist/identity/drizzle/DdnsRepository.js.map +1 -1
  90. package/dist/identity/drizzle/EdgeNodeRepository.d.ts +13 -6
  91. package/dist/identity/drizzle/EdgeNodeRepository.js +167 -66
  92. package/dist/identity/drizzle/EdgeNodeRepository.js.map +1 -1
  93. package/dist/identity/drizzle/PodLookupRepository.d.ts +7 -36
  94. package/dist/identity/drizzle/PodLookupRepository.js +103 -126
  95. package/dist/identity/drizzle/PodLookupRepository.js.map +1 -1
  96. package/dist/identity/drizzle/ServiceTokenRepository.d.ts +13 -1
  97. package/dist/identity/drizzle/ServiceTokenRepository.js +7 -0
  98. package/dist/identity/drizzle/ServiceTokenRepository.js.map +1 -1
  99. package/dist/identity/drizzle/db.d.ts +2 -1
  100. package/dist/identity/drizzle/db.js +173 -297
  101. package/dist/identity/drizzle/db.js.map +1 -1
  102. package/dist/identity/drizzle/schema.pg.d.ts +3 -11
  103. package/dist/identity/drizzle/schema.pg.js +10 -45
  104. package/dist/identity/drizzle/schema.pg.js.map +1 -1
  105. package/dist/identity/drizzle/schema.sqlite.d.ts +88 -531
  106. package/dist/identity/drizzle/schema.sqlite.js +13 -46
  107. package/dist/identity/drizzle/schema.sqlite.js.map +1 -1
  108. package/dist/identity/oidc/ScopedPickWebIdHandler.d.ts +3 -0
  109. package/dist/identity/oidc/ScopedPickWebIdHandler.js +18 -6
  110. package/dist/identity/oidc/ScopedPickWebIdHandler.js.map +1 -1
  111. package/dist/identity/oidc/ScopedPickWebIdHandler.jsonld +22 -0
  112. package/dist/provision/ProvisionCodeCodec.js +10 -1
  113. package/dist/provision/ProvisionCodeCodec.js.map +1 -1
  114. package/dist/provision/ProvisionPodCreator.d.ts +8 -2
  115. package/dist/provision/ProvisionPodCreator.js +134 -41
  116. package/dist/provision/ProvisionPodCreator.js.map +1 -1
  117. package/dist/provision/ProvisionPodCreator.jsonld +38 -3
  118. package/dist/quota/DrizzleQuotaService.d.ts +0 -4
  119. package/dist/quota/DrizzleQuotaService.js +1 -21
  120. package/dist/quota/DrizzleQuotaService.js.map +1 -1
  121. package/dist/quota/DrizzleQuotaService.jsonld +0 -16
  122. package/dist/quota/NoopQuotaService.d.ts +0 -4
  123. package/dist/quota/NoopQuotaService.js +0 -8
  124. package/dist/quota/NoopQuotaService.js.map +1 -1
  125. package/dist/quota/NoopQuotaService.jsonld +0 -16
  126. package/dist/quota/QuotaService.d.ts +0 -4
  127. package/dist/quota/QuotaService.js.map +1 -1
  128. package/dist/quota/QuotaService.jsonld +0 -16
  129. package/dist/service/EdgeNodeSignalClient.d.ts +0 -2
  130. package/dist/service/EdgeNodeSignalClient.js +0 -4
  131. package/dist/service/EdgeNodeSignalClient.js.map +1 -1
  132. package/dist/service/PodMigrationService.d.ts +2 -2
  133. package/dist/service/PodMigrationService.js +4 -4
  134. package/dist/service/PodMigrationService.js.map +1 -1
  135. package/dist/setup/LocalSetupServiceTokenRepository.d.ts +22 -0
  136. package/dist/setup/LocalSetupServiceTokenRepository.js +68 -0
  137. package/dist/setup/LocalSetupServiceTokenRepository.js.map +1 -0
  138. package/dist/storage/quota/PerAccountQuotaStrategy.js +2 -2
  139. package/dist/storage/quota/PerAccountQuotaStrategy.js.map +1 -1
  140. package/dist/storage/quota/UsageRepository.d.ts +10 -32
  141. package/dist/storage/quota/UsageRepository.js +84 -281
  142. package/dist/storage/quota/UsageRepository.js.map +1 -1
  143. package/dist/storage/vector/VectorIndexingListener.js +2 -2
  144. package/dist/storage/vector/VectorIndexingListener.js.map +1 -1
  145. package/dist/subdomain/SubdomainService.d.ts +1 -1
  146. package/dist/subdomain/SubdomainService.js +1 -1
  147. package/dist/subdomain/SubdomainService.js.map +1 -1
  148. package/dist/subdomain/SubdomainService.jsonld +1 -1
  149. package/node_modules/@undefineds.co/drizzle-solid/dist/core/exact-records.d.ts +21 -0
  150. package/node_modules/@undefineds.co/drizzle-solid/dist/core/exact-records.d.ts.map +1 -0
  151. package/node_modules/@undefineds.co/drizzle-solid/dist/core/exact-records.js +85 -0
  152. package/node_modules/@undefineds.co/drizzle-solid/dist/core/exact-records.js.map +1 -0
  153. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/default-id-template.d.ts +10 -0
  154. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/default-id-template.d.ts.map +1 -0
  155. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/default-id-template.js +365 -0
  156. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/default-id-template.js.map +1 -0
  157. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/index.d.ts +1 -0
  158. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/index.d.ts.map +1 -1
  159. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/index.js +3 -1
  160. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/index.js.map +1 -1
  161. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/insert-query-builder.d.ts.map +1 -1
  162. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/insert-query-builder.js +5 -1
  163. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/insert-query-builder.js.map +1 -1
  164. package/node_modules/@undefineds.co/drizzle-solid/dist/core/repository.d.ts +2 -0
  165. package/node_modules/@undefineds.co/drizzle-solid/dist/core/repository.d.ts.map +1 -1
  166. package/node_modules/@undefineds.co/drizzle-solid/dist/core/repository.js +2 -1
  167. package/node_modules/@undefineds.co/drizzle-solid/dist/core/repository.js.map +1 -1
  168. package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-reference.d.ts +18 -0
  169. package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-reference.d.ts.map +1 -1
  170. package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-reference.js +234 -10
  171. package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-reference.js.map +1 -1
  172. package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/pod-table.d.ts +13 -0
  173. package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/pod-table.d.ts.map +1 -1
  174. package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/pod-table.js +19 -0
  175. package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/pod-table.js.map +1 -1
  176. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/exact-records.d.ts +21 -0
  177. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/exact-records.d.ts.map +1 -0
  178. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/exact-records.js +78 -0
  179. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/exact-records.js.map +1 -0
  180. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/default-id-template.d.ts +10 -0
  181. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/default-id-template.d.ts.map +1 -0
  182. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/default-id-template.js +362 -0
  183. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/default-id-template.js.map +1 -0
  184. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/index.d.ts +1 -0
  185. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/index.d.ts.map +1 -1
  186. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/index.js +1 -0
  187. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/index.js.map +1 -1
  188. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/insert-query-builder.d.ts.map +1 -1
  189. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/insert-query-builder.js +5 -1
  190. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/insert-query-builder.js.map +1 -1
  191. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/repository.d.ts +2 -0
  192. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/repository.d.ts.map +1 -1
  193. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/repository.js +1 -0
  194. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/repository.js.map +1 -1
  195. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-reference.d.ts +18 -0
  196. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-reference.d.ts.map +1 -1
  197. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-reference.js +225 -10
  198. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-reference.js.map +1 -1
  199. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/pod-table.d.ts +13 -0
  200. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/pod-table.d.ts.map +1 -1
  201. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/pod-table.js +19 -0
  202. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/pod-table.js.map +1 -1
  203. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/index.d.ts +5 -4
  204. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/index.d.ts.map +1 -1
  205. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/index.js +4 -3
  206. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/index.js.map +1 -1
  207. package/node_modules/@undefineds.co/drizzle-solid/dist/index.d.ts +5 -4
  208. package/node_modules/@undefineds.co/drizzle-solid/dist/index.d.ts.map +1 -1
  209. package/node_modules/@undefineds.co/drizzle-solid/dist/index.js +20 -3
  210. package/node_modules/@undefineds.co/drizzle-solid/dist/index.js.map +1 -1
  211. package/node_modules/@undefineds.co/drizzle-solid/package.json +1 -1
  212. package/package.json +3 -3
  213. package/dist/api/handlers/ApiKeyHandler.d.ts +0 -15
  214. package/dist/api/handlers/ApiKeyHandler.js +0 -153
  215. package/dist/api/handlers/ApiKeyHandler.js.map +0 -1
  216. package/dist/api/store/DrizzleClientCredentialsStore.d.ts +0 -51
  217. package/dist/api/store/DrizzleClientCredentialsStore.js +0 -115
  218. 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
- * Repository for tracking pod and account usage metrics.
8
- * Supports both PostgreSQL and SQLite through unified schema abstraction.
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.incrementPodUsageWith(tx, accountId, podId, normalizedStorage, normalizedIngress, normalizedEgress);
24
- await this.incrementAccountUsageWith(tx, accountId, normalizedStorage, normalizedIngress, normalizedEgress);
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.upsertPodUsage(tx, owningAccountId, podId, normalized);
39
+ await this.upsertUsage(tx, POD_SCOPE, podId, owningAccountId, { storageBytes: normalized });
38
40
  if (delta !== 0) {
39
- await this.incrementAccountUsageWith(tx, owningAccountId, delta, 0, 0);
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
- const normalized = this.normalizeValue(storageBytes);
45
- await this.db.transaction(async (tx) => {
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 result = await this.db.select({
53
- storage: this.schema.accountUsage.storageBytes,
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
- const result = await this.db.select({
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.upsertAccountUsage(this.db, accountId, undefined, limit, undefined);
58
+ await this.upsertUsage(this.db, ACCOUNT_SCOPE, accountId, accountId, { storageLimitBytes: limit });
120
59
  }
121
60
  async setPodStorageLimit(podId, accountId, limit) {
122
- await this.upsertPodUsage(this.db, accountId, podId, undefined, limit, undefined);
61
+ await this.upsertUsage(this.db, POD_SCOPE, podId, accountId, { storageLimitBytes: limit });
123
62
  }
124
63
  async setAccountBandwidthLimit(accountId, limit) {
125
- await this.upsertAccountUsage(this.db, accountId, undefined, undefined, limit);
64
+ await this.upsertUsage(this.db, ACCOUNT_SCOPE, accountId, accountId, { bandwidthLimitBps: limit });
126
65
  }
127
66
  async setPodBandwidthLimit(podId, accountId, limit) {
128
- await this.upsertPodUsage(this.db, accountId, podId, undefined, undefined, limit);
67
+ await this.upsertUsage(this.db, POD_SCOPE, podId, accountId, { bandwidthLimitBps: limit });
129
68
  }
130
69
  async setAccountComputeLimit(accountId, limit) {
131
- await this.upsertAccountLimit(this.db, accountId, 'computeLimitSeconds', limit);
70
+ await this.upsertUsage(this.db, ACCOUNT_SCOPE, accountId, accountId, { computeLimitSeconds: limit });
132
71
  }
133
72
  async setAccountTokenLimit(accountId, limit) {
134
- await this.upsertAccountLimit(this.db, accountId, 'tokenLimitMonthly', limit);
73
+ await this.upsertUsage(this.db, ACCOUNT_SCOPE, accountId, accountId, { tokenLimitMonthly: limit });
135
74
  }
136
75
  async setPodComputeLimit(podId, accountId, limit) {
137
- await this.upsertPodLimit(this.db, accountId, podId, 'computeLimitSeconds', limit);
76
+ await this.upsertUsage(this.db, POD_SCOPE, podId, accountId, { computeLimitSeconds: limit });
138
77
  }
139
78
  async setPodTokenLimit(podId, accountId, limit) {
140
- await this.upsertPodLimit(this.db, accountId, podId, 'tokenLimitMonthly', limit);
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.incrementPodTokensWith(tx, accountId, podId, normalized);
152
- await this.incrementAccountTokensWith(tx, accountId, normalized);
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.incrementPodComputeWith(tx, accountId, podId, normalized);
165
- await this.incrementAccountComputeWith(tx, accountId, normalized);
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 incrementAccountTokensWith(client, accountId, tokensDelta) {
169
- await client.insert(this.schema.accountUsage)
170
- .values({
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 incrementPodTokensWith(client, accountId, podId, tokensDelta) {
186
- await client.insert(this.schema.podUsage)
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
- podId,
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.podUsage.podId,
134
+ target: [this.schema.usage.scopeType, this.schema.usage.scopeId],
197
135
  set: {
198
- tokensUsed: (0, drizzle_orm_1.sql) `${this.schema.podUsage.tokensUsed} + ${tokensDelta}`,
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 incrementAccountComputeWith(client, accountId, secondsDelta) {
205
- await client.insert(this.schema.accountUsage)
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
- podId,
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.podUsage.podId,
154
+ target: [this.schema.usage.scopeType, this.schema.usage.scopeId],
233
155
  set: {
234
- computeSeconds: (0, drizzle_orm_1.sql) `${this.schema.podUsage.computeSeconds} + ${secondsDelta}`,
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 incrementAccountUsageWith(client, accountId, storageDelta, ingressDelta, egressDelta) {
241
- await client.insert(this.schema.accountUsage)
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.accountUsage.accountId,
173
+ target: [this.schema.usage.scopeType, this.schema.usage.scopeId],
250
174
  set: {
251
- storageBytes: (0, drizzle_orm_1.sql) `${this.schema.accountUsage.storageBytes} + ${storageDelta}`,
252
- ingressBytes: (0, drizzle_orm_1.sql) `${this.schema.accountUsage.ingressBytes} + ${ingressDelta}`,
253
- egressBytes: (0, drizzle_orm_1.sql) `${this.schema.accountUsage.egressBytes} + ${egressDelta}`,
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 upsertAccountUsage(client, accountId, storageBytes, storageLimit, bandwidthLimit) {
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
- podId,
185
+ scopeType,
186
+ scopeId,
315
187
  accountId,
316
- storageBytes: storageValue ?? 0,
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
- if (typeof storageValue === 'number') {
331
- updateSet.storageBytes = storageValue;
332
- }
333
- if (storageLimit !== undefined) {
334
- updateSet.storageLimitBytes = storageLimit;
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.podUsage)
202
+ await client.insert(this.schema.usage)
340
203
  .values(insertValues)
341
204
  .onConflictDoUpdate({
342
- target: this.schema.podUsage.podId,
205
+ target: [this.schema.usage.scopeType, this.schema.usage.scopeId],
343
206
  set: updateSet,
344
207
  });
345
208
  }
346
- /**
347
- * Generic account limit setter for compute/token limits.
348
- */
349
- async upsertAccountLimit(client, accountId, field, value) {
350
- const insertValues = {
209
+ toAccountUsage(accountId, row) {
210
+ return {
351
211
  accountId,
352
- storageBytes: 0,
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
- * Generic pod limit setter for compute/token limits.
369
- */
370
- async upsertPodLimit(client, accountId, podId, field, value) {
371
- const insertValues = {
215
+ toPodUsage(podId, row) {
216
+ return {
372
217
  podId,
373
- accountId,
374
- storageBytes: 0,
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
- async getPodUsageWith(client, podId) {
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":";;;AAAA,6CAA2C;AAE3C,kDAAwE;AAMxE,MAAM,aAAa,GAAmB,SAAS,CAAC;AAChD,MAAM,SAAS,GAAmB,KAAK,CAAC;AAoBxC;;;GAGG;AACH,MAAa,eAAe;IAG1B,YAAoC,EAAoB;QAApB,OAAE,GAAF,EAAE,CAAkB;QACtD,IAAI,CAAC,MAAM,GAAG,IAAA,cAAS,EAAC,EAAE,CAAC,CAAC;IAC9B,CAAC;IAEM,KAAK,CAAC,cAAc,CAAC,SAAiB,EAAE,KAAa,EAAE,YAAoB,EAAE,YAAoB,EAAE,WAAmB;QAC3H,MAAM,iBAAiB,GAAG,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;QAC5D,MAAM,iBAAiB,GAAG,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;QAC5D,MAAM,gBAAgB,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QAC1D,IAAI,iBAAiB,KAAK,CAAC,IAAI,iBAAiB,KAAK,CAAC,IAAI,gBAAgB,KAAK,CAAC,EAAE,CAAC;YACjF,OAAO;QACT,CAAC;QACD,MAAM,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,EAAoB,EAAE,EAAE;YACvD,MAAM,IAAI,CAAC,kBAAkB,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,CAAC,CAAC;YACvH,MAAM,IAAI,CAAC,kBAAkB,CAAC,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,CAAC,CAAC;QACjI,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,KAAK,CAAC,kBAAkB,CAAC,SAAiB,EAAE,KAAa,EAAE,YAAoB,EAAE,WAAmB;QACzG,MAAM,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;IAC5E,CAAC;IAEM,KAAK,CAAC,aAAa,CAAC,SAAiB,EAAE,KAAa,EAAE,YAAoB;QAC/E,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;QACrD,MAAM,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,EAAoB,EAAE,EAAE;YACvD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;YACtD,MAAM,eAAe,GAAG,OAAO,EAAE,SAAS,IAAI,SAAS,CAAC;YACxD,MAAM,eAAe,GAAG,OAAO,EAAE,YAAY,IAAI,CAAC,CAAC;YACnD,MAAM,KAAK,GAAG,UAAU,GAAG,eAAe,CAAC;YAE3C,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,CAAC;YAC5F,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;gBAChB,MAAM,IAAI,CAAC,kBAAkB,CAAC,EAAE,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAClG,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,KAAK,CAAC,iBAAiB,CAAC,SAAiB,EAAE,YAAoB;QACpE,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE;YACnE,YAAY,EAAE,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC;SAChD,CAAC,CAAC;IACL,CAAC;IAEM,KAAK,CAAC,eAAe,CAAC,SAAiB;QAC5C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC;QACtE,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/D,CAAC;IAEM,KAAK,CAAC,WAAW,CAAC,KAAa;QACpC,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IAC9C,CAAC;IAEM,KAAK,CAAC,sBAAsB,CAAC,SAAiB,EAAE,KAAoB;QACzE,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC,CAAC;IACrG,CAAC;IAEM,KAAK,CAAC,kBAAkB,CAAC,KAAa,EAAE,SAAiB,EAAE,KAAoB;QACpF,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7F,CAAC;IAEM,KAAK,CAAC,wBAAwB,CAAC,SAAiB,EAAE,KAAoB;QAC3E,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC,CAAC;IACrG,CAAC;IAEM,KAAK,CAAC,oBAAoB,CAAC,KAAa,EAAE,SAAiB,EAAE,KAAoB;QACtF,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7F,CAAC;IAEM,KAAK,CAAC,sBAAsB,CAAC,SAAiB,EAAE,KAAoB;QACzE,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,mBAAmB,EAAE,KAAK,EAAE,CAAC,CAAC;IACvG,CAAC;IAEM,KAAK,CAAC,oBAAoB,CAAC,SAAiB,EAAE,KAAoB;QACvE,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC,CAAC;IACrG,CAAC;IAEM,KAAK,CAAC,kBAAkB,CAAC,KAAa,EAAE,SAAiB,EAAE,KAAoB;QACpF,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,mBAAmB,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/F,CAAC;IAEM,KAAK,CAAC,gBAAgB,CAAC,KAAa,EAAE,SAAiB,EAAE,KAAoB;QAClF,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7F,CAAC;IAEM,KAAK,CAAC,mBAAmB,CAAC,SAAiB,EAAE,KAAa,EAAE,WAAmB;QACpF,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QACpD,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QACD,MAAM,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,EAAoB,EAAE,EAAE;YACvD,MAAM,IAAI,CAAC,mBAAmB,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;YAC5E,MAAM,IAAI,CAAC,mBAAmB,CAAC,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;QACtF,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,KAAK,CAAC,qBAAqB,CAAC,SAAiB,EAAE,KAAa,EAAE,YAAoB;QACvF,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;QACrD,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QACD,MAAM,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,EAAoB,EAAE,EAAE;YACvD,MAAM,IAAI,CAAC,oBAAoB,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;YAC7E,MAAM,IAAI,CAAC,oBAAoB,CAAC,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;QACvF,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,eAAe,CAAC,MAAgB,EAAE,KAAa;QAC3D,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QAC7D,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvD,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,MAAgB,EAAE,SAAyB,EAAE,OAAe;QACpF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;YACjC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS;YACtC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY;YACvC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY;YACvC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW;YACrC,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB;YACjD,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB;YACnD,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc;YAChD,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU;YACxC,mBAAmB,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB;YAC1D,iBAAiB,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB;YACtD,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW;SAC3C,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;aACvB,KAAK,CAAC,IAAA,iBAAG,EACR,IAAA,gBAAE,EAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,SAAS,CAAC,EAC1C,IAAA,gBAAE,EAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CACvC,CAAC,CAAC;QACL,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC;IAEO,KAAK,CAAC,mBAAmB,CAAC,MAAgB,EAAE,SAAyB,EAAE,OAAe,EAAE,SAAiB,EAAE,WAAmB;QACpI,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;aACnC,MAAM,CAAC;YACN,SAAS;YACT,OAAO;YACP,SAAS;YACT,YAAY,EAAE,CAAC;YACf,YAAY,EAAE,CAAC;YACf,WAAW,EAAE,CAAC;YACd,UAAU,EAAE,WAAW;SACxB,CAAC;aACD,kBAAkB,CAAC;YAClB,MAAM,EAAE,CAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAE;YAClE,GAAG,EAAE;gBACH,UAAU,EAAE,IAAA,iBAAG,EAAA,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,MAAM,WAAW,EAAE;gBACjE,SAAS;gBACT,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACtB;SACF,CAAC,CAAC;IACP,CAAC;IAEO,KAAK,CAAC,oBAAoB,CAAC,MAAgB,EAAE,SAAyB,EAAE,OAAe,EAAE,SAAiB,EAAE,YAAoB;QACtI,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;aACnC,MAAM,CAAC;YACN,SAAS;YACT,OAAO;YACP,SAAS;YACT,YAAY,EAAE,CAAC;YACf,YAAY,EAAE,CAAC;YACf,WAAW,EAAE,CAAC;YACd,cAAc,EAAE,YAAY;SAC7B,CAAC;aACD,kBAAkB,CAAC;YAClB,MAAM,EAAE,CAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAE;YAClE,GAAG,EAAE;gBACH,cAAc,EAAE,IAAA,iBAAG,EAAA,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,MAAM,YAAY,EAAE;gBAC1E,SAAS;gBACT,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACtB;SACF,CAAC,CAAC;IACP,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAAC,MAAgB,EAAE,SAAyB,EAAE,OAAe,EAAE,SAAiB,EAAE,YAAoB,EAAE,YAAoB,EAAE,WAAmB;QAC/K,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;aACnC,MAAM,CAAC;YACN,SAAS;YACT,OAAO;YACP,SAAS;YACT,YAAY,EAAE,YAAY;YAC1B,YAAY,EAAE,YAAY;YAC1B,WAAW,EAAE,WAAW;SACzB,CAAC;aACD,kBAAkB,CAAC;YAClB,MAAM,EAAE,CAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAE;YAClE,GAAG,EAAE;gBACH,YAAY,EAAE,IAAA,iBAAG,EAAA,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,MAAM,YAAY,EAAE;gBACtE,YAAY,EAAE,IAAA,iBAAG,EAAA,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,MAAM,YAAY,EAAE;gBACtE,WAAW,EAAE,IAAA,iBAAG,EAAA,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,MAAM,WAAW,EAAE;gBACnE,SAAS;gBACT,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACtB;SACF,CAAC,CAAC;IACP,CAAC;IAEO,KAAK,CAAC,WAAW,CACvB,MAAgB,EAChB,SAAyB,EACzB,OAAe,EACf,SAAiB,EACjB,MAMC;QAED,MAAM,YAAY,GAA4B;YAC5C,SAAS;YACT,OAAO;YACP,SAAS;YACT,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,CAAC;YACtC,YAAY,EAAE,CAAC;YACf,WAAW,EAAE,CAAC;SACf,CAAC;QACF,MAAM,SAAS,GAA4B;YACzC,SAAS;YACT,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC;QACF,KAAK,MAAM,KAAK,IAAI,CAAE,cAAc,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,mBAAmB,CAAW,EAAE,CAAC;YACtI,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,SAAS,EAAE,CAAC;gBAChC,YAAY,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;gBACpC,SAAS,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QAED,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;aACnC,MAAM,CAAC,YAAY,CAAC;aACpB,kBAAkB,CAAC;YAClB,MAAM,EAAE,CAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAE;YAClE,GAAG,EAAE,SAAS;SACf,CAAC,CAAC;IACP,CAAC;IAEO,cAAc,CAAC,SAAiB,EAAE,GAA4B;QACpE,OAAO;YACL,SAAS;YACT,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC;SAC5B,CAAC;IACJ,CAAC;IAEO,UAAU,CAAC,KAAa,EAAE,GAA4B;QAC5D,OAAO;YACL,KAAK;YACL,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;YAChC,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC;SAC5B,CAAC;IACJ,CAAC;IAEO,cAAc,CAAC,GAA4B;QACjD,OAAO;YACL,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC;YAC5C,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC;YAC5C,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC;YAC1C,iBAAiB,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC;YACxD,iBAAiB,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC;YAC1D,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,CAAC;YACrD,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC;YAC7C,mBAAmB,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,mBAAmB,CAAC;YACjE,iBAAiB,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,iBAAiB,CAAC;YAC7D,WAAW,EAAE,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,WAAW,CAAC;SACnD,CAAC;IACJ,CAAC;IAEO,cAAc,CAAC,KAAa;QAClC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YAC3C,OAAO,CAAC,CAAC;QACX,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAEO,cAAc,CAAC,KAAa;QAClC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YAC1C,OAAO,CAAC,CAAC;QACX,CAAC;QACD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IACxC,CAAC;IAEO,YAAY,CAAC,KAAc;QACjC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;QACnC,OAAO,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC;IAEO,cAAc,CAAC,KAAc;QACnC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAEO,eAAe,CAAC,KAAc;QACpC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;QAC5C,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,GAAG;QACT,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;QAC7B,OAAO,IAAA,qBAAgB,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACxF,CAAC;CACF;AA9TD,0CA8TC","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"]}