import { Pool } from 'pg'; export interface TenantQuota { tenantId: string; totalRequestsThisMonth: number; quotaLimit: number; billingCycleResetDate: Date; } export declare class PostgresQuotaLimiter { private pool; private inMemoryQuotas; private pendingIncrements; private flushIntervalMs; private flushTimer; private isFlushing; constructor(pool: Pool, flushIntervalMs?: number); /** * Start the background flush timer */ start(): void; /** * Stop the background flush timer and flush any remaining increments */ stop(): Promise; /** * Synchronously validate a tenant's request against in-memory limits. * If a cache miss occurs, initializes with default limits and lazily loads from Postgres in the background. */ checkQuota(tenantId: string, defaultLimit?: number): { allowed: boolean; reason?: string; }; /** * Lazily loads tenant quota details from PostgreSQL in the background. * Merges loaded DB counts with any in-memory increments that accumulated in the meantime. */ private lazyLoadTenantQuota; /** * Queue increments in memory to await bulk batch flush */ private enqueueIncrement; /** * Performs an atomic database bulk UPSERT of all pending in-memory increments. * If a database error occurs, pending increments are safely rolled back and merged * into the in-memory map to try again in the next batch flush cycle. */ flushPendingIncrements(): Promise; /** * Helper to calculate the 1st of the next calendar month at midnight UTC */ private calculateNextResetDate; /** * For test harness only: directly seed an in-memory quota entry */ seedQuotaForTest(tenantId: string, quota: TenantQuota): void; /** * For test harness only: check in-memory status */ getInMemoryQuota(tenantId: string): TenantQuota | undefined; } //# sourceMappingURL=PostgresQuotaLimiter.d.ts.map