@happyvertical/smrt-subscriptions 0.30.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.
Files changed (59) hide show
  1. package/AGENTS.md +26 -0
  2. package/CLAUDE.md +1 -0
  3. package/LICENSE +7 -0
  4. package/dist/.tsbuildinfo +1 -0
  5. package/dist/__smrt-register__.d.ts +2 -0
  6. package/dist/__smrt-register__.d.ts.map +1 -0
  7. package/dist/collections/SubscriptionPlanCollection.d.ts +9 -0
  8. package/dist/collections/SubscriptionPlanCollection.d.ts.map +1 -0
  9. package/dist/collections/TenantSubscriptionCollection.d.ts +29 -0
  10. package/dist/collections/TenantSubscriptionCollection.d.ts.map +1 -0
  11. package/dist/collections/TenantUsageMetricCollection.d.ts +28 -0
  12. package/dist/collections/TenantUsageMetricCollection.d.ts.map +1 -0
  13. package/dist/collections/index.d.ts +4 -0
  14. package/dist/collections/index.d.ts.map +1 -0
  15. package/dist/index.d.ts +6 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +1271 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/manifest.json +1291 -0
  20. package/dist/models/SubscriptionPlan.d.ts +30 -0
  21. package/dist/models/SubscriptionPlan.d.ts.map +1 -0
  22. package/dist/models/TenantSubscription.d.ts +59 -0
  23. package/dist/models/TenantSubscription.d.ts.map +1 -0
  24. package/dist/models/TenantUsageMetric.d.ts +35 -0
  25. package/dist/models/TenantUsageMetric.d.ts.map +1 -0
  26. package/dist/models/index.d.ts +4 -0
  27. package/dist/models/index.d.ts.map +1 -0
  28. package/dist/services/index.d.ts +5 -0
  29. package/dist/services/index.d.ts.map +1 -0
  30. package/dist/services/subscription-resolver.d.ts +96 -0
  31. package/dist/services/subscription-resolver.d.ts.map +1 -0
  32. package/dist/services/threshold-evaluator.d.ts +4 -0
  33. package/dist/services/threshold-evaluator.d.ts.map +1 -0
  34. package/dist/services/usage-meter.d.ts +32 -0
  35. package/dist/services/usage-meter.d.ts.map +1 -0
  36. package/dist/smrt-knowledge.json +883 -0
  37. package/dist/svelte/PlanPicker.svelte +82 -0
  38. package/dist/svelte/PlanPicker.svelte.d.ts +10 -0
  39. package/dist/svelte/PlanPicker.svelte.d.ts.map +1 -0
  40. package/dist/svelte/SubscriptionSummary.svelte +65 -0
  41. package/dist/svelte/SubscriptionSummary.svelte.d.ts +8 -0
  42. package/dist/svelte/SubscriptionSummary.svelte.d.ts.map +1 -0
  43. package/dist/svelte/UsageThresholds.svelte +71 -0
  44. package/dist/svelte/UsageThresholds.svelte.d.ts +8 -0
  45. package/dist/svelte/UsageThresholds.svelte.d.ts.map +1 -0
  46. package/dist/svelte/i18n.d.ts +5 -0
  47. package/dist/svelte/i18n.d.ts.map +1 -0
  48. package/dist/svelte/i18n.js +9 -0
  49. package/dist/svelte/index.d.ts +4 -0
  50. package/dist/svelte/index.d.ts.map +1 -0
  51. package/dist/svelte/index.js +3 -0
  52. package/dist/types.d.ts +175 -0
  53. package/dist/types.d.ts.map +1 -0
  54. package/dist/types.js +2 -0
  55. package/dist/types.js.map +1 -0
  56. package/dist/utils.d.ts +59 -0
  57. package/dist/utils.d.ts.map +1 -0
  58. package/package.json +80 -0
  59. package/scripts/migrate-1454-drop-legacy-conflict-index.ts +110 -0
