@nxuss/lemma 0.5.5 → 0.5.7

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 (55) hide show
  1. package/dist/cjs/cli/lemma-proxy.d.ts.map +1 -1
  2. package/dist/cjs/cli/lemma-proxy.js +23 -1
  3. package/dist/cjs/cli/lemma-proxy.js.map +1 -1
  4. package/dist/cjs/cloud/BurstRateLimiter.d.ts +26 -0
  5. package/dist/cjs/cloud/BurstRateLimiter.d.ts.map +1 -0
  6. package/dist/cjs/cloud/BurstRateLimiter.js +63 -0
  7. package/dist/cjs/cloud/BurstRateLimiter.js.map +1 -0
  8. package/dist/cjs/cloud/KeyManager.d.ts +1 -0
  9. package/dist/cjs/cloud/KeyManager.d.ts.map +1 -1
  10. package/dist/cjs/cloud/KeyManager.js +28 -1
  11. package/dist/cjs/cloud/KeyManager.js.map +1 -1
  12. package/dist/cjs/cloud/PostgresQuotaLimiter.d.ts +60 -0
  13. package/dist/cjs/cloud/PostgresQuotaLimiter.d.ts.map +1 -0
  14. package/dist/cjs/cloud/PostgresQuotaLimiter.js +200 -0
  15. package/dist/cjs/cloud/PostgresQuotaLimiter.js.map +1 -0
  16. package/dist/cjs/cloud/TenantCache.d.ts +1 -1
  17. package/dist/cjs/cloud/TenantCache.d.ts.map +1 -1
  18. package/dist/cjs/cloud/TenantCache.js +21 -3
  19. package/dist/cjs/cloud/TenantCache.js.map +1 -1
  20. package/dist/cjs/cloud/server.d.ts +3 -1
  21. package/dist/cjs/cloud/server.d.ts.map +1 -1
  22. package/dist/cjs/cloud/server.js +42 -5
  23. package/dist/cjs/cloud/server.js.map +1 -1
  24. package/dist/cjs/cloud/types.d.ts +3 -0
  25. package/dist/cjs/cloud/types.d.ts.map +1 -1
  26. package/dist/cjs/cloud/types.js +3 -3
  27. package/dist/cjs/cloud/types.js.map +1 -1
  28. package/dist/esm/cli/lemma-proxy.d.ts.map +1 -1
  29. package/dist/esm/cli/lemma-proxy.js +23 -1
  30. package/dist/esm/cli/lemma-proxy.js.map +1 -1
  31. package/dist/esm/cloud/BurstRateLimiter.d.ts +26 -0
  32. package/dist/esm/cloud/BurstRateLimiter.d.ts.map +1 -0
  33. package/dist/esm/cloud/BurstRateLimiter.js +59 -0
  34. package/dist/esm/cloud/BurstRateLimiter.js.map +1 -0
  35. package/dist/esm/cloud/KeyManager.d.ts +1 -0
  36. package/dist/esm/cloud/KeyManager.d.ts.map +1 -1
  37. package/dist/esm/cloud/KeyManager.js +28 -1
  38. package/dist/esm/cloud/KeyManager.js.map +1 -1
  39. package/dist/esm/cloud/PostgresQuotaLimiter.d.ts +60 -0
  40. package/dist/esm/cloud/PostgresQuotaLimiter.d.ts.map +1 -0
  41. package/dist/esm/cloud/PostgresQuotaLimiter.js +196 -0
  42. package/dist/esm/cloud/PostgresQuotaLimiter.js.map +1 -0
  43. package/dist/esm/cloud/TenantCache.d.ts +1 -1
  44. package/dist/esm/cloud/TenantCache.d.ts.map +1 -1
  45. package/dist/esm/cloud/TenantCache.js +21 -3
  46. package/dist/esm/cloud/TenantCache.js.map +1 -1
  47. package/dist/esm/cloud/server.d.ts +3 -1
  48. package/dist/esm/cloud/server.d.ts.map +1 -1
  49. package/dist/esm/cloud/server.js +41 -5
  50. package/dist/esm/cloud/server.js.map +1 -1
  51. package/dist/esm/cloud/types.d.ts +3 -0
  52. package/dist/esm/cloud/types.d.ts.map +1 -1
  53. package/dist/esm/cloud/types.js +3 -3
  54. package/dist/esm/cloud/types.js.map +1 -1
  55. package/package.json +2 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BurstRateLimiter.js","sourceRoot":"","sources":["../../../src/cloud/BurstRateLimiter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,OAAO,gBAAgB;IAK3B,YAAY,MAAM,GAAG,EAAE,EAAE,YAAY,GAAG,IAAI;QAJpC,YAAO,GAAG,IAAI,GAAG,EAAoB,CAAC;QAK5C,IAAI,CAAC,oBAAoB,GAAG,MAAM,CAAC;QACnC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QAEjC,4DAA4D;QAC5D,WAAW,CAAC,GAAG,EAAE;YACf,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,MAAM,cAAc,GAAG,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC;YAE/C,KAAK,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;gBACvD,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC;gBAC1D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACxB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC3B,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;gBAChC,CAAC;YACH,CAAC;QACH,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,KAAa;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,cAAc,GAAG,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC;QAE/C,IAAI,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAE/C,iDAAiD;QACjD,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC;QAExD,IAAI,UAAU,CAAC,MAAM,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YACnD,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,SAAS,EAAE,CAAC;aACb,CAAC;QACJ,CAAC;QAED,2BAA2B;QAC3B,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAEpC,OAAO;YACL,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,IAAI,CAAC,oBAAoB,GAAG,UAAU,CAAC,MAAM;SACzD,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAa;QACjB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;CACF"}
