@happyvertical/smrt-subscriptions 0.39.4 → 0.39.6
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.
- package/AGENTS.md +2 -1
- package/dist/collections/TenantUsageMetricCollection.d.ts.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +653 -37
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +1305 -11
- package/dist/models/TenantUsageMetric.d.ts +4 -0
- package/dist/models/TenantUsageMetric.d.ts.map +1 -1
- package/dist/models/commercial.d.ts +81 -0
- package/dist/models/commercial.d.ts.map +1 -0
- package/dist/models/index.d.ts +2 -0
- package/dist/models/index.d.ts.map +1 -1
- package/dist/services/commercial.d.ts +62 -0
- package/dist/services/commercial.d.ts.map +1 -0
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/smrt-knowledge.json +1067 -30
- package/dist/svelte/CommercialOverview.svelte +46 -0
- package/dist/svelte/CommercialOverview.svelte.d.ts +16 -0
- package/dist/svelte/CommercialOverview.svelte.d.ts.map +1 -0
- package/dist/svelte/i18n.d.ts +1 -0
- package/dist/svelte/i18n.d.ts.map +1 -1
- package/dist/svelte/i18n.js +1 -0
- package/dist/svelte/index.d.ts +2 -0
- package/dist/svelte/index.d.ts.map +1 -1
- package/dist/svelte/index.js +1 -0
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +1 -0
- package/dist/utils.d.ts.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ObjectRegistry, SmrtCollection, SmrtObject, foreignKey, smrt } from "@happyvertical/smrt-core";
|
|
2
2
|
import { TenantScoped, tenantId } from "@happyvertical/smrt-tenancy";
|
|
3
3
|
//#region src/__smrt-register__.ts
|
|
4
|
-
ObjectRegistry.registerPackageManifest(JSON.parse("{\"version\":\"1.0.0\",\"timestamp\":1783819587762,\"packageName\":\"@happyvertical/smrt-subscriptions\",\"packageVersion\":\"0.39.4\",\"objects\":{\"@happyvertical/smrt-subscriptions:SubscriptionPlanCollection\":{\"name\":\"subscriptionplancollection\",\"className\":\"SubscriptionPlanCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:SubscriptionPlanCollection\",\"collection\":\"subscriptionplans\",\"filePath\":\"/home/runner/.local/share/pnpm/store/.workspaces/arc-happyvertical-node-phdrb-runner-b6zmd/smrt/smrt/packages/subscriptions/src/collections/SubscriptionPlanCollection.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{},\"methods\":{\"findByPlanKey\":{\"name\":\"findByPlanKey\",\"async\":true,\"parameters\":[{\"name\":\"planKey\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<SubscriptionPlan | null>\",\"isStatic\":false,\"isPublic\":true},\"findActive\":{\"name\":\"findActive\",\"async\":true,\"parameters\":[],\"returnType\":\"Promise<SubscriptionPlan[]>\",\"isStatic\":false,\"isPublic\":true},\"findByStripePriceId\":{\"name\":\"findByStripePriceId\",\"async\":true,\"parameters\":[{\"name\":\"stripePriceId\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<SubscriptionPlan | null>\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_subscription_plans\"},\"extends\":\"SmrtCollection\",\"extendsTypeArg\":\"SubscriptionPlan\",\"exportName\":\"SubscriptionPlanCollection\",\"collectionExportName\":\"SubscriptionPlanCollectionCollection\",\"schema\":{\"tableName\":\"_smrt_subscription_plans\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_subscription_plans\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"}},\"indexes\":[{\"name\":\"_smrt_subscription_plans_id_idx\",\"columns\":[\"id\"]},{\"name\":\"_smrt_subscription_plans_slug_context_idx\",\"columns\":[\"slug\",\"context\"],\"unique\":true}],\"version\":\"e693208d\"}},\"@happyvertical/smrt-subscriptions:TenantSubscriptionCollection\":{\"name\":\"tenantsubscriptioncollection\",\"className\":\"TenantSubscriptionCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:TenantSubscriptionCollection\",\"collection\":\"tenantsubscriptions\",\"filePath\":\"/home/runner/.local/share/pnpm/store/.workspaces/arc-happyvertical-node-phdrb-runner-b6zmd/smrt/smrt/packages/subscriptions/src/collections/TenantSubscriptionCollection.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{},\"methods\":{\"findByTenant\":{\"name\":\"findByTenant\",\"async\":true,\"parameters\":[{\"name\":\"tenantId\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<TenantSubscription[]>\",\"isStatic\":false,\"isPublic\":true},\"findCurrentForTenant\":{\"name\":\"findCurrentForTenant\",\"async\":true,\"parameters\":[{\"name\":\"tenantId\",\"type\":\"string\",\"optional\":false},{\"name\":\"now\",\"type\":\"any\",\"optional\":true}],\"returnType\":\"Promise<TenantSubscription | null>\",\"isStatic\":false,\"isPublic\":true},\"findCurrentForSubscriber\":{\"name\":\"findCurrentForSubscriber\",\"async\":true,\"parameters\":[{\"name\":\"subscriber\",\"type\":\"Subscriber\",\"optional\":false},{\"name\":\"now\",\"type\":\"any\",\"optional\":true}],\"returnType\":\"Promise<TenantSubscription | null>\",\"isStatic\":false,\"isPublic\":true},\"findByStripeSubscriptionId\":{\"name\":\"findByStripeSubscriptionId\",\"async\":true,\"parameters\":[{\"name\":\"stripeSubscriptionId\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<TenantSubscription | null>\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_tenant_subscriptions\"},\"extends\":\"SmrtCollection\",\"extendsTypeArg\":\"TenantSubscription\",\"exportName\":\"TenantSubscriptionCollection\",\"collectionExportName\":\"TenantSubscriptionCollectionCollection\",\"schema\":{\"tableName\":\"_smrt_tenant_subscriptions\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_tenant_subscriptions\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"}},\"indexes\":[{\"name\":\"_smrt_tenant_subscriptions_id_idx\",\"columns\":[\"id\"]},{\"name\":\"_smrt_tenant_subscriptions_slug_context_idx\",\"columns\":[\"slug\",\"context\"],\"unique\":true}],\"version\":\"1d17f963\"}},\"@happyvertical/smrt-subscriptions:TenantUsageMetricCollection\":{\"name\":\"tenantusagemetriccollection\",\"className\":\"TenantUsageMetricCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:TenantUsageMetricCollection\",\"collection\":\"tenantusagemetrics\",\"filePath\":\"/home/runner/.local/share/pnpm/store/.workspaces/arc-happyvertical-node-phdrb-runner-b6zmd/smrt/smrt/packages/subscriptions/src/collections/TenantUsageMetricCollection.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{},\"methods\":{\"recordUsage\":{\"name\":\"recordUsage\",\"async\":true,\"parameters\":[{\"name\":\"options\",\"type\":\"RecordUsageOptions\",\"optional\":false}],\"returnType\":\"Promise<TenantUsageMetric>\",\"isStatic\":false,\"isPublic\":true},\"findByTenantAndMetric\":{\"name\":\"findByTenantAndMetric\",\"async\":true,\"parameters\":[{\"name\":\"tenantId\",\"type\":\"string\",\"optional\":false},{\"name\":\"metricKey\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<TenantUsageMetric[]>\",\"isStatic\":false,\"isPublic\":true},\"summarizeUsage\":{\"name\":\"summarizeUsage\",\"async\":true,\"parameters\":[{\"name\":\"options\",\"type\":\"SummarizeUsageOptions\",\"optional\":false}],\"returnType\":\"Promise<UsageSummary>\",\"isStatic\":false,\"isPublic\":true},\"summarizeUsageBatch\":{\"name\":\"summarizeUsageBatch\",\"async\":true,\"parameters\":[{\"name\":\"options\",\"type\":\"SummarizeUsageBatchOptions\",\"optional\":false}],\"returnType\":\"Promise<UsageSummary[]>\",\"isStatic\":false,\"isPublic\":true},\"summarizeTenantAiUsage\":{\"name\":\"summarizeTenantAiUsage\",\"async\":true,\"parameters\":[{\"name\":\"options\",\"type\":\"SummarizeAiUsageOptions\",\"optional\":false}],\"returnType\":\"Promise<AiUsageSummary>\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_tenant_usage_metrics\"},\"extends\":\"SmrtCollection\",\"extendsTypeArg\":\"TenantUsageMetric\",\"exportName\":\"TenantUsageMetricCollection\",\"collectionExportName\":\"TenantUsageMetricCollectionCollection\",\"schema\":{\"tableName\":\"_smrt_tenant_usage_metrics\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_tenant_usage_metrics\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"}},\"indexes\":[{\"name\":\"_smrt_tenant_usage_metrics_id_idx\",\"columns\":[\"id\"]},{\"name\":\"_smrt_tenant_usage_metrics_slug_context_idx\",\"columns\":[\"slug\",\"context\"],\"unique\":true}],\"version\":\"8617d4ac\"}},\"@happyvertical/smrt-subscriptions:SubscriptionPlan\":{\"name\":\"subscriptionplan\",\"className\":\"SubscriptionPlan\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:SubscriptionPlan\",\"collection\":\"subscriptionplans\",\"filePath\":\"/home/runner/.local/share/pnpm/store/.workspaces/arc-happyvertical-node-phdrb-runner-b6zmd/smrt/smrt/packages/subscriptions/src/models/SubscriptionPlan.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{\"tenantId\":{\"type\":\"text\",\"required\":false,\"_meta\":{\"sqlType\":\"UUID\",\"nullable\":true,\"__tenancy\":{\"isTenantIdField\":true,\"autoFilter\":true,\"required\":false,\"autoPopulate\":true,\"nullable\":true,\"mode\":\"optional\",\"field\":\"tenantId\",\"allowSuperAdminBypass\":false}}},\"planKey\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"name\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"description\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"status\":{\"type\":\"text\",\"required\":false,\"default\":\"active\"},\"sortOrder\":{\"type\":\"integer\",\"required\":false,\"default\":0},\"priceAmount\":{\"type\":\"decimal\",\"required\":false,\"default\":0},\"currency\":{\"type\":\"text\",\"required\":false,\"default\":\"USD\"},\"billingInterval\":{\"type\":\"text\",\"required\":false,\"default\":\"month\"},\"externalProvider\":{\"type\":\"text\",\"required\":false,\"default\":\"stripe\"},\"stripeProductId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"stripePriceId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"features\":{\"type\":\"text\",\"required\":false,\"default\":\"[]\"},\"thresholds\":{\"type\":\"text\",\"required\":false,\"default\":\"[]\"},\"metadata\":{\"type\":\"text\",\"required\":false,\"default\":\"{}\"}},\"methods\":{\"isActive\":{\"name\":\"isActive\",\"async\":false,\"parameters\":[],\"returnType\":\"boolean\",\"isStatic\":false,\"isPublic\":true},\"getFeatureGrants\":{\"name\":\"getFeatureGrants\",\"async\":false,\"parameters\":[],\"returnType\":\"PlanFeatureGrant[]\",\"isStatic\":false,\"isPublic\":true},\"setFeatureGrants\":{\"name\":\"setFeatureGrants\",\"async\":false,\"parameters\":[{\"name\":\"grants\",\"type\":\"Array<string | PlanFeatureGrant>\",\"optional\":false}],\"returnType\":\"void\",\"isStatic\":false,\"isPublic\":true},\"getFeatureKeys\":{\"name\":\"getFeatureKeys\",\"async\":false,\"parameters\":[],\"returnType\":\"string[]\",\"isStatic\":false,\"isPublic\":true},\"getThresholds\":{\"name\":\"getThresholds\",\"async\":false,\"parameters\":[],\"returnType\":\"PlanThreshold[]\",\"isStatic\":false,\"isPublic\":true},\"setThresholds\":{\"name\":\"setThresholds\",\"async\":false,\"parameters\":[{\"name\":\"thresholds\",\"type\":\"PlanThreshold[]\",\"optional\":false}],\"returnType\":\"void\",\"isStatic\":false,\"isPublic\":true},\"getMetadata\":{\"name\":\"getMetadata\",\"async\":false,\"parameters\":[],\"returnType\":\"JsonObject\",\"isStatic\":false,\"isPublic\":true},\"setMetadata\":{\"name\":\"setMetadata\",\"async\":false,\"parameters\":[{\"name\":\"metadata\",\"type\":\"JsonObject\",\"optional\":false}],\"returnType\":\"void\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_subscription_plans\",\"api\":{\"include\":[\"list\",\"get\",\"create\",\"update\"]},\"cli\":true,\"mcp\":{\"include\":[\"list\",\"get\"]},\"conflictColumns\":[\"plan_key\"],\"tenantScoped\":{\"mode\":\"optional\"}},\"extends\":\"SmrtObject\",\"exportName\":\"SubscriptionPlan\",\"collectionExportName\":\"SubscriptionPlanCollection\",\"schema\":{\"tableName\":\"_smrt_subscription_plans\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_subscription_plans\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"tenant_id\\\" UUID,\\n \\\"plan_key\\\" TEXT DEFAULT '',\\n \\\"name\\\" TEXT DEFAULT '',\\n \\\"description\\\" TEXT DEFAULT '',\\n \\\"status\\\" TEXT DEFAULT 'active',\\n \\\"sort_order\\\" INTEGER DEFAULT 0,\\n \\\"price_amount\\\" REAL DEFAULT 0,\\n \\\"currency\\\" TEXT DEFAULT 'USD',\\n \\\"billing_interval\\\" TEXT DEFAULT 'month',\\n \\\"external_provider\\\" TEXT DEFAULT 'stripe',\\n \\\"stripe_product_id\\\" TEXT DEFAULT '',\\n \\\"stripe_price_id\\\" TEXT DEFAULT '',\\n \\\"features\\\" TEXT DEFAULT '[]',\\n \\\"thresholds\\\" TEXT DEFAULT '[]',\\n \\\"metadata\\\" TEXT DEFAULT '{}'\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"tenantId\",\"notNull\":false,\"unique\":false},\"plan_key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"name\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"description\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"status\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"active\"},\"sort_order\":{\"type\":\"INTEGER\",\"notNull\":false,\"unique\":false,\"default\":0},\"price_amount\":{\"type\":\"REAL\",\"notNull\":false,\"unique\":false,\"default\":0},\"currency\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"USD\"},\"billing_interval\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"month\"},\"external_provider\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"stripe\"},\"stripe_product_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"stripe_price_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"features\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"[]\"},\"thresholds\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"[]\"},\"metadata\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"{}\"}},\"indexes\":[{\"name\":\"_smrt_subscription_plans_id_idx\",\"columns\":[\"id\"]},{\"name\":\"_smrt_subscription_plans_plan_key_idx\",\"columns\":[\"plan_key\"],\"unique\":true}],\"version\":\"bbe13cf9\"}},\"@happyvertical/smrt-subscriptions:TenantSubscription\":{\"name\":\"tenantsubscription\",\"className\":\"TenantSubscription\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:TenantSubscription\",\"collection\":\"tenantsubscriptions\",\"filePath\":\"/home/runner/.local/share/pnpm/store/.workspaces/arc-happyvertical-node-phdrb-runner-b6zmd/smrt/smrt/packages/subscriptions/src/models/TenantSubscription.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{\"tenantId\":{\"type\":\"text\",\"required\":true,\"_meta\":{\"sqlType\":\"UUID\",\"__tenancy\":{\"isTenantIdField\":true,\"autoFilter\":true,\"required\":true,\"autoPopulate\":true,\"nullable\":false,\"mode\":\"required\",\"field\":\"tenantId\",\"allowSuperAdminBypass\":false}}},\"subscriberKind\":{\"type\":\"text\",\"required\":false,\"default\":\"tenant\"},\"subscriberExternalId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"planId\":{\"type\":\"foreignKey\",\"required\":false,\"related\":\"SubscriptionPlan\"},\"status\":{\"type\":\"text\",\"required\":false,\"default\":\"incomplete\"},\"startedAt\":{\"type\":\"datetime\",\"required\":false},\"currentPeriodStart\":{\"type\":\"datetime\",\"required\":false},\"currentPeriodEnd\":{\"type\":\"datetime\",\"required\":false},\"trialEndsAt\":{\"type\":\"datetime\",\"required\":false},\"cancelAtPeriodEnd\":{\"type\":\"boolean\",\"required\":false,\"default\":false},\"canceledAt\":{\"type\":\"datetime\",\"required\":false},\"externalProvider\":{\"type\":\"text\",\"required\":false,\"default\":\"stripe\"},\"stripeCustomerId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"stripeSubscriptionId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"stripeCheckoutSessionId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"metadata\":{\"type\":\"text\",\"required\":false,\"default\":\"{}\"}},\"methods\":{\"isEntitled\":{\"name\":\"isEntitled\",\"async\":false,\"parameters\":[{\"name\":\"now\",\"type\":\"any\",\"optional\":true}],\"returnType\":\"boolean\",\"isStatic\":false,\"isPublic\":true},\"getSubscriber\":{\"name\":\"getSubscriber\",\"async\":false,\"parameters\":[],\"returnType\":\"Subscriber | null\",\"isStatic\":false,\"isPublic\":true},\"getMetadata\":{\"name\":\"getMetadata\",\"async\":false,\"parameters\":[],\"returnType\":\"JsonObject\",\"isStatic\":false,\"isPublic\":true},\"setMetadata\":{\"name\":\"setMetadata\",\"async\":false,\"parameters\":[{\"name\":\"metadata\",\"type\":\"JsonObject\",\"optional\":false}],\"returnType\":\"void\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_tenant_subscriptions\",\"api\":{\"include\":[\"list\",\"get\",\"create\",\"update\"]},\"cli\":true,\"mcp\":{\"include\":[\"list\",\"get\"]},\"conflictColumns\":[\"tenant_id\",\"subscriber_kind\",\"subscriber_external_id\"],\"tenantScoped\":{\"mode\":\"required\"}},\"extends\":\"SmrtObject\",\"exportName\":\"TenantSubscription\",\"collectionExportName\":\"TenantSubscriptionCollection\",\"validationRules\":[{\"field\":\"tenantId\",\"rule\":\"required\",\"fieldType\":\"text\"}],\"schema\":{\"tableName\":\"_smrt_tenant_subscriptions\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_tenant_subscriptions\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"tenant_id\\\" UUID NOT NULL,\\n \\\"subscriber_kind\\\" TEXT DEFAULT 'tenant',\\n \\\"subscriber_external_id\\\" TEXT DEFAULT '',\\n \\\"plan_id\\\" UUID,\\n \\\"status\\\" TEXT DEFAULT 'incomplete',\\n \\\"started_at\\\" TIMESTAMP,\\n \\\"current_period_start\\\" TIMESTAMP,\\n \\\"current_period_end\\\" TIMESTAMP,\\n \\\"trial_ends_at\\\" TIMESTAMP,\\n \\\"cancel_at_period_end\\\" BOOLEAN DEFAULT FALSE,\\n \\\"canceled_at\\\" TIMESTAMP,\\n \\\"external_provider\\\" TEXT DEFAULT 'stripe',\\n \\\"stripe_customer_id\\\" TEXT DEFAULT '',\\n \\\"stripe_subscription_id\\\" TEXT DEFAULT '',\\n \\\"stripe_checkout_session_id\\\" TEXT DEFAULT '',\\n \\\"metadata\\\" TEXT DEFAULT '{}'\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"tenantId\",\"notNull\":true,\"unique\":false},\"subscriber_kind\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"tenant\"},\"subscriber_external_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"plan_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false},\"status\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"incomplete\"},\"started_at\":{\"type\":\"TIMESTAMP\",\"notNull\":false,\"unique\":false},\"current_period_start\":{\"type\":\"TIMESTAMP\",\"notNull\":false,\"unique\":false},\"current_period_end\":{\"type\":\"TIMESTAMP\",\"notNull\":false,\"unique\":false},\"trial_ends_at\":{\"type\":\"TIMESTAMP\",\"notNull\":false,\"unique\":false},\"cancel_at_period_end\":{\"type\":\"BOOLEAN\",\"notNull\":false,\"unique\":false,\"default\":false},\"canceled_at\":{\"type\":\"TIMESTAMP\",\"notNull\":false,\"unique\":false},\"external_provider\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"stripe\"},\"stripe_customer_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"stripe_subscription_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"stripe_checkout_session_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"metadata\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"{}\"}},\"indexes\":[{\"name\":\"_smrt_tenant_subscriptions_id_idx\",\"columns\":[\"id\"]},{\"name\":\"_smrt_tenant_subscriptions_tenant_id_subscriber_kind_idx\",\"columns\":[\"tenant_id\",\"subscriber_kind\",\"subscriber_external_id\"],\"unique\":true}],\"version\":\"ef3d8be5\"}},\"@happyvertical/smrt-subscriptions:TenantUsageMetric\":{\"name\":\"tenantusagemetric\",\"className\":\"TenantUsageMetric\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:TenantUsageMetric\",\"collection\":\"tenantusagemetrics\",\"filePath\":\"/home/runner/.local/share/pnpm/store/.workspaces/arc-happyvertical-node-phdrb-runner-b6zmd/smrt/smrt/packages/subscriptions/src/models/TenantUsageMetric.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{\"tenantId\":{\"type\":\"text\",\"required\":true,\"_meta\":{\"sqlType\":\"UUID\",\"__tenancy\":{\"isTenantIdField\":true,\"autoFilter\":true,\"required\":true,\"autoPopulate\":true,\"nullable\":false,\"mode\":\"required\",\"field\":\"tenantId\",\"allowSuperAdminBypass\":false}}},\"subscriberKind\":{\"type\":\"text\",\"required\":false,\"default\":\"tenant\"},\"subscriberExternalId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"metricKey\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"quantity\":{\"type\":\"decimal\",\"required\":false,\"default\":0},\"windowStart\":{\"type\":\"datetime\",\"required\":false},\"windowEnd\":{\"type\":\"datetime\",\"required\":false},\"source\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"sourceId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"dimensions\":{\"type\":\"text\",\"required\":false,\"default\":\"{}\"}},\"methods\":{\"getSubscriber\":{\"name\":\"getSubscriber\",\"async\":false,\"parameters\":[],\"returnType\":\"Subscriber | null\",\"isStatic\":false,\"isPublic\":true},\"getDimensions\":{\"name\":\"getDimensions\",\"async\":false,\"parameters\":[],\"returnType\":\"JsonObject\",\"isStatic\":false,\"isPublic\":true},\"setDimensions\":{\"name\":\"setDimensions\",\"async\":false,\"parameters\":[{\"name\":\"dimensions\",\"type\":\"JsonObject\",\"optional\":false}],\"returnType\":\"void\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_tenant_usage_metrics\",\"api\":{\"include\":[\"list\",\"get\",\"create\"]},\"cli\":true,\"mcp\":{\"include\":[\"list\",\"get\"]},\"tenantScoped\":{\"mode\":\"required\"}},\"extends\":\"SmrtObject\",\"exportName\":\"TenantUsageMetric\",\"collectionExportName\":\"TenantUsageMetricCollection\",\"validationRules\":[{\"field\":\"tenantId\",\"rule\":\"required\",\"fieldType\":\"text\"}],\"schema\":{\"tableName\":\"_smrt_tenant_usage_metrics\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_tenant_usage_metrics\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"tenant_id\\\" UUID NOT NULL,\\n \\\"subscriber_kind\\\" TEXT DEFAULT 'tenant',\\n \\\"subscriber_external_id\\\" TEXT DEFAULT '',\\n \\\"metric_key\\\" TEXT DEFAULT '',\\n \\\"quantity\\\" REAL DEFAULT 0,\\n \\\"window_start\\\" TIMESTAMP,\\n \\\"window_end\\\" TIMESTAMP,\\n \\\"source\\\" TEXT DEFAULT '',\\n \\\"source_id\\\" TEXT DEFAULT '',\\n \\\"dimensions\\\" TEXT DEFAULT '{}'\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"tenantId\",\"notNull\":true,\"unique\":false},\"subscriber_kind\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"tenant\"},\"subscriber_external_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"metric_key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"quantity\":{\"type\":\"REAL\",\"notNull\":false,\"unique\":false,\"default\":0},\"window_start\":{\"type\":\"TIMESTAMP\",\"notNull\":false,\"unique\":false},\"window_end\":{\"type\":\"TIMESTAMP\",\"notNull\":false,\"unique\":false},\"source\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"source_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"dimensions\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"{}\"}},\"indexes\":[{\"name\":\"_smrt_tenant_usage_metrics_id_idx\",\"columns\":[\"id\"]},{\"name\":\"_smrt_tenant_usage_metrics_slug_context_idx\",\"columns\":[\"slug\",\"context\"],\"unique\":true}],\"version\":\"ec6ea717\"}}},\"moduleType\":\"smrt\",\"smrtDependencies\":[\"@happyvertical/smrt-core\",\"@happyvertical/smrt-tenancy\"]}"));
|
|
4
|
+
ObjectRegistry.registerPackageManifest(JSON.parse("{\"version\":\"1.0.0\",\"timestamp\":1783845578957,\"packageName\":\"@happyvertical/smrt-subscriptions\",\"packageVersion\":\"0.39.6\",\"objects\":{\"@happyvertical/smrt-subscriptions:SubscriptionPlanCollection\":{\"name\":\"subscriptionplancollection\",\"className\":\"SubscriptionPlanCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:SubscriptionPlanCollection\",\"collection\":\"subscriptionplans\",\"filePath\":\"/home/runner/.local/share/pnpm/store/.workspaces/arc-happyvertical-node-phdrb-runner-xv52x/smrt/smrt/packages/subscriptions/src/collections/SubscriptionPlanCollection.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{},\"methods\":{\"findByPlanKey\":{\"name\":\"findByPlanKey\",\"async\":true,\"parameters\":[{\"name\":\"planKey\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<SubscriptionPlan | null>\",\"isStatic\":false,\"isPublic\":true},\"findActive\":{\"name\":\"findActive\",\"async\":true,\"parameters\":[],\"returnType\":\"Promise<SubscriptionPlan[]>\",\"isStatic\":false,\"isPublic\":true},\"findByStripePriceId\":{\"name\":\"findByStripePriceId\",\"async\":true,\"parameters\":[{\"name\":\"stripePriceId\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<SubscriptionPlan | null>\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_subscription_plans\"},\"extends\":\"SmrtCollection\",\"extendsTypeArg\":\"SubscriptionPlan\",\"exportName\":\"SubscriptionPlanCollection\",\"collectionExportName\":\"SubscriptionPlanCollectionCollection\",\"schema\":{\"tableName\":\"_smrt_subscription_plans\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_subscription_plans\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"}},\"indexes\":[{\"name\":\"_smrt_subscription_plans_id_idx\",\"columns\":[\"id\"]},{\"name\":\"_smrt_subscription_plans_slug_context_idx\",\"columns\":[\"slug\",\"context\"],\"unique\":true}],\"version\":\"e693208d\"}},\"@happyvertical/smrt-subscriptions:TenantSubscriptionCollection\":{\"name\":\"tenantsubscriptioncollection\",\"className\":\"TenantSubscriptionCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:TenantSubscriptionCollection\",\"collection\":\"tenantsubscriptions\",\"filePath\":\"/home/runner/.local/share/pnpm/store/.workspaces/arc-happyvertical-node-phdrb-runner-xv52x/smrt/smrt/packages/subscriptions/src/collections/TenantSubscriptionCollection.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{},\"methods\":{\"findByTenant\":{\"name\":\"findByTenant\",\"async\":true,\"parameters\":[{\"name\":\"tenantId\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<TenantSubscription[]>\",\"isStatic\":false,\"isPublic\":true},\"findCurrentForTenant\":{\"name\":\"findCurrentForTenant\",\"async\":true,\"parameters\":[{\"name\":\"tenantId\",\"type\":\"string\",\"optional\":false},{\"name\":\"now\",\"type\":\"any\",\"optional\":true}],\"returnType\":\"Promise<TenantSubscription | null>\",\"isStatic\":false,\"isPublic\":true},\"findCurrentForSubscriber\":{\"name\":\"findCurrentForSubscriber\",\"async\":true,\"parameters\":[{\"name\":\"subscriber\",\"type\":\"Subscriber\",\"optional\":false},{\"name\":\"now\",\"type\":\"any\",\"optional\":true}],\"returnType\":\"Promise<TenantSubscription | null>\",\"isStatic\":false,\"isPublic\":true},\"findByStripeSubscriptionId\":{\"name\":\"findByStripeSubscriptionId\",\"async\":true,\"parameters\":[{\"name\":\"stripeSubscriptionId\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<TenantSubscription | null>\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_tenant_subscriptions\"},\"extends\":\"SmrtCollection\",\"extendsTypeArg\":\"TenantSubscription\",\"exportName\":\"TenantSubscriptionCollection\",\"collectionExportName\":\"TenantSubscriptionCollectionCollection\",\"schema\":{\"tableName\":\"_smrt_tenant_subscriptions\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_tenant_subscriptions\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"}},\"indexes\":[{\"name\":\"_smrt_tenant_subscriptions_id_idx\",\"columns\":[\"id\"]},{\"name\":\"_smrt_tenant_subscriptions_slug_context_idx\",\"columns\":[\"slug\",\"context\"],\"unique\":true}],\"version\":\"1d17f963\"}},\"@happyvertical/smrt-subscriptions:TenantUsageMetricCollection\":{\"name\":\"tenantusagemetriccollection\",\"className\":\"TenantUsageMetricCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:TenantUsageMetricCollection\",\"collection\":\"tenantusagemetrics\",\"filePath\":\"/home/runner/.local/share/pnpm/store/.workspaces/arc-happyvertical-node-phdrb-runner-xv52x/smrt/smrt/packages/subscriptions/src/collections/TenantUsageMetricCollection.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{},\"methods\":{\"recordUsage\":{\"name\":\"recordUsage\",\"async\":true,\"parameters\":[{\"name\":\"options\",\"type\":\"RecordUsageOptions\",\"optional\":false}],\"returnType\":\"Promise<TenantUsageMetric>\",\"isStatic\":false,\"isPublic\":true},\"findByTenantAndMetric\":{\"name\":\"findByTenantAndMetric\",\"async\":true,\"parameters\":[{\"name\":\"tenantId\",\"type\":\"string\",\"optional\":false},{\"name\":\"metricKey\",\"type\":\"string\",\"optional\":false}],\"returnType\":\"Promise<TenantUsageMetric[]>\",\"isStatic\":false,\"isPublic\":true},\"summarizeUsage\":{\"name\":\"summarizeUsage\",\"async\":true,\"parameters\":[{\"name\":\"options\",\"type\":\"SummarizeUsageOptions\",\"optional\":false}],\"returnType\":\"Promise<UsageSummary>\",\"isStatic\":false,\"isPublic\":true},\"summarizeUsageBatch\":{\"name\":\"summarizeUsageBatch\",\"async\":true,\"parameters\":[{\"name\":\"options\",\"type\":\"SummarizeUsageBatchOptions\",\"optional\":false}],\"returnType\":\"Promise<UsageSummary[]>\",\"isStatic\":false,\"isPublic\":true},\"summarizeTenantAiUsage\":{\"name\":\"summarizeTenantAiUsage\",\"async\":true,\"parameters\":[{\"name\":\"options\",\"type\":\"SummarizeAiUsageOptions\",\"optional\":false}],\"returnType\":\"Promise<AiUsageSummary>\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_tenant_usage_metrics\"},\"extends\":\"SmrtCollection\",\"extendsTypeArg\":\"TenantUsageMetric\",\"exportName\":\"TenantUsageMetricCollection\",\"collectionExportName\":\"TenantUsageMetricCollectionCollection\",\"schema\":{\"tableName\":\"_smrt_tenant_usage_metrics\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_tenant_usage_metrics\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"}},\"indexes\":[{\"name\":\"_smrt_tenant_usage_metrics_id_idx\",\"columns\":[\"id\"]},{\"name\":\"_smrt_tenant_usage_metrics_slug_context_idx\",\"columns\":[\"slug\",\"context\"],\"unique\":true}],\"version\":\"8617d4ac\"}},\"@happyvertical/smrt-subscriptions:SubscriptionPlan\":{\"name\":\"subscriptionplan\",\"className\":\"SubscriptionPlan\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:SubscriptionPlan\",\"collection\":\"subscriptionplans\",\"filePath\":\"/home/runner/.local/share/pnpm/store/.workspaces/arc-happyvertical-node-phdrb-runner-xv52x/smrt/smrt/packages/subscriptions/src/models/SubscriptionPlan.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{\"tenantId\":{\"type\":\"text\",\"required\":false,\"_meta\":{\"sqlType\":\"UUID\",\"nullable\":true,\"__tenancy\":{\"isTenantIdField\":true,\"autoFilter\":true,\"required\":false,\"autoPopulate\":true,\"nullable\":true,\"mode\":\"optional\",\"field\":\"tenantId\",\"allowSuperAdminBypass\":false}}},\"planKey\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"name\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"description\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"status\":{\"type\":\"text\",\"required\":false,\"default\":\"active\"},\"sortOrder\":{\"type\":\"integer\",\"required\":false,\"default\":0},\"priceAmount\":{\"type\":\"decimal\",\"required\":false,\"default\":0},\"currency\":{\"type\":\"text\",\"required\":false,\"default\":\"USD\"},\"billingInterval\":{\"type\":\"text\",\"required\":false,\"default\":\"month\"},\"externalProvider\":{\"type\":\"text\",\"required\":false,\"default\":\"stripe\"},\"stripeProductId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"stripePriceId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"features\":{\"type\":\"text\",\"required\":false,\"default\":\"[]\"},\"thresholds\":{\"type\":\"text\",\"required\":false,\"default\":\"[]\"},\"metadata\":{\"type\":\"text\",\"required\":false,\"default\":\"{}\"}},\"methods\":{\"isActive\":{\"name\":\"isActive\",\"async\":false,\"parameters\":[],\"returnType\":\"boolean\",\"isStatic\":false,\"isPublic\":true},\"getFeatureGrants\":{\"name\":\"getFeatureGrants\",\"async\":false,\"parameters\":[],\"returnType\":\"PlanFeatureGrant[]\",\"isStatic\":false,\"isPublic\":true},\"setFeatureGrants\":{\"name\":\"setFeatureGrants\",\"async\":false,\"parameters\":[{\"name\":\"grants\",\"type\":\"Array<string | PlanFeatureGrant>\",\"optional\":false}],\"returnType\":\"void\",\"isStatic\":false,\"isPublic\":true},\"getFeatureKeys\":{\"name\":\"getFeatureKeys\",\"async\":false,\"parameters\":[],\"returnType\":\"string[]\",\"isStatic\":false,\"isPublic\":true},\"getThresholds\":{\"name\":\"getThresholds\",\"async\":false,\"parameters\":[],\"returnType\":\"PlanThreshold[]\",\"isStatic\":false,\"isPublic\":true},\"setThresholds\":{\"name\":\"setThresholds\",\"async\":false,\"parameters\":[{\"name\":\"thresholds\",\"type\":\"PlanThreshold[]\",\"optional\":false}],\"returnType\":\"void\",\"isStatic\":false,\"isPublic\":true},\"getMetadata\":{\"name\":\"getMetadata\",\"async\":false,\"parameters\":[],\"returnType\":\"JsonObject\",\"isStatic\":false,\"isPublic\":true},\"setMetadata\":{\"name\":\"setMetadata\",\"async\":false,\"parameters\":[{\"name\":\"metadata\",\"type\":\"JsonObject\",\"optional\":false}],\"returnType\":\"void\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_subscription_plans\",\"api\":{\"include\":[\"list\",\"get\",\"create\",\"update\"]},\"cli\":true,\"mcp\":{\"include\":[\"list\",\"get\"]},\"conflictColumns\":[\"plan_key\"],\"tenantScoped\":{\"mode\":\"optional\"}},\"extends\":\"SmrtObject\",\"exportName\":\"SubscriptionPlan\",\"collectionExportName\":\"SubscriptionPlanCollection\",\"schema\":{\"tableName\":\"_smrt_subscription_plans\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_subscription_plans\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"tenant_id\\\" UUID,\\n \\\"plan_key\\\" TEXT DEFAULT '',\\n \\\"name\\\" TEXT DEFAULT '',\\n \\\"description\\\" TEXT DEFAULT '',\\n \\\"status\\\" TEXT DEFAULT 'active',\\n \\\"sort_order\\\" INTEGER DEFAULT 0,\\n \\\"price_amount\\\" REAL DEFAULT 0,\\n \\\"currency\\\" TEXT DEFAULT 'USD',\\n \\\"billing_interval\\\" TEXT DEFAULT 'month',\\n \\\"external_provider\\\" TEXT DEFAULT 'stripe',\\n \\\"stripe_product_id\\\" TEXT DEFAULT '',\\n \\\"stripe_price_id\\\" TEXT DEFAULT '',\\n \\\"features\\\" TEXT DEFAULT '[]',\\n \\\"thresholds\\\" TEXT DEFAULT '[]',\\n \\\"metadata\\\" TEXT DEFAULT '{}'\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"tenantId\",\"notNull\":false,\"unique\":false},\"plan_key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"name\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"description\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"status\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"active\"},\"sort_order\":{\"type\":\"INTEGER\",\"notNull\":false,\"unique\":false,\"default\":0},\"price_amount\":{\"type\":\"REAL\",\"notNull\":false,\"unique\":false,\"default\":0},\"currency\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"USD\"},\"billing_interval\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"month\"},\"external_provider\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"stripe\"},\"stripe_product_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"stripe_price_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"features\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"[]\"},\"thresholds\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"[]\"},\"metadata\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"{}\"}},\"indexes\":[{\"name\":\"_smrt_subscription_plans_id_idx\",\"columns\":[\"id\"]},{\"name\":\"_smrt_subscription_plans_plan_key_idx\",\"columns\":[\"plan_key\"],\"unique\":true}],\"version\":\"bbe13cf9\"}},\"@happyvertical/smrt-subscriptions:TenantSubscription\":{\"name\":\"tenantsubscription\",\"className\":\"TenantSubscription\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:TenantSubscription\",\"collection\":\"tenantsubscriptions\",\"filePath\":\"/home/runner/.local/share/pnpm/store/.workspaces/arc-happyvertical-node-phdrb-runner-xv52x/smrt/smrt/packages/subscriptions/src/models/TenantSubscription.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{\"tenantId\":{\"type\":\"text\",\"required\":true,\"_meta\":{\"sqlType\":\"UUID\",\"__tenancy\":{\"isTenantIdField\":true,\"autoFilter\":true,\"required\":true,\"autoPopulate\":true,\"nullable\":false,\"mode\":\"required\",\"field\":\"tenantId\",\"allowSuperAdminBypass\":false}}},\"subscriberKind\":{\"type\":\"text\",\"required\":false,\"default\":\"tenant\"},\"subscriberExternalId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"planId\":{\"type\":\"foreignKey\",\"required\":false,\"related\":\"SubscriptionPlan\"},\"status\":{\"type\":\"text\",\"required\":false,\"default\":\"incomplete\"},\"startedAt\":{\"type\":\"datetime\",\"required\":false},\"currentPeriodStart\":{\"type\":\"datetime\",\"required\":false},\"currentPeriodEnd\":{\"type\":\"datetime\",\"required\":false},\"trialEndsAt\":{\"type\":\"datetime\",\"required\":false},\"cancelAtPeriodEnd\":{\"type\":\"boolean\",\"required\":false,\"default\":false},\"canceledAt\":{\"type\":\"datetime\",\"required\":false},\"externalProvider\":{\"type\":\"text\",\"required\":false,\"default\":\"stripe\"},\"stripeCustomerId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"stripeSubscriptionId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"stripeCheckoutSessionId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"metadata\":{\"type\":\"text\",\"required\":false,\"default\":\"{}\"}},\"methods\":{\"isEntitled\":{\"name\":\"isEntitled\",\"async\":false,\"parameters\":[{\"name\":\"now\",\"type\":\"any\",\"optional\":true}],\"returnType\":\"boolean\",\"isStatic\":false,\"isPublic\":true},\"getSubscriber\":{\"name\":\"getSubscriber\",\"async\":false,\"parameters\":[],\"returnType\":\"Subscriber | null\",\"isStatic\":false,\"isPublic\":true},\"getMetadata\":{\"name\":\"getMetadata\",\"async\":false,\"parameters\":[],\"returnType\":\"JsonObject\",\"isStatic\":false,\"isPublic\":true},\"setMetadata\":{\"name\":\"setMetadata\",\"async\":false,\"parameters\":[{\"name\":\"metadata\",\"type\":\"JsonObject\",\"optional\":false}],\"returnType\":\"void\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_tenant_subscriptions\",\"api\":{\"include\":[\"list\",\"get\",\"create\",\"update\"]},\"cli\":true,\"mcp\":{\"include\":[\"list\",\"get\"]},\"conflictColumns\":[\"tenant_id\",\"subscriber_kind\",\"subscriber_external_id\"],\"tenantScoped\":{\"mode\":\"required\"}},\"extends\":\"SmrtObject\",\"exportName\":\"TenantSubscription\",\"collectionExportName\":\"TenantSubscriptionCollection\",\"validationRules\":[{\"field\":\"tenantId\",\"rule\":\"required\",\"fieldType\":\"text\"}],\"schema\":{\"tableName\":\"_smrt_tenant_subscriptions\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_tenant_subscriptions\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"tenant_id\\\" UUID NOT NULL,\\n \\\"subscriber_kind\\\" TEXT DEFAULT 'tenant',\\n \\\"subscriber_external_id\\\" TEXT DEFAULT '',\\n \\\"plan_id\\\" UUID,\\n \\\"status\\\" TEXT DEFAULT 'incomplete',\\n \\\"started_at\\\" TIMESTAMP,\\n \\\"current_period_start\\\" TIMESTAMP,\\n \\\"current_period_end\\\" TIMESTAMP,\\n \\\"trial_ends_at\\\" TIMESTAMP,\\n \\\"cancel_at_period_end\\\" BOOLEAN DEFAULT FALSE,\\n \\\"canceled_at\\\" TIMESTAMP,\\n \\\"external_provider\\\" TEXT DEFAULT 'stripe',\\n \\\"stripe_customer_id\\\" TEXT DEFAULT '',\\n \\\"stripe_subscription_id\\\" TEXT DEFAULT '',\\n \\\"stripe_checkout_session_id\\\" TEXT DEFAULT '',\\n \\\"metadata\\\" TEXT DEFAULT '{}'\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"tenantId\",\"notNull\":true,\"unique\":false},\"subscriber_kind\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"tenant\"},\"subscriber_external_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"plan_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false},\"status\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"incomplete\"},\"started_at\":{\"type\":\"TIMESTAMP\",\"notNull\":false,\"unique\":false},\"current_period_start\":{\"type\":\"TIMESTAMP\",\"notNull\":false,\"unique\":false},\"current_period_end\":{\"type\":\"TIMESTAMP\",\"notNull\":false,\"unique\":false},\"trial_ends_at\":{\"type\":\"TIMESTAMP\",\"notNull\":false,\"unique\":false},\"cancel_at_period_end\":{\"type\":\"BOOLEAN\",\"notNull\":false,\"unique\":false,\"default\":false},\"canceled_at\":{\"type\":\"TIMESTAMP\",\"notNull\":false,\"unique\":false},\"external_provider\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"stripe\"},\"stripe_customer_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"stripe_subscription_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"stripe_checkout_session_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"metadata\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"{}\"}},\"indexes\":[{\"name\":\"_smrt_tenant_subscriptions_id_idx\",\"columns\":[\"id\"]},{\"name\":\"_smrt_tenant_subscriptions_tenant_id_subscriber_kind_idx\",\"columns\":[\"tenant_id\",\"subscriber_kind\",\"subscriber_external_id\"],\"unique\":true}],\"version\":\"ef3d8be5\"}},\"@happyvertical/smrt-subscriptions:TenantUsageMetric\":{\"name\":\"tenantusagemetric\",\"className\":\"TenantUsageMetric\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:TenantUsageMetric\",\"collection\":\"tenantusagemetrics\",\"filePath\":\"/home/runner/.local/share/pnpm/store/.workspaces/arc-happyvertical-node-phdrb-runner-xv52x/smrt/smrt/packages/subscriptions/src/models/TenantUsageMetric.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{\"tenantId\":{\"type\":\"text\",\"required\":true,\"_meta\":{\"sqlType\":\"UUID\",\"__tenancy\":{\"isTenantIdField\":true,\"autoFilter\":true,\"required\":true,\"autoPopulate\":true,\"nullable\":false,\"mode\":\"required\",\"field\":\"tenantId\",\"allowSuperAdminBypass\":false}}},\"subscriberKind\":{\"type\":\"text\",\"required\":false,\"default\":\"tenant\"},\"subscriberExternalId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"metricKey\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"quantity\":{\"type\":\"decimal\",\"required\":false,\"default\":0},\"windowStart\":{\"type\":\"datetime\",\"required\":false},\"windowEnd\":{\"type\":\"datetime\",\"required\":false},\"source\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"sourceId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"projectId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"workRefType\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"workRefId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"provider\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"dimensions\":{\"type\":\"text\",\"required\":false,\"default\":\"{}\"}},\"methods\":{\"getSubscriber\":{\"name\":\"getSubscriber\",\"async\":false,\"parameters\":[],\"returnType\":\"Subscriber | null\",\"isStatic\":false,\"isPublic\":true},\"getDimensions\":{\"name\":\"getDimensions\",\"async\":false,\"parameters\":[],\"returnType\":\"JsonObject\",\"isStatic\":false,\"isPublic\":true},\"setDimensions\":{\"name\":\"setDimensions\",\"async\":false,\"parameters\":[{\"name\":\"dimensions\",\"type\":\"JsonObject\",\"optional\":false}],\"returnType\":\"void\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_tenant_usage_metrics\",\"api\":{\"include\":[\"list\",\"get\",\"create\"]},\"cli\":{\"include\":[\"list\",\"get\",\"create\"]},\"mcp\":{\"include\":[\"list\",\"get\"]},\"tenantScoped\":{\"mode\":\"required\"}},\"extends\":\"SmrtObject\",\"exportName\":\"TenantUsageMetric\",\"collectionExportName\":\"TenantUsageMetricCollection\",\"validationRules\":[{\"field\":\"tenantId\",\"rule\":\"required\",\"fieldType\":\"text\"}],\"schema\":{\"tableName\":\"_smrt_tenant_usage_metrics\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_tenant_usage_metrics\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"tenant_id\\\" UUID NOT NULL,\\n \\\"subscriber_kind\\\" TEXT DEFAULT 'tenant',\\n \\\"subscriber_external_id\\\" TEXT DEFAULT '',\\n \\\"metric_key\\\" TEXT DEFAULT '',\\n \\\"quantity\\\" REAL DEFAULT 0,\\n \\\"window_start\\\" TIMESTAMP,\\n \\\"window_end\\\" TIMESTAMP,\\n \\\"source\\\" TEXT DEFAULT '',\\n \\\"source_id\\\" TEXT DEFAULT '',\\n \\\"project_id\\\" TEXT DEFAULT '',\\n \\\"work_ref_type\\\" TEXT DEFAULT '',\\n \\\"work_ref_id\\\" TEXT DEFAULT '',\\n \\\"provider\\\" TEXT DEFAULT '',\\n \\\"dimensions\\\" TEXT DEFAULT '{}'\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"tenantId\",\"notNull\":true,\"unique\":false},\"subscriber_kind\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"tenant\"},\"subscriber_external_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"metric_key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"quantity\":{\"type\":\"REAL\",\"notNull\":false,\"unique\":false,\"default\":0},\"window_start\":{\"type\":\"TIMESTAMP\",\"notNull\":false,\"unique\":false},\"window_end\":{\"type\":\"TIMESTAMP\",\"notNull\":false,\"unique\":false},\"source\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"source_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"project_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"work_ref_type\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"work_ref_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"provider\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"dimensions\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"{}\"}},\"indexes\":[{\"name\":\"_smrt_tenant_usage_metrics_id_idx\",\"columns\":[\"id\"]},{\"name\":\"_smrt_tenant_usage_metrics_slug_context_idx\",\"columns\":[\"slug\",\"context\"],\"unique\":true}],\"version\":\"b799c746\"}},\"@happyvertical/smrt-subscriptions:PricingRule\":{\"name\":\"pricingrule\",\"className\":\"PricingRule\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:PricingRule\",\"collection\":\"pricingrules\",\"filePath\":\"/home/runner/.local/share/pnpm/store/.workspaces/arc-happyvertical-node-phdrb-runner-xv52x/smrt/smrt/packages/subscriptions/src/models/commercial.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{\"tenantId\":{\"type\":\"text\",\"required\":true,\"_meta\":{\"sqlType\":\"UUID\",\"__tenancy\":{\"isTenantIdField\":true,\"autoFilter\":true,\"required\":true,\"autoPopulate\":true,\"nullable\":false,\"mode\":\"required\",\"field\":\"tenantId\",\"allowSuperAdminBypass\":false}}},\"ruleKey\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"metricKey\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"serviceKey\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"strategy\":{\"type\":\"text\",\"required\":false,\"default\":\"fixed_unit\"},\"currency\":{\"type\":\"text\",\"required\":false,\"default\":\"USD\"},\"effectiveFrom\":{\"type\":\"datetime\",\"required\":false},\"effectiveTo\":{\"type\":\"datetime\",\"required\":false},\"priority\":{\"type\":\"integer\",\"required\":false,\"default\":0},\"terms\":{\"type\":\"text\",\"required\":false,\"default\":\"{}\"},\"active\":{\"type\":\"boolean\",\"required\":false,\"default\":true}},\"methods\":{\"getTerms\":{\"name\":\"getTerms\",\"async\":false,\"parameters\":[],\"returnType\":\"Record<string>\",\"isStatic\":false,\"isPublic\":true},\"setTerms\":{\"name\":\"setTerms\",\"async\":false,\"parameters\":[{\"name\":\"value\",\"type\":\"Record<string>\",\"optional\":false}],\"returnType\":\"void\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_pricing_rules\",\"api\":true,\"cli\":true,\"mcp\":true,\"tenantScoped\":{\"mode\":\"required\"}},\"extends\":\"SmrtObject\",\"exportName\":\"PricingRule\",\"collectionExportName\":\"PricingRuleCollection\",\"validationRules\":[{\"field\":\"tenantId\",\"rule\":\"required\",\"fieldType\":\"text\"}],\"schema\":{\"tableName\":\"_smrt_pricing_rules\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_pricing_rules\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"tenant_id\\\" UUID NOT NULL,\\n \\\"rule_key\\\" TEXT DEFAULT '',\\n \\\"metric_key\\\" TEXT DEFAULT '',\\n \\\"service_key\\\" TEXT DEFAULT '',\\n \\\"strategy\\\" TEXT DEFAULT 'fixed_unit',\\n \\\"currency\\\" TEXT DEFAULT 'USD',\\n \\\"effective_from\\\" TIMESTAMP,\\n \\\"effective_to\\\" TIMESTAMP,\\n \\\"priority\\\" INTEGER DEFAULT 0,\\n \\\"terms\\\" TEXT DEFAULT '{}',\\n \\\"active\\\" BOOLEAN DEFAULT TRUE\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"tenantId\",\"notNull\":true,\"unique\":false},\"rule_key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"metric_key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"service_key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"strategy\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"fixed_unit\"},\"currency\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"USD\"},\"effective_from\":{\"type\":\"TIMESTAMP\",\"notNull\":false,\"unique\":false},\"effective_to\":{\"type\":\"TIMESTAMP\",\"notNull\":false,\"unique\":false},\"priority\":{\"type\":\"INTEGER\",\"notNull\":false,\"unique\":false,\"default\":0},\"terms\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"{}\"},\"active\":{\"type\":\"BOOLEAN\",\"notNull\":false,\"unique\":false,\"default\":true}},\"indexes\":[{\"name\":\"_smrt_pricing_rules_id_idx\",\"columns\":[\"id\"]},{\"name\":\"_smrt_pricing_rules_slug_context_idx\",\"columns\":[\"slug\",\"context\"],\"unique\":true}],\"version\":\"88642897\"}},\"@happyvertical/smrt-subscriptions:ClientCharge\":{\"name\":\"clientcharge\",\"className\":\"ClientCharge\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:ClientCharge\",\"collection\":\"clientcharges\",\"filePath\":\"/home/runner/.local/share/pnpm/store/.workspaces/arc-happyvertical-node-phdrb-runner-xv52x/smrt/smrt/packages/subscriptions/src/models/commercial.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{\"tenantId\":{\"type\":\"text\",\"required\":true,\"_meta\":{\"sqlType\":\"UUID\",\"__tenancy\":{\"isTenantIdField\":true,\"autoFilter\":true,\"required\":true,\"autoPopulate\":true,\"nullable\":false,\"mode\":\"required\",\"field\":\"tenantId\",\"allowSuperAdminBypass\":false}}},\"usageEventId\":{\"type\":\"foreignKey\",\"required\":false,\"related\":\"TenantUsageMetric\"},\"subscriberKind\":{\"type\":\"text\",\"required\":false,\"default\":\"tenant\"},\"subscriberExternalId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"projectId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"workRefType\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"workRefId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"provider\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"serviceKey\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"metricKey\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"quantity\":{\"type\":\"decimal\",\"required\":false,\"default\":0},\"amount\":{\"type\":\"decimal\",\"required\":false,\"default\":0},\"currency\":{\"type\":\"text\",\"required\":false,\"default\":\"USD\"},\"pricingRuleId\":{\"type\":\"foreignKey\",\"required\":false,\"related\":\"PricingRule\"},\"pricingSnapshot\":{\"type\":\"text\",\"required\":false,\"default\":\"{}\"},\"status\":{\"type\":\"text\",\"required\":false,\"default\":\"draft\"},\"approvedAt\":{\"type\":\"datetime\",\"required\":false}},\"methods\":{\"getPricingSnapshot\":{\"name\":\"getPricingSnapshot\",\"async\":false,\"parameters\":[],\"returnType\":\"Record<string>\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_client_charges\",\"api\":{\"include\":[\"list\",\"get\"]},\"cli\":{\"include\":[\"list\",\"get\"]},\"mcp\":{\"include\":[\"list\",\"get\"]},\"conflictColumns\":[\"usage_event_id\"],\"tenantScoped\":{\"mode\":\"required\"}},\"extends\":\"SmrtObject\",\"exportName\":\"ClientCharge\",\"collectionExportName\":\"ClientChargeCollection\",\"validationRules\":[{\"field\":\"tenantId\",\"rule\":\"required\",\"fieldType\":\"text\"}],\"schema\":{\"tableName\":\"_smrt_client_charges\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_client_charges\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"tenant_id\\\" UUID NOT NULL,\\n \\\"usage_event_id\\\" UUID,\\n \\\"subscriber_kind\\\" TEXT DEFAULT 'tenant',\\n \\\"subscriber_external_id\\\" TEXT DEFAULT '',\\n \\\"project_id\\\" TEXT DEFAULT '',\\n \\\"work_ref_type\\\" TEXT DEFAULT '',\\n \\\"work_ref_id\\\" TEXT DEFAULT '',\\n \\\"provider\\\" TEXT DEFAULT '',\\n \\\"service_key\\\" TEXT DEFAULT '',\\n \\\"metric_key\\\" TEXT DEFAULT '',\\n \\\"quantity\\\" REAL DEFAULT 0,\\n \\\"amount\\\" REAL DEFAULT 0,\\n \\\"currency\\\" TEXT DEFAULT 'USD',\\n \\\"pricing_rule_id\\\" UUID,\\n \\\"pricing_snapshot\\\" TEXT DEFAULT '{}',\\n \\\"status\\\" TEXT DEFAULT 'draft',\\n \\\"approved_at\\\" TIMESTAMP\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"tenantId\",\"notNull\":true,\"unique\":false},\"usage_event_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false},\"subscriber_kind\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"tenant\"},\"subscriber_external_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"project_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"work_ref_type\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"work_ref_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"provider\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"service_key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"metric_key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"quantity\":{\"type\":\"REAL\",\"notNull\":false,\"unique\":false,\"default\":0},\"amount\":{\"type\":\"REAL\",\"notNull\":false,\"unique\":false,\"default\":0},\"currency\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"USD\"},\"pricing_rule_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false},\"pricing_snapshot\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"{}\"},\"status\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"draft\"},\"approved_at\":{\"type\":\"TIMESTAMP\",\"notNull\":false,\"unique\":false}},\"indexes\":[{\"name\":\"_smrt_client_charges_id_idx\",\"columns\":[\"id\"]},{\"name\":\"_smrt_client_charges_usage_event_id_idx\",\"columns\":[\"usage_event_id\"],\"unique\":true}],\"version\":\"9bee0a3e\"}},\"@happyvertical/smrt-subscriptions:BillingAdjustment\":{\"name\":\"billingadjustment\",\"className\":\"BillingAdjustment\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:BillingAdjustment\",\"collection\":\"billingadjustments\",\"filePath\":\"/home/runner/.local/share/pnpm/store/.workspaces/arc-happyvertical-node-phdrb-runner-xv52x/smrt/smrt/packages/subscriptions/src/models/commercial.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{\"tenantId\":{\"type\":\"text\",\"required\":true,\"_meta\":{\"sqlType\":\"UUID\",\"__tenancy\":{\"isTenantIdField\":true,\"autoFilter\":true,\"required\":true,\"autoPopulate\":true,\"nullable\":false,\"mode\":\"required\",\"field\":\"tenantId\",\"allowSuperAdminBypass\":false}}},\"clientChargeId\":{\"type\":\"foreignKey\",\"required\":false,\"related\":\"ClientCharge\"},\"amount\":{\"type\":\"decimal\",\"required\":false,\"default\":0},\"currency\":{\"type\":\"text\",\"required\":false,\"default\":\"USD\"},\"reason\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"source\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"sourceId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"createdBy\":{\"type\":\"text\",\"required\":false,\"default\":\"\"}},\"methods\":{},\"decoratorConfig\":{\"tableName\":\"_smrt_billing_adjustments\",\"api\":{\"include\":[\"list\",\"get\"]},\"cli\":{\"include\":[\"list\",\"get\"]},\"mcp\":{\"include\":[\"list\",\"get\"]},\"tenantScoped\":{\"mode\":\"required\"}},\"extends\":\"SmrtObject\",\"exportName\":\"BillingAdjustment\",\"collectionExportName\":\"BillingAdjustmentCollection\",\"validationRules\":[{\"field\":\"tenantId\",\"rule\":\"required\",\"fieldType\":\"text\"}],\"schema\":{\"tableName\":\"_smrt_billing_adjustments\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_billing_adjustments\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"tenant_id\\\" UUID NOT NULL,\\n \\\"client_charge_id\\\" UUID,\\n \\\"amount\\\" REAL DEFAULT 0,\\n \\\"currency\\\" TEXT DEFAULT 'USD',\\n \\\"reason\\\" TEXT DEFAULT '',\\n \\\"source\\\" TEXT DEFAULT '',\\n \\\"source_id\\\" TEXT DEFAULT '',\\n \\\"created_by\\\" TEXT DEFAULT ''\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"tenantId\",\"notNull\":true,\"unique\":false},\"client_charge_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false},\"amount\":{\"type\":\"REAL\",\"notNull\":false,\"unique\":false,\"default\":0},\"currency\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"USD\"},\"reason\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"source\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"source_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"created_by\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"}},\"indexes\":[{\"name\":\"_smrt_billing_adjustments_id_idx\",\"columns\":[\"id\"]},{\"name\":\"_smrt_billing_adjustments_slug_context_idx\",\"columns\":[\"slug\",\"context\"],\"unique\":true}],\"version\":\"fefa2538\"}},\"@happyvertical/smrt-subscriptions:SpendingPolicy\":{\"name\":\"spendingpolicy\",\"className\":\"SpendingPolicy\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:SpendingPolicy\",\"collection\":\"spendingpolicies\",\"filePath\":\"/home/runner/.local/share/pnpm/store/.workspaces/arc-happyvertical-node-phdrb-runner-xv52x/smrt/smrt/packages/subscriptions/src/models/commercial.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{\"tenantId\":{\"type\":\"text\",\"required\":true,\"_meta\":{\"sqlType\":\"UUID\",\"__tenancy\":{\"isTenantIdField\":true,\"autoFilter\":true,\"required\":true,\"autoPopulate\":true,\"nullable\":false,\"mode\":\"required\",\"field\":\"tenantId\",\"allowSuperAdminBypass\":false}}},\"name\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"subscriberKind\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"subscriberExternalId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"projectId\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"serviceKey\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"metricKey\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"period\":{\"type\":\"text\",\"required\":false,\"default\":\"month\"},\"rollingSeconds\":{\"type\":\"integer\",\"required\":false,\"default\":0},\"limitAmount\":{\"type\":\"decimal\",\"required\":false,\"default\":0},\"currency\":{\"type\":\"text\",\"required\":false,\"default\":\"USD\"},\"behavior\":{\"type\":\"text\",\"required\":false,\"default\":\"observe\"},\"priority\":{\"type\":\"integer\",\"required\":false,\"default\":0},\"active\":{\"type\":\"boolean\",\"required\":false,\"default\":true}},\"methods\":{},\"decoratorConfig\":{\"tableName\":\"_smrt_spending_policies\",\"conflictColumns\":[\"tenant_id\",\"subscriber_kind\",\"subscriber_external_id\",\"project_id\",\"service_key\",\"metric_key\",\"period\",\"name\"],\"api\":true,\"cli\":true,\"mcp\":true,\"tenantScoped\":{\"mode\":\"required\"}},\"extends\":\"SmrtObject\",\"exportName\":\"SpendingPolicy\",\"collectionExportName\":\"SpendingPolicyCollection\",\"validationRules\":[{\"field\":\"tenantId\",\"rule\":\"required\",\"fieldType\":\"text\"}],\"schema\":{\"tableName\":\"_smrt_spending_policies\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_spending_policies\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"tenant_id\\\" UUID NOT NULL,\\n \\\"name\\\" TEXT DEFAULT '',\\n \\\"subscriber_kind\\\" TEXT DEFAULT '',\\n \\\"subscriber_external_id\\\" TEXT DEFAULT '',\\n \\\"project_id\\\" TEXT DEFAULT '',\\n \\\"service_key\\\" TEXT DEFAULT '',\\n \\\"metric_key\\\" TEXT DEFAULT '',\\n \\\"period\\\" TEXT DEFAULT 'month',\\n \\\"rolling_seconds\\\" INTEGER DEFAULT 0,\\n \\\"limit_amount\\\" REAL DEFAULT 0,\\n \\\"currency\\\" TEXT DEFAULT 'USD',\\n \\\"behavior\\\" TEXT DEFAULT 'observe',\\n \\\"priority\\\" INTEGER DEFAULT 0,\\n \\\"active\\\" BOOLEAN DEFAULT TRUE\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"tenantId\",\"notNull\":true,\"unique\":false},\"name\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"subscriber_kind\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"subscriber_external_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"project_id\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"service_key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"metric_key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"period\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"month\"},\"rolling_seconds\":{\"type\":\"INTEGER\",\"notNull\":false,\"unique\":false,\"default\":0},\"limit_amount\":{\"type\":\"REAL\",\"notNull\":false,\"unique\":false,\"default\":0},\"currency\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"USD\"},\"behavior\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"observe\"},\"priority\":{\"type\":\"INTEGER\",\"notNull\":false,\"unique\":false,\"default\":0},\"active\":{\"type\":\"BOOLEAN\",\"notNull\":false,\"unique\":false,\"default\":true}},\"indexes\":[{\"name\":\"_smrt_spending_policies_id_idx\",\"columns\":[\"id\"]},{\"name\":\"_smrt_spending_policies_tenant_id_subscriber_kind_idx\",\"columns\":[\"tenant_id\",\"subscriber_kind\",\"subscriber_external_id\",\"project_id\",\"service_key\",\"metric_key\",\"period\",\"name\"],\"unique\":true}],\"version\":\"af20dc21\"}},\"@happyvertical/smrt-subscriptions:PricingRuleCollection\":{\"name\":\"pricingrulecollection\",\"className\":\"PricingRuleCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:PricingRuleCollection\",\"collection\":\"pricingrules\",\"filePath\":\"/home/runner/.local/share/pnpm/store/.workspaces/arc-happyvertical-node-phdrb-runner-xv52x/smrt/smrt/packages/subscriptions/src/models/commercial.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{},\"methods\":{},\"decoratorConfig\":{\"tableName\":\"_smrt_pricing_rules\"},\"extends\":\"SmrtCollection\",\"extendsTypeArg\":\"PricingRule\",\"exportName\":\"PricingRuleCollection\",\"collectionExportName\":\"PricingRuleCollectionCollection\",\"schema\":{\"tableName\":\"_smrt_pricing_rules\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_pricing_rules\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"}},\"indexes\":[{\"name\":\"_smrt_pricing_rules_id_idx\",\"columns\":[\"id\"]},{\"name\":\"_smrt_pricing_rules_slug_context_idx\",\"columns\":[\"slug\",\"context\"],\"unique\":true}],\"version\":\"3fb55a6a\"}},\"@happyvertical/smrt-subscriptions:ClientChargeCollection\":{\"name\":\"clientchargecollection\",\"className\":\"ClientChargeCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:ClientChargeCollection\",\"collection\":\"clientcharges\",\"filePath\":\"/home/runner/.local/share/pnpm/store/.workspaces/arc-happyvertical-node-phdrb-runner-xv52x/smrt/smrt/packages/subscriptions/src/models/commercial.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{},\"methods\":{},\"decoratorConfig\":{\"tableName\":\"_smrt_client_charges\"},\"extends\":\"SmrtCollection\",\"extendsTypeArg\":\"ClientCharge\",\"exportName\":\"ClientChargeCollection\",\"collectionExportName\":\"ClientChargeCollectionCollection\",\"schema\":{\"tableName\":\"_smrt_client_charges\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_client_charges\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"}},\"indexes\":[{\"name\":\"_smrt_client_charges_id_idx\",\"columns\":[\"id\"]},{\"name\":\"_smrt_client_charges_slug_context_idx\",\"columns\":[\"slug\",\"context\"],\"unique\":true}],\"version\":\"96756a5d\"}},\"@happyvertical/smrt-subscriptions:BillingAdjustmentCollection\":{\"name\":\"billingadjustmentcollection\",\"className\":\"BillingAdjustmentCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:BillingAdjustmentCollection\",\"collection\":\"billingadjustments\",\"filePath\":\"/home/runner/.local/share/pnpm/store/.workspaces/arc-happyvertical-node-phdrb-runner-xv52x/smrt/smrt/packages/subscriptions/src/models/commercial.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{},\"methods\":{},\"decoratorConfig\":{\"tableName\":\"_smrt_billing_adjustments\"},\"extends\":\"SmrtCollection\",\"extendsTypeArg\":\"BillingAdjustment\",\"exportName\":\"BillingAdjustmentCollection\",\"collectionExportName\":\"BillingAdjustmentCollectionCollection\",\"schema\":{\"tableName\":\"_smrt_billing_adjustments\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_billing_adjustments\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"}},\"indexes\":[{\"name\":\"_smrt_billing_adjustments_id_idx\",\"columns\":[\"id\"]},{\"name\":\"_smrt_billing_adjustments_slug_context_idx\",\"columns\":[\"slug\",\"context\"],\"unique\":true}],\"version\":\"5ca89c74\"}},\"@happyvertical/smrt-subscriptions:SpendingPolicyCollection\":{\"name\":\"spendingpolicycollection\",\"className\":\"SpendingPolicyCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:SpendingPolicyCollection\",\"collection\":\"spendingpolicies\",\"filePath\":\"/home/runner/.local/share/pnpm/store/.workspaces/arc-happyvertical-node-phdrb-runner-xv52x/smrt/smrt/packages/subscriptions/src/models/commercial.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{},\"methods\":{},\"decoratorConfig\":{\"tableName\":\"_smrt_spending_policies\"},\"extends\":\"SmrtCollection\",\"extendsTypeArg\":\"SpendingPolicy\",\"exportName\":\"SpendingPolicyCollection\",\"collectionExportName\":\"SpendingPolicyCollectionCollection\",\"schema\":{\"tableName\":\"_smrt_spending_policies\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_spending_policies\\\" (\\n \\\"id\\\" UUID PRIMARY KEY NOT NULL,\\n \\\"slug\\\" TEXT NOT NULL,\\n \\\"context\\\" TEXT NOT NULL DEFAULT '',\\n \\\"created_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\\"updated_at\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp\\n);\",\"columns\":{\"id\":{\"type\":\"UUID\",\"primaryKey\":true,\"referenceKind\":\"id\",\"notNull\":true},\"slug\":{\"type\":\"TEXT\",\"notNull\":true},\"context\":{\"type\":\"TEXT\",\"notNull\":true,\"default\":\"\"},\"created_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"},\"updated_at\":{\"type\":\"TIMESTAMP\",\"notNull\":true,\"default\":\"current_timestamp\"}},\"indexes\":[{\"name\":\"_smrt_spending_policies_id_idx\",\"columns\":[\"id\"]},{\"name\":\"_smrt_spending_policies_slug_context_idx\",\"columns\":[\"slug\",\"context\"],\"unique\":true}],\"version\":\"4f25df0f\"}}},\"moduleType\":\"smrt\",\"smrtDependencies\":[\"@happyvertical/smrt-core\",\"@happyvertical/smrt-tenancy\"]}"));
|
|
5
5
|
//#endregion
|
|
6
6
|
//#region src/utils.ts
|
|
7
7
|
var THRESHOLD_WINDOWS = [
|
|
@@ -16,6 +16,20 @@ var THRESHOLD_ENFORCEMENTS = [
|
|
|
16
16
|
"warn",
|
|
17
17
|
"block"
|
|
18
18
|
];
|
|
19
|
+
async function deterministicUuid(parts) {
|
|
20
|
+
const bytes = new TextEncoder().encode(JSON.stringify(parts));
|
|
21
|
+
const uuid = new Uint8Array(await crypto.subtle.digest("SHA-256", bytes)).slice(0, 16);
|
|
22
|
+
uuid[6] = uuid[6] & 15 | 80;
|
|
23
|
+
uuid[8] = uuid[8] & 63 | 128;
|
|
24
|
+
const hex = Array.from(uuid, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
25
|
+
return [
|
|
26
|
+
hex.slice(0, 8),
|
|
27
|
+
hex.slice(8, 12),
|
|
28
|
+
hex.slice(12, 16),
|
|
29
|
+
hex.slice(16, 20),
|
|
30
|
+
hex.slice(20)
|
|
31
|
+
].join("-");
|
|
32
|
+
}
|
|
19
33
|
function parseJsonArray(value, fallback = []) {
|
|
20
34
|
if (!value) return fallback;
|
|
21
35
|
try {
|
|
@@ -142,12 +156,12 @@ function utcWindow(now, unit) {
|
|
|
142
156
|
}
|
|
143
157
|
//#endregion
|
|
144
158
|
//#region src/models/SubscriptionPlan.ts
|
|
145
|
-
var __defProp$
|
|
146
|
-
var __getOwnPropDesc$
|
|
147
|
-
var __decorateClass$
|
|
148
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$
|
|
159
|
+
var __defProp$3 = Object.defineProperty;
|
|
160
|
+
var __getOwnPropDesc$3 = Object.getOwnPropertyDescriptor;
|
|
161
|
+
var __decorateClass$3 = (decorators, target, key, kind) => {
|
|
162
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$3(target, key) : target;
|
|
149
163
|
for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
150
|
-
if (kind && result) __defProp$
|
|
164
|
+
if (kind && result) __defProp$3(target, key, result);
|
|
151
165
|
return result;
|
|
152
166
|
};
|
|
153
167
|
var SubscriptionPlan = class extends SmrtObject {
|
|
@@ -209,8 +223,8 @@ var SubscriptionPlan = class extends SmrtObject {
|
|
|
209
223
|
this.metadata = stringifyJson(metadata);
|
|
210
224
|
}
|
|
211
225
|
};
|
|
212
|
-
__decorateClass$
|
|
213
|
-
SubscriptionPlan = __decorateClass$
|
|
226
|
+
__decorateClass$3([tenantId({ nullable: true })], SubscriptionPlan.prototype, "tenantId", 2);
|
|
227
|
+
SubscriptionPlan = __decorateClass$3([TenantScoped({ mode: "optional" }), smrt({
|
|
214
228
|
tableName: "_smrt_subscription_plans",
|
|
215
229
|
api: { include: [
|
|
216
230
|
"list",
|
|
@@ -247,12 +261,12 @@ var SubscriptionPlanCollection = class extends SmrtCollection {
|
|
|
247
261
|
};
|
|
248
262
|
//#endregion
|
|
249
263
|
//#region src/models/TenantSubscription.ts
|
|
250
|
-
var __defProp$
|
|
251
|
-
var __getOwnPropDesc$
|
|
252
|
-
var __decorateClass$
|
|
253
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$
|
|
264
|
+
var __defProp$2 = Object.defineProperty;
|
|
265
|
+
var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
|
|
266
|
+
var __decorateClass$2 = (decorators, target, key, kind) => {
|
|
267
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target;
|
|
254
268
|
for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
255
|
-
if (kind && result) __defProp$
|
|
269
|
+
if (kind && result) __defProp$2(target, key, result);
|
|
256
270
|
return result;
|
|
257
271
|
};
|
|
258
272
|
var TenantSubscription = class extends SmrtObject {
|
|
@@ -360,9 +374,9 @@ var TenantSubscription = class extends SmrtObject {
|
|
|
360
374
|
this.metadata = stringifyJson(metadata);
|
|
361
375
|
}
|
|
362
376
|
};
|
|
363
|
-
__decorateClass$
|
|
364
|
-
__decorateClass$
|
|
365
|
-
TenantSubscription = __decorateClass$
|
|
377
|
+
__decorateClass$2([tenantId()], TenantSubscription.prototype, "tenantId", 2);
|
|
378
|
+
__decorateClass$2([foreignKey("SubscriptionPlan")], TenantSubscription.prototype, "planId", 2);
|
|
379
|
+
TenantSubscription = __decorateClass$2([TenantScoped({ mode: "required" }), smrt({
|
|
366
380
|
tableName: "_smrt_tenant_subscriptions",
|
|
367
381
|
api: { include: [
|
|
368
382
|
"list",
|
|
@@ -433,12 +447,12 @@ var TenantSubscriptionCollection = class extends SmrtCollection {
|
|
|
433
447
|
};
|
|
434
448
|
//#endregion
|
|
435
449
|
//#region src/models/TenantUsageMetric.ts
|
|
436
|
-
var __defProp = Object.defineProperty;
|
|
437
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
438
|
-
var __decorateClass = (decorators, target, key, kind) => {
|
|
439
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
450
|
+
var __defProp$1 = Object.defineProperty;
|
|
451
|
+
var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
|
|
452
|
+
var __decorateClass$1 = (decorators, target, key, kind) => {
|
|
453
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
|
|
440
454
|
for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
441
|
-
if (kind && result) __defProp(target, key, result);
|
|
455
|
+
if (kind && result) __defProp$1(target, key, result);
|
|
442
456
|
return result;
|
|
443
457
|
};
|
|
444
458
|
var TenantUsageMetric = class extends SmrtObject {
|
|
@@ -460,6 +474,10 @@ var TenantUsageMetric = class extends SmrtObject {
|
|
|
460
474
|
windowEnd = /* @__PURE__ */ new Date();
|
|
461
475
|
source = "";
|
|
462
476
|
sourceId = "";
|
|
477
|
+
projectId = "";
|
|
478
|
+
workRefType = "";
|
|
479
|
+
workRefId = "";
|
|
480
|
+
provider = "";
|
|
463
481
|
dimensions = "{}";
|
|
464
482
|
constructor(options = {}) {
|
|
465
483
|
super(options);
|
|
@@ -476,6 +494,10 @@ var TenantUsageMetric = class extends SmrtObject {
|
|
|
476
494
|
if (options.windowEnd !== void 0) this.windowEnd = options.windowEnd;
|
|
477
495
|
if (options.source !== void 0) this.source = options.source;
|
|
478
496
|
if (options.sourceId !== void 0) this.sourceId = options.sourceId;
|
|
497
|
+
if (options.projectId !== void 0) this.projectId = options.projectId;
|
|
498
|
+
if (options.workRefType !== void 0) this.workRefType = options.workRefType;
|
|
499
|
+
if (options.workRefId !== void 0) this.workRefId = options.workRefId;
|
|
500
|
+
if (options.provider !== void 0) this.provider = options.provider;
|
|
479
501
|
if (options.dimensions !== void 0) this.dimensions = options.dimensions;
|
|
480
502
|
}
|
|
481
503
|
/** See `TenantSubscription.validateBeforeSave` for the rationale. */
|
|
@@ -485,6 +507,44 @@ var TenantUsageMetric = class extends SmrtObject {
|
|
|
485
507
|
subscriberKind: this.subscriberKind,
|
|
486
508
|
subscriberExternalId: this.subscriberExternalId
|
|
487
509
|
});
|
|
510
|
+
if (this.id) {
|
|
511
|
+
const row = await this.db.get(this.tableName, { id: this.id });
|
|
512
|
+
if (row) {
|
|
513
|
+
const persisted = [
|
|
514
|
+
row.tenant_id,
|
|
515
|
+
row.subscriber_kind,
|
|
516
|
+
row.subscriber_external_id,
|
|
517
|
+
row.metric_key,
|
|
518
|
+
row.quantity,
|
|
519
|
+
row.window_start,
|
|
520
|
+
row.window_end,
|
|
521
|
+
row.source,
|
|
522
|
+
row.source_id,
|
|
523
|
+
row.project_id,
|
|
524
|
+
row.work_ref_type,
|
|
525
|
+
row.work_ref_id,
|
|
526
|
+
row.provider,
|
|
527
|
+
row.dimensions
|
|
528
|
+
];
|
|
529
|
+
const current = [
|
|
530
|
+
this.tenantId,
|
|
531
|
+
this.subscriberKind,
|
|
532
|
+
this.subscriberExternalId,
|
|
533
|
+
this.metricKey,
|
|
534
|
+
this.quantity,
|
|
535
|
+
this.windowStart,
|
|
536
|
+
this.windowEnd,
|
|
537
|
+
this.source,
|
|
538
|
+
this.sourceId,
|
|
539
|
+
this.projectId,
|
|
540
|
+
this.workRefType,
|
|
541
|
+
this.workRefId,
|
|
542
|
+
this.provider,
|
|
543
|
+
this.dimensions
|
|
544
|
+
];
|
|
545
|
+
if (persisted.some((value, index) => normalizeEvidence(value) !== normalizeEvidence(current[index]))) throw new Error("Usage events are immutable; record a new event instead.");
|
|
546
|
+
}
|
|
547
|
+
}
|
|
488
548
|
}
|
|
489
549
|
/**
|
|
490
550
|
* Project this row's polymorphic subscriber columns onto the
|
|
@@ -512,17 +572,29 @@ var TenantUsageMetric = class extends SmrtObject {
|
|
|
512
572
|
this.dimensions = stringifyJson(dimensions);
|
|
513
573
|
}
|
|
514
574
|
};
|
|
515
|
-
__decorateClass([tenantId()], TenantUsageMetric.prototype, "tenantId", 2);
|
|
516
|
-
TenantUsageMetric = __decorateClass([TenantScoped({ mode: "required" }), smrt({
|
|
575
|
+
__decorateClass$1([tenantId()], TenantUsageMetric.prototype, "tenantId", 2);
|
|
576
|
+
TenantUsageMetric = __decorateClass$1([TenantScoped({ mode: "required" }), smrt({
|
|
517
577
|
tableName: "_smrt_tenant_usage_metrics",
|
|
518
578
|
api: { include: [
|
|
519
579
|
"list",
|
|
520
580
|
"get",
|
|
521
581
|
"create"
|
|
522
582
|
] },
|
|
523
|
-
cli:
|
|
583
|
+
cli: { include: [
|
|
584
|
+
"list",
|
|
585
|
+
"get",
|
|
586
|
+
"create"
|
|
587
|
+
] },
|
|
524
588
|
mcp: { include: ["list", "get"] }
|
|
525
589
|
})], TenantUsageMetric);
|
|
590
|
+
function normalizeEvidence(value) {
|
|
591
|
+
if (value instanceof Date) return value.toISOString();
|
|
592
|
+
if (typeof value === "string") {
|
|
593
|
+
const timestamp = Date.parse(value);
|
|
594
|
+
if (/^\d{4}-\d{2}-\d{2}[T ]/.test(value) && Number.isFinite(timestamp)) return new Date(timestamp).toISOString();
|
|
595
|
+
}
|
|
596
|
+
return String(value ?? "");
|
|
597
|
+
}
|
|
526
598
|
//#endregion
|
|
527
599
|
//#region src/collections/TenantUsageMetricCollection.ts
|
|
528
600
|
var TenantUsageMetricCollection = class extends SmrtCollection {
|
|
@@ -533,18 +605,45 @@ var TenantUsageMetricCollection = class extends SmrtCollection {
|
|
|
533
605
|
subscriberKind: options.subscriberKind,
|
|
534
606
|
subscriberExternalId: options.subscriberExternalId
|
|
535
607
|
}));
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
608
|
+
const sourcedId = options.source && options.sourceId ? await deterministicUuid([
|
|
609
|
+
"tenant-usage",
|
|
610
|
+
columns.tenantId,
|
|
611
|
+
columns.subscriberKind,
|
|
612
|
+
columns.subscriberExternalId,
|
|
613
|
+
options.metricKey,
|
|
614
|
+
options.source,
|
|
615
|
+
options.sourceId
|
|
616
|
+
]) : null;
|
|
617
|
+
if (options.source && options.sourceId) {
|
|
618
|
+
const existing = await this.get(sourcedId);
|
|
619
|
+
if (existing) return existing;
|
|
620
|
+
}
|
|
621
|
+
try {
|
|
622
|
+
return await this.create({
|
|
623
|
+
...sourcedId ? { id: sourcedId } : {},
|
|
624
|
+
tenantId: columns.tenantId,
|
|
625
|
+
subscriberKind: columns.subscriberKind,
|
|
626
|
+
subscriberExternalId: columns.subscriberExternalId,
|
|
627
|
+
metricKey: options.metricKey,
|
|
628
|
+
quantity: options.quantity,
|
|
629
|
+
windowStart: options.windowStart,
|
|
630
|
+
windowEnd: options.windowEnd,
|
|
631
|
+
source: options.source ?? "",
|
|
632
|
+
sourceId: options.sourceId ?? "",
|
|
633
|
+
projectId: options.projectId ?? "",
|
|
634
|
+
workRefType: options.workRefType ?? "",
|
|
635
|
+
workRefId: options.workRefId ?? "",
|
|
636
|
+
provider: options.provider ?? "",
|
|
637
|
+
dimensions: stringifyJson(options.dimensions ?? {}),
|
|
638
|
+
_insertOnly: Boolean(sourcedId)
|
|
639
|
+
});
|
|
640
|
+
} catch (error) {
|
|
641
|
+
if (sourcedId) {
|
|
642
|
+
const existing = await this.get(sourcedId);
|
|
643
|
+
if (existing) return existing;
|
|
644
|
+
}
|
|
645
|
+
throw error;
|
|
646
|
+
}
|
|
548
647
|
}
|
|
549
648
|
/**
|
|
550
649
|
* Legacy accessor — finds metrics for `subscriberKind = 'tenant'` under the
|
|
@@ -693,6 +792,523 @@ function numberFromRow(row, key) {
|
|
|
693
792
|
return 0;
|
|
694
793
|
}
|
|
695
794
|
//#endregion
|
|
795
|
+
//#region src/models/commercial.ts
|
|
796
|
+
var __defProp = Object.defineProperty;
|
|
797
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
798
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
799
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
800
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
801
|
+
if (kind && result) __defProp(target, key, result);
|
|
802
|
+
return result;
|
|
803
|
+
};
|
|
804
|
+
var PricingRule = class extends SmrtObject {
|
|
805
|
+
tenantId;
|
|
806
|
+
ruleKey = "";
|
|
807
|
+
metricKey = "";
|
|
808
|
+
serviceKey = "";
|
|
809
|
+
strategy = "fixed_unit";
|
|
810
|
+
currency = "USD";
|
|
811
|
+
effectiveFrom = /* @__PURE__ */ new Date();
|
|
812
|
+
effectiveTo = null;
|
|
813
|
+
priority = 0;
|
|
814
|
+
terms = "{}";
|
|
815
|
+
active = true;
|
|
816
|
+
getTerms() {
|
|
817
|
+
try {
|
|
818
|
+
return JSON.parse(this.terms);
|
|
819
|
+
} catch {
|
|
820
|
+
return {};
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
setTerms(value) {
|
|
824
|
+
this.terms = JSON.stringify(value);
|
|
825
|
+
}
|
|
826
|
+
};
|
|
827
|
+
__decorateClass([tenantId()], PricingRule.prototype, "tenantId", 2);
|
|
828
|
+
PricingRule = __decorateClass([TenantScoped({ mode: "required" }), smrt({
|
|
829
|
+
tableName: "_smrt_pricing_rules",
|
|
830
|
+
api: true,
|
|
831
|
+
cli: true,
|
|
832
|
+
mcp: true
|
|
833
|
+
})], PricingRule);
|
|
834
|
+
var ClientCharge = class extends SmrtObject {
|
|
835
|
+
tenantId;
|
|
836
|
+
usageEventId = "";
|
|
837
|
+
subscriberKind = "tenant";
|
|
838
|
+
subscriberExternalId = "";
|
|
839
|
+
projectId = "";
|
|
840
|
+
workRefType = "";
|
|
841
|
+
workRefId = "";
|
|
842
|
+
provider = "";
|
|
843
|
+
serviceKey = "";
|
|
844
|
+
metricKey = "";
|
|
845
|
+
quantity = 0;
|
|
846
|
+
amount = 0;
|
|
847
|
+
currency = "USD";
|
|
848
|
+
pricingRuleId = "";
|
|
849
|
+
pricingSnapshot = "{}";
|
|
850
|
+
status = "draft";
|
|
851
|
+
approvedAt = null;
|
|
852
|
+
getPricingSnapshot() {
|
|
853
|
+
try {
|
|
854
|
+
return JSON.parse(this.pricingSnapshot);
|
|
855
|
+
} catch {
|
|
856
|
+
return {};
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
async validateBeforeSave() {
|
|
860
|
+
await super.validateBeforeSave();
|
|
861
|
+
if (!this.id) return;
|
|
862
|
+
const row = await this.db.get(this.tableName, { id: this.id });
|
|
863
|
+
if (!row || row.status !== "approved" && row.status !== "adjusted") return;
|
|
864
|
+
if (row.status === "approved" && this.status !== "approved" && this.status !== "adjusted" || row.status === "adjusted" && this.status !== "adjusted") throw new Error("Approved client charges cannot be reverted to an editable status.");
|
|
865
|
+
const persisted = [
|
|
866
|
+
row.tenant_id,
|
|
867
|
+
row.usage_event_id,
|
|
868
|
+
row.subscriber_kind,
|
|
869
|
+
row.subscriber_external_id,
|
|
870
|
+
row.project_id,
|
|
871
|
+
row.work_ref_type,
|
|
872
|
+
row.work_ref_id,
|
|
873
|
+
row.provider,
|
|
874
|
+
row.service_key,
|
|
875
|
+
row.metric_key,
|
|
876
|
+
row.quantity,
|
|
877
|
+
row.amount,
|
|
878
|
+
row.currency,
|
|
879
|
+
row.pricing_rule_id,
|
|
880
|
+
row.pricing_snapshot,
|
|
881
|
+
row.approved_at
|
|
882
|
+
];
|
|
883
|
+
const current = [
|
|
884
|
+
this.tenantId,
|
|
885
|
+
this.usageEventId,
|
|
886
|
+
this.subscriberKind,
|
|
887
|
+
this.subscriberExternalId,
|
|
888
|
+
this.projectId,
|
|
889
|
+
this.workRefType,
|
|
890
|
+
this.workRefId,
|
|
891
|
+
this.provider,
|
|
892
|
+
this.serviceKey,
|
|
893
|
+
this.metricKey,
|
|
894
|
+
this.quantity,
|
|
895
|
+
this.amount,
|
|
896
|
+
this.currency,
|
|
897
|
+
this.pricingRuleId,
|
|
898
|
+
this.pricingSnapshot,
|
|
899
|
+
this.approvedAt
|
|
900
|
+
];
|
|
901
|
+
if (persisted.some((value, index) => normalizeSnapshot(value) !== normalizeSnapshot(current[index]))) throw new Error("Approved client charges are immutable; append a BillingAdjustment instead.");
|
|
902
|
+
}
|
|
903
|
+
};
|
|
904
|
+
__decorateClass([tenantId()], ClientCharge.prototype, "tenantId", 2);
|
|
905
|
+
__decorateClass([foreignKey("TenantUsageMetric")], ClientCharge.prototype, "usageEventId", 2);
|
|
906
|
+
__decorateClass([foreignKey("PricingRule")], ClientCharge.prototype, "pricingRuleId", 2);
|
|
907
|
+
ClientCharge = __decorateClass([TenantScoped({ mode: "required" }), smrt({
|
|
908
|
+
tableName: "_smrt_client_charges",
|
|
909
|
+
api: { include: ["list", "get"] },
|
|
910
|
+
cli: { include: ["list", "get"] },
|
|
911
|
+
mcp: { include: ["list", "get"] },
|
|
912
|
+
conflictColumns: ["usage_event_id"]
|
|
913
|
+
})], ClientCharge);
|
|
914
|
+
var BillingAdjustment = class extends SmrtObject {
|
|
915
|
+
tenantId;
|
|
916
|
+
clientChargeId = "";
|
|
917
|
+
amount = 0;
|
|
918
|
+
currency = "USD";
|
|
919
|
+
reason = "";
|
|
920
|
+
source = "";
|
|
921
|
+
sourceId = "";
|
|
922
|
+
createdBy = "";
|
|
923
|
+
async validateBeforeSave() {
|
|
924
|
+
await super.validateBeforeSave();
|
|
925
|
+
if (!this.id) return;
|
|
926
|
+
if (await this.db.get(this.tableName, { id: this.id })) throw new Error("Billing adjustments are append-only; create a new adjustment instead.");
|
|
927
|
+
}
|
|
928
|
+
};
|
|
929
|
+
__decorateClass([tenantId()], BillingAdjustment.prototype, "tenantId", 2);
|
|
930
|
+
__decorateClass([foreignKey("ClientCharge")], BillingAdjustment.prototype, "clientChargeId", 2);
|
|
931
|
+
BillingAdjustment = __decorateClass([TenantScoped({ mode: "required" }), smrt({
|
|
932
|
+
tableName: "_smrt_billing_adjustments",
|
|
933
|
+
api: { include: ["list", "get"] },
|
|
934
|
+
cli: { include: ["list", "get"] },
|
|
935
|
+
mcp: { include: ["list", "get"] }
|
|
936
|
+
})], BillingAdjustment);
|
|
937
|
+
var SpendingPolicy = class extends SmrtObject {
|
|
938
|
+
tenantId;
|
|
939
|
+
name = "";
|
|
940
|
+
subscriberKind = "";
|
|
941
|
+
subscriberExternalId = "";
|
|
942
|
+
projectId = "";
|
|
943
|
+
serviceKey = "";
|
|
944
|
+
metricKey = "";
|
|
945
|
+
period = "month";
|
|
946
|
+
rollingSeconds = 0;
|
|
947
|
+
limitAmount = 0;
|
|
948
|
+
currency = "USD";
|
|
949
|
+
behavior = "observe";
|
|
950
|
+
priority = 0;
|
|
951
|
+
active = true;
|
|
952
|
+
async validateBeforeSave() {
|
|
953
|
+
await super.validateBeforeSave();
|
|
954
|
+
if (this.subscriberExternalId && !this.subscriberKind) throw new Error("Spending policies with subscriberExternalId require subscriberKind.");
|
|
955
|
+
if (this.period === "rolling" && (!Number.isFinite(this.rollingSeconds) || this.rollingSeconds <= 0)) throw new Error("Rolling spending policies require rollingSeconds greater than zero.");
|
|
956
|
+
}
|
|
957
|
+
};
|
|
958
|
+
__decorateClass([tenantId()], SpendingPolicy.prototype, "tenantId", 2);
|
|
959
|
+
SpendingPolicy = __decorateClass([TenantScoped({ mode: "required" }), smrt({
|
|
960
|
+
tableName: "_smrt_spending_policies",
|
|
961
|
+
conflictColumns: [
|
|
962
|
+
"tenant_id",
|
|
963
|
+
"subscriber_kind",
|
|
964
|
+
"subscriber_external_id",
|
|
965
|
+
"project_id",
|
|
966
|
+
"service_key",
|
|
967
|
+
"metric_key",
|
|
968
|
+
"period",
|
|
969
|
+
"name"
|
|
970
|
+
],
|
|
971
|
+
api: true,
|
|
972
|
+
cli: true,
|
|
973
|
+
mcp: true
|
|
974
|
+
})], SpendingPolicy);
|
|
975
|
+
var PricingRuleCollection = class extends SmrtCollection {
|
|
976
|
+
static _itemClass = PricingRule;
|
|
977
|
+
};
|
|
978
|
+
var ClientChargeCollection = class extends SmrtCollection {
|
|
979
|
+
static _itemClass = ClientCharge;
|
|
980
|
+
};
|
|
981
|
+
var BillingAdjustmentCollection = class extends SmrtCollection {
|
|
982
|
+
static _itemClass = BillingAdjustment;
|
|
983
|
+
};
|
|
984
|
+
var SpendingPolicyCollection = class extends SmrtCollection {
|
|
985
|
+
static _itemClass = SpendingPolicy;
|
|
986
|
+
};
|
|
987
|
+
function normalizeSnapshot(value) {
|
|
988
|
+
if (value instanceof Date) return value.toISOString();
|
|
989
|
+
if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}[T ]/.test(value)) {
|
|
990
|
+
const timestamp = Date.parse(value);
|
|
991
|
+
if (Number.isFinite(timestamp)) return new Date(timestamp).toISOString();
|
|
992
|
+
}
|
|
993
|
+
return String(value ?? "");
|
|
994
|
+
}
|
|
995
|
+
//#endregion
|
|
996
|
+
//#region src/services/commercial.ts
|
|
997
|
+
var CommercialUsageService = class CommercialUsageService {
|
|
998
|
+
constructor(usage, rules, charges, adjustments) {
|
|
999
|
+
this.usage = usage;
|
|
1000
|
+
this.rules = rules;
|
|
1001
|
+
this.charges = charges;
|
|
1002
|
+
this.adjustments = adjustments;
|
|
1003
|
+
}
|
|
1004
|
+
usage;
|
|
1005
|
+
rules;
|
|
1006
|
+
charges;
|
|
1007
|
+
adjustments;
|
|
1008
|
+
customStrategies = /* @__PURE__ */ new Map();
|
|
1009
|
+
static async create(options = {}) {
|
|
1010
|
+
const usage = await TenantUsageMetricCollection.create(options);
|
|
1011
|
+
const sharedOptions = {
|
|
1012
|
+
...options,
|
|
1013
|
+
db: usage.db
|
|
1014
|
+
};
|
|
1015
|
+
return new CommercialUsageService(usage, await PricingRuleCollection.create(sharedOptions), await ClientChargeCollection.create(sharedOptions), await BillingAdjustmentCollection.create(sharedOptions));
|
|
1016
|
+
}
|
|
1017
|
+
registerCustomStrategy(key, strategy) {
|
|
1018
|
+
this.customStrategies.set(key, strategy);
|
|
1019
|
+
}
|
|
1020
|
+
async record(options) {
|
|
1021
|
+
return this.usage.recordUsage(options);
|
|
1022
|
+
}
|
|
1023
|
+
async price(options) {
|
|
1024
|
+
const existing = await this.charges.list({
|
|
1025
|
+
where: { usageEventId: options.usageEventId },
|
|
1026
|
+
limit: 1
|
|
1027
|
+
});
|
|
1028
|
+
if (existing[0]) return this.approveCharge(existing[0], options.approved);
|
|
1029
|
+
const usage = await this.usage.get(options.usageEventId);
|
|
1030
|
+
if (!usage) throw new Error(`Usage event ${options.usageEventId} was not found.`);
|
|
1031
|
+
const at = options.at ?? usage.windowStart;
|
|
1032
|
+
const dimensions = usage.getDimensions();
|
|
1033
|
+
const rule = selectRule(await this.rules.list({ where: {
|
|
1034
|
+
tenantId: usage.tenantId,
|
|
1035
|
+
metricKey: usage.metricKey,
|
|
1036
|
+
active: true
|
|
1037
|
+
} }), at, String(dimensions.serviceKey ?? ""));
|
|
1038
|
+
if (!rule) throw new Error(`No effective pricing rule for metric '${usage.metricKey}'.`);
|
|
1039
|
+
if (!usage.id) throw new Error(`Usage event ${options.usageEventId} has no persisted id.`);
|
|
1040
|
+
if (!rule.id) throw new Error(`Pricing rule '${rule.ruleKey}' has no persisted id.`);
|
|
1041
|
+
const amount = await this.calculateAmount(rule, usage.quantity, dimensions);
|
|
1042
|
+
const chargeId = await deterministicUuid([
|
|
1043
|
+
"client-charge",
|
|
1044
|
+
String(usage.tenantId),
|
|
1045
|
+
String(usage.id)
|
|
1046
|
+
]);
|
|
1047
|
+
try {
|
|
1048
|
+
return await this.charges.create({
|
|
1049
|
+
id: chargeId,
|
|
1050
|
+
tenantId: usage.tenantId,
|
|
1051
|
+
usageEventId: String(usage.id),
|
|
1052
|
+
subscriberKind: usage.subscriberKind,
|
|
1053
|
+
subscriberExternalId: usage.subscriberExternalId,
|
|
1054
|
+
projectId: usage.projectId,
|
|
1055
|
+
workRefType: usage.workRefType,
|
|
1056
|
+
workRefId: usage.workRefId,
|
|
1057
|
+
provider: usage.provider,
|
|
1058
|
+
serviceKey: String(dimensions.serviceKey ?? ""),
|
|
1059
|
+
metricKey: usage.metricKey,
|
|
1060
|
+
quantity: usage.quantity,
|
|
1061
|
+
amount,
|
|
1062
|
+
currency: rule.currency,
|
|
1063
|
+
pricingRuleId: String(rule.id),
|
|
1064
|
+
pricingSnapshot: JSON.stringify({
|
|
1065
|
+
ruleKey: rule.ruleKey,
|
|
1066
|
+
strategy: rule.strategy,
|
|
1067
|
+
terms: rule.getTerms(),
|
|
1068
|
+
effectiveFrom: rule.effectiveFrom
|
|
1069
|
+
}),
|
|
1070
|
+
status: options.approved ? "approved" : "draft",
|
|
1071
|
+
approvedAt: options.approved ? /* @__PURE__ */ new Date() : null,
|
|
1072
|
+
_insertOnly: true
|
|
1073
|
+
});
|
|
1074
|
+
} catch (error) {
|
|
1075
|
+
const concurrent = await this.charges.get(chargeId);
|
|
1076
|
+
if (!concurrent) throw error;
|
|
1077
|
+
return this.approveCharge(concurrent, options.approved);
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
async approveCharge(charge, approved = false) {
|
|
1081
|
+
if (approved && charge.status === "draft") {
|
|
1082
|
+
charge.status = "approved";
|
|
1083
|
+
charge.approvedAt = /* @__PURE__ */ new Date();
|
|
1084
|
+
await charge.save();
|
|
1085
|
+
}
|
|
1086
|
+
return charge;
|
|
1087
|
+
}
|
|
1088
|
+
async adjust(chargeId, amount, reason, source = "", sourceId = "") {
|
|
1089
|
+
const charge = await this.charges.get(chargeId);
|
|
1090
|
+
if (!charge) throw new Error(`Client charge ${chargeId} was not found.`);
|
|
1091
|
+
if (charge.status !== "approved" && charge.status !== "adjusted") throw new Error(`Client charge ${chargeId} must be approved before it can be adjusted.`);
|
|
1092
|
+
const sourcedId = source && sourceId ? await deterministicUuid([
|
|
1093
|
+
"billing-adjustment",
|
|
1094
|
+
String(charge.tenantId),
|
|
1095
|
+
chargeId,
|
|
1096
|
+
source,
|
|
1097
|
+
sourceId
|
|
1098
|
+
]) : null;
|
|
1099
|
+
let adjustment = sourcedId ? await this.adjustments.get(sourcedId) : void 0;
|
|
1100
|
+
if (!adjustment) try {
|
|
1101
|
+
adjustment = await this.adjustments.create({
|
|
1102
|
+
...sourcedId ? { id: sourcedId } : {},
|
|
1103
|
+
tenantId: charge.tenantId,
|
|
1104
|
+
clientChargeId: chargeId,
|
|
1105
|
+
amount,
|
|
1106
|
+
currency: charge.currency,
|
|
1107
|
+
reason,
|
|
1108
|
+
source,
|
|
1109
|
+
sourceId,
|
|
1110
|
+
_insertOnly: Boolean(sourcedId)
|
|
1111
|
+
});
|
|
1112
|
+
} catch (error) {
|
|
1113
|
+
if (sourcedId) adjustment = await this.adjustments.get(sourcedId);
|
|
1114
|
+
if (!adjustment) throw error;
|
|
1115
|
+
}
|
|
1116
|
+
if (charge.status === "approved") {
|
|
1117
|
+
charge.status = "adjusted";
|
|
1118
|
+
await charge.save();
|
|
1119
|
+
}
|
|
1120
|
+
return adjustment;
|
|
1121
|
+
}
|
|
1122
|
+
async calculateAmount(rule, quantity, dimensions = {}) {
|
|
1123
|
+
const terms = rule.getTerms();
|
|
1124
|
+
const number = (key, fallback = 0) => Number(terms[key] ?? fallback);
|
|
1125
|
+
let amount;
|
|
1126
|
+
switch (rule.strategy) {
|
|
1127
|
+
case "fixed_unit":
|
|
1128
|
+
amount = quantity * number("unitPrice");
|
|
1129
|
+
break;
|
|
1130
|
+
case "cost_plus":
|
|
1131
|
+
amount = Number(dimensions.providerCost ?? 0) + number("fixedMarkup") + Number(dimensions.providerCost ?? 0) * number("markupRatio");
|
|
1132
|
+
break;
|
|
1133
|
+
case "multiplier":
|
|
1134
|
+
amount = Number(dimensions.providerCost ?? quantity) * number("multiplier", 1);
|
|
1135
|
+
break;
|
|
1136
|
+
case "flat":
|
|
1137
|
+
amount = number("amount");
|
|
1138
|
+
break;
|
|
1139
|
+
case "included_overage":
|
|
1140
|
+
amount = Math.max(0, quantity - number("includedQuantity")) * number("overageUnitPrice");
|
|
1141
|
+
break;
|
|
1142
|
+
case "tiered":
|
|
1143
|
+
amount = priceTiers(quantity, Array.isArray(terms.tiers) ? terms.tiers : []);
|
|
1144
|
+
break;
|
|
1145
|
+
case "custom": {
|
|
1146
|
+
const custom = this.customStrategies.get(String(terms.strategyKey ?? ""));
|
|
1147
|
+
if (!custom) throw new Error(`Custom pricing strategy '${String(terms.strategyKey ?? "")}' is not registered.`);
|
|
1148
|
+
amount = await custom({
|
|
1149
|
+
usage: {
|
|
1150
|
+
quantity,
|
|
1151
|
+
dimensions
|
|
1152
|
+
},
|
|
1153
|
+
rule,
|
|
1154
|
+
terms
|
|
1155
|
+
});
|
|
1156
|
+
break;
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
if (!Number.isFinite(amount) || amount < 0) throw new Error("Pricing produced an invalid amount.");
|
|
1160
|
+
return Math.round(amount * 1e6) / 1e6;
|
|
1161
|
+
}
|
|
1162
|
+
};
|
|
1163
|
+
var SpendingPolicyEvaluator = class SpendingPolicyEvaluator {
|
|
1164
|
+
constructor(policies, charges, adjustments) {
|
|
1165
|
+
this.policies = policies;
|
|
1166
|
+
this.charges = charges;
|
|
1167
|
+
this.adjustments = adjustments;
|
|
1168
|
+
}
|
|
1169
|
+
policies;
|
|
1170
|
+
charges;
|
|
1171
|
+
adjustments;
|
|
1172
|
+
static async create(options = {}) {
|
|
1173
|
+
const policies = await SpendingPolicyCollection.create(options);
|
|
1174
|
+
const sharedOptions = {
|
|
1175
|
+
...options,
|
|
1176
|
+
db: policies.db
|
|
1177
|
+
};
|
|
1178
|
+
return new SpendingPolicyEvaluator(policies, await ClientChargeCollection.create(sharedOptions), await BillingAdjustmentCollection.create(sharedOptions));
|
|
1179
|
+
}
|
|
1180
|
+
async evaluate(input) {
|
|
1181
|
+
const at = input.at ?? /* @__PURE__ */ new Date();
|
|
1182
|
+
const normalizedInput = {
|
|
1183
|
+
...input,
|
|
1184
|
+
...subscriberToColumns(normalizeSubscriber({
|
|
1185
|
+
tenantId: input.tenantId,
|
|
1186
|
+
subscriberKind: input.subscriberKind,
|
|
1187
|
+
subscriberExternalId: input.subscriberExternalId
|
|
1188
|
+
}))
|
|
1189
|
+
};
|
|
1190
|
+
const matchingPolicies = selectPolicies(await this.policies.list({ where: {
|
|
1191
|
+
tenantId: input.tenantId,
|
|
1192
|
+
currency: input.currency,
|
|
1193
|
+
active: true
|
|
1194
|
+
} }), normalizedInput);
|
|
1195
|
+
if (matchingPolicies.length === 0) return {
|
|
1196
|
+
allowed: true,
|
|
1197
|
+
approvalRequired: false,
|
|
1198
|
+
state: "ok",
|
|
1199
|
+
projectedAmount: input.estimatedAmount,
|
|
1200
|
+
matchedPolicyId: null
|
|
1201
|
+
};
|
|
1202
|
+
return (await Promise.all(matchingPolicies.map((policy) => this.evaluatePolicy(policy, normalizedInput, at)))).reduce((mostRestrictive, decision) => decisionRank(decision) > decisionRank(mostRestrictive) ? decision : mostRestrictive);
|
|
1203
|
+
}
|
|
1204
|
+
async evaluatePolicy(policy, input, at) {
|
|
1205
|
+
const [start, end] = policyWindow(policy, at);
|
|
1206
|
+
const chargeWhere = {
|
|
1207
|
+
tenantId: input.tenantId,
|
|
1208
|
+
currency: policy.currency,
|
|
1209
|
+
status: ["approved", "adjusted"],
|
|
1210
|
+
"approvedAt >=": start.toISOString(),
|
|
1211
|
+
"approvedAt <": end.toISOString()
|
|
1212
|
+
};
|
|
1213
|
+
if (policy.metricKey) chargeWhere.metricKey = policy.metricKey;
|
|
1214
|
+
if (policy.projectId) chargeWhere.projectId = policy.projectId;
|
|
1215
|
+
if (policy.serviceKey) chargeWhere.serviceKey = policy.serviceKey;
|
|
1216
|
+
if (policy.subscriberKind) chargeWhere.subscriberKind = policy.subscriberKind;
|
|
1217
|
+
if (policy.subscriberExternalId) chargeWhere.subscriberExternalId = policy.subscriberExternalId;
|
|
1218
|
+
const scopedCharges = (await this.charges.list({ where: chargeWhere })).filter((charge) => (charge.status === "approved" || charge.status === "adjusted") && matchesChargeScope(policy, charge));
|
|
1219
|
+
const chargeIds = scopedCharges.map((charge) => charge.id).filter((id) => Boolean(id));
|
|
1220
|
+
const chargeIdSet = new Set(chargeIds);
|
|
1221
|
+
const adjustmentRows = chargeIds.length > 0 ? await this.adjustments.list({ where: {
|
|
1222
|
+
tenantId: input.tenantId,
|
|
1223
|
+
currency: policy.currency,
|
|
1224
|
+
clientChargeId: chargeIds
|
|
1225
|
+
} }) : [];
|
|
1226
|
+
const projectedAmount = scopedCharges.reduce((sum, charge) => sum + charge.amount, 0) + adjustmentRows.filter((adjustment) => chargeIdSet.has(adjustment.clientChargeId)).reduce((sum, adjustment) => sum + adjustment.amount, 0) + input.estimatedAmount;
|
|
1227
|
+
const exceeded = projectedAmount > policy.limitAmount;
|
|
1228
|
+
if (!exceeded || policy.behavior === "observe") return {
|
|
1229
|
+
allowed: true,
|
|
1230
|
+
approvalRequired: false,
|
|
1231
|
+
state: exceeded ? "observed" : "ok",
|
|
1232
|
+
projectedAmount,
|
|
1233
|
+
matchedPolicyId: policy.id ?? null
|
|
1234
|
+
};
|
|
1235
|
+
if (policy.behavior === "warn") return {
|
|
1236
|
+
allowed: true,
|
|
1237
|
+
approvalRequired: false,
|
|
1238
|
+
state: "warned",
|
|
1239
|
+
projectedAmount,
|
|
1240
|
+
matchedPolicyId: policy.id ?? null
|
|
1241
|
+
};
|
|
1242
|
+
if (policy.behavior === "approval_required") return {
|
|
1243
|
+
allowed: false,
|
|
1244
|
+
approvalRequired: true,
|
|
1245
|
+
state: "approval_required",
|
|
1246
|
+
projectedAmount,
|
|
1247
|
+
matchedPolicyId: policy.id ?? null
|
|
1248
|
+
};
|
|
1249
|
+
return {
|
|
1250
|
+
allowed: false,
|
|
1251
|
+
approvalRequired: false,
|
|
1252
|
+
state: "blocked",
|
|
1253
|
+
projectedAmount,
|
|
1254
|
+
matchedPolicyId: policy.id ?? null
|
|
1255
|
+
};
|
|
1256
|
+
}
|
|
1257
|
+
};
|
|
1258
|
+
function selectRule(rules, at, serviceKey) {
|
|
1259
|
+
return rules.filter((rule) => rule.effectiveFrom <= at && (!rule.effectiveTo || rule.effectiveTo > at) && (!rule.serviceKey || rule.serviceKey === serviceKey)).sort((a, b) => Number(Boolean(b.serviceKey)) - Number(Boolean(a.serviceKey)) || b.priority - a.priority || b.effectiveFrom.getTime() - a.effectiveFrom.getTime())[0];
|
|
1260
|
+
}
|
|
1261
|
+
function priceTiers(quantity, tiers) {
|
|
1262
|
+
let remaining = quantity, prior = 0, amount = 0;
|
|
1263
|
+
for (const raw of tiers) {
|
|
1264
|
+
const upTo = raw.upTo == null ? Infinity : Number(raw.upTo);
|
|
1265
|
+
const units = Math.max(0, Math.min(remaining, upTo - prior));
|
|
1266
|
+
amount += units * Number(raw.unitPrice ?? 0);
|
|
1267
|
+
remaining -= units;
|
|
1268
|
+
prior = upTo;
|
|
1269
|
+
if (remaining <= 0) break;
|
|
1270
|
+
}
|
|
1271
|
+
return amount;
|
|
1272
|
+
}
|
|
1273
|
+
function selectPolicies(policies, input) {
|
|
1274
|
+
return policies.filter((p) => hasValidSubscriberScope(p) && (!p.metricKey || p.metricKey === input.metricKey) && p.currency === input.currency && (!p.projectId || p.projectId === input.projectId) && (!p.serviceKey || p.serviceKey === input.serviceKey) && (!p.subscriberKind || p.subscriberKind === (input.subscriberKind ?? "tenant") && (!p.subscriberExternalId || p.subscriberExternalId === input.subscriberExternalId))).sort((a, b) => scopeScore(b) - scopeScore(a) || b.priority - a.priority);
|
|
1275
|
+
}
|
|
1276
|
+
function decisionRank(decision) {
|
|
1277
|
+
return {
|
|
1278
|
+
ok: 0,
|
|
1279
|
+
observed: 1,
|
|
1280
|
+
warned: 2,
|
|
1281
|
+
approval_required: 3,
|
|
1282
|
+
blocked: 4
|
|
1283
|
+
}[decision.state];
|
|
1284
|
+
}
|
|
1285
|
+
function scopeScore(p) {
|
|
1286
|
+
return Number(Boolean(p.subscriberKind)) + Number(Boolean(p.subscriberExternalId)) + Number(Boolean(p.projectId)) + Number(Boolean(p.serviceKey)) + Number(Boolean(p.metricKey));
|
|
1287
|
+
}
|
|
1288
|
+
function matchesChargeScope(p, c) {
|
|
1289
|
+
return hasValidSubscriberScope(p) && (!p.projectId || p.projectId === c.projectId) && (!p.serviceKey || p.serviceKey === c.serviceKey) && (!p.metricKey || p.metricKey === c.metricKey) && (!p.subscriberKind || p.subscriberKind === c.subscriberKind && (!p.subscriberExternalId || p.subscriberExternalId === c.subscriberExternalId));
|
|
1290
|
+
}
|
|
1291
|
+
function hasValidSubscriberScope(p) {
|
|
1292
|
+
return !p.subscriberExternalId || Boolean(p.subscriberKind);
|
|
1293
|
+
}
|
|
1294
|
+
function policyWindow(policy, at) {
|
|
1295
|
+
const end = new Date(at);
|
|
1296
|
+
const start = new Date(at);
|
|
1297
|
+
if (policy.period === "rolling") start.setTime(at.getTime() - policy.rollingSeconds * 1e3);
|
|
1298
|
+
else if (policy.period === "day") start.setUTCHours(0, 0, 0, 0);
|
|
1299
|
+
else if (policy.period === "week") {
|
|
1300
|
+
start.setUTCHours(0, 0, 0, 0);
|
|
1301
|
+
start.setUTCDate(start.getUTCDate() - (start.getUTCDay() + 6) % 7);
|
|
1302
|
+
} else if (policy.period === "month") {
|
|
1303
|
+
start.setUTCDate(1);
|
|
1304
|
+
start.setUTCHours(0, 0, 0, 0);
|
|
1305
|
+
} else {
|
|
1306
|
+
start.setUTCMonth(0, 1);
|
|
1307
|
+
start.setUTCHours(0, 0, 0, 0);
|
|
1308
|
+
}
|
|
1309
|
+
return [start, end];
|
|
1310
|
+
}
|
|
1311
|
+
//#endregion
|
|
696
1312
|
//#region src/services/threshold-evaluator.ts
|
|
697
1313
|
function evaluateThreshold(threshold, usage) {
|
|
698
1314
|
const ratio = threshold.limit === 0 ? usage.quantity > 0 ? Infinity : 0 : usage.quantity / threshold.limit;
|
|
@@ -1117,6 +1733,6 @@ function emptyUsageSummary(subscriber, metricKey, window) {
|
|
|
1117
1733
|
return summary;
|
|
1118
1734
|
}
|
|
1119
1735
|
//#endregion
|
|
1120
|
-
export { SubscriptionPlan, SubscriptionPlanCollection, SubscriptionResolver, TenantSubscription, TenantSubscriptionCollection, TenantUsageMeter, TenantUsageMetric, TenantUsageMetricCollection, assertSubscriberInvariant, evaluateThreshold, evaluateThresholds, getWindowForThreshold, getWindowKey, isValidThreshold, normalizeFeatureGrants, normalizeSubscriber, subscriberToColumns };
|
|
1736
|
+
export { BillingAdjustment, BillingAdjustmentCollection, ClientCharge, ClientChargeCollection, CommercialUsageService, PricingRule, PricingRuleCollection, SpendingPolicy, SpendingPolicyCollection, SpendingPolicyEvaluator, SubscriptionPlan, SubscriptionPlanCollection, SubscriptionResolver, TenantSubscription, TenantSubscriptionCollection, TenantUsageMeter, TenantUsageMetric, TenantUsageMetricCollection, assertSubscriberInvariant, evaluateThreshold, evaluateThresholds, getWindowForThreshold, getWindowKey, isValidThreshold, normalizeFeatureGrants, normalizeSubscriber, subscriberToColumns };
|
|
1121
1737
|
|
|
1122
1738
|
//# sourceMappingURL=index.js.map
|