@parsrun/payments 0.1.0

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.
@@ -0,0 +1,2674 @@
1
+ import { PaymentProviderType } from '../types.js';
2
+ import { k as BillingLogger$1, n as BillingSubscription, B as BillingService } from '../billing-service-LsAFesou.js';
3
+ import { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
4
+ import { NeonHttpDatabase } from 'drizzle-orm/neon-http';
5
+ import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
6
+ import '@parsrun/types';
7
+ import '../webhooks/index.js';
8
+
9
+ /**
10
+ * @parsrun/payments - Usage Types
11
+ * Types for usage-based billing
12
+ */
13
+
14
+ type BillingLogger = BillingLogger$1;
15
+ /**
16
+ * Plan tier levels
17
+ */
18
+ type PlanTier = 0 | 1 | 2 | 3 | 4;
19
+ /**
20
+ * Billing interval
21
+ */
22
+ type BillingInterval = "month" | "year";
23
+ /**
24
+ * Limit period for features
25
+ */
26
+ type LimitPeriod = "hour" | "day" | "month" | null;
27
+ /**
28
+ * Reset period for quotas
29
+ * - monthly: Reset on the 1st of each calendar month
30
+ * - billing_cycle: Reset on subscription renewal date
31
+ */
32
+ type ResetPeriod = "monthly" | "billing_cycle";
33
+ /**
34
+ * Customer access status
35
+ * - active: Full access, subscription is current
36
+ * - past_due: Limited access, payment failed but grace period active
37
+ * - suspended: No access, multiple payment failures
38
+ * - canceled: No access, subscription canceled
39
+ * - unpaid: No access, subscription unpaid
40
+ */
41
+ type AccessStatus = "active" | "past_due" | "suspended" | "canceled" | "unpaid";
42
+ /**
43
+ * Access status info for a customer
44
+ */
45
+ interface AccessStatusInfo {
46
+ status: AccessStatus;
47
+ /** When the status was last updated */
48
+ updatedAt: Date;
49
+ /** Reason for current status */
50
+ reason?: string;
51
+ /** When access will be suspended (for past_due) */
52
+ suspensionDate?: Date;
53
+ /** Number of failed payment attempts */
54
+ failedPaymentAttempts?: number;
55
+ /** Grace period end date */
56
+ gracePeriodEnd?: Date;
57
+ }
58
+ /**
59
+ * Plan definition
60
+ */
61
+ interface Plan$1 {
62
+ id: string;
63
+ name: string;
64
+ displayName: string;
65
+ description: string | null;
66
+ tier: PlanTier;
67
+ basePrice: number;
68
+ currency: string;
69
+ billingInterval: BillingInterval;
70
+ features: PlanFeature$1[];
71
+ isActive: boolean;
72
+ metadata?: Record<string, unknown>;
73
+ createdAt: Date;
74
+ updatedAt: Date;
75
+ }
76
+ /**
77
+ * Plan feature with limits
78
+ */
79
+ interface PlanFeature$1 {
80
+ id: string;
81
+ planId: string;
82
+ featureKey: string;
83
+ limitValue: number | null;
84
+ limitPeriod: LimitPeriod;
85
+ isEnabled: boolean;
86
+ metadata?: Record<string, unknown>;
87
+ }
88
+ /**
89
+ * Usage event record
90
+ */
91
+ interface UsageEvent {
92
+ id: string;
93
+ tenantId: string;
94
+ customerId: string;
95
+ subscriptionId?: string;
96
+ featureKey: string;
97
+ quantity: number;
98
+ timestamp: Date;
99
+ metadata?: Record<string, unknown>;
100
+ idempotencyKey?: string;
101
+ }
102
+ /**
103
+ * Options for tracking usage
104
+ */
105
+ interface TrackUsageOptions {
106
+ tenantId: string;
107
+ customerId: string;
108
+ subscriptionId?: string;
109
+ featureKey: string;
110
+ quantity?: number;
111
+ metadata?: Record<string, unknown>;
112
+ idempotencyKey?: string;
113
+ timestamp?: Date;
114
+ }
115
+ /**
116
+ * Period type for aggregation
117
+ */
118
+ type PeriodType = "hour" | "day" | "month";
119
+ /**
120
+ * Usage aggregate record
121
+ */
122
+ interface UsageAggregate {
123
+ id: string;
124
+ tenantId: string;
125
+ customerId: string;
126
+ subscriptionId?: string;
127
+ featureKey: string;
128
+ periodStart: Date;
129
+ periodEnd: Date;
130
+ periodType: PeriodType;
131
+ totalQuantity: number;
132
+ eventCount: number;
133
+ lastUpdated: Date;
134
+ }
135
+ /**
136
+ * Options for getting usage
137
+ */
138
+ interface GetUsageOptions {
139
+ featureKey?: string;
140
+ periodType?: PeriodType;
141
+ startDate?: Date;
142
+ endDate?: Date;
143
+ subscriptionId?: string;
144
+ }
145
+ /**
146
+ * Quota status for a feature
147
+ */
148
+ interface QuotaStatus {
149
+ featureKey: string;
150
+ limit: number | null;
151
+ used: number;
152
+ remaining: number | null;
153
+ percentUsed: number | null;
154
+ periodStart: Date;
155
+ periodEnd: Date;
156
+ isExceeded: boolean;
157
+ isUnlimited: boolean;
158
+ /** Overage amount (used - limit) when soft limits enabled */
159
+ overage?: number;
160
+ /** Whether overage is allowed for this feature */
161
+ overageAllowed?: boolean;
162
+ }
163
+ /**
164
+ * Quota check result
165
+ */
166
+ interface QuotaCheckResult {
167
+ allowed: boolean;
168
+ currentUsage: number;
169
+ limit: number | null;
170
+ remaining: number | null;
171
+ wouldExceed: boolean;
172
+ percentAfter: number | null;
173
+ }
174
+ /**
175
+ * Alert status
176
+ */
177
+ type AlertStatus = "pending" | "triggered" | "acknowledged" | "resolved";
178
+ /**
179
+ * Usage alert
180
+ */
181
+ interface UsageAlert {
182
+ id: string;
183
+ tenantId: string;
184
+ customerId: string;
185
+ subscriptionId?: string;
186
+ featureKey: string;
187
+ thresholdPercent: number;
188
+ status: AlertStatus;
189
+ currentUsage: number;
190
+ limit: number;
191
+ triggeredAt?: Date;
192
+ acknowledgedAt?: Date;
193
+ resolvedAt?: Date;
194
+ metadata?: Record<string, unknown>;
195
+ createdAt: Date;
196
+ }
197
+ /**
198
+ * Subscription lifecycle event types
199
+ */
200
+ type SubscriptionEventType = "subscription.created" | "subscription.activated" | "subscription.updated" | "subscription.plan_changed" | "subscription.canceled" | "subscription.expired" | "subscription.renewed" | "subscription.trial_started" | "subscription.trial_ended" | "subscription.payment_failed" | "subscription.payment_succeeded" | "subscription.period_reset";
201
+ /**
202
+ * Subscription lifecycle event
203
+ */
204
+ interface SubscriptionEvent {
205
+ type: SubscriptionEventType;
206
+ subscription: BillingSubscription;
207
+ previousPlan?: Plan$1;
208
+ newPlan?: Plan$1;
209
+ timestamp: Date;
210
+ provider: PaymentProviderType;
211
+ metadata?: Record<string, unknown>;
212
+ }
213
+ /**
214
+ * Subscription event handler
215
+ */
216
+ type SubscriptionHandler = (event: SubscriptionEvent) => void | Promise<void>;
217
+ /**
218
+ * Usage-specific webhook event types
219
+ */
220
+ type UsageWebhookEventType = "usage.recorded" | "usage.threshold_reached" | "usage.limit_exceeded" | "usage.limit_reset" | "plan.upgraded" | "plan.downgraded";
221
+ /**
222
+ * Usage storage interface
223
+ * Allows pluggable storage backends (database, in-memory, etc.)
224
+ */
225
+ interface UsageStorage {
226
+ getPlan(planId: string): Promise<Plan$1 | null>;
227
+ getPlanByName(name: string): Promise<Plan$1 | null>;
228
+ listPlans(options?: {
229
+ activeOnly?: boolean;
230
+ }): Promise<Plan$1[]>;
231
+ getPlanFeatures(planId: string): Promise<PlanFeature$1[]>;
232
+ getFeatureLimit(planId: string, featureKey: string): Promise<PlanFeature$1 | null>;
233
+ getCustomerPlanId(customerId: string): Promise<string | null>;
234
+ setCustomerPlanId(customerId: string, planId: string): Promise<void>;
235
+ recordUsage(event: Omit<UsageEvent, "id">): Promise<UsageEvent>;
236
+ recordUsageBatch(events: Omit<UsageEvent, "id">[]): Promise<UsageEvent[]>;
237
+ getUsageEvents(customerId: string, options: GetUsageOptions): Promise<UsageEvent[]>;
238
+ getAggregate(customerId: string, featureKey: string, periodType: PeriodType, periodStart: Date): Promise<UsageAggregate | null>;
239
+ upsertAggregate(aggregate: Omit<UsageAggregate, "id">): Promise<UsageAggregate>;
240
+ getAggregates(customerId: string, options: GetUsageOptions): Promise<UsageAggregate[]>;
241
+ getCurrentPeriodUsage(customerId: string, featureKey: string, periodStart: Date): Promise<number>;
242
+ createAlert(alert: Omit<UsageAlert, "id" | "createdAt">): Promise<UsageAlert>;
243
+ getActiveAlerts(customerId: string): Promise<UsageAlert[]>;
244
+ updateAlertStatus(alertId: string, status: AlertStatus): Promise<void>;
245
+ /** Reset usage for a customer (all features or specific ones) */
246
+ resetUsage(customerId: string, featureKeys?: string[], periodStart?: Date): Promise<void>;
247
+ /** Reset all aggregates for a customer */
248
+ resetAggregates(customerId: string, featureKeys?: string[]): Promise<void>;
249
+ /** Get customer access status */
250
+ getAccessStatus(customerId: string): Promise<AccessStatusInfo | null>;
251
+ /** Set customer access status */
252
+ setAccessStatus(customerId: string, status: AccessStatusInfo): Promise<void>;
253
+ /** Get customer's current billing cycle dates */
254
+ getBillingCycle(customerId: string): Promise<{
255
+ start: Date;
256
+ end: Date;
257
+ } | null>;
258
+ /** Set customer's billing cycle dates */
259
+ setBillingCycle(customerId: string, start: Date, end: Date): Promise<void>;
260
+ }
261
+ /**
262
+ * Usage service configuration
263
+ */
264
+ interface UsageServiceConfig {
265
+ /** Storage backend */
266
+ storage: UsageStorage;
267
+ /** Logger */
268
+ logger?: BillingLogger;
269
+ /** Alert thresholds (default: [80, 100]) */
270
+ alertThresholds?: number[];
271
+ /** Aggregate usage immediately (default: false - async) */
272
+ aggregateImmediately?: boolean;
273
+ /**
274
+ * Reset period for quotas
275
+ * - monthly: Reset on the 1st of each calendar month (default)
276
+ * - billing_cycle: Reset on subscription renewal date
277
+ */
278
+ resetPeriod?: ResetPeriod;
279
+ /**
280
+ * Auto-reset quotas on subscription renewal
281
+ * Default: true
282
+ */
283
+ autoResetOnRenewal?: boolean;
284
+ /**
285
+ * Grace period in days before access is suspended after payment failure
286
+ * Default: 3 days
287
+ */
288
+ paymentGraceDays?: number;
289
+ /**
290
+ * Number of failed payments before suspending access
291
+ * Default: 3
292
+ */
293
+ maxFailedPayments?: number;
294
+ /** Callback when threshold is reached */
295
+ onThresholdReached?: (alert: UsageAlert) => void | Promise<void>;
296
+ /** Callback when limit is exceeded */
297
+ onLimitExceeded?: (quota: QuotaStatus, customerId: string) => void | Promise<void>;
298
+ /** Callback when period resets */
299
+ onPeriodReset?: (customerId: string, featureKey: string) => void | Promise<void>;
300
+ /** Callback when access status changes */
301
+ onAccessStatusChanged?: (customerId: string, status: AccessStatusInfo, previousStatus?: AccessStatus) => void | Promise<void>;
302
+ }
303
+ /**
304
+ * Quota manager configuration
305
+ */
306
+ interface QuotaManagerConfig {
307
+ /** Storage backend */
308
+ storage: UsageStorage;
309
+ /** Logger */
310
+ logger?: BillingLogger;
311
+ /** Soft limit behavior - warn but allow (default: false) */
312
+ softLimits?: boolean;
313
+ /** Grace period percentage over limit (default: 0) */
314
+ gracePercent?: number;
315
+ /**
316
+ * Features that allow overage (soft limits)
317
+ * If set, only these features will allow overage.
318
+ * If not set and softLimits=true, all features allow overage.
319
+ */
320
+ overageAllowedFeatures?: string[];
321
+ /**
322
+ * Callback when overage is recorded
323
+ * Called when usage exceeds limit for a soft-limit feature
324
+ */
325
+ onOverage?: (customerId: string, featureKey: string, overage: number, limit: number) => void | Promise<void>;
326
+ }
327
+ /**
328
+ * Usage error codes
329
+ */
330
+ declare const UsageErrorCodes: {
331
+ readonly QUOTA_EXCEEDED: "QUOTA_EXCEEDED";
332
+ readonly PLAN_NOT_FOUND: "PLAN_NOT_FOUND";
333
+ readonly FEATURE_NOT_FOUND: "FEATURE_NOT_FOUND";
334
+ readonly CUSTOMER_NOT_FOUND: "CUSTOMER_NOT_FOUND";
335
+ readonly DUPLICATE_EVENT: "DUPLICATE_EVENT";
336
+ readonly STORAGE_ERROR: "STORAGE_ERROR";
337
+ readonly INVALID_PERIOD: "INVALID_PERIOD";
338
+ };
339
+ type UsageErrorCode = keyof typeof UsageErrorCodes;
340
+ /**
341
+ * Usage error
342
+ */
343
+ declare class UsageError extends Error {
344
+ readonly code: UsageErrorCode;
345
+ readonly details?: Record<string, unknown> | undefined;
346
+ constructor(message: string, code: UsageErrorCode, details?: Record<string, unknown> | undefined);
347
+ }
348
+ /**
349
+ * Quota exceeded error
350
+ */
351
+ declare class QuotaExceededError extends UsageError {
352
+ readonly featureKey: string;
353
+ readonly limit: number | null;
354
+ readonly currentUsage: number;
355
+ readonly requestedQuantity: number;
356
+ constructor(featureKey: string, limit: number | null, currentUsage: number, requestedQuantity?: number);
357
+ }
358
+
359
+ /**
360
+ * @parsrun/payments - In-Memory Usage Storage
361
+ * Default storage implementation for development and testing
362
+ */
363
+
364
+ /**
365
+ * In-memory usage storage
366
+ * For development, testing, and single-instance deployments
367
+ */
368
+ declare class MemoryUsageStorage implements UsageStorage {
369
+ private plans;
370
+ private planFeatures;
371
+ private customerPlans;
372
+ private usageEvents;
373
+ private usageAggregates;
374
+ private alerts;
375
+ private idempotencyKeys;
376
+ private accessStatuses;
377
+ private billingCycles;
378
+ getPlan(planId: string): Promise<Plan$1 | null>;
379
+ getPlanByName(name: string): Promise<Plan$1 | null>;
380
+ listPlans(options?: {
381
+ activeOnly?: boolean;
382
+ }): Promise<Plan$1[]>;
383
+ /**
384
+ * Add a plan (for testing/setup)
385
+ */
386
+ addPlan(plan: Plan$1): void;
387
+ getPlanFeatures(planId: string): Promise<PlanFeature$1[]>;
388
+ getFeatureLimit(planId: string, featureKey: string): Promise<PlanFeature$1 | null>;
389
+ /**
390
+ * Add plan features (for testing/setup)
391
+ */
392
+ addPlanFeatures(planId: string, features: PlanFeature$1[]): void;
393
+ getCustomerPlanId(customerId: string): Promise<string | null>;
394
+ setCustomerPlanId(customerId: string, planId: string): Promise<void>;
395
+ recordUsage(event: Omit<UsageEvent, "id">): Promise<UsageEvent>;
396
+ recordUsageBatch(events: Omit<UsageEvent, "id">[]): Promise<UsageEvent[]>;
397
+ getUsageEvents(customerId: string, options: GetUsageOptions): Promise<UsageEvent[]>;
398
+ private getAggregateKey;
399
+ getAggregate(customerId: string, featureKey: string, periodType: PeriodType, periodStart: Date): Promise<UsageAggregate | null>;
400
+ upsertAggregate(aggregate: Omit<UsageAggregate, "id">): Promise<UsageAggregate>;
401
+ getAggregates(customerId: string, options: GetUsageOptions): Promise<UsageAggregate[]>;
402
+ getCurrentPeriodUsage(customerId: string, featureKey: string, periodStart: Date): Promise<number>;
403
+ createAlert(alert: Omit<UsageAlert, "id" | "createdAt">): Promise<UsageAlert>;
404
+ getActiveAlerts(customerId: string): Promise<UsageAlert[]>;
405
+ updateAlertStatus(alertId: string, status: AlertStatus): Promise<void>;
406
+ resetUsage(customerId: string, featureKeys?: string[], periodStart?: Date): Promise<void>;
407
+ resetAggregates(customerId: string, featureKeys?: string[]): Promise<void>;
408
+ getAccessStatus(customerId: string): Promise<AccessStatusInfo | null>;
409
+ setAccessStatus(customerId: string, status: AccessStatusInfo): Promise<void>;
410
+ getBillingCycle(customerId: string): Promise<{
411
+ start: Date;
412
+ end: Date;
413
+ } | null>;
414
+ setBillingCycle(customerId: string, start: Date, end: Date): Promise<void>;
415
+ /**
416
+ * Clear all data (for testing)
417
+ */
418
+ clear(): void;
419
+ /**
420
+ * Get stats (for debugging)
421
+ */
422
+ getStats(): {
423
+ plans: number;
424
+ customers: number;
425
+ events: number;
426
+ aggregates: number;
427
+ alerts: number;
428
+ accessStatuses: number;
429
+ billingCycles: number;
430
+ };
431
+ }
432
+ /**
433
+ * Create in-memory usage storage
434
+ */
435
+ declare function createMemoryUsageStorage(): MemoryUsageStorage;
436
+
437
+ /**
438
+ * @parsrun/payments - Drizzle Usage Storage
439
+ * Database-backed storage implementation using Drizzle ORM
440
+ *
441
+ * @example
442
+ * ```typescript
443
+ * import { createDrizzleUsageStorage } from "@parsrun/payments";
444
+ * import { drizzle } from "drizzle-orm/postgres-js";
445
+ * import postgres from "postgres";
446
+ *
447
+ * const client = postgres(process.env.DATABASE_URL);
448
+ * const db = drizzle(client);
449
+ *
450
+ * const storage = createDrizzleUsageStorage({ db });
451
+ *
452
+ * const usageService = createUsageService({ storage });
453
+ * ```
454
+ */
455
+
456
+ /**
457
+ * Supported Drizzle database types
458
+ */
459
+ type DrizzleDb = PostgresJsDatabase<any> | NeonHttpDatabase<any>;
460
+ /**
461
+ * Drizzle storage configuration
462
+ */
463
+ interface DrizzleUsageStorageConfig {
464
+ /** Drizzle database instance */
465
+ db: DrizzleDb;
466
+ /** Table prefix (optional, for multi-tenant setups) */
467
+ tablePrefix?: string;
468
+ }
469
+ /**
470
+ * Drizzle-backed usage storage
471
+ * Persists all usage data to PostgreSQL/Neon database
472
+ */
473
+ declare class DrizzleUsageStorage implements UsageStorage {
474
+ private readonly db;
475
+ constructor(config: DrizzleUsageStorageConfig);
476
+ getPlan(planId: string): Promise<Plan$1 | null>;
477
+ getPlanByName(name: string): Promise<Plan$1 | null>;
478
+ listPlans(options?: {
479
+ activeOnly?: boolean;
480
+ }): Promise<Plan$1[]>;
481
+ private mapRowToPlan;
482
+ getPlanFeatures(planId: string): Promise<PlanFeature$1[]>;
483
+ getFeatureLimit(planId: string, featureKey: string): Promise<PlanFeature$1 | null>;
484
+ private mapRowToPlanFeature;
485
+ getCustomerPlanId(customerId: string): Promise<string | null>;
486
+ setCustomerPlanId(customerId: string, planId: string): Promise<void>;
487
+ recordUsage(event: Omit<UsageEvent, "id">): Promise<UsageEvent>;
488
+ recordUsageBatch(events: Omit<UsageEvent, "id">[]): Promise<UsageEvent[]>;
489
+ getUsageEvents(customerId: string, options: GetUsageOptions): Promise<UsageEvent[]>;
490
+ private mapRowToUsageEvent;
491
+ getAggregate(customerId: string, featureKey: string, periodType: PeriodType, periodStart: Date): Promise<UsageAggregate | null>;
492
+ upsertAggregate(aggregate: Omit<UsageAggregate, "id">): Promise<UsageAggregate>;
493
+ getAggregates(customerId: string, options: GetUsageOptions): Promise<UsageAggregate[]>;
494
+ getCurrentPeriodUsage(customerId: string, featureKey: string, periodStart: Date): Promise<number>;
495
+ private mapRowToUsageAggregate;
496
+ createAlert(alert: Omit<UsageAlert, "id" | "createdAt">): Promise<UsageAlert>;
497
+ getActiveAlerts(customerId: string): Promise<UsageAlert[]>;
498
+ updateAlertStatus(alertId: string, status: AlertStatus): Promise<void>;
499
+ private mapRowToUsageAlert;
500
+ resetUsage(customerId: string, featureKeys?: string[], periodStart?: Date): Promise<void>;
501
+ resetAggregates(customerId: string, featureKeys?: string[]): Promise<void>;
502
+ getAccessStatus(customerId: string): Promise<AccessStatusInfo | null>;
503
+ setAccessStatus(customerId: string, status: AccessStatusInfo): Promise<void>;
504
+ getBillingCycle(customerId: string): Promise<{
505
+ start: Date;
506
+ end: Date;
507
+ } | null>;
508
+ setBillingCycle(customerId: string, start: Date, end: Date): Promise<void>;
509
+ /**
510
+ * Create or update a plan
511
+ */
512
+ upsertPlan(plan: Omit<Plan$1, "createdAt" | "updatedAt">): Promise<Plan$1>;
513
+ /**
514
+ * Delete a plan
515
+ */
516
+ deletePlan(planId: string): Promise<void>;
517
+ }
518
+ /**
519
+ * Create Drizzle-backed usage storage
520
+ */
521
+ declare function createDrizzleUsageStorage(config: DrizzleUsageStorageConfig): DrizzleUsageStorage;
522
+
523
+ /**
524
+ * @parsrun/payments - Usage Database Schema
525
+ * Drizzle ORM schema for usage-based billing tables
526
+ *
527
+ * These tables store:
528
+ * - Plans and features with limits
529
+ * - Customer plan assignments
530
+ * - Usage events and aggregates
531
+ * - Access status and billing cycles
532
+ * - Usage alerts
533
+ */
534
+ /**
535
+ * Plans table - defines billing plans with tiers
536
+ */
537
+ declare const plans: drizzle_orm_pg_core.PgTableWithColumns<{
538
+ name: "usage_plans";
539
+ schema: undefined;
540
+ columns: {
541
+ id: drizzle_orm_pg_core.PgColumn<{
542
+ name: "id";
543
+ tableName: "usage_plans";
544
+ dataType: "string";
545
+ columnType: "PgText";
546
+ data: string;
547
+ driverParam: string;
548
+ notNull: true;
549
+ hasDefault: false;
550
+ isPrimaryKey: true;
551
+ isAutoincrement: false;
552
+ hasRuntimeDefault: false;
553
+ enumValues: [string, ...string[]];
554
+ baseColumn: never;
555
+ identity: undefined;
556
+ generated: undefined;
557
+ }, {}, {}>;
558
+ name: drizzle_orm_pg_core.PgColumn<{
559
+ name: "name";
560
+ tableName: "usage_plans";
561
+ dataType: "string";
562
+ columnType: "PgText";
563
+ data: string;
564
+ driverParam: string;
565
+ notNull: true;
566
+ hasDefault: false;
567
+ isPrimaryKey: false;
568
+ isAutoincrement: false;
569
+ hasRuntimeDefault: false;
570
+ enumValues: [string, ...string[]];
571
+ baseColumn: never;
572
+ identity: undefined;
573
+ generated: undefined;
574
+ }, {}, {}>;
575
+ displayName: drizzle_orm_pg_core.PgColumn<{
576
+ name: "display_name";
577
+ tableName: "usage_plans";
578
+ dataType: "string";
579
+ columnType: "PgText";
580
+ data: string;
581
+ driverParam: string;
582
+ notNull: true;
583
+ hasDefault: false;
584
+ isPrimaryKey: false;
585
+ isAutoincrement: false;
586
+ hasRuntimeDefault: false;
587
+ enumValues: [string, ...string[]];
588
+ baseColumn: never;
589
+ identity: undefined;
590
+ generated: undefined;
591
+ }, {}, {}>;
592
+ description: drizzle_orm_pg_core.PgColumn<{
593
+ name: "description";
594
+ tableName: "usage_plans";
595
+ dataType: "string";
596
+ columnType: "PgText";
597
+ data: string;
598
+ driverParam: string;
599
+ notNull: false;
600
+ hasDefault: false;
601
+ isPrimaryKey: false;
602
+ isAutoincrement: false;
603
+ hasRuntimeDefault: false;
604
+ enumValues: [string, ...string[]];
605
+ baseColumn: never;
606
+ identity: undefined;
607
+ generated: undefined;
608
+ }, {}, {}>;
609
+ tier: drizzle_orm_pg_core.PgColumn<{
610
+ name: "tier";
611
+ tableName: "usage_plans";
612
+ dataType: "number";
613
+ columnType: "PgInteger";
614
+ data: number;
615
+ driverParam: string | number;
616
+ notNull: true;
617
+ hasDefault: true;
618
+ isPrimaryKey: false;
619
+ isAutoincrement: false;
620
+ hasRuntimeDefault: false;
621
+ enumValues: undefined;
622
+ baseColumn: never;
623
+ identity: undefined;
624
+ generated: undefined;
625
+ }, {}, {}>;
626
+ basePrice: drizzle_orm_pg_core.PgColumn<{
627
+ name: "base_price";
628
+ tableName: "usage_plans";
629
+ dataType: "number";
630
+ columnType: "PgInteger";
631
+ data: number;
632
+ driverParam: string | number;
633
+ notNull: true;
634
+ hasDefault: true;
635
+ isPrimaryKey: false;
636
+ isAutoincrement: false;
637
+ hasRuntimeDefault: false;
638
+ enumValues: undefined;
639
+ baseColumn: never;
640
+ identity: undefined;
641
+ generated: undefined;
642
+ }, {}, {}>;
643
+ currency: drizzle_orm_pg_core.PgColumn<{
644
+ name: "currency";
645
+ tableName: "usage_plans";
646
+ dataType: "string";
647
+ columnType: "PgText";
648
+ data: string;
649
+ driverParam: string;
650
+ notNull: true;
651
+ hasDefault: true;
652
+ isPrimaryKey: false;
653
+ isAutoincrement: false;
654
+ hasRuntimeDefault: false;
655
+ enumValues: [string, ...string[]];
656
+ baseColumn: never;
657
+ identity: undefined;
658
+ generated: undefined;
659
+ }, {}, {}>;
660
+ billingInterval: drizzle_orm_pg_core.PgColumn<{
661
+ name: "billing_interval";
662
+ tableName: "usage_plans";
663
+ dataType: "string";
664
+ columnType: "PgText";
665
+ data: string;
666
+ driverParam: string;
667
+ notNull: true;
668
+ hasDefault: true;
669
+ isPrimaryKey: false;
670
+ isAutoincrement: false;
671
+ hasRuntimeDefault: false;
672
+ enumValues: [string, ...string[]];
673
+ baseColumn: never;
674
+ identity: undefined;
675
+ generated: undefined;
676
+ }, {}, {}>;
677
+ isActive: drizzle_orm_pg_core.PgColumn<{
678
+ name: "is_active";
679
+ tableName: "usage_plans";
680
+ dataType: "boolean";
681
+ columnType: "PgBoolean";
682
+ data: boolean;
683
+ driverParam: boolean;
684
+ notNull: true;
685
+ hasDefault: true;
686
+ isPrimaryKey: false;
687
+ isAutoincrement: false;
688
+ hasRuntimeDefault: false;
689
+ enumValues: undefined;
690
+ baseColumn: never;
691
+ identity: undefined;
692
+ generated: undefined;
693
+ }, {}, {}>;
694
+ metadata: drizzle_orm_pg_core.PgColumn<{
695
+ name: "metadata";
696
+ tableName: "usage_plans";
697
+ dataType: "json";
698
+ columnType: "PgJsonb";
699
+ data: Record<string, unknown>;
700
+ driverParam: unknown;
701
+ notNull: false;
702
+ hasDefault: false;
703
+ isPrimaryKey: false;
704
+ isAutoincrement: false;
705
+ hasRuntimeDefault: false;
706
+ enumValues: undefined;
707
+ baseColumn: never;
708
+ identity: undefined;
709
+ generated: undefined;
710
+ }, {}, {
711
+ $type: Record<string, unknown>;
712
+ }>;
713
+ createdAt: drizzle_orm_pg_core.PgColumn<{
714
+ name: "created_at";
715
+ tableName: "usage_plans";
716
+ dataType: "date";
717
+ columnType: "PgTimestamp";
718
+ data: Date;
719
+ driverParam: string;
720
+ notNull: true;
721
+ hasDefault: true;
722
+ isPrimaryKey: false;
723
+ isAutoincrement: false;
724
+ hasRuntimeDefault: false;
725
+ enumValues: undefined;
726
+ baseColumn: never;
727
+ identity: undefined;
728
+ generated: undefined;
729
+ }, {}, {}>;
730
+ updatedAt: drizzle_orm_pg_core.PgColumn<{
731
+ name: "updated_at";
732
+ tableName: "usage_plans";
733
+ dataType: "date";
734
+ columnType: "PgTimestamp";
735
+ data: Date;
736
+ driverParam: string;
737
+ notNull: true;
738
+ hasDefault: true;
739
+ isPrimaryKey: false;
740
+ isAutoincrement: false;
741
+ hasRuntimeDefault: false;
742
+ enumValues: undefined;
743
+ baseColumn: never;
744
+ identity: undefined;
745
+ generated: undefined;
746
+ }, {}, {}>;
747
+ };
748
+ dialect: "pg";
749
+ }>;
750
+ /**
751
+ * Plan features table - defines feature limits for each plan
752
+ */
753
+ declare const planFeatures: drizzle_orm_pg_core.PgTableWithColumns<{
754
+ name: "usage_plan_features";
755
+ schema: undefined;
756
+ columns: {
757
+ id: drizzle_orm_pg_core.PgColumn<{
758
+ name: "id";
759
+ tableName: "usage_plan_features";
760
+ dataType: "string";
761
+ columnType: "PgText";
762
+ data: string;
763
+ driverParam: string;
764
+ notNull: true;
765
+ hasDefault: false;
766
+ isPrimaryKey: true;
767
+ isAutoincrement: false;
768
+ hasRuntimeDefault: false;
769
+ enumValues: [string, ...string[]];
770
+ baseColumn: never;
771
+ identity: undefined;
772
+ generated: undefined;
773
+ }, {}, {}>;
774
+ planId: drizzle_orm_pg_core.PgColumn<{
775
+ name: "plan_id";
776
+ tableName: "usage_plan_features";
777
+ dataType: "string";
778
+ columnType: "PgText";
779
+ data: string;
780
+ driverParam: string;
781
+ notNull: true;
782
+ hasDefault: false;
783
+ isPrimaryKey: false;
784
+ isAutoincrement: false;
785
+ hasRuntimeDefault: false;
786
+ enumValues: [string, ...string[]];
787
+ baseColumn: never;
788
+ identity: undefined;
789
+ generated: undefined;
790
+ }, {}, {}>;
791
+ featureKey: drizzle_orm_pg_core.PgColumn<{
792
+ name: "feature_key";
793
+ tableName: "usage_plan_features";
794
+ dataType: "string";
795
+ columnType: "PgText";
796
+ data: string;
797
+ driverParam: string;
798
+ notNull: true;
799
+ hasDefault: false;
800
+ isPrimaryKey: false;
801
+ isAutoincrement: false;
802
+ hasRuntimeDefault: false;
803
+ enumValues: [string, ...string[]];
804
+ baseColumn: never;
805
+ identity: undefined;
806
+ generated: undefined;
807
+ }, {}, {}>;
808
+ limitValue: drizzle_orm_pg_core.PgColumn<{
809
+ name: "limit_value";
810
+ tableName: "usage_plan_features";
811
+ dataType: "number";
812
+ columnType: "PgInteger";
813
+ data: number;
814
+ driverParam: string | number;
815
+ notNull: false;
816
+ hasDefault: false;
817
+ isPrimaryKey: false;
818
+ isAutoincrement: false;
819
+ hasRuntimeDefault: false;
820
+ enumValues: undefined;
821
+ baseColumn: never;
822
+ identity: undefined;
823
+ generated: undefined;
824
+ }, {}, {}>;
825
+ limitPeriod: drizzle_orm_pg_core.PgColumn<{
826
+ name: "limit_period";
827
+ tableName: "usage_plan_features";
828
+ dataType: "string";
829
+ columnType: "PgText";
830
+ data: string;
831
+ driverParam: string;
832
+ notNull: false;
833
+ hasDefault: false;
834
+ isPrimaryKey: false;
835
+ isAutoincrement: false;
836
+ hasRuntimeDefault: false;
837
+ enumValues: [string, ...string[]];
838
+ baseColumn: never;
839
+ identity: undefined;
840
+ generated: undefined;
841
+ }, {}, {}>;
842
+ isEnabled: drizzle_orm_pg_core.PgColumn<{
843
+ name: "is_enabled";
844
+ tableName: "usage_plan_features";
845
+ dataType: "boolean";
846
+ columnType: "PgBoolean";
847
+ data: boolean;
848
+ driverParam: boolean;
849
+ notNull: true;
850
+ hasDefault: true;
851
+ isPrimaryKey: false;
852
+ isAutoincrement: false;
853
+ hasRuntimeDefault: false;
854
+ enumValues: undefined;
855
+ baseColumn: never;
856
+ identity: undefined;
857
+ generated: undefined;
858
+ }, {}, {}>;
859
+ metadata: drizzle_orm_pg_core.PgColumn<{
860
+ name: "metadata";
861
+ tableName: "usage_plan_features";
862
+ dataType: "json";
863
+ columnType: "PgJsonb";
864
+ data: Record<string, unknown>;
865
+ driverParam: unknown;
866
+ notNull: false;
867
+ hasDefault: false;
868
+ isPrimaryKey: false;
869
+ isAutoincrement: false;
870
+ hasRuntimeDefault: false;
871
+ enumValues: undefined;
872
+ baseColumn: never;
873
+ identity: undefined;
874
+ generated: undefined;
875
+ }, {}, {
876
+ $type: Record<string, unknown>;
877
+ }>;
878
+ };
879
+ dialect: "pg";
880
+ }>;
881
+ /**
882
+ * Customer plans table - maps customers to their current plan
883
+ */
884
+ declare const customerPlans: drizzle_orm_pg_core.PgTableWithColumns<{
885
+ name: "usage_customer_plans";
886
+ schema: undefined;
887
+ columns: {
888
+ customerId: drizzle_orm_pg_core.PgColumn<{
889
+ name: "customer_id";
890
+ tableName: "usage_customer_plans";
891
+ dataType: "string";
892
+ columnType: "PgText";
893
+ data: string;
894
+ driverParam: string;
895
+ notNull: true;
896
+ hasDefault: false;
897
+ isPrimaryKey: true;
898
+ isAutoincrement: false;
899
+ hasRuntimeDefault: false;
900
+ enumValues: [string, ...string[]];
901
+ baseColumn: never;
902
+ identity: undefined;
903
+ generated: undefined;
904
+ }, {}, {}>;
905
+ planId: drizzle_orm_pg_core.PgColumn<{
906
+ name: "plan_id";
907
+ tableName: "usage_customer_plans";
908
+ dataType: "string";
909
+ columnType: "PgText";
910
+ data: string;
911
+ driverParam: string;
912
+ notNull: true;
913
+ hasDefault: false;
914
+ isPrimaryKey: false;
915
+ isAutoincrement: false;
916
+ hasRuntimeDefault: false;
917
+ enumValues: [string, ...string[]];
918
+ baseColumn: never;
919
+ identity: undefined;
920
+ generated: undefined;
921
+ }, {}, {}>;
922
+ assignedAt: drizzle_orm_pg_core.PgColumn<{
923
+ name: "assigned_at";
924
+ tableName: "usage_customer_plans";
925
+ dataType: "date";
926
+ columnType: "PgTimestamp";
927
+ data: Date;
928
+ driverParam: string;
929
+ notNull: true;
930
+ hasDefault: true;
931
+ isPrimaryKey: false;
932
+ isAutoincrement: false;
933
+ hasRuntimeDefault: false;
934
+ enumValues: undefined;
935
+ baseColumn: never;
936
+ identity: undefined;
937
+ generated: undefined;
938
+ }, {}, {}>;
939
+ metadata: drizzle_orm_pg_core.PgColumn<{
940
+ name: "metadata";
941
+ tableName: "usage_customer_plans";
942
+ dataType: "json";
943
+ columnType: "PgJsonb";
944
+ data: Record<string, unknown>;
945
+ driverParam: unknown;
946
+ notNull: false;
947
+ hasDefault: false;
948
+ isPrimaryKey: false;
949
+ isAutoincrement: false;
950
+ hasRuntimeDefault: false;
951
+ enumValues: undefined;
952
+ baseColumn: never;
953
+ identity: undefined;
954
+ generated: undefined;
955
+ }, {}, {
956
+ $type: Record<string, unknown>;
957
+ }>;
958
+ };
959
+ dialect: "pg";
960
+ }>;
961
+ /**
962
+ * Customer access status table - tracks access status for each customer
963
+ */
964
+ declare const customerAccessStatus: drizzle_orm_pg_core.PgTableWithColumns<{
965
+ name: "usage_customer_access_status";
966
+ schema: undefined;
967
+ columns: {
968
+ customerId: drizzle_orm_pg_core.PgColumn<{
969
+ name: "customer_id";
970
+ tableName: "usage_customer_access_status";
971
+ dataType: "string";
972
+ columnType: "PgText";
973
+ data: string;
974
+ driverParam: string;
975
+ notNull: true;
976
+ hasDefault: false;
977
+ isPrimaryKey: true;
978
+ isAutoincrement: false;
979
+ hasRuntimeDefault: false;
980
+ enumValues: [string, ...string[]];
981
+ baseColumn: never;
982
+ identity: undefined;
983
+ generated: undefined;
984
+ }, {}, {}>;
985
+ status: drizzle_orm_pg_core.PgColumn<{
986
+ name: "status";
987
+ tableName: "usage_customer_access_status";
988
+ dataType: "string";
989
+ columnType: "PgText";
990
+ data: string;
991
+ driverParam: string;
992
+ notNull: true;
993
+ hasDefault: true;
994
+ isPrimaryKey: false;
995
+ isAutoincrement: false;
996
+ hasRuntimeDefault: false;
997
+ enumValues: [string, ...string[]];
998
+ baseColumn: never;
999
+ identity: undefined;
1000
+ generated: undefined;
1001
+ }, {}, {}>;
1002
+ reason: drizzle_orm_pg_core.PgColumn<{
1003
+ name: "reason";
1004
+ tableName: "usage_customer_access_status";
1005
+ dataType: "string";
1006
+ columnType: "PgText";
1007
+ data: string;
1008
+ driverParam: string;
1009
+ notNull: false;
1010
+ hasDefault: false;
1011
+ isPrimaryKey: false;
1012
+ isAutoincrement: false;
1013
+ hasRuntimeDefault: false;
1014
+ enumValues: [string, ...string[]];
1015
+ baseColumn: never;
1016
+ identity: undefined;
1017
+ generated: undefined;
1018
+ }, {}, {}>;
1019
+ suspensionDate: drizzle_orm_pg_core.PgColumn<{
1020
+ name: "suspension_date";
1021
+ tableName: "usage_customer_access_status";
1022
+ dataType: "date";
1023
+ columnType: "PgTimestamp";
1024
+ data: Date;
1025
+ driverParam: string;
1026
+ notNull: false;
1027
+ hasDefault: false;
1028
+ isPrimaryKey: false;
1029
+ isAutoincrement: false;
1030
+ hasRuntimeDefault: false;
1031
+ enumValues: undefined;
1032
+ baseColumn: never;
1033
+ identity: undefined;
1034
+ generated: undefined;
1035
+ }, {}, {}>;
1036
+ failedPaymentAttempts: drizzle_orm_pg_core.PgColumn<{
1037
+ name: "failed_payment_attempts";
1038
+ tableName: "usage_customer_access_status";
1039
+ dataType: "number";
1040
+ columnType: "PgInteger";
1041
+ data: number;
1042
+ driverParam: string | number;
1043
+ notNull: false;
1044
+ hasDefault: true;
1045
+ isPrimaryKey: false;
1046
+ isAutoincrement: false;
1047
+ hasRuntimeDefault: false;
1048
+ enumValues: undefined;
1049
+ baseColumn: never;
1050
+ identity: undefined;
1051
+ generated: undefined;
1052
+ }, {}, {}>;
1053
+ gracePeriodEnd: drizzle_orm_pg_core.PgColumn<{
1054
+ name: "grace_period_end";
1055
+ tableName: "usage_customer_access_status";
1056
+ dataType: "date";
1057
+ columnType: "PgTimestamp";
1058
+ data: Date;
1059
+ driverParam: string;
1060
+ notNull: false;
1061
+ hasDefault: false;
1062
+ isPrimaryKey: false;
1063
+ isAutoincrement: false;
1064
+ hasRuntimeDefault: false;
1065
+ enumValues: undefined;
1066
+ baseColumn: never;
1067
+ identity: undefined;
1068
+ generated: undefined;
1069
+ }, {}, {}>;
1070
+ updatedAt: drizzle_orm_pg_core.PgColumn<{
1071
+ name: "updated_at";
1072
+ tableName: "usage_customer_access_status";
1073
+ dataType: "date";
1074
+ columnType: "PgTimestamp";
1075
+ data: Date;
1076
+ driverParam: string;
1077
+ notNull: true;
1078
+ hasDefault: true;
1079
+ isPrimaryKey: false;
1080
+ isAutoincrement: false;
1081
+ hasRuntimeDefault: false;
1082
+ enumValues: undefined;
1083
+ baseColumn: never;
1084
+ identity: undefined;
1085
+ generated: undefined;
1086
+ }, {}, {}>;
1087
+ };
1088
+ dialect: "pg";
1089
+ }>;
1090
+ /**
1091
+ * Customer billing cycles table - tracks billing period for each customer
1092
+ */
1093
+ declare const customerBillingCycles: drizzle_orm_pg_core.PgTableWithColumns<{
1094
+ name: "usage_customer_billing_cycles";
1095
+ schema: undefined;
1096
+ columns: {
1097
+ customerId: drizzle_orm_pg_core.PgColumn<{
1098
+ name: "customer_id";
1099
+ tableName: "usage_customer_billing_cycles";
1100
+ dataType: "string";
1101
+ columnType: "PgText";
1102
+ data: string;
1103
+ driverParam: string;
1104
+ notNull: true;
1105
+ hasDefault: false;
1106
+ isPrimaryKey: true;
1107
+ isAutoincrement: false;
1108
+ hasRuntimeDefault: false;
1109
+ enumValues: [string, ...string[]];
1110
+ baseColumn: never;
1111
+ identity: undefined;
1112
+ generated: undefined;
1113
+ }, {}, {}>;
1114
+ periodStart: drizzle_orm_pg_core.PgColumn<{
1115
+ name: "period_start";
1116
+ tableName: "usage_customer_billing_cycles";
1117
+ dataType: "date";
1118
+ columnType: "PgTimestamp";
1119
+ data: Date;
1120
+ driverParam: string;
1121
+ notNull: true;
1122
+ hasDefault: false;
1123
+ isPrimaryKey: false;
1124
+ isAutoincrement: false;
1125
+ hasRuntimeDefault: false;
1126
+ enumValues: undefined;
1127
+ baseColumn: never;
1128
+ identity: undefined;
1129
+ generated: undefined;
1130
+ }, {}, {}>;
1131
+ periodEnd: drizzle_orm_pg_core.PgColumn<{
1132
+ name: "period_end";
1133
+ tableName: "usage_customer_billing_cycles";
1134
+ dataType: "date";
1135
+ columnType: "PgTimestamp";
1136
+ data: Date;
1137
+ driverParam: string;
1138
+ notNull: true;
1139
+ hasDefault: false;
1140
+ isPrimaryKey: false;
1141
+ isAutoincrement: false;
1142
+ hasRuntimeDefault: false;
1143
+ enumValues: undefined;
1144
+ baseColumn: never;
1145
+ identity: undefined;
1146
+ generated: undefined;
1147
+ }, {}, {}>;
1148
+ updatedAt: drizzle_orm_pg_core.PgColumn<{
1149
+ name: "updated_at";
1150
+ tableName: "usage_customer_billing_cycles";
1151
+ dataType: "date";
1152
+ columnType: "PgTimestamp";
1153
+ data: Date;
1154
+ driverParam: string;
1155
+ notNull: true;
1156
+ hasDefault: true;
1157
+ isPrimaryKey: false;
1158
+ isAutoincrement: false;
1159
+ hasRuntimeDefault: false;
1160
+ enumValues: undefined;
1161
+ baseColumn: never;
1162
+ identity: undefined;
1163
+ generated: undefined;
1164
+ }, {}, {}>;
1165
+ };
1166
+ dialect: "pg";
1167
+ }>;
1168
+ /**
1169
+ * Usage events table - raw usage event log
1170
+ */
1171
+ declare const usageEvents: drizzle_orm_pg_core.PgTableWithColumns<{
1172
+ name: "usage_events";
1173
+ schema: undefined;
1174
+ columns: {
1175
+ id: drizzle_orm_pg_core.PgColumn<{
1176
+ name: "id";
1177
+ tableName: "usage_events";
1178
+ dataType: "string";
1179
+ columnType: "PgText";
1180
+ data: string;
1181
+ driverParam: string;
1182
+ notNull: true;
1183
+ hasDefault: false;
1184
+ isPrimaryKey: true;
1185
+ isAutoincrement: false;
1186
+ hasRuntimeDefault: false;
1187
+ enumValues: [string, ...string[]];
1188
+ baseColumn: never;
1189
+ identity: undefined;
1190
+ generated: undefined;
1191
+ }, {}, {}>;
1192
+ tenantId: drizzle_orm_pg_core.PgColumn<{
1193
+ name: "tenant_id";
1194
+ tableName: "usage_events";
1195
+ dataType: "string";
1196
+ columnType: "PgText";
1197
+ data: string;
1198
+ driverParam: string;
1199
+ notNull: true;
1200
+ hasDefault: false;
1201
+ isPrimaryKey: false;
1202
+ isAutoincrement: false;
1203
+ hasRuntimeDefault: false;
1204
+ enumValues: [string, ...string[]];
1205
+ baseColumn: never;
1206
+ identity: undefined;
1207
+ generated: undefined;
1208
+ }, {}, {}>;
1209
+ customerId: drizzle_orm_pg_core.PgColumn<{
1210
+ name: "customer_id";
1211
+ tableName: "usage_events";
1212
+ dataType: "string";
1213
+ columnType: "PgText";
1214
+ data: string;
1215
+ driverParam: string;
1216
+ notNull: true;
1217
+ hasDefault: false;
1218
+ isPrimaryKey: false;
1219
+ isAutoincrement: false;
1220
+ hasRuntimeDefault: false;
1221
+ enumValues: [string, ...string[]];
1222
+ baseColumn: never;
1223
+ identity: undefined;
1224
+ generated: undefined;
1225
+ }, {}, {}>;
1226
+ subscriptionId: drizzle_orm_pg_core.PgColumn<{
1227
+ name: "subscription_id";
1228
+ tableName: "usage_events";
1229
+ dataType: "string";
1230
+ columnType: "PgText";
1231
+ data: string;
1232
+ driverParam: string;
1233
+ notNull: false;
1234
+ hasDefault: false;
1235
+ isPrimaryKey: false;
1236
+ isAutoincrement: false;
1237
+ hasRuntimeDefault: false;
1238
+ enumValues: [string, ...string[]];
1239
+ baseColumn: never;
1240
+ identity: undefined;
1241
+ generated: undefined;
1242
+ }, {}, {}>;
1243
+ featureKey: drizzle_orm_pg_core.PgColumn<{
1244
+ name: "feature_key";
1245
+ tableName: "usage_events";
1246
+ dataType: "string";
1247
+ columnType: "PgText";
1248
+ data: string;
1249
+ driverParam: string;
1250
+ notNull: true;
1251
+ hasDefault: false;
1252
+ isPrimaryKey: false;
1253
+ isAutoincrement: false;
1254
+ hasRuntimeDefault: false;
1255
+ enumValues: [string, ...string[]];
1256
+ baseColumn: never;
1257
+ identity: undefined;
1258
+ generated: undefined;
1259
+ }, {}, {}>;
1260
+ quantity: drizzle_orm_pg_core.PgColumn<{
1261
+ name: "quantity";
1262
+ tableName: "usage_events";
1263
+ dataType: "number";
1264
+ columnType: "PgInteger";
1265
+ data: number;
1266
+ driverParam: string | number;
1267
+ notNull: true;
1268
+ hasDefault: true;
1269
+ isPrimaryKey: false;
1270
+ isAutoincrement: false;
1271
+ hasRuntimeDefault: false;
1272
+ enumValues: undefined;
1273
+ baseColumn: never;
1274
+ identity: undefined;
1275
+ generated: undefined;
1276
+ }, {}, {}>;
1277
+ timestamp: drizzle_orm_pg_core.PgColumn<{
1278
+ name: "timestamp";
1279
+ tableName: "usage_events";
1280
+ dataType: "date";
1281
+ columnType: "PgTimestamp";
1282
+ data: Date;
1283
+ driverParam: string;
1284
+ notNull: true;
1285
+ hasDefault: true;
1286
+ isPrimaryKey: false;
1287
+ isAutoincrement: false;
1288
+ hasRuntimeDefault: false;
1289
+ enumValues: undefined;
1290
+ baseColumn: never;
1291
+ identity: undefined;
1292
+ generated: undefined;
1293
+ }, {}, {}>;
1294
+ metadata: drizzle_orm_pg_core.PgColumn<{
1295
+ name: "metadata";
1296
+ tableName: "usage_events";
1297
+ dataType: "json";
1298
+ columnType: "PgJsonb";
1299
+ data: Record<string, unknown>;
1300
+ driverParam: unknown;
1301
+ notNull: false;
1302
+ hasDefault: false;
1303
+ isPrimaryKey: false;
1304
+ isAutoincrement: false;
1305
+ hasRuntimeDefault: false;
1306
+ enumValues: undefined;
1307
+ baseColumn: never;
1308
+ identity: undefined;
1309
+ generated: undefined;
1310
+ }, {}, {
1311
+ $type: Record<string, unknown>;
1312
+ }>;
1313
+ idempotencyKey: drizzle_orm_pg_core.PgColumn<{
1314
+ name: "idempotency_key";
1315
+ tableName: "usage_events";
1316
+ dataType: "string";
1317
+ columnType: "PgText";
1318
+ data: string;
1319
+ driverParam: string;
1320
+ notNull: false;
1321
+ hasDefault: false;
1322
+ isPrimaryKey: false;
1323
+ isAutoincrement: false;
1324
+ hasRuntimeDefault: false;
1325
+ enumValues: [string, ...string[]];
1326
+ baseColumn: never;
1327
+ identity: undefined;
1328
+ generated: undefined;
1329
+ }, {}, {}>;
1330
+ };
1331
+ dialect: "pg";
1332
+ }>;
1333
+ /**
1334
+ * Usage aggregates table - pre-computed usage summaries for performance
1335
+ */
1336
+ declare const usageAggregates: drizzle_orm_pg_core.PgTableWithColumns<{
1337
+ name: "usage_aggregates";
1338
+ schema: undefined;
1339
+ columns: {
1340
+ id: drizzle_orm_pg_core.PgColumn<{
1341
+ name: "id";
1342
+ tableName: "usage_aggregates";
1343
+ dataType: "string";
1344
+ columnType: "PgText";
1345
+ data: string;
1346
+ driverParam: string;
1347
+ notNull: true;
1348
+ hasDefault: false;
1349
+ isPrimaryKey: true;
1350
+ isAutoincrement: false;
1351
+ hasRuntimeDefault: false;
1352
+ enumValues: [string, ...string[]];
1353
+ baseColumn: never;
1354
+ identity: undefined;
1355
+ generated: undefined;
1356
+ }, {}, {}>;
1357
+ tenantId: drizzle_orm_pg_core.PgColumn<{
1358
+ name: "tenant_id";
1359
+ tableName: "usage_aggregates";
1360
+ dataType: "string";
1361
+ columnType: "PgText";
1362
+ data: string;
1363
+ driverParam: string;
1364
+ notNull: true;
1365
+ hasDefault: false;
1366
+ isPrimaryKey: false;
1367
+ isAutoincrement: false;
1368
+ hasRuntimeDefault: false;
1369
+ enumValues: [string, ...string[]];
1370
+ baseColumn: never;
1371
+ identity: undefined;
1372
+ generated: undefined;
1373
+ }, {}, {}>;
1374
+ customerId: drizzle_orm_pg_core.PgColumn<{
1375
+ name: "customer_id";
1376
+ tableName: "usage_aggregates";
1377
+ dataType: "string";
1378
+ columnType: "PgText";
1379
+ data: string;
1380
+ driverParam: string;
1381
+ notNull: true;
1382
+ hasDefault: false;
1383
+ isPrimaryKey: false;
1384
+ isAutoincrement: false;
1385
+ hasRuntimeDefault: false;
1386
+ enumValues: [string, ...string[]];
1387
+ baseColumn: never;
1388
+ identity: undefined;
1389
+ generated: undefined;
1390
+ }, {}, {}>;
1391
+ subscriptionId: drizzle_orm_pg_core.PgColumn<{
1392
+ name: "subscription_id";
1393
+ tableName: "usage_aggregates";
1394
+ dataType: "string";
1395
+ columnType: "PgText";
1396
+ data: string;
1397
+ driverParam: string;
1398
+ notNull: false;
1399
+ hasDefault: false;
1400
+ isPrimaryKey: false;
1401
+ isAutoincrement: false;
1402
+ hasRuntimeDefault: false;
1403
+ enumValues: [string, ...string[]];
1404
+ baseColumn: never;
1405
+ identity: undefined;
1406
+ generated: undefined;
1407
+ }, {}, {}>;
1408
+ featureKey: drizzle_orm_pg_core.PgColumn<{
1409
+ name: "feature_key";
1410
+ tableName: "usage_aggregates";
1411
+ dataType: "string";
1412
+ columnType: "PgText";
1413
+ data: string;
1414
+ driverParam: string;
1415
+ notNull: true;
1416
+ hasDefault: false;
1417
+ isPrimaryKey: false;
1418
+ isAutoincrement: false;
1419
+ hasRuntimeDefault: false;
1420
+ enumValues: [string, ...string[]];
1421
+ baseColumn: never;
1422
+ identity: undefined;
1423
+ generated: undefined;
1424
+ }, {}, {}>;
1425
+ periodStart: drizzle_orm_pg_core.PgColumn<{
1426
+ name: "period_start";
1427
+ tableName: "usage_aggregates";
1428
+ dataType: "date";
1429
+ columnType: "PgTimestamp";
1430
+ data: Date;
1431
+ driverParam: string;
1432
+ notNull: true;
1433
+ hasDefault: false;
1434
+ isPrimaryKey: false;
1435
+ isAutoincrement: false;
1436
+ hasRuntimeDefault: false;
1437
+ enumValues: undefined;
1438
+ baseColumn: never;
1439
+ identity: undefined;
1440
+ generated: undefined;
1441
+ }, {}, {}>;
1442
+ periodEnd: drizzle_orm_pg_core.PgColumn<{
1443
+ name: "period_end";
1444
+ tableName: "usage_aggregates";
1445
+ dataType: "date";
1446
+ columnType: "PgTimestamp";
1447
+ data: Date;
1448
+ driverParam: string;
1449
+ notNull: true;
1450
+ hasDefault: false;
1451
+ isPrimaryKey: false;
1452
+ isAutoincrement: false;
1453
+ hasRuntimeDefault: false;
1454
+ enumValues: undefined;
1455
+ baseColumn: never;
1456
+ identity: undefined;
1457
+ generated: undefined;
1458
+ }, {}, {}>;
1459
+ periodType: drizzle_orm_pg_core.PgColumn<{
1460
+ name: "period_type";
1461
+ tableName: "usage_aggregates";
1462
+ dataType: "string";
1463
+ columnType: "PgText";
1464
+ data: string;
1465
+ driverParam: string;
1466
+ notNull: true;
1467
+ hasDefault: false;
1468
+ isPrimaryKey: false;
1469
+ isAutoincrement: false;
1470
+ hasRuntimeDefault: false;
1471
+ enumValues: [string, ...string[]];
1472
+ baseColumn: never;
1473
+ identity: undefined;
1474
+ generated: undefined;
1475
+ }, {}, {}>;
1476
+ totalQuantity: drizzle_orm_pg_core.PgColumn<{
1477
+ name: "total_quantity";
1478
+ tableName: "usage_aggregates";
1479
+ dataType: "number";
1480
+ columnType: "PgInteger";
1481
+ data: number;
1482
+ driverParam: string | number;
1483
+ notNull: true;
1484
+ hasDefault: true;
1485
+ isPrimaryKey: false;
1486
+ isAutoincrement: false;
1487
+ hasRuntimeDefault: false;
1488
+ enumValues: undefined;
1489
+ baseColumn: never;
1490
+ identity: undefined;
1491
+ generated: undefined;
1492
+ }, {}, {}>;
1493
+ eventCount: drizzle_orm_pg_core.PgColumn<{
1494
+ name: "event_count";
1495
+ tableName: "usage_aggregates";
1496
+ dataType: "number";
1497
+ columnType: "PgInteger";
1498
+ data: number;
1499
+ driverParam: string | number;
1500
+ notNull: true;
1501
+ hasDefault: true;
1502
+ isPrimaryKey: false;
1503
+ isAutoincrement: false;
1504
+ hasRuntimeDefault: false;
1505
+ enumValues: undefined;
1506
+ baseColumn: never;
1507
+ identity: undefined;
1508
+ generated: undefined;
1509
+ }, {}, {}>;
1510
+ lastUpdated: drizzle_orm_pg_core.PgColumn<{
1511
+ name: "last_updated";
1512
+ tableName: "usage_aggregates";
1513
+ dataType: "date";
1514
+ columnType: "PgTimestamp";
1515
+ data: Date;
1516
+ driverParam: string;
1517
+ notNull: true;
1518
+ hasDefault: true;
1519
+ isPrimaryKey: false;
1520
+ isAutoincrement: false;
1521
+ hasRuntimeDefault: false;
1522
+ enumValues: undefined;
1523
+ baseColumn: never;
1524
+ identity: undefined;
1525
+ generated: undefined;
1526
+ }, {}, {}>;
1527
+ };
1528
+ dialect: "pg";
1529
+ }>;
1530
+ /**
1531
+ * Usage alerts table - tracks quota threshold alerts
1532
+ */
1533
+ declare const usageAlerts: drizzle_orm_pg_core.PgTableWithColumns<{
1534
+ name: "usage_alerts";
1535
+ schema: undefined;
1536
+ columns: {
1537
+ id: drizzle_orm_pg_core.PgColumn<{
1538
+ name: "id";
1539
+ tableName: "usage_alerts";
1540
+ dataType: "string";
1541
+ columnType: "PgText";
1542
+ data: string;
1543
+ driverParam: string;
1544
+ notNull: true;
1545
+ hasDefault: false;
1546
+ isPrimaryKey: true;
1547
+ isAutoincrement: false;
1548
+ hasRuntimeDefault: false;
1549
+ enumValues: [string, ...string[]];
1550
+ baseColumn: never;
1551
+ identity: undefined;
1552
+ generated: undefined;
1553
+ }, {}, {}>;
1554
+ tenantId: drizzle_orm_pg_core.PgColumn<{
1555
+ name: "tenant_id";
1556
+ tableName: "usage_alerts";
1557
+ dataType: "string";
1558
+ columnType: "PgText";
1559
+ data: string;
1560
+ driverParam: string;
1561
+ notNull: true;
1562
+ hasDefault: false;
1563
+ isPrimaryKey: false;
1564
+ isAutoincrement: false;
1565
+ hasRuntimeDefault: false;
1566
+ enumValues: [string, ...string[]];
1567
+ baseColumn: never;
1568
+ identity: undefined;
1569
+ generated: undefined;
1570
+ }, {}, {}>;
1571
+ customerId: drizzle_orm_pg_core.PgColumn<{
1572
+ name: "customer_id";
1573
+ tableName: "usage_alerts";
1574
+ dataType: "string";
1575
+ columnType: "PgText";
1576
+ data: string;
1577
+ driverParam: string;
1578
+ notNull: true;
1579
+ hasDefault: false;
1580
+ isPrimaryKey: false;
1581
+ isAutoincrement: false;
1582
+ hasRuntimeDefault: false;
1583
+ enumValues: [string, ...string[]];
1584
+ baseColumn: never;
1585
+ identity: undefined;
1586
+ generated: undefined;
1587
+ }, {}, {}>;
1588
+ subscriptionId: drizzle_orm_pg_core.PgColumn<{
1589
+ name: "subscription_id";
1590
+ tableName: "usage_alerts";
1591
+ dataType: "string";
1592
+ columnType: "PgText";
1593
+ data: string;
1594
+ driverParam: string;
1595
+ notNull: false;
1596
+ hasDefault: false;
1597
+ isPrimaryKey: false;
1598
+ isAutoincrement: false;
1599
+ hasRuntimeDefault: false;
1600
+ enumValues: [string, ...string[]];
1601
+ baseColumn: never;
1602
+ identity: undefined;
1603
+ generated: undefined;
1604
+ }, {}, {}>;
1605
+ featureKey: drizzle_orm_pg_core.PgColumn<{
1606
+ name: "feature_key";
1607
+ tableName: "usage_alerts";
1608
+ dataType: "string";
1609
+ columnType: "PgText";
1610
+ data: string;
1611
+ driverParam: string;
1612
+ notNull: true;
1613
+ hasDefault: false;
1614
+ isPrimaryKey: false;
1615
+ isAutoincrement: false;
1616
+ hasRuntimeDefault: false;
1617
+ enumValues: [string, ...string[]];
1618
+ baseColumn: never;
1619
+ identity: undefined;
1620
+ generated: undefined;
1621
+ }, {}, {}>;
1622
+ thresholdPercent: drizzle_orm_pg_core.PgColumn<{
1623
+ name: "threshold_percent";
1624
+ tableName: "usage_alerts";
1625
+ dataType: "number";
1626
+ columnType: "PgInteger";
1627
+ data: number;
1628
+ driverParam: string | number;
1629
+ notNull: true;
1630
+ hasDefault: false;
1631
+ isPrimaryKey: false;
1632
+ isAutoincrement: false;
1633
+ hasRuntimeDefault: false;
1634
+ enumValues: undefined;
1635
+ baseColumn: never;
1636
+ identity: undefined;
1637
+ generated: undefined;
1638
+ }, {}, {}>;
1639
+ status: drizzle_orm_pg_core.PgColumn<{
1640
+ name: "status";
1641
+ tableName: "usage_alerts";
1642
+ dataType: "string";
1643
+ columnType: "PgText";
1644
+ data: string;
1645
+ driverParam: string;
1646
+ notNull: true;
1647
+ hasDefault: true;
1648
+ isPrimaryKey: false;
1649
+ isAutoincrement: false;
1650
+ hasRuntimeDefault: false;
1651
+ enumValues: [string, ...string[]];
1652
+ baseColumn: never;
1653
+ identity: undefined;
1654
+ generated: undefined;
1655
+ }, {}, {}>;
1656
+ currentUsage: drizzle_orm_pg_core.PgColumn<{
1657
+ name: "current_usage";
1658
+ tableName: "usage_alerts";
1659
+ dataType: "number";
1660
+ columnType: "PgInteger";
1661
+ data: number;
1662
+ driverParam: string | number;
1663
+ notNull: true;
1664
+ hasDefault: false;
1665
+ isPrimaryKey: false;
1666
+ isAutoincrement: false;
1667
+ hasRuntimeDefault: false;
1668
+ enumValues: undefined;
1669
+ baseColumn: never;
1670
+ identity: undefined;
1671
+ generated: undefined;
1672
+ }, {}, {}>;
1673
+ limit: drizzle_orm_pg_core.PgColumn<{
1674
+ name: "limit";
1675
+ tableName: "usage_alerts";
1676
+ dataType: "number";
1677
+ columnType: "PgInteger";
1678
+ data: number;
1679
+ driverParam: string | number;
1680
+ notNull: true;
1681
+ hasDefault: false;
1682
+ isPrimaryKey: false;
1683
+ isAutoincrement: false;
1684
+ hasRuntimeDefault: false;
1685
+ enumValues: undefined;
1686
+ baseColumn: never;
1687
+ identity: undefined;
1688
+ generated: undefined;
1689
+ }, {}, {}>;
1690
+ triggeredAt: drizzle_orm_pg_core.PgColumn<{
1691
+ name: "triggered_at";
1692
+ tableName: "usage_alerts";
1693
+ dataType: "date";
1694
+ columnType: "PgTimestamp";
1695
+ data: Date;
1696
+ driverParam: string;
1697
+ notNull: false;
1698
+ hasDefault: false;
1699
+ isPrimaryKey: false;
1700
+ isAutoincrement: false;
1701
+ hasRuntimeDefault: false;
1702
+ enumValues: undefined;
1703
+ baseColumn: never;
1704
+ identity: undefined;
1705
+ generated: undefined;
1706
+ }, {}, {}>;
1707
+ acknowledgedAt: drizzle_orm_pg_core.PgColumn<{
1708
+ name: "acknowledged_at";
1709
+ tableName: "usage_alerts";
1710
+ dataType: "date";
1711
+ columnType: "PgTimestamp";
1712
+ data: Date;
1713
+ driverParam: string;
1714
+ notNull: false;
1715
+ hasDefault: false;
1716
+ isPrimaryKey: false;
1717
+ isAutoincrement: false;
1718
+ hasRuntimeDefault: false;
1719
+ enumValues: undefined;
1720
+ baseColumn: never;
1721
+ identity: undefined;
1722
+ generated: undefined;
1723
+ }, {}, {}>;
1724
+ resolvedAt: drizzle_orm_pg_core.PgColumn<{
1725
+ name: "resolved_at";
1726
+ tableName: "usage_alerts";
1727
+ dataType: "date";
1728
+ columnType: "PgTimestamp";
1729
+ data: Date;
1730
+ driverParam: string;
1731
+ notNull: false;
1732
+ hasDefault: false;
1733
+ isPrimaryKey: false;
1734
+ isAutoincrement: false;
1735
+ hasRuntimeDefault: false;
1736
+ enumValues: undefined;
1737
+ baseColumn: never;
1738
+ identity: undefined;
1739
+ generated: undefined;
1740
+ }, {}, {}>;
1741
+ metadata: drizzle_orm_pg_core.PgColumn<{
1742
+ name: "metadata";
1743
+ tableName: "usage_alerts";
1744
+ dataType: "json";
1745
+ columnType: "PgJsonb";
1746
+ data: Record<string, unknown>;
1747
+ driverParam: unknown;
1748
+ notNull: false;
1749
+ hasDefault: false;
1750
+ isPrimaryKey: false;
1751
+ isAutoincrement: false;
1752
+ hasRuntimeDefault: false;
1753
+ enumValues: undefined;
1754
+ baseColumn: never;
1755
+ identity: undefined;
1756
+ generated: undefined;
1757
+ }, {}, {
1758
+ $type: Record<string, unknown>;
1759
+ }>;
1760
+ createdAt: drizzle_orm_pg_core.PgColumn<{
1761
+ name: "created_at";
1762
+ tableName: "usage_alerts";
1763
+ dataType: "date";
1764
+ columnType: "PgTimestamp";
1765
+ data: Date;
1766
+ driverParam: string;
1767
+ notNull: true;
1768
+ hasDefault: true;
1769
+ isPrimaryKey: false;
1770
+ isAutoincrement: false;
1771
+ hasRuntimeDefault: false;
1772
+ enumValues: undefined;
1773
+ baseColumn: never;
1774
+ identity: undefined;
1775
+ generated: undefined;
1776
+ }, {}, {}>;
1777
+ };
1778
+ dialect: "pg";
1779
+ }>;
1780
+ type Plan = typeof plans.$inferSelect;
1781
+ type NewPlan = typeof plans.$inferInsert;
1782
+ type PlanFeature = typeof planFeatures.$inferSelect;
1783
+ type NewPlanFeature = typeof planFeatures.$inferInsert;
1784
+ type CustomerPlan = typeof customerPlans.$inferSelect;
1785
+ type NewCustomerPlan = typeof customerPlans.$inferInsert;
1786
+ type CustomerAccessStatusRow = typeof customerAccessStatus.$inferSelect;
1787
+ type NewCustomerAccessStatus = typeof customerAccessStatus.$inferInsert;
1788
+ type CustomerBillingCycle = typeof customerBillingCycles.$inferSelect;
1789
+ type NewCustomerBillingCycle = typeof customerBillingCycles.$inferInsert;
1790
+ type UsageEventRow = typeof usageEvents.$inferSelect;
1791
+ type NewUsageEvent = typeof usageEvents.$inferInsert;
1792
+ type UsageAggregateRow = typeof usageAggregates.$inferSelect;
1793
+ type NewUsageAggregate = typeof usageAggregates.$inferInsert;
1794
+ type UsageAlertRow = typeof usageAlerts.$inferSelect;
1795
+ type NewUsageAlert = typeof usageAlerts.$inferInsert;
1796
+
1797
+ type schema_CustomerAccessStatusRow = CustomerAccessStatusRow;
1798
+ type schema_CustomerBillingCycle = CustomerBillingCycle;
1799
+ type schema_CustomerPlan = CustomerPlan;
1800
+ type schema_NewCustomerAccessStatus = NewCustomerAccessStatus;
1801
+ type schema_NewCustomerBillingCycle = NewCustomerBillingCycle;
1802
+ type schema_NewCustomerPlan = NewCustomerPlan;
1803
+ type schema_NewPlan = NewPlan;
1804
+ type schema_NewPlanFeature = NewPlanFeature;
1805
+ type schema_NewUsageAggregate = NewUsageAggregate;
1806
+ type schema_NewUsageAlert = NewUsageAlert;
1807
+ type schema_NewUsageEvent = NewUsageEvent;
1808
+ type schema_Plan = Plan;
1809
+ type schema_PlanFeature = PlanFeature;
1810
+ type schema_UsageAggregateRow = UsageAggregateRow;
1811
+ type schema_UsageAlertRow = UsageAlertRow;
1812
+ type schema_UsageEventRow = UsageEventRow;
1813
+ declare const schema_customerAccessStatus: typeof customerAccessStatus;
1814
+ declare const schema_customerBillingCycles: typeof customerBillingCycles;
1815
+ declare const schema_customerPlans: typeof customerPlans;
1816
+ declare const schema_planFeatures: typeof planFeatures;
1817
+ declare const schema_plans: typeof plans;
1818
+ declare const schema_usageAggregates: typeof usageAggregates;
1819
+ declare const schema_usageAlerts: typeof usageAlerts;
1820
+ declare const schema_usageEvents: typeof usageEvents;
1821
+ declare namespace schema {
1822
+ export { type schema_CustomerAccessStatusRow as CustomerAccessStatusRow, type schema_CustomerBillingCycle as CustomerBillingCycle, type schema_CustomerPlan as CustomerPlan, type schema_NewCustomerAccessStatus as NewCustomerAccessStatus, type schema_NewCustomerBillingCycle as NewCustomerBillingCycle, type schema_NewCustomerPlan as NewCustomerPlan, type schema_NewPlan as NewPlan, type schema_NewPlanFeature as NewPlanFeature, type schema_NewUsageAggregate as NewUsageAggregate, type schema_NewUsageAlert as NewUsageAlert, type schema_NewUsageEvent as NewUsageEvent, type schema_Plan as Plan, type schema_PlanFeature as PlanFeature, type schema_UsageAggregateRow as UsageAggregateRow, type schema_UsageAlertRow as UsageAlertRow, type schema_UsageEventRow as UsageEventRow, schema_customerAccessStatus as customerAccessStatus, schema_customerBillingCycles as customerBillingCycles, schema_customerPlans as customerPlans, schema_planFeatures as planFeatures, schema_plans as plans, schema_usageAggregates as usageAggregates, schema_usageAlerts as usageAlerts, schema_usageEvents as usageEvents };
1823
+ }
1824
+
1825
+ /**
1826
+ * @parsrun/payments - Quota Manager
1827
+ * Handles quota checking and enforcement
1828
+ */
1829
+
1830
+ /**
1831
+ * Quota Manager
1832
+ * Handles checking and enforcing usage quotas
1833
+ */
1834
+ declare class QuotaManager {
1835
+ private readonly storage;
1836
+ private readonly logger;
1837
+ private readonly softLimits;
1838
+ private readonly gracePercent;
1839
+ private readonly overageAllowedFeatures;
1840
+ private readonly onOverage?;
1841
+ constructor(config: QuotaManagerConfig);
1842
+ /**
1843
+ * Check if overage is allowed for a feature
1844
+ */
1845
+ private isOverageAllowed;
1846
+ /**
1847
+ * Check if quota allows the requested quantity
1848
+ */
1849
+ checkQuota(customerId: string, featureKey: string, requestedQuantity?: number): Promise<QuotaCheckResult>;
1850
+ /**
1851
+ * Enforce quota - throws if exceeded
1852
+ */
1853
+ enforceQuota(customerId: string, featureKey: string, requestedQuantity?: number): Promise<void>;
1854
+ /**
1855
+ * Get quota status for a feature
1856
+ */
1857
+ getQuotaStatus(customerId: string, featureKey: string): Promise<QuotaStatus>;
1858
+ /**
1859
+ * Get all quota statuses for a customer
1860
+ */
1861
+ getAllQuotas(customerId: string): Promise<QuotaStatus[]>;
1862
+ /**
1863
+ * Check if any quota is exceeded
1864
+ */
1865
+ hasExceededQuotas(customerId: string): Promise<boolean>;
1866
+ /**
1867
+ * Get exceeded quotas
1868
+ */
1869
+ getExceededQuotas(customerId: string): Promise<QuotaStatus[]>;
1870
+ }
1871
+ /**
1872
+ * Create quota manager
1873
+ */
1874
+ declare function createQuotaManager(config: QuotaManagerConfig): QuotaManager;
1875
+
1876
+ /**
1877
+ * @parsrun/payments - Usage Tracker
1878
+ * Handles recording and tracking usage events
1879
+ */
1880
+
1881
+ /**
1882
+ * Usage tracker configuration
1883
+ */
1884
+ interface UsageTrackerConfig {
1885
+ storage: UsageStorage;
1886
+ logger?: BillingLogger;
1887
+ /** Update aggregates immediately on each event (default: true) */
1888
+ aggregateOnRecord?: boolean;
1889
+ /** Alert thresholds as percentages (default: [80, 100]) */
1890
+ alertThresholds?: number[];
1891
+ /** Callback when threshold is reached */
1892
+ onThresholdReached?: (alert: UsageAlert) => void | Promise<void>;
1893
+ }
1894
+ /**
1895
+ * Usage Tracker
1896
+ * Records usage events and maintains aggregates
1897
+ */
1898
+ declare class UsageTracker {
1899
+ private readonly storage;
1900
+ private readonly logger;
1901
+ private readonly aggregateOnRecord;
1902
+ private readonly alertThresholds;
1903
+ private readonly onThresholdReached?;
1904
+ constructor(config: UsageTrackerConfig);
1905
+ /**
1906
+ * Track a usage event
1907
+ */
1908
+ trackUsage(options: TrackUsageOptions): Promise<UsageEvent>;
1909
+ /**
1910
+ * Track multiple usage events
1911
+ */
1912
+ trackBatch(events: TrackUsageOptions[]): Promise<UsageEvent[]>;
1913
+ /**
1914
+ * Update aggregates for an event
1915
+ */
1916
+ private updateAggregates;
1917
+ /**
1918
+ * Check thresholds and create alerts if needed
1919
+ */
1920
+ private checkThresholds;
1921
+ /**
1922
+ * Get usage for a customer
1923
+ */
1924
+ getUsage(customerId: string, featureKey: string, periodType?: PeriodType): Promise<number>;
1925
+ /**
1926
+ * Get usage aggregates
1927
+ */
1928
+ getAggregates(customerId: string, featureKey: string, periodType: PeriodType, startDate?: Date, endDate?: Date): Promise<UsageAggregate[]>;
1929
+ /**
1930
+ * Force aggregate recalculation for a period
1931
+ */
1932
+ recalculateAggregates(customerId: string, featureKey: string, periodType: PeriodType, periodStart: Date): Promise<UsageAggregate>;
1933
+ }
1934
+ /**
1935
+ * Create usage tracker
1936
+ */
1937
+ declare function createUsageTracker(config: UsageTrackerConfig): UsageTracker;
1938
+
1939
+ /**
1940
+ * @parsrun/payments - Subscription Lifecycle Hooks
1941
+ * Event-driven subscription lifecycle management
1942
+ */
1943
+
1944
+ /**
1945
+ * Subscription Lifecycle
1946
+ * Manages subscription event handlers
1947
+ */
1948
+ declare class SubscriptionLifecycle {
1949
+ private readonly handlers;
1950
+ private readonly logger;
1951
+ constructor(logger?: BillingLogger);
1952
+ /**
1953
+ * Register an event handler
1954
+ */
1955
+ on(event: SubscriptionEventType | "*", handler: SubscriptionHandler): this;
1956
+ /**
1957
+ * Remove an event handler
1958
+ */
1959
+ off(event: SubscriptionEventType | "*", handler: SubscriptionHandler): this;
1960
+ /**
1961
+ * Emit an event to all handlers
1962
+ */
1963
+ emit(event: SubscriptionEvent): Promise<void>;
1964
+ /**
1965
+ * Check if there are handlers for an event
1966
+ */
1967
+ hasHandlers(event: SubscriptionEventType | "*"): boolean;
1968
+ /**
1969
+ * Get handler count for an event
1970
+ */
1971
+ handlerCount(event: SubscriptionEventType | "*"): number;
1972
+ /**
1973
+ * Clear all handlers
1974
+ */
1975
+ clear(): void;
1976
+ /**
1977
+ * Handle subscription created
1978
+ */
1979
+ onCreated(handler: SubscriptionHandler): this;
1980
+ /**
1981
+ * Handle subscription activated
1982
+ */
1983
+ onActivated(handler: SubscriptionHandler): this;
1984
+ /**
1985
+ * Handle subscription updated
1986
+ */
1987
+ onUpdated(handler: SubscriptionHandler): this;
1988
+ /**
1989
+ * Handle plan changed
1990
+ */
1991
+ onPlanChanged(handler: SubscriptionHandler): this;
1992
+ /**
1993
+ * Handle subscription canceled
1994
+ */
1995
+ onCanceled(handler: SubscriptionHandler): this;
1996
+ /**
1997
+ * Handle subscription expired
1998
+ */
1999
+ onExpired(handler: SubscriptionHandler): this;
2000
+ /**
2001
+ * Handle subscription renewed
2002
+ */
2003
+ onRenewed(handler: SubscriptionHandler): this;
2004
+ /**
2005
+ * Handle trial started
2006
+ */
2007
+ onTrialStarted(handler: SubscriptionHandler): this;
2008
+ /**
2009
+ * Handle trial ended
2010
+ */
2011
+ onTrialEnded(handler: SubscriptionHandler): this;
2012
+ /**
2013
+ * Handle payment failed
2014
+ */
2015
+ onPaymentFailed(handler: SubscriptionHandler): this;
2016
+ /**
2017
+ * Handle payment succeeded
2018
+ */
2019
+ onPaymentSucceeded(handler: SubscriptionHandler): this;
2020
+ /**
2021
+ * Handle period reset
2022
+ */
2023
+ onPeriodReset(handler: SubscriptionHandler): this;
2024
+ /**
2025
+ * Handle all events
2026
+ */
2027
+ onAll(handler: SubscriptionHandler): this;
2028
+ }
2029
+ /**
2030
+ * Create subscription lifecycle manager
2031
+ */
2032
+ declare function createSubscriptionLifecycle(logger?: BillingLogger): SubscriptionLifecycle;
2033
+
2034
+ /**
2035
+ * Usage Service
2036
+ *
2037
+ * High-level API for usage-based billing:
2038
+ * - Track usage events
2039
+ * - Check and enforce quotas
2040
+ * - Manage subscription lifecycle
2041
+ * - Generate usage reports
2042
+ *
2043
+ * @example
2044
+ * ```typescript
2045
+ * const usageService = createUsageService({
2046
+ * storage: createMemoryUsageStorage(),
2047
+ * alertThresholds: [80, 100],
2048
+ * onThresholdReached: async (alert) => {
2049
+ * await sendEmail(alert.customerId, "usage-warning");
2050
+ * },
2051
+ * });
2052
+ *
2053
+ * // Track usage
2054
+ * await usageService.trackUsage({
2055
+ * tenantId: "tenant_123",
2056
+ * customerId: "cus_456",
2057
+ * featureKey: "api_calls",
2058
+ * quantity: 1,
2059
+ * });
2060
+ *
2061
+ * // Check quota
2062
+ * const quota = await usageService.getQuotaStatus("cus_456", "api_calls");
2063
+ * if (quota.isExceeded) {
2064
+ * throw new Error("Quota exceeded");
2065
+ * }
2066
+ *
2067
+ * // Lifecycle hooks
2068
+ * usageService.onPlanChanged(async (event) => {
2069
+ * console.log(`Plan changed from ${event.previousPlan?.name} to ${event.newPlan?.name}`);
2070
+ * });
2071
+ * ```
2072
+ */
2073
+ declare class UsageService {
2074
+ private readonly storage;
2075
+ private readonly logger;
2076
+ private readonly quotaManager;
2077
+ private readonly usageTracker;
2078
+ private readonly lifecycle;
2079
+ private readonly limitExceededHandler?;
2080
+ private readonly resetPeriod;
2081
+ private readonly autoResetOnRenewal;
2082
+ private readonly paymentGraceDays;
2083
+ private readonly maxFailedPayments;
2084
+ private readonly accessStatusChangedHandler?;
2085
+ private readonly periodResetHandler?;
2086
+ constructor(config: UsageServiceConfig);
2087
+ /**
2088
+ * Track a usage event
2089
+ */
2090
+ trackUsage(options: TrackUsageOptions): Promise<UsageEvent>;
2091
+ /**
2092
+ * Track multiple usage events
2093
+ */
2094
+ trackBatch(events: TrackUsageOptions[]): Promise<UsageEvent[]>;
2095
+ /**
2096
+ * Get current usage for a feature
2097
+ */
2098
+ getUsage(customerId: string, featureKey: string, periodType?: PeriodType): Promise<number>;
2099
+ /**
2100
+ * Get usage aggregates
2101
+ */
2102
+ getAggregates(customerId: string, options?: GetUsageOptions): Promise<UsageAggregate[]>;
2103
+ /**
2104
+ * Check if quota allows the requested quantity
2105
+ */
2106
+ checkQuota(customerId: string, featureKey: string, quantity?: number): Promise<QuotaCheckResult>;
2107
+ /**
2108
+ * Enforce quota - throws if exceeded
2109
+ */
2110
+ enforceQuota(customerId: string, featureKey: string, quantity?: number): Promise<void>;
2111
+ /**
2112
+ * Get quota status for a feature
2113
+ */
2114
+ getQuotaStatus(customerId: string, featureKey: string): Promise<QuotaStatus>;
2115
+ /**
2116
+ * Get all quota statuses for a customer
2117
+ */
2118
+ getAllQuotas(customerId: string): Promise<QuotaStatus[]>;
2119
+ /**
2120
+ * Check if any quota is exceeded
2121
+ */
2122
+ hasExceededQuotas(customerId: string): Promise<boolean>;
2123
+ /**
2124
+ * Get customer's current plan
2125
+ */
2126
+ getCustomerPlan(customerId: string): Promise<Plan$1 | null>;
2127
+ /**
2128
+ * Set customer's plan
2129
+ */
2130
+ setCustomerPlan(customerId: string, planId: string): Promise<void>;
2131
+ /**
2132
+ * Get plan by ID
2133
+ */
2134
+ getPlan(planId: string): Promise<Plan$1 | null>;
2135
+ /**
2136
+ * Get plan by name
2137
+ */
2138
+ getPlanByName(name: string): Promise<Plan$1 | null>;
2139
+ /**
2140
+ * List all plans
2141
+ */
2142
+ listPlans(options?: {
2143
+ activeOnly?: boolean;
2144
+ }): Promise<Plan$1[]>;
2145
+ /**
2146
+ * Get plan features
2147
+ */
2148
+ getPlanFeatures(planId: string): Promise<PlanFeature$1[]>;
2149
+ /**
2150
+ * Register a subscription event handler
2151
+ */
2152
+ on(event: SubscriptionEventType | "*", handler: SubscriptionHandler): this;
2153
+ /**
2154
+ * Remove a subscription event handler
2155
+ */
2156
+ off(event: SubscriptionEventType | "*", handler: SubscriptionHandler): this;
2157
+ /**
2158
+ * Handle subscription created
2159
+ */
2160
+ onSubscriptionCreated(handler: SubscriptionHandler): this;
2161
+ /**
2162
+ * Handle subscription updated
2163
+ */
2164
+ onSubscriptionUpdated(handler: SubscriptionHandler): this;
2165
+ /**
2166
+ * Handle subscription canceled
2167
+ */
2168
+ onSubscriptionCanceled(handler: SubscriptionHandler): this;
2169
+ /**
2170
+ * Handle plan changed
2171
+ */
2172
+ onPlanChanged(handler: SubscriptionHandler): this;
2173
+ /**
2174
+ * Handle subscription renewed
2175
+ */
2176
+ onRenewed(handler: SubscriptionHandler): this;
2177
+ /**
2178
+ * Handle payment failed
2179
+ */
2180
+ onPaymentFailed(handler: SubscriptionHandler): this;
2181
+ /**
2182
+ * Handle period reset
2183
+ */
2184
+ onPeriodReset(handler: SubscriptionHandler): this;
2185
+ /**
2186
+ * Get the lifecycle manager for advanced usage
2187
+ */
2188
+ get lifecycleManager(): SubscriptionLifecycle;
2189
+ /**
2190
+ * Get active alerts for a customer
2191
+ */
2192
+ getActiveAlerts(customerId: string): Promise<UsageAlert[]>;
2193
+ /**
2194
+ * Acknowledge an alert
2195
+ */
2196
+ acknowledgeAlert(alertId: string): Promise<void>;
2197
+ /**
2198
+ * Resolve an alert
2199
+ */
2200
+ resolveAlert(alertId: string): Promise<void>;
2201
+ /**
2202
+ * Reset usage for a customer
2203
+ * Typically called on subscription renewal
2204
+ */
2205
+ resetUsage(customerId: string, featureKeys?: string[]): Promise<void>;
2206
+ /**
2207
+ * Get the period start date based on reset period setting
2208
+ */
2209
+ private getResetPeriodStart;
2210
+ /**
2211
+ * Get feature keys for a customer's plan
2212
+ */
2213
+ private getCustomerFeatureKeys;
2214
+ /**
2215
+ * Check if auto-reset on renewal is enabled
2216
+ */
2217
+ get autoResetEnabled(): boolean;
2218
+ /**
2219
+ * Get current reset period setting
2220
+ */
2221
+ get currentResetPeriod(): ResetPeriod;
2222
+ /**
2223
+ * Get customer access status
2224
+ */
2225
+ getAccessStatus(customerId: string): Promise<AccessStatusInfo>;
2226
+ /**
2227
+ * Set customer access status
2228
+ */
2229
+ setAccessStatus(customerId: string, status: AccessStatus, options?: {
2230
+ reason?: string;
2231
+ suspensionDate?: Date;
2232
+ failedPaymentAttempts?: number;
2233
+ gracePeriodEnd?: Date;
2234
+ }): Promise<void>;
2235
+ /**
2236
+ * Handle payment failure - update access status
2237
+ */
2238
+ handlePaymentFailure(customerId: string): Promise<void>;
2239
+ /**
2240
+ * Handle successful payment - restore access status
2241
+ */
2242
+ handlePaymentSuccess(customerId: string): Promise<void>;
2243
+ /**
2244
+ * Check if customer has access (not suspended/canceled)
2245
+ */
2246
+ hasAccess(customerId: string): Promise<boolean>;
2247
+ /**
2248
+ * Check if customer is in grace period
2249
+ */
2250
+ isInGracePeriod(customerId: string): Promise<boolean>;
2251
+ /**
2252
+ * Set customer billing cycle
2253
+ */
2254
+ setBillingCycle(customerId: string, start: Date, end: Date): Promise<void>;
2255
+ /**
2256
+ * Get customer billing cycle
2257
+ */
2258
+ getBillingCycle(customerId: string): Promise<{
2259
+ start: Date;
2260
+ end: Date;
2261
+ } | null>;
2262
+ /**
2263
+ * Get the underlying storage
2264
+ */
2265
+ get storageBackend(): UsageStorage;
2266
+ /**
2267
+ * Get the quota manager
2268
+ */
2269
+ get quotas(): QuotaManager;
2270
+ /**
2271
+ * Get the usage tracker
2272
+ */
2273
+ get tracker(): UsageTracker;
2274
+ }
2275
+ /**
2276
+ * Create usage service
2277
+ */
2278
+ declare function createUsageService(config: UsageServiceConfig): UsageService;
2279
+
2280
+ /**
2281
+ * @parsrun/payments - Billing Integration
2282
+ * Connects BillingService webhooks to UsageService lifecycle
2283
+ */
2284
+
2285
+ /**
2286
+ * Billing integration configuration
2287
+ */
2288
+ interface BillingIntegrationConfig {
2289
+ /** Billing service instance */
2290
+ billing: BillingService;
2291
+ /** Usage service instance */
2292
+ usage: UsageService;
2293
+ /** Logger */
2294
+ logger?: BillingLogger;
2295
+ /** Auto-initialize customer plan on subscription creation */
2296
+ autoInitializePlan?: boolean;
2297
+ /**
2298
+ * Auto-reset quotas on subscription renewal
2299
+ * Default: true (uses UsageService.autoResetOnRenewal setting)
2300
+ */
2301
+ autoResetOnRenewal?: boolean;
2302
+ /**
2303
+ * Auto-update access status based on payment events
2304
+ * Default: true
2305
+ */
2306
+ autoManageAccessStatus?: boolean;
2307
+ /** Plan ID resolver - maps payment provider price IDs to internal plan IDs */
2308
+ resolvePlanId?: (priceId: string, provider: PaymentProviderType) => string | Promise<string>;
2309
+ /** Custom event handlers */
2310
+ onSubscriptionCreated?: (event: SubscriptionEvent) => void | Promise<void>;
2311
+ onSubscriptionCanceled?: (event: SubscriptionEvent) => void | Promise<void>;
2312
+ onSubscriptionRenewed?: (event: SubscriptionEvent) => void | Promise<void>;
2313
+ onPlanChanged?: (event: SubscriptionEvent) => void | Promise<void>;
2314
+ onPaymentFailed?: (event: SubscriptionEvent) => void | Promise<void>;
2315
+ }
2316
+ /**
2317
+ * Billing Integration
2318
+ *
2319
+ * Connects BillingService webhooks to UsageService lifecycle events.
2320
+ * This enables automatic:
2321
+ * - Customer plan initialization on subscription creation
2322
+ * - Plan updates when subscription changes
2323
+ * - Usage reset on subscription renewal
2324
+ * - Lifecycle event emission
2325
+ *
2326
+ * @example
2327
+ * ```typescript
2328
+ * import { createBillingService, createUsageService, integrateBillingWithUsage } from "@parsrun/payments";
2329
+ *
2330
+ * const billing = createBillingService({
2331
+ * providers: { default: stripeProvider },
2332
+ * });
2333
+ *
2334
+ * const usage = createUsageService({
2335
+ * storage: createMemoryUsageStorage(),
2336
+ * });
2337
+ *
2338
+ * // Connect them
2339
+ * const integration = integrateBillingWithUsage({
2340
+ * billing,
2341
+ * usage,
2342
+ * autoInitializePlan: true,
2343
+ * resolvePlanId: (priceId) => {
2344
+ * // Map Stripe price IDs to your internal plan IDs
2345
+ * const mapping: Record<string, string> = {
2346
+ * "price_starter": "starter",
2347
+ * "price_pro": "pro",
2348
+ * "price_enterprise": "enterprise",
2349
+ * };
2350
+ * return mapping[priceId] ?? "free";
2351
+ * },
2352
+ * });
2353
+ *
2354
+ * // Now subscription webhooks automatically update usage quotas
2355
+ * ```
2356
+ */
2357
+ declare class BillingIntegration {
2358
+ private readonly billing;
2359
+ private readonly usage;
2360
+ private readonly logger;
2361
+ private readonly autoInitializePlan;
2362
+ private readonly autoResetOnRenewal;
2363
+ private readonly autoManageAccessStatus;
2364
+ private readonly resolvePlanId;
2365
+ private readonly config;
2366
+ constructor(config: BillingIntegrationConfig);
2367
+ /**
2368
+ * Setup webhook handlers on billing service
2369
+ */
2370
+ private setupWebhookHandlers;
2371
+ /**
2372
+ * Handle subscription created webhook
2373
+ */
2374
+ private handleSubscriptionCreated;
2375
+ /**
2376
+ * Handle subscription updated webhook
2377
+ */
2378
+ private handleSubscriptionUpdated;
2379
+ /**
2380
+ * Handle subscription canceled webhook
2381
+ */
2382
+ private handleSubscriptionCanceled;
2383
+ /**
2384
+ * Handle invoice paid webhook (renewal)
2385
+ */
2386
+ private handleInvoicePaid;
2387
+ /**
2388
+ * Handle payment failed webhook
2389
+ */
2390
+ private handlePaymentFailed;
2391
+ /**
2392
+ * Manually sync customer plan from billing provider
2393
+ */
2394
+ syncCustomerPlan(customerId: string, provider?: PaymentProviderType): Promise<Plan$1 | null>;
2395
+ }
2396
+ /**
2397
+ * Create billing integration
2398
+ *
2399
+ * Connects BillingService webhooks to UsageService lifecycle events.
2400
+ *
2401
+ * @example
2402
+ * ```typescript
2403
+ * const integration = integrateBillingWithUsage({
2404
+ * billing,
2405
+ * usage,
2406
+ * autoInitializePlan: true,
2407
+ * resolvePlanId: (priceId) => priceMapping[priceId] ?? "free",
2408
+ * });
2409
+ * ```
2410
+ */
2411
+ declare function integrateBillingWithUsage(config: BillingIntegrationConfig): BillingIntegration;
2412
+ /**
2413
+ * Alias for integrateBillingWithUsage
2414
+ */
2415
+ declare const createBillingIntegration: typeof integrateBillingWithUsage;
2416
+
2417
+ /**
2418
+ * @parsrun/payments - Usage Meter
2419
+ * Buffers usage events and syncs to payment provider
2420
+ *
2421
+ * This solves the problem of:
2422
+ * - Not hitting provider API limits with per-request calls
2423
+ * - Reducing latency by batching usage reports
2424
+ * - Ensuring reliable usage reporting with retry logic
2425
+ */
2426
+
2427
+ /**
2428
+ * Usage record to report to provider
2429
+ */
2430
+ interface UsageRecord {
2431
+ /** Subscription item ID (Stripe) or subscription ID (Paddle) */
2432
+ subscriptionItemId: string;
2433
+ /** Usage quantity */
2434
+ quantity: number;
2435
+ /** Timestamp of usage (defaults to now) */
2436
+ timestamp?: Date;
2437
+ /** Action: increment (add to existing) or set (replace) */
2438
+ action?: "increment" | "set";
2439
+ /** Idempotency key to prevent duplicates */
2440
+ idempotencyKey?: string;
2441
+ }
2442
+ /**
2443
+ * Buffered usage record with metadata
2444
+ */
2445
+ interface BufferedRecord {
2446
+ record: UsageRecord;
2447
+ customerId: string;
2448
+ featureKey: string;
2449
+ addedAt: Date;
2450
+ attempts: number;
2451
+ }
2452
+ /**
2453
+ * Usage reporter interface - implemented by providers
2454
+ */
2455
+ interface UsageReporter {
2456
+ /**
2457
+ * Report usage to the payment provider
2458
+ */
2459
+ reportUsage(record: UsageRecord): Promise<void>;
2460
+ /**
2461
+ * Report multiple usage records (batch)
2462
+ */
2463
+ reportUsageBatch?(records: UsageRecord[]): Promise<void>;
2464
+ /**
2465
+ * Get subscription item ID for a subscription and price
2466
+ */
2467
+ getSubscriptionItemId?(subscriptionId: string, priceId: string): Promise<string | null>;
2468
+ }
2469
+ /**
2470
+ * Sync strategy configuration
2471
+ */
2472
+ type SyncStrategy = {
2473
+ type: "interval";
2474
+ intervalMs: number;
2475
+ } | {
2476
+ type: "threshold";
2477
+ maxRecords: number;
2478
+ maxAgeMs: number;
2479
+ } | {
2480
+ type: "manual";
2481
+ };
2482
+ /**
2483
+ * Usage meter configuration
2484
+ */
2485
+ interface UsageMeterConfig {
2486
+ /** Usage reporter (provider with reportUsage method) */
2487
+ reporter: UsageReporter;
2488
+ /** Provider type for logging */
2489
+ providerType: PaymentProviderType;
2490
+ /** Sync strategy */
2491
+ strategy: SyncStrategy;
2492
+ /** Logger */
2493
+ logger?: BillingLogger;
2494
+ /** Max retry attempts for failed syncs */
2495
+ maxRetries?: number;
2496
+ /** Retry delay in ms */
2497
+ retryDelayMs?: number;
2498
+ /** Callback on successful sync */
2499
+ onSyncSuccess?: (count: number) => void;
2500
+ /** Callback on sync failure */
2501
+ onSyncError?: (error: Error, records: BufferedRecord[]) => void;
2502
+ /** Callback when buffer is getting full (>80%) */
2503
+ onBufferWarning?: (size: number, maxSize: number) => void;
2504
+ /** Maximum buffer size before forcing sync */
2505
+ maxBufferSize?: number;
2506
+ }
2507
+ /**
2508
+ * Usage Meter
2509
+ *
2510
+ * Buffers usage events and syncs to payment provider periodically.
2511
+ * Supports multiple sync strategies:
2512
+ * - interval: Sync every N milliseconds
2513
+ * - threshold: Sync when buffer reaches N records or records are older than N ms
2514
+ * - manual: Only sync when explicitly called
2515
+ *
2516
+ * @example
2517
+ * ```typescript
2518
+ * import { createUsageMeter } from "@parsrun/payments";
2519
+ *
2520
+ * const meter = createUsageMeter({
2521
+ * reporter: stripeProvider, // Provider must implement UsageReporter
2522
+ * providerType: "stripe",
2523
+ * strategy: { type: "interval", intervalMs: 60000 }, // Sync every minute
2524
+ * });
2525
+ *
2526
+ * // Record usage (buffered, not sent immediately)
2527
+ * meter.record({
2528
+ * customerId: "cus_123",
2529
+ * featureKey: "api_calls",
2530
+ * subscriptionItemId: "si_xxx",
2531
+ * quantity: 1,
2532
+ * });
2533
+ *
2534
+ * // Force immediate sync
2535
+ * await meter.flush();
2536
+ *
2537
+ * // Cleanup when done
2538
+ * meter.stop();
2539
+ * ```
2540
+ */
2541
+ declare class UsageMeter {
2542
+ private readonly reporter;
2543
+ private readonly providerType;
2544
+ private readonly logger;
2545
+ private readonly strategy;
2546
+ private readonly maxRetries;
2547
+ private readonly retryDelayMs;
2548
+ private readonly maxBufferSize;
2549
+ private readonly config;
2550
+ private buffer;
2551
+ private intervalId;
2552
+ private isSyncing;
2553
+ private isRunning;
2554
+ constructor(config: UsageMeterConfig);
2555
+ /**
2556
+ * Start the meter (auto-sync based on strategy)
2557
+ */
2558
+ start(): void;
2559
+ /**
2560
+ * Stop the meter
2561
+ */
2562
+ stop(): void;
2563
+ /**
2564
+ * Record usage (buffered)
2565
+ */
2566
+ record(options: {
2567
+ customerId: string;
2568
+ featureKey: string;
2569
+ subscriptionItemId: string;
2570
+ quantity: number;
2571
+ timestamp?: Date;
2572
+ action?: "increment" | "set";
2573
+ idempotencyKey?: string;
2574
+ }): void;
2575
+ /**
2576
+ * Check threshold and trigger sync if needed
2577
+ */
2578
+ private checkThreshold;
2579
+ /**
2580
+ * Flush buffer to provider
2581
+ */
2582
+ flush(): Promise<number>;
2583
+ /**
2584
+ * Aggregate records by subscription item ID
2585
+ */
2586
+ private aggregateRecords;
2587
+ /**
2588
+ * Sync single record with retry
2589
+ */
2590
+ private syncWithRetry;
2591
+ /**
2592
+ * Delay helper
2593
+ */
2594
+ private delay;
2595
+ /**
2596
+ * Get buffer size
2597
+ */
2598
+ get bufferSize(): number;
2599
+ /**
2600
+ * Get sync status
2601
+ */
2602
+ get syncing(): boolean;
2603
+ /**
2604
+ * Get running status
2605
+ */
2606
+ get running(): boolean;
2607
+ /**
2608
+ * Get buffer contents (for debugging)
2609
+ */
2610
+ getBuffer(): ReadonlyArray<BufferedRecord>;
2611
+ }
2612
+ /**
2613
+ * Create usage meter
2614
+ */
2615
+ declare function createUsageMeter(config: UsageMeterConfig): UsageMeter;
2616
+ /**
2617
+ * Subscription item mapping
2618
+ * Maps (customerId, featureKey) to subscriptionItemId
2619
+ */
2620
+ interface SubscriptionItemMapping {
2621
+ customerId: string;
2622
+ featureKey: string;
2623
+ subscriptionId: string;
2624
+ subscriptionItemId: string;
2625
+ priceId: string;
2626
+ createdAt: Date;
2627
+ }
2628
+ /**
2629
+ * Subscription item resolver configuration
2630
+ */
2631
+ interface SubscriptionItemResolverConfig {
2632
+ /** Reporter to fetch subscription items */
2633
+ reporter: UsageReporter;
2634
+ /** Cache TTL in ms (default: 1 hour) */
2635
+ cacheTtlMs?: number;
2636
+ /** Logger */
2637
+ logger?: BillingLogger;
2638
+ }
2639
+ /**
2640
+ * Subscription Item Resolver
2641
+ *
2642
+ * Resolves and caches subscription item IDs.
2643
+ * Stripe requires subscription_item_id for metered billing,
2644
+ * this resolver handles the lookup and caching.
2645
+ */
2646
+ declare class SubscriptionItemResolver {
2647
+ private readonly reporter;
2648
+ private readonly cacheTtlMs;
2649
+ private readonly logger;
2650
+ private cache;
2651
+ constructor(config: SubscriptionItemResolverConfig);
2652
+ /**
2653
+ * Get subscription item ID
2654
+ */
2655
+ resolve(subscriptionId: string, priceId: string): Promise<string | null>;
2656
+ /**
2657
+ * Set cache entry manually (useful when creating subscriptions)
2658
+ */
2659
+ setCache(subscriptionId: string, priceId: string, itemId: string): void;
2660
+ /**
2661
+ * Clear cache
2662
+ */
2663
+ clearCache(): void;
2664
+ /**
2665
+ * Get cache size
2666
+ */
2667
+ get cacheSize(): number;
2668
+ }
2669
+ /**
2670
+ * Create subscription item resolver
2671
+ */
2672
+ declare function createSubscriptionItemResolver(config: SubscriptionItemResolverConfig): SubscriptionItemResolver;
2673
+
2674
+ export { type AccessStatus, type AccessStatusInfo, type AlertStatus, BillingIntegration, type BillingIntegrationConfig, type BillingInterval, type BillingLogger, type DrizzleDb, DrizzleUsageStorage, type DrizzleUsageStorageConfig, type GetUsageOptions, type LimitPeriod, MemoryUsageStorage, type PeriodType, type Plan$1 as Plan, type PlanFeature$1 as PlanFeature, type PlanTier, type QuotaCheckResult, QuotaExceededError, QuotaManager, type QuotaManagerConfig, type QuotaStatus, type ResetPeriod, type SubscriptionEvent, type SubscriptionEventType, type SubscriptionHandler, type SubscriptionItemMapping, SubscriptionItemResolver, type SubscriptionItemResolverConfig, SubscriptionLifecycle, type SyncStrategy, type TrackUsageOptions, type UsageAggregate, type UsageAlert, UsageError, type UsageErrorCode, UsageErrorCodes, type UsageEvent, UsageMeter, type UsageMeterConfig, type UsageRecord, type UsageReporter, UsageService, type UsageServiceConfig, type UsageStorage, UsageTracker, type UsageTrackerConfig, type UsageWebhookEventType, createBillingIntegration, createDrizzleUsageStorage, createMemoryUsageStorage, createQuotaManager, createSubscriptionItemResolver, createSubscriptionLifecycle, createUsageMeter, createUsageService, createUsageTracker, integrateBillingWithUsage, schema as usageSchema };