@@ -22,6 +22,7 @@ export declare class KeyManager {
22
22
  getByTenant(tenantId: string): ApiKey[];
23
23
  get(keyId: string): ApiKey | undefined;
24
24
  private maybeResetDaily;
25
+ private maybeResetMonthly;
25
26
  private scheduleSave;
26
27
  private save;
27
28
  private load;
@@ -1 +1 @@
1
- {"version":3,"file":"KeyManager.d.ts","sourceRoot":"","sources":["../../../src/cloud/KeyManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,MAAM,EAAe,MAAM,SAAS,CAAC;AAE9C,qBAAa,UAAU;IACrB,OAAO,CAAC,IAAI,CAA6B;IACzC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAA+B;gBAEpC,SAAS,SAAqB;IAO1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,CAAU,GAAG,MAAM;IAkB/E,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IA4B1E,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAUlC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,OAAO;IAQzD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAQ9B,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAIvC,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAMtC,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,IAAI;IAWZ,OAAO,CAAC,IAAI;CAYb"}
1
+ {"version":3,"file":"KeyManager.d.ts","sourceRoot":"","sources":["../../../src/cloud/KeyManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,MAAM,EAAe,MAAM,SAAS,CAAC;AAE9C,qBAAa,UAAU;IACrB,OAAO,CAAC,IAAI,CAA6B;IACzC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAA+B;gBAEpC,SAAS,SAAqB;IAO1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,CAAU,GAAG,MAAM;IAkB/E,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAsC1E,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAWlC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,OAAO;IAQzD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAQ9B,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAIvC,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAMtC,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,IAAI;IAWZ,OAAO,CAAC,IAAI;CAiBb"}
@@ -25,7 +25,7 @@ export class KeyManager {
25
25
  plan,
26
26
  createdAt: Date.now(),
27
27
  active: true,
28
- usage: { today: 0, total: 0, lastReset: Date.now() },
28
+ usage: { today: 0, monthly: 0, total: 0, lastReset: Date.now(), lastMonthlyReset: Date.now() },
29
29
  };
30
30
  this.keys.set(id, key);
31
31
  this.scheduleSave();
@@ -43,6 +43,8 @@ export class KeyManager {
43
43
  }
44
44
  // Reset daily counter if needed
45
45
  this.maybeResetDaily(key);
46
+ // Reset monthly counter if needed
47
+ this.maybeResetMonthly(key);
46
48
  // Check plan limits
47
49
  const limits = PLAN_LIMITS[key.plan];
48
50
  if (key.usage.today >= limits.dailyRequests) {
@@ -53,6 +55,12 @@ export class KeyManager {
53
55
  : 'Daily request limit reached. Contact support to increase limits.',
54
56
  };
55
57
  }
58
+ if (!process.env.DATABASE_URL && key.usage.monthly >= limits.monthlyRequests) {
59
+ return {
60
+ valid: false,
61
+ reason: 'Monthly Cloud Quota Exceeded. Please upgrade your plan.',
62
+ };
63
+ }
56
64
  return { valid: true, key };
57
65
  }
58
66
  // ─── Usage Tracking ─────────────────────────────────────────────────────────
@@ -61,6 +69,7 @@ export class KeyManager {
61
69
  if (!key)
62
70
  return;
63
71
  key.usage.today++;
72
+ key.usage.monthly++;
64
73
  key.usage.total++;
65
74
  this.scheduleSave();
66
75
  }
@@ -97,6 +106,17 @@ export class KeyManager {
97
106
  key.usage.lastReset = now;
98
107
  }
99
108
  }
109
+ maybeResetMonthly(key) {
110
+ const now = Date.now();
111
+ const currentDate = new Date(now);
112
+ const lastResetDate = new Date(key.usage.lastMonthlyReset || 0);
113
+ if (currentDate.getUTCMonth() !== lastResetDate.getUTCMonth() ||
114
+ currentDate.getUTCFullYear() !== lastResetDate.getUTCFullYear()) {
115
+ key.usage.monthly = 0;
116
+ key.usage.lastMonthlyReset = now;
117
+ this.scheduleSave();
118
+ }
119
+ }
100
120
  scheduleSave() {
101
121
  if (this.saveTimer)
102
122
  return;
@@ -123,6 +143,13 @@ export class KeyManager {
123
143
  return;
124
144
  const data = JSON.parse(fs.readFileSync(this.storePath, 'utf-8'));
125
145
  for (const [id, key] of data) {
146
+ // Upgrade legacy schema key attributes
147
+ if (key && key.usage) {
148
+ if (key.usage.monthly === undefined)
149
+ key.usage.monthly = 0;
150
+ if (key.usage.lastMonthlyReset === undefined)
151
+ key.usage.lastMonthlyReset = key.usage.lastReset || Date.now();
152
+ }
126
153
  this.keys.set(id, key);
127
154
  }
128
155
  console.log(`[KeyManager] Loaded ${this.keys.size} keys`);
@@ -1 +1 @@
1
- {"version":3,"file":"KeyManager.js","sourceRoot":"","sources":["../../../src/cloud/KeyManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"KeyManager.js","sourceRoot":"","sources":["../../../src/cloud/KeyManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import { Pool } from 'pg';
2
+ export interface TenantQuota {
3
+ tenantId: string;
4
+ totalRequestsThisMonth: number;
5
+ quotaLimit: number;
6
+ billingCycleResetDate: Date;
7
+ }
8
+ export declare class PostgresQuotaLimiter {
9
+ private pool;
10
+ private inMemoryQuotas;
11
+ private pendingIncrements;
12
+ private flushIntervalMs;
13
+ private flushTimer;
14
+ private isFlushing;
15
+ constructor(pool: Pool, flushIntervalMs?: number);
16
+ /**
17
+ * Start the background flush timer
18
+ */
19
+ start(): void;
20
+ /**
21
+ * Stop the background flush timer and flush any remaining increments
22
+ */
23
+ stop(): Promise<void>;
24
+ /**
25
+ * Synchronously validate a tenant's request against in-memory limits.
26
+ * If a cache miss occurs, initializes with default limits and lazily loads from Postgres in the background.
27
+ */
28
+ checkQuota(tenantId: string, defaultLimit?: number): {
29
+ allowed: boolean;
30
+ reason?: string;
31
+ };
32
+ /**
33
+ * Lazily loads tenant quota details from PostgreSQL in the background.
34
+ * Merges loaded DB counts with any in-memory increments that accumulated in the meantime.
35
+ */
36
+ private lazyLoadTenantQuota;
37
+ /**
38
+ * Queue increments in memory to await bulk batch flush
39
+ */
40
+ private enqueueIncrement;
41
+ /**
42
+ * Performs an atomic database bulk UPSERT of all pending in-memory increments.
43
+ * If a database error occurs, pending increments are safely rolled back and merged
44
+ * into the in-memory map to try again in the next batch flush cycle.
45
+ */
46
+ flushPendingIncrements(): Promise<void>;
47
+ /**
48
+ * Helper to calculate the 1st of the next calendar month at midnight UTC
49
+ */
50
+ private calculateNextResetDate;
51
+ /**
52
+ * For test harness only: directly seed an in-memory quota entry
53
+ */
54
+ seedQuotaForTest(tenantId: string, quota: TenantQuota): void;
55
+ /**
56
+ * For test harness only: check in-memory status
57
+ */
58
+ getInMemoryQuota(tenantId: string): TenantQuota | undefined;
59
+ }
60
+ //# sourceMappingURL=PostgresQuotaLimiter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PostgresQuotaLimiter.d.ts","sourceRoot":"","sources":["../../../src/cloud/PostgresQuotaLimiter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE1B,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,qBAAqB,EAAE,IAAI,CAAC;CAC7B;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,IAAI,CAAO;IACnB,OAAO,CAAC,cAAc,CAAkC;IACxD,OAAO,CAAC,iBAAiB,CAA6B;IACtD,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,UAAU,CAAS;gBAEf,IAAI,EAAE,IAAI,EAAE,eAAe,SAAO;IAK9C;;OAEG;IACH,KAAK,IAAI,IAAI;IAUb;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B;;;OAGG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,SAAQ,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IA6CzF;;;OAGG;YACW,mBAAmB;IA8CjC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAKxB;;;;OAIG;IACG,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;IAiD7C;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAQ9B;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI;IAI5D;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;CAG5D"}
@@ -0,0 +1,196 @@
1
+ export class PostgresQuotaLimiter {
2
+ constructor(pool, flushIntervalMs = 5000) {
3
+ this.inMemoryQuotas = new Map();
4
+ this.pendingIncrements = new Map();
5
+ this.flushTimer = null;
6
+ this.isFlushing = false;
7
+ this.pool = pool;
8
+ this.flushIntervalMs = flushIntervalMs;
9
+ }
10
+ /**
11
+ * Start the background flush timer
12
+ */
13
+ start() {
14
+ if (this.flushTimer)
15
+ return;
16
+ this.flushTimer = setInterval(() => {
17
+ this.flushPendingIncrements().catch(err => {
18
+ console.error('[PostgresQuotaLimiter] Background flush failed:', err);
19
+ });
20
+ }, this.flushIntervalMs).unref();
21
+ console.log(`[PostgresQuotaLimiter] Asynchronous batch flusher started (interval: ${this.flushIntervalMs}ms)`);
22
+ }
23
+ /**
24
+ * Stop the background flush timer and flush any remaining increments
25
+ */
26
+ async stop() {
27
+ if (this.flushTimer) {
28
+ clearInterval(this.flushTimer);
29
+ this.flushTimer = null;
30
+ }
31
+ console.log('[PostgresQuotaLimiter] Stopping flusher, performing final flush...');
32
+ await this.flushPendingIncrements();
33
+ }
34
+ /**
35
+ * Synchronously validate a tenant's request against in-memory limits.
36
+ * If a cache miss occurs, initializes with default limits and lazily loads from Postgres in the background.
37
+ */
38
+ checkQuota(tenantId, defaultLimit = 50000) {
39
+ let quota = this.inMemoryQuotas.get(tenantId);
40
+ if (!quota) {
41
+ // 1. First-time seen in this memory session: initialize with sensible default
42
+ const nextReset = this.calculateNextResetDate();
43
+ quota = {
44
+ tenantId,
45
+ totalRequestsThisMonth: 0,
46
+ quotaLimit: defaultLimit,
47
+ billingCycleResetDate: nextReset,
48
+ };
49
+ this.inMemoryQuotas.set(tenantId, quota);
50
+ // 2. Trigger asynchronous, non-blocking load from PostgreSQL
51
+ this.lazyLoadTenantQuota(tenantId, defaultLimit).catch(err => {
52
+ console.error(`[PostgresQuotaLimiter] Failed to lazy load quota for ${tenantId}:`, err);
53
+ });
54
+ }
55
+ const now = Date.now();
56
+ // 3. Handle calendar reset boundary checking
57
+ if (now >= quota.billingCycleResetDate.getTime()) {
58
+ quota.totalRequestsThisMonth = 0;
59
+ quota.billingCycleResetDate = this.calculateNextResetDate();
60
+ // Record a zero-increment upsert to sync the new reset date to Postgres
61
+ this.enqueueIncrement(tenantId, 0);
62
+ }
63
+ // 4. Validate quota limit
64
+ if (quota.totalRequestsThisMonth >= quota.quotaLimit) {
65
+ return {
66
+ allowed: false,
67
+ reason: 'Monthly Cloud Quota Exceeded. Please upgrade your plan.',
68
+ };
69
+ }
70
+ // 5. Allow request, increment counter locally, and queue the increment
71
+ quota.totalRequestsThisMonth++;
72
+ this.enqueueIncrement(tenantId, 1);
73
+ return { allowed: true };
74
+ }
75
+ /**
76
+ * Lazily loads tenant quota details from PostgreSQL in the background.
77
+ * Merges loaded DB counts with any in-memory increments that accumulated in the meantime.
78
+ */
79
+ async lazyLoadTenantQuota(tenantId, defaultLimit) {
80
+ try {
81
+ const result = await this.pool.query('SELECT total_requests_this_month, quota_limit, billing_cycle_reset_date FROM tenant_quotas WHERE tenant_id = $1', [tenantId]);
82
+ const nextReset = this.calculateNextResetDate();
83
+ if (result.rows.length > 0) {
84
+ const row = result.rows[0];
85
+ const dbQuota = {
86
+ tenantId,
87
+ totalRequestsThisMonth: parseInt(row.total_requests_this_month, 10),
88
+ quotaLimit: parseInt(row.quota_limit, 10),
89
+ billingCycleResetDate: new Date(row.billing_cycle_reset_date),
90
+ };
91
+ const currentQuota = this.inMemoryQuotas.get(tenantId);
92
+ if (currentQuota) {
93
+ // Check if DB stored reset date has expired in the real world
94
+ if (Date.now() >= dbQuota.billingCycleResetDate.getTime()) {
95
+ dbQuota.totalRequestsThisMonth = 0;
96
+ dbQuota.billingCycleResetDate = nextReset;
97
+ }
98
+ // Merge: Add currently accumulated pending increments onto DB count
99
+ const pending = this.pendingIncrements.get(tenantId) || 0;
100
+ currentQuota.totalRequestsThisMonth = dbQuota.totalRequestsThisMonth + pending;
101
+ currentQuota.quotaLimit = dbQuota.quotaLimit;
102
+ currentQuota.billingCycleResetDate = dbQuota.billingCycleResetDate;
103
+ }
104
+ }
105
+ else {
106
+ // First-time tenant insertion in Postgres (UPSERT to initialize)
107
+ await this.pool.query(`INSERT INTO tenant_quotas (tenant_id, total_requests_this_month, quota_limit, billing_cycle_reset_date)
108
+ VALUES ($1, 0, $2, $3)
109
+ ON CONFLICT (tenant_id) DO NOTHING`, [tenantId, defaultLimit, nextReset]);
110
+ }
111
+ }
112
+ catch (err) {
113
+ console.error(`[PostgresQuotaLimiter] Database load error for tenant ${tenantId}:`, err);
114
+ }
115
+ }
116
+ /**
117
+ * Queue increments in memory to await bulk batch flush
118
+ */
119
+ enqueueIncrement(tenantId, amount) {
120
+ const current = this.pendingIncrements.get(tenantId) || 0;
121
+ this.pendingIncrements.set(tenantId, current + amount);
122
+ }
123
+ /**
124
+ * Performs an atomic database bulk UPSERT of all pending in-memory increments.
125
+ * If a database error occurs, pending increments are safely rolled back and merged
126
+ * into the in-memory map to try again in the next batch flush cycle.
127
+ */
128
+ async flushPendingIncrements() {
129
+ if (this.isFlushing || this.pendingIncrements.size === 0)
130
+ return;
131
+ this.isFlushing = true;
132
+ // Shallow copy and clear the queue immediately to avoid race conditions
133
+ // with new inbound requests accumulating during database I/O
134
+ const incrementsToFlush = new Map(this.pendingIncrements);
135
+ this.pendingIncrements.clear();
136
+ try {
137
+ const client = await this.pool.connect();
138
+ try {
139
+ await client.query('BEGIN');
140
+ for (const [tenantId, increment] of incrementsToFlush.entries()) {
141
+ const quota = this.inMemoryQuotas.get(tenantId);
142
+ const limit = quota ? quota.quotaLimit : 50000;
143
+ const resetDate = quota ? quota.billingCycleResetDate : this.calculateNextResetDate();
144
+ await client.query(`INSERT INTO tenant_quotas (tenant_id, total_requests_this_month, quota_limit, billing_cycle_reset_date)
145
+ VALUES ($1, $2, $3, $4)
146
+ ON CONFLICT (tenant_id) DO UPDATE
147
+ SET total_requests_this_month = tenant_quotas.total_requests_this_month + EXCLUDED.total_requests_this_month,
148
+ billing_cycle_reset_date = EXCLUDED.billing_cycle_reset_date,
149
+ updated_at = CURRENT_TIMESTAMP`, [tenantId, increment, limit, resetDate]);
150
+ }
151
+ await client.query('COMMIT');
152
+ }
153
+ catch (err) {
154
+ await client.query('ROLLBACK');
155
+ throw err;
156
+ }
157
+ finally {
158
+ client.release();
159
+ }
160
+ }
161
+ catch (err) {
162
+ console.error('[PostgresQuotaLimiter] Batch flush database error. Restoring increments:', err);
163
+ // Restore increments back to pending list so they are retried on the next run
164
+ for (const [tenantId, increment] of incrementsToFlush.entries()) {
165
+ const current = this.pendingIncrements.get(tenantId) || 0;
166
+ this.pendingIncrements.set(tenantId, current + increment);
167
+ }
168
+ }
169
+ finally {
170
+ this.isFlushing = false;
171
+ }
172
+ }
173
+ /**
174
+ * Helper to calculate the 1st of the next calendar month at midnight UTC
175
+ */
176
+ calculateNextResetDate() {
177
+ const d = new Date();
178
+ d.setUTCMonth(d.getUTCMonth() + 1);
179
+ d.setUTCDate(1);
180
+ d.setUTCHours(0, 0, 0, 0);
181
+ return d;
182
+ }
183
+ /**
184
+ * For test harness only: directly seed an in-memory quota entry
185
+ */
186
+ seedQuotaForTest(tenantId, quota) {
187
+ this.inMemoryQuotas.set(tenantId, quota);
188
+ }
189
+ /**
190
+ * For test harness only: check in-memory status
191
+ */
192
+ getInMemoryQuota(tenantId) {
193
+ return this.inMemoryQuotas.get(tenantId);
194
+ }
195
+ }
196
+ //# sourceMappingURL=PostgresQuotaLimiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PostgresQuotaLimiter.js","sourceRoot":"","sources":["../../../src/cloud/PostgresQuotaLimiter.ts"],"names":[],"mappings":"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"}
@@ -23,7 +23,7 @@ export declare class TenantCache {
23
23
  data?: any;
24
24
  similarity?: number;
25
25
  }>;
26
- store(key: string, input: string, data: any, ttl: number): Promise<void>;
26
+ store(key: string, input: string, data: any, ttl: number, maxEntries?: number): Promise<void>;
27
27
  getStats(): Promise<TenantStats>;
28
28
  private embed;
29
29
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TenantCache.d.ts","sourceRoot":"","sources":["../../../src/cloud/TenantCache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,WAAW,EAAuD,MAAM,SAAS,CAAC;AAU3F,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,cAAc,CAAS;IAE/B,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,SAAS,CAAa;IAE9B,OAAO,CAAC,KAAK,CAA0B;gBAE3B,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAS3E,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAW3B,KAAK,CACT,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,GAAG,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IA0CvD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBxE,QAAQ,IAAI,OAAO,CAAC,WAAW,CAAC;YAyBxB,KAAK;CAyCpB"}
1
+ {"version":3,"file":"TenantCache.d.ts","sourceRoot":"","sources":["../../../src/cloud/TenantCache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,WAAW,EAAuD,MAAM,SAAS,CAAC;AAU3F,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,cAAc,CAAS;IAE/B,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,SAAS,CAAa;IAE9B,OAAO,CAAC,KAAK,CAA0B;gBAE3B,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAS3E,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAW3B,KAAK,CACT,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,GAAG,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAuDvD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,SAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IA+B5F,QAAQ,IAAI,OAAO,CAAC,WAAW,CAAC;YAyBxB,KAAK;CAyCpB"}
@@ -49,9 +49,21 @@ export class TenantCache {
49
49
  return { hit: false };
50
50
  }
51
51
  const meta = results.metadatas[0][0];
52
- // Check TTL
53
- if (meta.ttl > 0 && Date.now() - meta.createdAt > meta.ttl) {
52
+ const age = Date.now() - meta.createdAt;
53
+ // 1. Enforce strict 7-day TTL cache eviction policy (Pro/SaaS tier)
54
+ const MAX_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
55
+ if (age > MAX_TTL_MS) {
54
56
  this.stats.misses++;
57
+ // Evict expired entry from vector database in background
58
+ const expiredId = results.ids[0][0];
59
+ this.chromaCollection.delete({ ids: [expiredId] }).catch(() => { });
60
+ return { hit: false };
61
+ }
62
+ // 2. Check custom entry TTL
63
+ if (meta.ttl > 0 && age > meta.ttl) {
64
+ this.stats.misses++;
65
+ const expiredId = results.ids[0][0];
66
+ this.chromaCollection.delete({ ids: [expiredId] }).catch(() => { });
55
67
  return { hit: false };
56
68
  }
57
69
  this.stats.hits++;
@@ -63,10 +75,16 @@ export class TenantCache {
63
75
  }
64
76
  }
65
77
  // ─── Store ──────────────────────────────────────────────────────────────────
66
- async store(key, input, data, ttl) {
78
+ async store(key, input, data, ttl, maxEntries = 10000) {
67
79
  if (!this.chromaCollection)
68
80
  await this.initialize();
69
81
  try {
82
+ // Enforce maximum cache entries constraint to prevent storage bloat
83
+ const count = await this.chromaCollection.count();
84
+ if (count >= maxEntries) {
85
+ console.warn(`⚠️ [TenantCache:${this.tenantId}] Vector cache limit reached (${count}/${maxEntries} entries). Skipping store to prevent storage bloat.`);
86
+ return;
87
+ }
70
88
  const embedding = await this.embed(input);
71
89
  await this.chromaCollection.upsert({
72
90
  ids: [key],
@@ -1 +1 @@
1
- {"version":3,"file":"TenantCache.js","sourceRoot":"","sources":["../../../src/cloud/TenantCache.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TenantCache.js","sourceRoot":"","sources":["../../../src/cloud/TenantCache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAA4B,sBAAsB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAU3F,MAAM,OAAO,WAAW;IActB,YAAY,QAAgB,EAAE,SAAiB,EAAE,SAAiB,EAAE,KAAa;QAPzE,iBAAY,GAAQ,IAAI,CAAC;QACzB,qBAAgB,GAAQ,IAAI,CAAC;QAC7B,mBAAc,GAAG,IAAI,GAAG,EAAoB,CAAC;QAC7C,cAAS,GAAQ,IAAI,CAAC;QAEtB,UAAK,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QAGrC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,iDAAiD;QACjD,IAAI,CAAC,cAAc,GAAG,SAAS,QAAQ,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;IACtF,CAAC;IAED,KAAK,CAAC,UAAU;QACd,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;QAClD,IAAI,CAAC,YAAY,GAAG,IAAI,YAAY,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QAC/D,IAAI,CAAC,gBAAgB,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,qBAAqB,CAAC;YACpE,IAAI,EAAE,IAAI,CAAC,cAAc;YACzB,QAAQ,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE;SAC5D,CAAC,CAAC;IACL,CAAC;IAED,+EAA+E;IAE/E,KAAK,CAAC,KAAK,CACT,KAAa,EACb,SAAiB;QAEjB,IAAI,CAAC,IAAI,CAAC,gBAAgB;YAAE,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QAEpD,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC;gBAChD,eAAe,EAAE,CAAC,SAAS,CAAC;gBAC5B,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC;aACpC,CAAC,CAAC;YAEH,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;gBAC9B,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACpB,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;YACxB,CAAC;YAED,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACzC,MAAM,UAAU,GAAG,CAAC,GAAG,QAAQ,CAAC;YAEhC,IAAI,UAAU,GAAG,SAAS,EAAE,CAAC;gBAC3B,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACpB,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;YACxB,CAAC;YAED,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAQ,CAAC;YAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC;YAExC,oEAAoE;YACpE,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,SAAS;YACrD,IAAI,GAAG,GAAG,UAAU,EAAE,CAAC;gBACrB,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACpB,yDAAyD;gBACzD,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;gBACnE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;YACxB,CAAC;YAED,4BAA4B;YAC5B,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBACnC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACpB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;gBACnE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;YACxB,CAAC;YAED,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAClB,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC;QAChE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,gBAAgB,IAAI,CAAC,QAAQ,gBAAgB,EAAE,GAAG,CAAC,CAAC;YAClE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;QACxB,CAAC;IACH,CAAC;IAED,+EAA+E;IAE/E,KAAK,CAAC,KAAK,CAAC,GAAW,EAAE,KAAa,EAAE,IAAS,EAAE,GAAW,EAAE,UAAU,GAAG,KAAK;QAChF,IAAI,CAAC,IAAI,CAAC,gBAAgB;YAAE,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QAEpD,IAAI,CAAC;YACH,oEAAoE;YACpE,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;YAClD,IAAI,KAAK,IAAI,UAAU,EAAE,CAAC;gBACxB,OAAO,CAAC,IAAI,CAAC,oBAAoB,IAAI,CAAC,QAAQ,iCAAiC,KAAK,IAAI,UAAU,qDAAqD,CAAC,CAAC;gBACzJ,OAAO;YACT,CAAC;YAED,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1C,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;gBACjC,GAAG,EAAE,CAAC,GAAG,CAAC;gBACV,UAAU,EAAE,CAAC,SAAS,CAAC;gBACvB,SAAS,EAAE,CAAC,KAAK,CAAC;gBAClB,SAAS,EAAE,CAAC;wBACV,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;wBAC1B,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;wBACrB,GAAG;wBACH,MAAM,EAAE,IAAI,CAAC,QAAQ;qBACtB,CAAC;aACH,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,gBAAgB,IAAI,CAAC,QAAQ,gBAAgB,EAAE,GAAG,CAAC,CAAC;YAClE,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,+EAA+E;IAE/E,KAAK,CAAC,QAAQ;QACZ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QAClD,MAAM,OAAO,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACxD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,sBAAsB,CAAC;QAC7D,IAAI,SAAS,GAAG,CAAC,CAAC;QAElB,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,gBAAgB;gBAAE,SAAS,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;QAC7E,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QAEV,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,IAAI,EAAE,KAAK,EAAE,yBAAyB;YACtC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;YACrB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;YACzB,aAAa,EAAE,KAAK;YACpB,OAAO;YACP,oBAAoB,EAAE,WAAW;YACjC,kBAAkB,EAAE,UAAU,CAAC,CAAC,WAAW,GAAG,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACzE,SAAS;SACV,CAAC;IACJ,CAAC;IAED,+EAA+E;IAEvE,KAAK,CAAC,KAAK,CAAC,IAAY;QAC9B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC7C,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC;YAAE,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAE,CAAC;QAErF,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,QAAQ,CAAC;QAC5D,IAAI,SAAS,GAAa,EAAE,CAAC;QAE7B,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1B,MAAM,KAAK,GAAG,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;YAC9C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAC1B,sCAAsC,EACtC,EAAE,KAAK,EAAE,wBAAwB,EAAE,KAAK,EAAE,IAAI,EAAE,EAChD;gBACE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE;gBAClE,OAAO,EAAE,KAAK;aACf,CACF,CAAC;YACF,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACzC,CAAC;aAAM,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,aAAa;YACb,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;YAC1D,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;gBACpB,IAAI,CAAC,SAAS,GAAG,MAAM,QAAQ,CAAC,oBAAoB,EAAE,yBAAyB,CAAC,CAAC;YACnF,CAAC;YACD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7E,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAa,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,GAAG,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;YAC9C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAC1B,GAAG,IAAI,CAAC,SAAS,iBAAiB,EAClC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,EACnC,EAAE,OAAO,EAAE,KAAK,EAAE,CACnB,CAAC;YACF,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;QACjC,CAAC;QAED,+BAA+B;QAC/B,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,GAAG,IAAI;YAAE,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QACjE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAC/C,OAAO,SAAS,CAAC;IACnB,CAAC;CACF"}
@@ -10,8 +10,10 @@
10
10
  */
11
11
  import { KeyManager } from './KeyManager';
12
12
  import { TenantCache } from './TenantCache';
13
+ import { PostgresQuotaLimiter } from './PostgresQuotaLimiter';
13
14
  declare const app: import("express-serve-static-core").Express;
14
15
  declare const keyManager: KeyManager;
15
16
  declare const tenantCaches: Map<string, TenantCache>;
16
- export { app, keyManager, tenantCaches };
17
+ declare let postgresQuotaLimiter: PostgresQuotaLimiter | null;
18
+ export { app, keyManager, tenantCaches, postgresQuotaLimiter };
17
19
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/cloud/server.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AAIH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,QAAA,MAAM,GAAG,6CAAY,CAAC;AAYtB,QAAA,MAAM,UAAU,YAAmB,CAAC;AACpC,QAAA,MAAM,YAAY,0BAAiC,CAAC;AAySpD,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/cloud/server.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AAIH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAI5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAG9D,QAAA,MAAM,GAAG,6CAAY,CAAC;AAYtB,QAAA,MAAM,UAAU,YAAmB,CAAC;AACpC,QAAA,MAAM,YAAY,0BAAiC,CAAC;AAIpD,QAAA,IAAI,oBAAoB,EAAE,oBAAoB,GAAG,IAAW,CAAC;AA6U7D,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,YAAY,EAAE,oBAAoB,EAAE,CAAC"}
@@ -12,6 +12,10 @@ import express from 'express';
12
12
  import crypto from 'crypto';
13
13
  import { KeyManager } from './KeyManager';
14
14
  import { TenantCache } from './TenantCache';
15
+ import { PLAN_LIMITS } from './types';
16
+ import { BurstRateLimiter } from './BurstRateLimiter';
17
+ import { Pool } from 'pg';
18
+ import { PostgresQuotaLimiter } from './PostgresQuotaLimiter';
15
19
  const app = express();
16
20
  app.use(express.json({ limit: '10mb' }));
17
21
  // ─── Config ───────────────────────────────────────────────────────────────────
@@ -22,19 +26,50 @@ const OLLAMA_MODEL = process.env.OLLAMA_MODEL || 'nomic-embed-text';
22
26
  // ─── State ────────────────────────────────────────────────────────────────────
23
27
  const keyManager = new KeyManager();
24
28
  const tenantCaches = new Map();
29
+ const burstRateLimiter = new BurstRateLimiter(10, 1000); // 10 RPS cap
30
+ // Setup PostgreSQL-backed Lean Rate Limiter if DATABASE_URL is configured
31
+ let postgresQuotaLimiter = null;
32
+ if (process.env.DATABASE_URL) {
33
+ const pgPool = new Pool({
34
+ connectionString: process.env.DATABASE_URL,
35
+ ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : undefined,
36
+ });
37
+ postgresQuotaLimiter = new PostgresQuotaLimiter(pgPool, 5000);
38
+ postgresQuotaLimiter.start();
39
+ }
25
40
  function authenticate(req, res, next) {
26
41
  const auth = req.headers.authorization;
27
42
  if (!auth || !auth.startsWith('Bearer ')) {
28
43
  return res.status(401).json({ error: 'Missing or invalid Authorization header' });
29
44
  }
30
45
  const keyId = auth.replace('Bearer ', '');
46
+ // 1. Enforce Sliding Window Burst Rate Limiting (10 RPS)
47
+ const burstCheck = burstRateLimiter.check(keyId);
48
+ if (!burstCheck.allowed) {
49
+ return res.status(429).json({
50
+ error: 'Too Many Requests. Burst rate limit of 10 RPS exceeded. Please back off.',
51
+ });
52
+ }
53
+ // 2. Validate Key Status & Daily Limits
31
54
  const validation = keyManager.validate(keyId);
32
55
  if (!validation.valid) {
33
- return res.status(validation.reason?.includes('limit') ? 429 : 403).json({
56
+ const isLimitExceeded = validation.reason?.includes('limit') || validation.reason?.includes('Quota');
57
+ return res.status(isLimitExceeded ? 429 : 403).json({
34
58
  error: validation.reason,
35
59
  });
36
60
  }
37
- req.apiKey = validation.key;
61
+ const apiKey = validation.key;
62
+ // 3. Enforce PostgreSQL Lean Monthly Quota
63
+ if (postgresQuotaLimiter) {
64
+ const monthlyLimit = PLAN_LIMITS[apiKey.plan]?.monthlyRequests || 50000;
65
+ const quotaCheck = postgresQuotaLimiter.checkQuota(apiKey.tenantId, monthlyLimit);
66
+ if (!quotaCheck.allowed) {
67
+ return res.status(429).json({
68
+ error: quotaCheck.reason,
69
+ });
70
+ }
71
+ }
72
+ req.apiKey = apiKey;
38
73
  keyManager.recordRequest(keyId);
39
74
  next();
40
75
  }
@@ -89,7 +124,8 @@ app.post('/v1/cache', authenticate, async (req, res) => {
89
124
  }
90
125
  try {
91
126
  const cache = getTenantCache(req.apiKey.tenantId);
92
- await cache.store(key, input, data, ttl);
127
+ const maxEntries = PLAN_LIMITS[req.apiKey.plan]?.cacheEntries || 10000;
128
+ await cache.store(key, input, data, ttl, maxEntries);
93
129
  res.json({ ok: true });
94
130
  }
95
131
  catch (err) {
@@ -207,7 +243,7 @@ app.post(['/v1/payments/stripe-webhook', '/api/v1/payments/stripe-webhook'], (re
207
243
  plan: 'pro',
208
244
  createdAt: Date.now(),
209
245
  active: true,
210
- usage: { today: 0, total: 0, lastReset: Date.now() },
246
+ usage: { today: 0, monthly: 0, total: 0, lastReset: Date.now(), lastMonthlyReset: Date.now() },
211
247
  };
212
248
  // Register in KeyManager keys Map
213
249
  // @ts-ignore CJS private access bypass
@@ -272,5 +308,5 @@ app.listen(PORT, () => {
272
308
  console.log(' POST /admin/keys/:id/upgrade — Upgrade plan');
273
309
  console.log('');
274
310
  });
275
- export { app, keyManager, tenantCaches };
311
+ export { app, keyManager, tenantCaches, postgresQuotaLimiter };
276
312
  //# sourceMappingURL=server.js.map