@@ -0,0 +1,30 @@
1
+ import { SmrtObject } from '@happyvertical/smrt-core';
2
+ import { BillingInterval, JsonObject, PlanFeatureGrant, PlanThreshold, SubscriptionPlanStatus } from '../types.js';
3
+ export declare class SubscriptionPlan extends SmrtObject {
4
+ tenantId: string | null;
5
+ planKey: string;
6
+ name: string;
7
+ description: string;
8
+ status: SubscriptionPlanStatus;
9
+ sortOrder: number;
10
+ priceAmount: number;
11
+ currency: string;
12
+ billingInterval: BillingInterval;
13
+ externalProvider: string;
14
+ stripeProductId: string;
15
+ stripePriceId: string;
16
+ features: string;
17
+ thresholds: string;
18
+ metadata: string;
19
+ constructor(options?: any);
20
+ isActive(): boolean;
21
+ getFeatureGrants(): PlanFeatureGrant[];
22
+ setFeatureGrants(grants: Array<string | PlanFeatureGrant>): void;
23
+ getFeatureKeys(): string[];
24
+ getThresholds(): PlanThreshold[];
25
+ setThresholds(thresholds: PlanThreshold[]): void;
26
+ getMetadata(): JsonObject;
27
+ setMetadata(metadata: JsonObject): void;
28
+ }
29
+ export default SubscriptionPlan;
30
+ //# sourceMappingURL=SubscriptionPlan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubscriptionPlan.d.ts","sourceRoot":"","sources":["../../src/models/SubscriptionPlan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAQ,MAAM,0BAA0B,CAAC;AAE5D,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,sBAAsB,EACvB,MAAM,aAAa,CAAC;AAQrB,qBAQa,gBAAiB,SAAQ,UAAU;IAE9C,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B,OAAO,EAAE,MAAM,CAAM;IACrB,IAAI,EAAE,MAAM,CAAM;IAClB,WAAW,EAAE,MAAM,CAAM;IACzB,MAAM,EAAE,sBAAsB,CAAY;IAC1C,SAAS,EAAE,MAAM,CAAK;IACtB,WAAW,EAAE,MAAM,CAAO;IAC1B,QAAQ,EAAE,MAAM,CAAS;IACzB,eAAe,EAAE,eAAe,CAAW;IAC3C,gBAAgB,EAAE,MAAM,CAAY;IACpC,eAAe,EAAE,MAAM,CAAM;IAC7B,aAAa,EAAE,MAAM,CAAM;IAC3B,QAAQ,EAAE,MAAM,CAAQ;IACxB,UAAU,EAAE,MAAM,CAAQ;IAC1B,QAAQ,EAAE,MAAM,CAAQ;gBAEZ,OAAO,GAAE,GAAQ;IA6B7B,QAAQ,IAAI,OAAO;IAInB,gBAAgB,IAAI,gBAAgB,EAAE;IAMtC,gBAAgB,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,gBAAgB,CAAC,GAAG,IAAI;IAIhE,cAAc,IAAI,MAAM,EAAE;IAM1B,aAAa,IAAI,aAAa,EAAE;IAMhC,aAAa,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,IAAI;IAIhD,WAAW,IAAI,UAAU;IAIzB,WAAW,CAAC,QAAQ,EAAE,UAAU,GAAG,IAAI;CAGxC;AAED,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,59 @@
1
+ import { SmrtObject } from '@happyvertical/smrt-core';
2
+ import { JsonObject, Subscriber, SubscriberKind, SubscriptionStatus } from '../types.js';
3
+ export declare class TenantSubscription extends SmrtObject {
4
+ tenantId?: string;
5
+ /**
6
+ * Discriminator for the subscriber identity.
7
+ *
8
+ * - `'tenant'` (default): the subscriber IS the owning `tenantId` — the
9
+ * pre-polymorphic shape. All existing rows continue to behave this way.
10
+ * - `'external'`: the subscriber is `subscriberExternalId`, scoped under the
11
+ * issuing `tenantId`. Used for B2C buyers, anonymous-email subscribers,
12
+ * agent identities, and any other caller-defined identity.
13
+ */
14
+ subscriberKind: SubscriberKind;
15
+ /**
16
+ * Caller-namespaced opaque identifier for the subscriber when
17
+ * `subscriberKind === 'external'`. Empty string when kind is `'tenant'`.
18
+ *
19
+ * The package treats this as opaque — no FK, no inferred semantics. Callers
20
+ * are expected to namespace (e.g. `buyer-contact:abc123`,
21
+ * `agent:hermes-7`, `email:foo@example.com`).
22
+ */
23
+ subscriberExternalId: string;
24
+ planId: string;
25
+ status: SubscriptionStatus;
26
+ startedAt: Date;
27
+ currentPeriodStart: Date | null;
28
+ currentPeriodEnd: Date | null;
29
+ trialEndsAt: Date | null;
30
+ cancelAtPeriodEnd: boolean;
31
+ canceledAt: Date | null;
32
+ externalProvider: string;
33
+ stripeCustomerId: string;
34
+ stripeSubscriptionId: string;
35
+ stripeCheckoutSessionId: string;
36
+ metadata: string;
37
+ constructor(options?: any);
38
+ /**
39
+ * Validates the subscriber XOR invariant before every save. Critical for the
40
+ * generated update path: `SmrtCollection.update()` mutates the existing
41
+ * instance via `Object.assign()` and calls `save()` directly — the
42
+ * constructor never re-runs, so without this hook a partial update like
43
+ * `{ subscriberExternalId: 'buyer:alice' }` on a tenant-kind row would
44
+ * persist a malformed conflict key and let two tenant-kind rows coexist
45
+ * under the same tenant.
46
+ */
47
+ protected validateBeforeSave(): Promise<void>;
48
+ isEntitled(now?: Date): boolean;
49
+ /**
50
+ * Project this row's polymorphic subscriber columns onto the
51
+ * {@link Subscriber} discriminated union. Returns `null` when the owning
52
+ * tenant is absent — that's an invalid row that should not be acted on.
53
+ */
54
+ getSubscriber(): Subscriber | null;
55
+ getMetadata(): JsonObject;
56
+ setMetadata(metadata: JsonObject): void;
57
+ }
58
+ export default TenantSubscription;
59
+ //# sourceMappingURL=TenantSubscription.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TenantSubscription.d.ts","sourceRoot":"","sources":["../../src/models/TenantSubscription.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,UAAU,EAAQ,MAAM,0BAA0B,CAAC;AAExE,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,cAAc,EACd,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAOrB,qBAwBa,kBAAmB,SAAQ,UAAU;IAEhD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;;;;OAQG;IACH,cAAc,EAAE,cAAc,CAAY;IAE1C;;;;;;;OAOG;IACH,oBAAoB,EAAE,MAAM,CAAM;IAGlC,MAAM,EAAE,MAAM,CAAM;IAEpB,MAAM,EAAE,kBAAkB,CAAgB;IAC1C,SAAS,EAAE,IAAI,CAAc;IAC7B,kBAAkB,EAAE,IAAI,GAAG,IAAI,CAAQ;IACvC,gBAAgB,EAAE,IAAI,GAAG,IAAI,CAAQ;IACrC,WAAW,EAAE,IAAI,GAAG,IAAI,CAAQ;IAChC,iBAAiB,EAAE,OAAO,CAAS;IACnC,UAAU,EAAE,IAAI,GAAG,IAAI,CAAQ;IAC/B,gBAAgB,EAAE,MAAM,CAAY;IACpC,gBAAgB,EAAE,MAAM,CAAM;IAC9B,oBAAoB,EAAE,MAAM,CAAM;IAClC,uBAAuB,EAAE,MAAM,CAAM;IACrC,QAAQ,EAAE,MAAM,CAAQ;gBAEZ,OAAO,GAAE,GAAQ;IA8C7B;;;;;;;;OAQG;cACa,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAQnD,UAAU,CAAC,GAAG,OAAa,GAAG,OAAO;IAarC;;;;OAIG;IACH,aAAa,IAAI,UAAU,GAAG,IAAI;IAiBlC,WAAW,IAAI,UAAU;IAIzB,WAAW,CAAC,QAAQ,EAAE,UAAU,GAAG,IAAI;CAGxC;AAED,eAAe,kBAAkB,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { SmrtObject } from '@happyvertical/smrt-core';
2
+ import { JsonObject, Subscriber, SubscriberKind } from '../types.js';
3
+ export declare class TenantUsageMetric extends SmrtObject {
4
+ tenantId?: string;
5
+ /**
6
+ * Discriminator for which subscriber identity recorded this usage.
7
+ * `'tenant'` (default) preserves the legacy shape; `'external'` indicates
8
+ * the subscriber is `subscriberExternalId` under the issuing `tenantId`.
9
+ */
10
+ subscriberKind: SubscriberKind;
11
+ /**
12
+ * Opaque caller-namespaced subscriber id when `subscriberKind === 'external'`.
13
+ * Empty string when kind is `'tenant'`.
14
+ */
15
+ subscriberExternalId: string;
16
+ metricKey: string;
17
+ quantity: number;
18
+ windowStart: Date;
19
+ windowEnd: Date;
20
+ source: string;
21
+ sourceId: string;
22
+ dimensions: string;
23
+ constructor(options?: any);
24
+ /** See `TenantSubscription.validateBeforeSave` for the rationale. */
25
+ protected validateBeforeSave(): Promise<void>;
26
+ /**
27
+ * Project this row's polymorphic subscriber columns onto the
28
+ * {@link Subscriber} discriminated union.
29
+ */
30
+ getSubscriber(): Subscriber | null;
31
+ getDimensions(): JsonObject;
32
+ setDimensions(dimensions: JsonObject): void;
33
+ }
34
+ export default TenantUsageMetric;
35
+ //# sourceMappingURL=TenantUsageMetric.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TenantUsageMetric.d.ts","sourceRoot":"","sources":["../../src/models/TenantUsageMetric.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAQ,MAAM,0BAA0B,CAAC;AAE5D,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAO1E,qBAOa,iBAAkB,SAAQ,UAAU;IAE/C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;OAIG;IACH,cAAc,EAAE,cAAc,CAAY;IAE1C;;;OAGG;IACH,oBAAoB,EAAE,MAAM,CAAM;IAElC,SAAS,EAAE,MAAM,CAAM;IACvB,QAAQ,EAAE,MAAM,CAAO;IACvB,WAAW,EAAE,IAAI,CAAc;IAC/B,SAAS,EAAE,IAAI,CAAc;IAC7B,MAAM,EAAE,MAAM,CAAM;IACpB,QAAQ,EAAE,MAAM,CAAM;IACtB,UAAU,EAAE,MAAM,CAAQ;gBAEd,OAAO,GAAE,GAAQ;IAuB7B,qEAAqE;cACrD,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAQnD;;;OAGG;IACH,aAAa,IAAI,UAAU,GAAG,IAAI;IAiBlC,aAAa,IAAI,UAAU;IAI3B,aAAa,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;CAG5C;AAED,eAAe,iBAAiB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { SubscriptionPlan } from './SubscriptionPlan.js';
2
+ export { TenantSubscription } from './TenantSubscription.js';
3
+ export { TenantUsageMetric } from './TenantUsageMetric.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export type { EntitlementResolutionContext } from '../types.js';
2
+ export { type SubscriptionPlanReader, SubscriptionResolver, type SubscriptionResolverReaders, type TenantSubscriptionReader, type UsageSummaryReader, } from './subscription-resolver.js';
3
+ export { evaluateThreshold, evaluateThresholds, } from './threshold-evaluator.js';
4
+ export { TenantUsageMeter } from './usage-meter.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EACL,KAAK,sBAAsB,EAC3B,oBAAoB,EACpB,KAAK,2BAA2B,EAChC,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,GACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,96 @@
1
+ import { SubscriptionPlan } from '../models/SubscriptionPlan.js';
2
+ import { TenantSubscription } from '../models/TenantSubscription.js';
3
+ import { EntitlementResolution, EntitlementResolutionContext, PlanThreshold, SmrtClassOptions, Subscriber, SubscriptionResolverOptions, UsageSummary, UsageWindow } from '../types.js';
4
+ export interface SubscriptionPlanReader {
5
+ get(criteria: {
6
+ id: string;
7
+ }): Promise<SubscriptionPlan | null>;
8
+ }
9
+ /**
10
+ * Reader contract for finding the current subscription for a subscriber.
11
+ *
12
+ * The legacy `findCurrentForTenant(tenantId)` signature stays for backward
13
+ * compatibility with the original tenant-only resolver. New implementations
14
+ * should provide `findCurrentForSubscriber(subscriber)` — it's preferred when
15
+ * present and lets the resolver work with both `'tenant'` and `'external'`
16
+ * subscribers without callers having to pre-narrow the discriminator.
17
+ */
18
+ export interface TenantSubscriptionReader {
19
+ findCurrentForTenant(tenantId: string, now?: Date): Promise<TenantSubscription | null>;
20
+ findCurrentForSubscriber?(subscriber: Subscriber, now?: Date): Promise<TenantSubscription | null>;
21
+ }
22
+ /**
23
+ * Reader contract for summarizing usage.
24
+ *
25
+ * `summarize(options)` already accepts the polymorphic
26
+ * `subscriberKind`/`subscriberExternalId` fields. When omitted the reader
27
+ * defaults to `'tenant'`, which is what existing callers got before this
28
+ * change — no behavior shift for them. The discriminator type is derived
29
+ * from `Subscriber['kind']` rather than inlined so any future additions to
30
+ * the union stay consistent across the package.
31
+ */
32
+ export interface UsageSummaryReader {
33
+ summarize(options: {
34
+ tenantId: string;
35
+ subscriberKind?: Subscriber['kind'];
36
+ subscriberExternalId?: string;
37
+ metricKey: string;
38
+ window: UsageWindow;
39
+ }): Promise<UsageSummary>;
40
+ summarizeBatch?(options: {
41
+ tenantId: string;
42
+ subscriberKind?: Subscriber['kind'];
43
+ subscriberExternalId?: string;
44
+ metricKeys: string[];
45
+ window: UsageWindow;
46
+ }): Promise<UsageSummary[]>;
47
+ }
48
+ export interface SubscriptionResolverReaders {
49
+ plans: SubscriptionPlanReader;
50
+ subscriptions: TenantSubscriptionReader;
51
+ usage: UsageSummaryReader;
52
+ }
53
+ export declare class SubscriptionResolver {
54
+ private readonly readers;
55
+ constructor(readers: SubscriptionResolverReaders);
56
+ /**
57
+ * Build the default resolver readers once for a request or app lifecycle and
58
+ * reuse the returned resolver across entitlement checks.
59
+ */
60
+ static create(classOptions?: SmrtClassOptions): Promise<SubscriptionResolver>;
61
+ /**
62
+ * Load the subscription/plan pair used by entitlement resolution. Callers
63
+ * that need both the entitlement snapshot and the backing records can load
64
+ * this once, then pass it back via `options.context`.
65
+ */
66
+ loadEntitlementContext(subscriberOrTenantId: Subscriber | string, options?: SubscriptionResolverOptions): Promise<EntitlementResolutionContext>;
67
+ /**
68
+ * Polymorphic entitlement resolution. Works for both `'tenant'`-kind and
69
+ * `'external'`-kind subscribers and is the preferred surface — the
70
+ * `resolveTenantEntitlements(tenantId)` method below is a thin wrapper.
71
+ */
72
+ resolveEntitlements(subscriber: Subscriber, options?: SubscriptionResolverOptions): Promise<EntitlementResolution>;
73
+ /**
74
+ * Legacy single-tenant wrapper around {@link resolveEntitlements}. Kept so
75
+ * existing tenant-only callers don't need to update their call sites.
76
+ */
77
+ resolveTenantEntitlements(tenantId: string, options?: SubscriptionResolverOptions): Promise<EntitlementResolution>;
78
+ isFeatureEnabled(subscriberOrTenantId: Subscriber | string, featureKey: string, options?: SubscriptionResolverOptions): Promise<boolean>;
79
+ assertWithinThresholds(subscriberOrTenantId: Subscriber | string, options?: SubscriptionResolverOptions): Promise<void>;
80
+ private resolveSubscription;
81
+ private resolvePlan;
82
+ /**
83
+ * Bridge the legacy and polymorphic reader contracts.
84
+ *
85
+ * Prefers `findCurrentForSubscriber` when the reader provides it (the
86
+ * preferred shape). For `'tenant'` subscribers we fall back to the legacy
87
+ * `findCurrentForTenant`. For `'external'` subscribers the reader MUST
88
+ * implement `findCurrentForSubscriber` — otherwise we have no way to scope
89
+ * the lookup and we throw rather than silently returning the tenant's
90
+ * primary subscription.
91
+ */
92
+ private findCurrentSubscription;
93
+ private resolveThresholdEvaluations;
94
+ }
95
+ export type { PlanThreshold };
96
+ //# sourceMappingURL=subscription-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription-resolver.d.ts","sourceRoot":"","sources":["../../src/services/subscription-resolver.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,KAAK,EACV,qBAAqB,EACrB,4BAA4B,EAC5B,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,2BAA2B,EAE3B,YAAY,EACZ,WAAW,EACZ,MAAM,aAAa,CAAC;AASrB,MAAM,WAAW,sBAAsB;IACrC,GAAG,CAAC,QAAQ,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;CACjE;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,wBAAwB;IACvC,oBAAoB,CAClB,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,IAAI,GACT,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IACtC,wBAAwB,CAAC,CACvB,UAAU,EAAE,UAAU,EACtB,GAAG,CAAC,EAAE,IAAI,GACT,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;CACvC;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,OAAO,EAAE;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;QACpC,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,WAAW,CAAC;KACrB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1B,cAAc,CAAC,CAAC,OAAO,EAAE;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;QACpC,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,MAAM,EAAE,WAAW,CAAC;KACrB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,sBAAsB,CAAC;IAC9B,aAAa,EAAE,wBAAwB,CAAC;IACxC,KAAK,EAAE,kBAAkB,CAAC;CAC3B;AAED,qBAAa,oBAAoB;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,2BAA2B;IAEjE;;;OAGG;WACU,MAAM,CACjB,YAAY,GAAE,gBAAqB,GAClC,OAAO,CAAC,oBAAoB,CAAC;IAShC;;;;OAIG;IACG,sBAAsB,CAC1B,oBAAoB,EAAE,UAAU,GAAG,MAAM,EACzC,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,4BAA4B,CAAC;IAYxC;;;;OAIG;IACG,mBAAmB,CACvB,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,qBAAqB,CAAC;IA2CjC;;;OAGG;IACG,yBAAyB,CAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,qBAAqB,CAAC;IAI3B,gBAAgB,CACpB,oBAAoB,EAAE,UAAU,GAAG,MAAM,EACzC,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,OAAO,CAAC;IAQb,sBAAsB,CAC1B,oBAAoB,EAAE,UAAU,GAAG,MAAM,EACzC,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,IAAI,CAAC;YAkBF,mBAAmB;YAanB,WAAW;IAezB;;;;;;;;;OASG;YACW,uBAAuB;YAsBvB,2BAA2B;CA4E1C;AAmGD,YAAY,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { PlanThreshold, ThresholdEvaluation, UsageSummary } from '../types.js';
2
+ export declare function evaluateThreshold(threshold: PlanThreshold, usage: UsageSummary): ThresholdEvaluation;
3
+ export declare function evaluateThresholds(thresholds: PlanThreshold[], usage: UsageSummary[]): ThresholdEvaluation[];
4
+ //# sourceMappingURL=threshold-evaluator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"threshold-evaluator.d.ts","sourceRoot":"","sources":["../../src/services/threshold-evaluator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,mBAAmB,EACnB,YAAY,EACb,MAAM,aAAa,CAAC;AAErB,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,YAAY,GAClB,mBAAmB,CAuBrB;AAED,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,aAAa,EAAE,EAC3B,KAAK,EAAE,YAAY,EAAE,GACpB,mBAAmB,EAAE,CAWvB"}
@@ -0,0 +1,32 @@
1
+ import { SmrtClassOptions } from '@happyvertical/smrt-core';
2
+ import { TenantUsageMetricCollection } from '../collections/TenantUsageMetricCollection.js';
3
+ import { AiUsageSummary, RecordUsageOptions, SummarizeAiUsageOptions, SummarizeUsageBatchOptions, SummarizeUsageOptions, UsageSummary } from '../types.js';
4
+ export declare class TenantUsageMeter {
5
+ private readonly metrics;
6
+ private readonly classOptions;
7
+ constructor(metrics: TenantUsageMetricCollection, classOptions?: SmrtClassOptions);
8
+ static create(classOptions?: SmrtClassOptions): Promise<TenantUsageMeter>;
9
+ /**
10
+ * Record one usage row.
11
+ *
12
+ * Accepts the polymorphic subscriber fields directly on the options object
13
+ * (`subscriberKind`/`subscriberExternalId`); when omitted defaults to a
14
+ * `'tenant'`-kind row keyed off `tenantId`. The collection layer enforces
15
+ * the XOR invariant — passing `subscriberKind: 'external'` without a
16
+ * non-empty `subscriberExternalId` throws.
17
+ */
18
+ record(options: RecordUsageOptions): Promise<void>;
19
+ /**
20
+ * Summarize usage over a window for a given subscriber.
21
+ *
22
+ * The `ai.*` short-circuit only fires for `'tenant'`-kind subscribers since
23
+ * the `_smrt_ai_usage` system table is tenant-scoped; external subscribers
24
+ * fall through to the normal `_smrt_tenant_usage_metrics` aggregation.
25
+ */
26
+ summarize(options: SummarizeUsageOptions): Promise<UsageSummary>;
27
+ summarizeBatch(options: SummarizeUsageBatchOptions): Promise<UsageSummary[]>;
28
+ summarizeAiUsage(options: SummarizeAiUsageOptions): Promise<AiUsageSummary>;
29
+ getOptions(): SmrtClassOptions;
30
+ private trySummarizeAiMetric;
31
+ }
32
+ //# sourceMappingURL=usage-meter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-meter.d.ts","sourceRoot":"","sources":["../../src/services/usage-meter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,2BAA2B,EAAE,MAAM,+CAA+C,CAAC;AAC5F,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,uBAAuB,EACvB,0BAA0B,EAC1B,qBAAqB,EACrB,YAAY,EACb,MAAM,aAAa,CAAC;AAGrB,qBAAa,gBAAgB;IAEzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,YAAY;gBADZ,OAAO,EAAE,2BAA2B,EACpC,YAAY,GAAE,gBAAqB;WAGzC,MAAM,CACjB,YAAY,GAAE,gBAAqB,GAClC,OAAO,CAAC,gBAAgB,CAAC;IAK5B;;;;;;;;OAQG;IACG,MAAM,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxD;;;;;;OAMG;IACG,SAAS,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,YAAY,CAAC;IAoBhE,cAAc,CAClB,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,YAAY,EAAE,CAAC;IAoDpB,gBAAgB,CACpB,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,cAAc,CAAC;IAI1B,UAAU,IAAI,gBAAgB;YAIhB,oBAAoB;CA+BnC"}