@happyvertical/smrt-subscriptions 0.51.21 → 0.51.22
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 +29 -1
- package/README.md +126 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1067 -94
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +1758 -13
- package/dist/models/commercial.d.ts +61 -1
- package/dist/models/commercial.d.ts.map +1 -1
- package/dist/models/index.d.ts +3 -1
- package/dist/models/index.d.ts.map +1 -1
- package/dist/models/reseller.d.ts +107 -0
- package/dist/models/reseller.d.ts.map +1 -0
- package/dist/services/commercial.d.ts +147 -6
- package/dist/services/commercial.d.ts.map +1 -1
- package/dist/services/index.d.ts +3 -1
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/reseller-errors.d.ts +7 -0
- package/dist/services/reseller-errors.d.ts.map +1 -0
- package/dist/services/reseller.d.ts +154 -0
- package/dist/services/reseller.d.ts.map +1 -0
- package/dist/smrt-knowledge.json +962 -183
- package/dist/utils.d.ts +2 -0
- package/dist/utils.d.ts.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ObjectRegistry, SmrtCollection, SmrtObject, foreignKey, isDatabaseInterface, isEmbeddedDatabase, smrt, withEmbeddedWriteTransaction } from "@happyvertical/smrt-core";
|
|
2
|
-
import { TenantScoped, tenantId } from "@happyvertical/smrt-tenancy";
|
|
1
|
+
import { ObjectRegistry, SmrtCollection, SmrtObject, crossPackageRef, field, foreignKey, isDatabaseInterface, isEmbeddedDatabase, isPostgresDatabase, smrt, withEmbeddedWriteTransaction } from "@happyvertical/smrt-core";
|
|
2
|
+
import { TenantIsolationError, TenantScoped, getTenantId, isSuperAdminBypass, isSystemContext, tenantId, withSystemContext } from "@happyvertical/smrt-tenancy";
|
|
3
3
|
import { preflightMinorUnitsRescale, rescaleMoneyColumnsToMinorUnits } from "@happyvertical/smrt-core/migrations";
|
|
4
4
|
//#region src/__smrt-register__.ts
|
|
5
|
-
ObjectRegistry.registerPackageManifest(JSON.parse("{\"version\":\"1.0.0\",\"timestamp\":0,\"packageName\":\"@happyvertical/smrt-subscriptions\",\"packageVersion\":\"0.51.21\",\"objects\":{\"@happyvertical/smrt-subscriptions:SubscriptionPlanCollection\":{\"name\":\"subscriptionplancollection\",\"className\":\"SubscriptionPlanCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:SubscriptionPlanCollection\",\"collection\":\"subscriptionplans\",\"filePath\":\"/home/runner/work/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 \\\"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\\\" INTEGER 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\":\"INTEGER\",\"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_plan_key_idx\",\"columns\":[\"plan_key\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_subscription_plans_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_subscription_plans_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]}],\"version\":\"65765fd0\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:TenantSubscriptionCollection\":{\"name\":\"tenantsubscriptioncollection\",\"className\":\"TenantSubscriptionCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:TenantSubscriptionCollection\",\"collection\":\"tenantsubscriptions\",\"filePath\":\"/home/runner/work/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 \\\"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,\"foreignKey\":{\"table\":\"_smrt_subscription_plans\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"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_tenant_id_subscriber_kind_idx\",\"columns\":[\"tenant_id\",\"subscriber_kind\",\"subscriber_external_id\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_tenant_subscriptions_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_tenant_subscriptions_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]},{\"name\":\"_smrt_tenant_subscriptions_plan_id_idx\",\"columns\":[\"plan_id\"]}],\"version\":\"ac93fb43\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:TenantUsageMetricCollection\":{\"name\":\"tenantusagemetriccollection\",\"className\":\"TenantUsageMetricCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:TenantUsageMetricCollection\",\"collection\":\"tenantusagemetrics\",\"filePath\":\"/home/runner/work/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 \\\"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_slug_context_idx\",\"columns\":[\"tenant_id\",\"slug\",\"context\"],\"unique\":true},{\"name\":\"_smrt_tenant_usage_metrics_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]}],\"version\":\"b799c746\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:SubscriptionPlan\":{\"name\":\"subscriptionplan\",\"className\":\"SubscriptionPlan\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:SubscriptionPlan\",\"collection\":\"subscriptionplans\",\"filePath\":\"/home/runner/work/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\":\"integer\",\"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\":{\"skipApiCheck\":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\\\" INTEGER 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\":\"INTEGER\",\"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_plan_key_idx\",\"columns\":[\"plan_key\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_subscription_plans_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_subscription_plans_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]}],\"version\":\"65765fd0\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:TenantSubscription\":{\"name\":\"tenantsubscription\",\"className\":\"TenantSubscription\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:TenantSubscription\",\"collection\":\"tenantsubscriptions\",\"filePath\":\"/home/runner/work/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\":{\"skipApiCheck\":true},\"mcp\":{\"include\":[\"list\",\"get\"]},\"conflictColumns\":[\"tenant_id\",\"subscriber_kind\",\"subscriber_external_id\"],\"tenantScoped\":{\"mode\":\"required\"}},\"extends\":\"SmrtObject\",\"exportName\":\"TenantSubscription\",\"collectionExportName\":\"TenantSubscriptionCollection\",\"validationRules\":[],\"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,\"foreignKey\":{\"table\":\"_smrt_subscription_plans\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"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_tenant_id_subscriber_kind_idx\",\"columns\":[\"tenant_id\",\"subscriber_kind\",\"subscriber_external_id\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_tenant_subscriptions_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_tenant_subscriptions_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]},{\"name\":\"_smrt_tenant_subscriptions_plan_id_idx\",\"columns\":[\"plan_id\"]}],\"version\":\"ac93fb43\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:TenantUsageMetric\":{\"name\":\"tenantusagemetric\",\"className\":\"TenantUsageMetric\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:TenantUsageMetric\",\"collection\":\"tenantusagemetrics\",\"filePath\":\"/home/runner/work/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\"},\"conflictColumns\":[\"tenant_id\",\"slug\",\"context\"]},\"extends\":\"SmrtObject\",\"exportName\":\"TenantUsageMetric\",\"collectionExportName\":\"TenantUsageMetricCollection\",\"validationRules\":[],\"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_slug_context_idx\",\"columns\":[\"tenant_id\",\"slug\",\"context\"],\"unique\":true},{\"name\":\"_smrt_tenant_usage_metrics_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]}],\"version\":\"b799c746\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:PricingRule\":{\"name\":\"pricingrule\",\"className\":\"PricingRule\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:PricingRule\",\"collection\":\"pricingrules\",\"filePath\":\"/home/runner/work/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, unknown>\",\"isStatic\":false,\"isPublic\":true},\"setTerms\":{\"name\":\"setTerms\",\"async\":false,\"parameters\":[{\"name\":\"value\",\"type\":\"Record<string, unknown>\",\"optional\":false}],\"returnType\":\"void\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_pricing_rules\",\"api\":true,\"cli\":true,\"mcp\":true,\"tenantScoped\":{\"mode\":\"required\"},\"conflictColumns\":[\"tenant_id\",\"slug\",\"context\"]},\"extends\":\"SmrtObject\",\"exportName\":\"PricingRule\",\"collectionExportName\":\"PricingRuleCollection\",\"validationRules\":[],\"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_slug_context_idx\",\"columns\":[\"tenant_id\",\"slug\",\"context\"],\"unique\":true},{\"name\":\"_smrt_pricing_rules_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]}],\"version\":\"88642897\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:ClientCharge\":{\"name\":\"clientcharge\",\"className\":\"ClientCharge\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:ClientCharge\",\"collection\":\"clientcharges\",\"filePath\":\"/home/runner/work/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\":\"integer\",\"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, unknown>\",\"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\":[],\"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\\\" INTEGER 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,\"foreignKey\":{\"table\":\"_smrt_tenant_usage_metrics\",\"column\":\"id\",\"onDelete\":\"CASCADE\",\"onUpdate\":\"CASCADE\"}},\"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\":\"INTEGER\",\"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,\"foreignKey\":{\"table\":\"_smrt_pricing_rules\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"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_usage_event_id_idx\",\"columns\":[\"usage_event_id\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_client_charges_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_client_charges_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]},{\"name\":\"_smrt_client_charges_pricing_rule_id_idx\",\"columns\":[\"pricing_rule_id\"]}],\"version\":\"a1a33c54\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:BillingAdjustment\":{\"name\":\"billingadjustment\",\"className\":\"BillingAdjustment\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:BillingAdjustment\",\"collection\":\"billingadjustments\",\"filePath\":\"/home/runner/work/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\":\"integer\",\"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\"},\"conflictColumns\":[\"tenant_id\",\"slug\",\"context\"]},\"extends\":\"SmrtObject\",\"exportName\":\"BillingAdjustment\",\"collectionExportName\":\"BillingAdjustmentCollection\",\"validationRules\":[],\"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\\\" INTEGER 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,\"foreignKey\":{\"table\":\"_smrt_client_charges\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"amount\":{\"type\":\"INTEGER\",\"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_slug_context_idx\",\"columns\":[\"tenant_id\",\"slug\",\"context\"],\"unique\":true},{\"name\":\"_smrt_billing_adjustments_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]},{\"name\":\"_smrt_billing_adjustments_client_charge_id_idx\",\"columns\":[\"client_charge_id\"]}],\"version\":\"cded0b52\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:SpendingPolicy\":{\"name\":\"spendingpolicy\",\"className\":\"SpendingPolicy\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:SpendingPolicy\",\"collection\":\"spendingpolicies\",\"filePath\":\"/home/runner/work/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\":\"integer\",\"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\":[],\"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\\\" INTEGER 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\":\"INTEGER\",\"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_tenant_id_subscriber_kind_idx\",\"columns\":[\"tenant_id\",\"subscriber_kind\",\"subscriber_external_id\",\"project_id\",\"service_key\",\"metric_key\",\"period\",\"name\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_spending_policies_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_spending_policies_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]}],\"version\":\"6a413cf4\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:PricingRuleCollection\":{\"name\":\"pricingrulecollection\",\"className\":\"PricingRuleCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:PricingRuleCollection\",\"collection\":\"pricingrules\",\"filePath\":\"/home/runner/work/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 \\\"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_slug_context_idx\",\"columns\":[\"tenant_id\",\"slug\",\"context\"],\"unique\":true},{\"name\":\"_smrt_pricing_rules_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]}],\"version\":\"88642897\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:ClientChargeCollection\":{\"name\":\"clientchargecollection\",\"className\":\"ClientChargeCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:ClientChargeCollection\",\"collection\":\"clientcharges\",\"filePath\":\"/home/runner/work/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 \\\"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\\\" INTEGER 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,\"foreignKey\":{\"table\":\"_smrt_tenant_usage_metrics\",\"column\":\"id\",\"onDelete\":\"CASCADE\",\"onUpdate\":\"CASCADE\"}},\"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\":\"INTEGER\",\"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,\"foreignKey\":{\"table\":\"_smrt_pricing_rules\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"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_usage_event_id_idx\",\"columns\":[\"usage_event_id\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_client_charges_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_client_charges_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]},{\"name\":\"_smrt_client_charges_pricing_rule_id_idx\",\"columns\":[\"pricing_rule_id\"]}],\"version\":\"a1a33c54\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:BillingAdjustmentCollection\":{\"name\":\"billingadjustmentcollection\",\"className\":\"BillingAdjustmentCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:BillingAdjustmentCollection\",\"collection\":\"billingadjustments\",\"filePath\":\"/home/runner/work/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 \\\"tenant_id\\\" UUID NOT NULL,\\n \\\"client_charge_id\\\" UUID,\\n \\\"amount\\\" INTEGER 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,\"foreignKey\":{\"table\":\"_smrt_client_charges\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"amount\":{\"type\":\"INTEGER\",\"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_slug_context_idx\",\"columns\":[\"tenant_id\",\"slug\",\"context\"],\"unique\":true},{\"name\":\"_smrt_billing_adjustments_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]},{\"name\":\"_smrt_billing_adjustments_client_charge_id_idx\",\"columns\":[\"client_charge_id\"]}],\"version\":\"cded0b52\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:SpendingPolicyCollection\":{\"name\":\"spendingpolicycollection\",\"className\":\"SpendingPolicyCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:SpendingPolicyCollection\",\"collection\":\"spendingpolicies\",\"filePath\":\"/home/runner/work/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 \\\"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\\\" INTEGER 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\":\"INTEGER\",\"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_tenant_id_subscriber_kind_idx\",\"columns\":[\"tenant_id\",\"subscriber_kind\",\"subscriber_external_id\",\"project_id\",\"service_key\",\"metric_key\",\"period\",\"name\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_spending_policies_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_spending_policies_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]}],\"version\":\"6a413cf4\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"}},\"moduleType\":\"smrt\",\"smrtDependencies\":[\"@happyvertical/smrt-core\",\"@happyvertical/smrt-tenancy\"]}"));
|
|
5
|
+
ObjectRegistry.registerPackageManifest(JSON.parse("{\"version\":\"1.0.0\",\"timestamp\":0,\"packageName\":\"@happyvertical/smrt-subscriptions\",\"packageVersion\":\"0.51.22\",\"objects\":{\"@happyvertical/smrt-subscriptions:SubscriptionPlanCollection\":{\"name\":\"subscriptionplancollection\",\"className\":\"SubscriptionPlanCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:SubscriptionPlanCollection\",\"collection\":\"subscriptionplans\",\"filePath\":\"/home/runner/work/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 \\\"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\\\" INTEGER 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\":\"INTEGER\",\"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_plan_key_idx\",\"columns\":[\"plan_key\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_subscription_plans_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_subscription_plans_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]}],\"version\":\"65765fd0\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:TenantSubscriptionCollection\":{\"name\":\"tenantsubscriptioncollection\",\"className\":\"TenantSubscriptionCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:TenantSubscriptionCollection\",\"collection\":\"tenantsubscriptions\",\"filePath\":\"/home/runner/work/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 \\\"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,\"foreignKey\":{\"table\":\"_smrt_subscription_plans\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"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_tenant_id_subscriber_kind_idx\",\"columns\":[\"tenant_id\",\"subscriber_kind\",\"subscriber_external_id\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_tenant_subscriptions_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_tenant_subscriptions_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]},{\"name\":\"_smrt_tenant_subscriptions_plan_id_idx\",\"columns\":[\"plan_id\"]}],\"version\":\"ac93fb43\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:TenantUsageMetricCollection\":{\"name\":\"tenantusagemetriccollection\",\"className\":\"TenantUsageMetricCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:TenantUsageMetricCollection\",\"collection\":\"tenantusagemetrics\",\"filePath\":\"/home/runner/work/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 \\\"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_slug_context_idx\",\"columns\":[\"tenant_id\",\"slug\",\"context\"],\"unique\":true},{\"name\":\"_smrt_tenant_usage_metrics_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]}],\"version\":\"b799c746\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:SubscriptionPlan\":{\"name\":\"subscriptionplan\",\"className\":\"SubscriptionPlan\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:SubscriptionPlan\",\"collection\":\"subscriptionplans\",\"filePath\":\"/home/runner/work/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\":\"integer\",\"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\":{\"skipApiCheck\":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\\\" INTEGER 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\":\"INTEGER\",\"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_plan_key_idx\",\"columns\":[\"plan_key\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_subscription_plans_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_subscription_plans_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]}],\"version\":\"65765fd0\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:TenantSubscription\":{\"name\":\"tenantsubscription\",\"className\":\"TenantSubscription\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:TenantSubscription\",\"collection\":\"tenantsubscriptions\",\"filePath\":\"/home/runner/work/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\":{\"skipApiCheck\":true},\"mcp\":{\"include\":[\"list\",\"get\"]},\"conflictColumns\":[\"tenant_id\",\"subscriber_kind\",\"subscriber_external_id\"],\"tenantScoped\":{\"mode\":\"required\"}},\"extends\":\"SmrtObject\",\"exportName\":\"TenantSubscription\",\"collectionExportName\":\"TenantSubscriptionCollection\",\"validationRules\":[],\"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,\"foreignKey\":{\"table\":\"_smrt_subscription_plans\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"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_tenant_id_subscriber_kind_idx\",\"columns\":[\"tenant_id\",\"subscriber_kind\",\"subscriber_external_id\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_tenant_subscriptions_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_tenant_subscriptions_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]},{\"name\":\"_smrt_tenant_subscriptions_plan_id_idx\",\"columns\":[\"plan_id\"]}],\"version\":\"ac93fb43\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:TenantUsageMetric\":{\"name\":\"tenantusagemetric\",\"className\":\"TenantUsageMetric\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:TenantUsageMetric\",\"collection\":\"tenantusagemetrics\",\"filePath\":\"/home/runner/work/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\"},\"conflictColumns\":[\"tenant_id\",\"slug\",\"context\"]},\"extends\":\"SmrtObject\",\"exportName\":\"TenantUsageMetric\",\"collectionExportName\":\"TenantUsageMetricCollection\",\"validationRules\":[],\"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_slug_context_idx\",\"columns\":[\"tenant_id\",\"slug\",\"context\"],\"unique\":true},{\"name\":\"_smrt_tenant_usage_metrics_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]}],\"version\":\"b799c746\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:PricingRule\":{\"name\":\"pricingrule\",\"className\":\"PricingRule\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:PricingRule\",\"collection\":\"pricingrules\",\"filePath\":\"/home/runner/work/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},\"priceBookId\":{\"type\":\"foreignKey\",\"required\":false,\"related\":\"PriceBook\"}},\"methods\":{\"getTerms\":{\"name\":\"getTerms\",\"async\":false,\"parameters\":[],\"returnType\":\"Record<string, unknown>\",\"isStatic\":false,\"isPublic\":true},\"setTerms\":{\"name\":\"setTerms\",\"async\":false,\"parameters\":[{\"name\":\"value\",\"type\":\"Record<string, unknown>\",\"optional\":false}],\"returnType\":\"void\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_pricing_rules\",\"api\":true,\"cli\":true,\"mcp\":true,\"tenantScoped\":{\"mode\":\"required\"},\"conflictColumns\":[\"tenant_id\",\"slug\",\"context\"]},\"extends\":\"SmrtObject\",\"exportName\":\"PricingRule\",\"collectionExportName\":\"PricingRuleCollection\",\"validationRules\":[],\"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 \\\"price_book_id\\\" UUID\\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},\"price_book_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false,\"foreignKey\":{\"table\":\"_smrt_price_books\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}}},\"indexes\":[{\"name\":\"_smrt_pricing_rules_slug_context_idx\",\"columns\":[\"tenant_id\",\"slug\",\"context\"],\"unique\":true},{\"name\":\"_smrt_pricing_rules_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]},{\"name\":\"_smrt_pricing_rules_price_book_id_idx\",\"columns\":[\"price_book_id\"]}],\"version\":\"65ce9b3f\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:ClientCharge\":{\"name\":\"clientcharge\",\"className\":\"ClientCharge\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:ClientCharge\",\"collection\":\"clientcharges\",\"filePath\":\"/home/runner/work/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\"},\"usageTenantId\":{\"type\":\"crossPackageRef\",\"required\":false,\"related\":\"@happyvertical/smrt-users:Tenant\"},\"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\":\"integer\",\"required\":false,\"default\":0},\"currency\":{\"type\":\"text\",\"required\":false,\"default\":\"USD\"},\"pricingRuleId\":{\"type\":\"foreignKey\",\"required\":false,\"related\":\"PricingRule\"},\"priceBookId\":{\"type\":\"foreignKey\",\"required\":false,\"related\":\"PriceBook\"},\"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, unknown>\",\"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\":[],\"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 \\\"usage_tenant_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\\\" INTEGER DEFAULT 0,\\n \\\"currency\\\" TEXT DEFAULT 'USD',\\n \\\"pricing_rule_id\\\" UUID,\\n \\\"price_book_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,\"foreignKey\":{\"table\":\"_smrt_tenant_usage_metrics\",\"column\":\"id\",\"onDelete\":\"CASCADE\",\"onUpdate\":\"CASCADE\"}},\"usage_tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"crossPackageRef\",\"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\":\"INTEGER\",\"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,\"foreignKey\":{\"table\":\"_smrt_pricing_rules\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"price_book_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false,\"foreignKey\":{\"table\":\"_smrt_price_books\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"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_usage_event_id_idx\",\"columns\":[\"usage_event_id\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_client_charges_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_client_charges_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]},{\"name\":\"_smrt_client_charges_usage_tenant_id_idx\",\"columns\":[\"usage_tenant_id\"]},{\"name\":\"_smrt_client_charges_pricing_rule_id_idx\",\"columns\":[\"pricing_rule_id\"]},{\"name\":\"_smrt_client_charges_price_book_id_idx\",\"columns\":[\"price_book_id\"]}],\"version\":\"e542be95\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:BillingAdjustment\":{\"name\":\"billingadjustment\",\"className\":\"BillingAdjustment\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:BillingAdjustment\",\"collection\":\"billingadjustments\",\"filePath\":\"/home/runner/work/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\":\"integer\",\"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\"},\"conflictColumns\":[\"tenant_id\",\"slug\",\"context\"]},\"extends\":\"SmrtObject\",\"exportName\":\"BillingAdjustment\",\"collectionExportName\":\"BillingAdjustmentCollection\",\"validationRules\":[],\"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\\\" INTEGER 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,\"foreignKey\":{\"table\":\"_smrt_client_charges\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"amount\":{\"type\":\"INTEGER\",\"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_slug_context_idx\",\"columns\":[\"tenant_id\",\"slug\",\"context\"],\"unique\":true},{\"name\":\"_smrt_billing_adjustments_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]},{\"name\":\"_smrt_billing_adjustments_client_charge_id_idx\",\"columns\":[\"client_charge_id\"]}],\"version\":\"cded0b52\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:SpendingPolicy\":{\"name\":\"spendingpolicy\",\"className\":\"SpendingPolicy\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:SpendingPolicy\",\"collection\":\"spendingpolicies\",\"filePath\":\"/home/runner/work/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\":\"integer\",\"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},\"basis\":{\"type\":\"text\",\"required\":false,\"default\":\"billed\"},\"setByTenantId\":{\"type\":\"crossPackageRef\",\"required\":false,\"related\":\"@happyvertical/smrt-users:Tenant\"},\"balanceFrom\":{\"type\":\"datetime\",\"required\":false}},\"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,\"hooks\":{\"beforeDelete\":\"assertDelegationAuthority\"},\"tenantScoped\":{\"mode\":\"required\"}},\"extends\":\"SmrtObject\",\"exportName\":\"SpendingPolicy\",\"collectionExportName\":\"SpendingPolicyCollection\",\"validationRules\":[],\"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\\\" INTEGER DEFAULT 0,\\n \\\"currency\\\" TEXT DEFAULT 'USD',\\n \\\"behavior\\\" TEXT DEFAULT 'observe',\\n \\\"priority\\\" INTEGER DEFAULT 0,\\n \\\"active\\\" BOOLEAN DEFAULT TRUE,\\n \\\"basis\\\" TEXT DEFAULT 'billed',\\n \\\"set_by_tenant_id\\\" UUID,\\n \\\"balance_from\\\" 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},\"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\":\"INTEGER\",\"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},\"basis\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"billed\"},\"set_by_tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"crossPackageRef\",\"notNull\":false,\"unique\":false},\"balance_from\":{\"type\":\"TIMESTAMP\",\"notNull\":false,\"unique\":false}},\"indexes\":[{\"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,\"nullsNotDistinct\":true},{\"name\":\"_smrt_spending_policies_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_spending_policies_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]},{\"name\":\"_smrt_spending_policies_set_by_tenant_id_idx\",\"columns\":[\"set_by_tenant_id\"]}],\"version\":\"c4ac2f49\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:PricingRuleCollection\":{\"name\":\"pricingrulecollection\",\"className\":\"PricingRuleCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:PricingRuleCollection\",\"collection\":\"pricingrules\",\"filePath\":\"/home/runner/work/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 \\\"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 \\\"price_book_id\\\" UUID\\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},\"price_book_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false,\"foreignKey\":{\"table\":\"_smrt_price_books\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}}},\"indexes\":[{\"name\":\"_smrt_pricing_rules_slug_context_idx\",\"columns\":[\"tenant_id\",\"slug\",\"context\"],\"unique\":true},{\"name\":\"_smrt_pricing_rules_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]},{\"name\":\"_smrt_pricing_rules_price_book_id_idx\",\"columns\":[\"price_book_id\"]}],\"version\":\"65ce9b3f\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:ClientChargeCollection\":{\"name\":\"clientchargecollection\",\"className\":\"ClientChargeCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:ClientChargeCollection\",\"collection\":\"clientcharges\",\"filePath\":\"/home/runner/work/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 \\\"tenant_id\\\" UUID NOT NULL,\\n \\\"usage_event_id\\\" UUID,\\n \\\"usage_tenant_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\\\" INTEGER DEFAULT 0,\\n \\\"currency\\\" TEXT DEFAULT 'USD',\\n \\\"pricing_rule_id\\\" UUID,\\n \\\"price_book_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,\"foreignKey\":{\"table\":\"_smrt_tenant_usage_metrics\",\"column\":\"id\",\"onDelete\":\"CASCADE\",\"onUpdate\":\"CASCADE\"}},\"usage_tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"crossPackageRef\",\"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\":\"INTEGER\",\"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,\"foreignKey\":{\"table\":\"_smrt_pricing_rules\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"price_book_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false,\"foreignKey\":{\"table\":\"_smrt_price_books\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"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_usage_event_id_idx\",\"columns\":[\"usage_event_id\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_client_charges_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_client_charges_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]},{\"name\":\"_smrt_client_charges_usage_tenant_id_idx\",\"columns\":[\"usage_tenant_id\"]},{\"name\":\"_smrt_client_charges_pricing_rule_id_idx\",\"columns\":[\"pricing_rule_id\"]},{\"name\":\"_smrt_client_charges_price_book_id_idx\",\"columns\":[\"price_book_id\"]}],\"version\":\"e542be95\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:BillingAdjustmentCollection\":{\"name\":\"billingadjustmentcollection\",\"className\":\"BillingAdjustmentCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:BillingAdjustmentCollection\",\"collection\":\"billingadjustments\",\"filePath\":\"/home/runner/work/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 \\\"tenant_id\\\" UUID NOT NULL,\\n \\\"client_charge_id\\\" UUID,\\n \\\"amount\\\" INTEGER 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,\"foreignKey\":{\"table\":\"_smrt_client_charges\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"amount\":{\"type\":\"INTEGER\",\"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_slug_context_idx\",\"columns\":[\"tenant_id\",\"slug\",\"context\"],\"unique\":true},{\"name\":\"_smrt_billing_adjustments_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]},{\"name\":\"_smrt_billing_adjustments_client_charge_id_idx\",\"columns\":[\"client_charge_id\"]}],\"version\":\"cded0b52\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:SpendingPolicyCollection\":{\"name\":\"spendingpolicycollection\",\"className\":\"SpendingPolicyCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:SpendingPolicyCollection\",\"collection\":\"spendingpolicies\",\"filePath\":\"/home/runner/work/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 \\\"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\\\" INTEGER DEFAULT 0,\\n \\\"currency\\\" TEXT DEFAULT 'USD',\\n \\\"behavior\\\" TEXT DEFAULT 'observe',\\n \\\"priority\\\" INTEGER DEFAULT 0,\\n \\\"active\\\" BOOLEAN DEFAULT TRUE,\\n \\\"basis\\\" TEXT DEFAULT 'billed',\\n \\\"set_by_tenant_id\\\" UUID,\\n \\\"balance_from\\\" 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},\"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\":\"INTEGER\",\"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},\"basis\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"billed\"},\"set_by_tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"crossPackageRef\",\"notNull\":false,\"unique\":false},\"balance_from\":{\"type\":\"TIMESTAMP\",\"notNull\":false,\"unique\":false}},\"indexes\":[{\"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,\"nullsNotDistinct\":true},{\"name\":\"_smrt_spending_policies_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_spending_policies_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]},{\"name\":\"_smrt_spending_policies_set_by_tenant_id_idx\",\"columns\":[\"set_by_tenant_id\"]}],\"version\":\"c4ac2f49\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:PriceBook\":{\"name\":\"pricebook\",\"className\":\"PriceBook\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:PriceBook\",\"collection\":\"pricebooks\",\"filePath\":\"/home/runner/work/smrt/smrt/packages/subscriptions/src/models/reseller.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}}},\"bookKey\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"name\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"kind\":{\"type\":\"text\",\"required\":false,\"default\":\"retail\"},\"active\":{\"type\":\"boolean\",\"required\":false,\"default\":true}},\"methods\":{},\"decoratorConfig\":{\"tableName\":\"_smrt_price_books\",\"conflictColumns\":[\"tenant_id\",\"book_key\"],\"api\":false,\"cli\":false,\"mcp\":false,\"tenantScoped\":{\"mode\":\"required\"}},\"extends\":\"SmrtObject\",\"exportName\":\"PriceBook\",\"collectionExportName\":\"PriceBookCollection\",\"validationRules\":[],\"schema\":{\"tableName\":\"_smrt_price_books\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_price_books\\\" (\\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 \\\"book_key\\\" TEXT DEFAULT '',\\n \\\"name\\\" TEXT DEFAULT '',\\n \\\"kind\\\" TEXT DEFAULT 'retail',\\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},\"book_key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"name\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"kind\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"retail\"},\"active\":{\"type\":\"BOOLEAN\",\"notNull\":false,\"unique\":false,\"default\":true}},\"indexes\":[{\"name\":\"_smrt_price_books_tenant_id_book_key_idx\",\"columns\":[\"tenant_id\",\"book_key\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_price_books_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_price_books_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]}],\"version\":\"c7e5f5e0\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:PriceBookAssignment\":{\"name\":\"pricebookassignment\",\"className\":\"PriceBookAssignment\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:PriceBookAssignment\",\"collection\":\"pricebookassignments\",\"filePath\":\"/home/runner/work/smrt/smrt/packages/subscriptions/src/models/reseller.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{\"childTenantId\":{\"type\":\"crossPackageRef\",\"required\":true,\"related\":\"@happyvertical/smrt-users:Tenant\",\"_meta\":{\"required\":true}},\"resellerTenantId\":{\"type\":\"crossPackageRef\",\"required\":true,\"related\":\"@happyvertical/smrt-users:Tenant\",\"_meta\":{\"required\":true}},\"wholesalePriceBookId\":{\"type\":\"foreignKey\",\"required\":false,\"related\":\"PriceBook\"},\"wholesaleCurrency\":{\"type\":\"text\",\"required\":false,\"default\":\"\"},\"retailPriceBookId\":{\"type\":\"foreignKey\",\"required\":false,\"related\":\"PriceBook\"},\"retailCurrency\":{\"type\":\"text\",\"required\":false,\"default\":\"\"}},\"methods\":{},\"decoratorConfig\":{\"tableName\":\"_smrt_price_book_assignments\",\"conflictColumns\":[\"child_tenant_id\"],\"api\":false,\"cli\":false,\"mcp\":false},\"extends\":\"SmrtObject\",\"exportName\":\"PriceBookAssignment\",\"collectionExportName\":\"PriceBookAssignmentCollection\",\"validationRules\":[{\"field\":\"childTenantId\",\"rule\":\"required\",\"fieldType\":\"crossPackageRef\"},{\"field\":\"resellerTenantId\",\"rule\":\"required\",\"fieldType\":\"crossPackageRef\"}],\"schema\":{\"tableName\":\"_smrt_price_book_assignments\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_price_book_assignments\\\" (\\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 \\\"child_tenant_id\\\" UUID NOT NULL,\\n \\\"reseller_tenant_id\\\" UUID NOT NULL,\\n \\\"wholesale_price_book_id\\\" UUID,\\n \\\"wholesale_currency\\\" TEXT DEFAULT '',\\n \\\"retail_price_book_id\\\" UUID,\\n \\\"retail_currency\\\" 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\"},\"child_tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"crossPackageRef\",\"notNull\":true,\"unique\":false},\"reseller_tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"crossPackageRef\",\"notNull\":true,\"unique\":false},\"wholesale_price_book_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false,\"foreignKey\":{\"table\":\"_smrt_price_books\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"wholesale_currency\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"retail_price_book_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false,\"foreignKey\":{\"table\":\"_smrt_price_books\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"retail_currency\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"}},\"indexes\":[{\"name\":\"_smrt_price_book_assignments_child_tenant_id_idx\",\"columns\":[\"child_tenant_id\"],\"unique\":true},{\"name\":\"_smrt_price_book_assignments_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_price_book_assignments_created_at_idx\",\"columns\":[\"created_at\"]},{\"name\":\"_smrt_price_book_assignments_reseller_tenant_id_idx\",\"columns\":[\"reseller_tenant_id\"]},{\"name\":\"_smrt_price_book_assignments_wholesale_price_book_id_idx\",\"columns\":[\"wholesale_price_book_id\"]},{\"name\":\"_smrt_price_book_assignments_retail_price_book_id_idx\",\"columns\":[\"retail_price_book_id\"]}],\"version\":\"f24f020e\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:RetailCharge\":{\"name\":\"retailcharge\",\"className\":\"RetailCharge\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:RetailCharge\",\"collection\":\"retailcharges\",\"filePath\":\"/home/runner/work/smrt/smrt/packages/subscriptions/src/models/reseller.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}}},\"resellerTenantId\":{\"type\":\"crossPackageRef\",\"required\":false,\"related\":\"@happyvertical/smrt-users:Tenant\"},\"usageEventId\":{\"type\":\"foreignKey\",\"required\":false,\"related\":\"TenantUsageMetric\"},\"clientChargeId\":{\"type\":\"foreignKey\",\"required\":false,\"related\":\"ClientCharge\"},\"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\":\"integer\",\"required\":false,\"default\":0},\"currency\":{\"type\":\"text\",\"required\":false,\"default\":\"USD\"},\"priceBookId\":{\"type\":\"foreignKey\",\"required\":false,\"related\":\"PriceBook\"},\"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, unknown>\",\"isStatic\":false,\"isPublic\":true}},\"decoratorConfig\":{\"tableName\":\"_smrt_retail_charges\",\"api\":{\"include\":[\"list\",\"get\"]},\"cli\":{\"include\":[\"list\",\"get\"]},\"mcp\":{\"include\":[\"list\",\"get\"]},\"conflictColumns\":[\"usage_event_id\"],\"tenantScoped\":{\"mode\":\"required\"}},\"extends\":\"SmrtObject\",\"exportName\":\"RetailCharge\",\"collectionExportName\":\"RetailChargeCollection\",\"validationRules\":[],\"schema\":{\"tableName\":\"_smrt_retail_charges\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_retail_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 \\\"reseller_tenant_id\\\" UUID,\\n \\\"usage_event_id\\\" UUID,\\n \\\"client_charge_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\\\" INTEGER DEFAULT 0,\\n \\\"currency\\\" TEXT DEFAULT 'USD',\\n \\\"price_book_id\\\" UUID,\\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},\"reseller_tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"crossPackageRef\",\"notNull\":false,\"unique\":false},\"usage_event_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false,\"foreignKey\":{\"table\":\"_smrt_tenant_usage_metrics\",\"column\":\"id\",\"onDelete\":\"CASCADE\",\"onUpdate\":\"CASCADE\"}},\"client_charge_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false,\"foreignKey\":{\"table\":\"_smrt_client_charges\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"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\":\"INTEGER\",\"notNull\":false,\"unique\":false,\"default\":0},\"currency\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"USD\"},\"price_book_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false,\"foreignKey\":{\"table\":\"_smrt_price_books\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"pricing_rule_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false,\"foreignKey\":{\"table\":\"_smrt_pricing_rules\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"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_retail_charges_usage_event_id_idx\",\"columns\":[\"usage_event_id\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_retail_charges_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_retail_charges_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]},{\"name\":\"_smrt_retail_charges_reseller_tenant_id_idx\",\"columns\":[\"reseller_tenant_id\"]},{\"name\":\"_smrt_retail_charges_client_charge_id_idx\",\"columns\":[\"client_charge_id\"]},{\"name\":\"_smrt_retail_charges_price_book_id_idx\",\"columns\":[\"price_book_id\"]},{\"name\":\"_smrt_retail_charges_pricing_rule_id_idx\",\"columns\":[\"pricing_rule_id\"]}],\"version\":\"1c1ae3c8\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:CreditGrant\":{\"name\":\"creditgrant\",\"className\":\"CreditGrant\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:CreditGrant\",\"collection\":\"creditgrants\",\"filePath\":\"/home/runner/work/smrt/smrt/packages/subscriptions/src/models/reseller.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}}},\"spendingPolicyId\":{\"type\":\"foreignKey\",\"required\":false,\"related\":\"SpendingPolicy\"},\"amount\":{\"type\":\"integer\",\"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\":\"\"},\"grantedByTenantId\":{\"type\":\"crossPackageRef\",\"required\":false,\"related\":\"@happyvertical/smrt-users:Tenant\"}},\"methods\":{},\"decoratorConfig\":{\"tableName\":\"_smrt_credit_grants\",\"api\":{\"include\":[\"list\",\"get\"]},\"cli\":{\"include\":[\"list\",\"get\"]},\"mcp\":{\"include\":[\"list\",\"get\"]},\"hooks\":{\"beforeDelete\":\"refuseDelete\"},\"tenantScoped\":{\"mode\":\"required\"},\"conflictColumns\":[\"tenant_id\",\"slug\",\"context\"]},\"extends\":\"SmrtObject\",\"exportName\":\"CreditGrant\",\"collectionExportName\":\"CreditGrantCollection\",\"validationRules\":[],\"schema\":{\"tableName\":\"_smrt_credit_grants\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_credit_grants\\\" (\\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 \\\"spending_policy_id\\\" UUID,\\n \\\"amount\\\" INTEGER DEFAULT 0,\\n \\\"currency\\\" TEXT DEFAULT 'USD',\\n \\\"reason\\\" TEXT DEFAULT '',\\n \\\"source\\\" TEXT DEFAULT '',\\n \\\"source_id\\\" TEXT DEFAULT '',\\n \\\"granted_by_tenant_id\\\" UUID\\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},\"spending_policy_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false,\"foreignKey\":{\"table\":\"_smrt_spending_policies\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"amount\":{\"type\":\"INTEGER\",\"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\":\"\"},\"granted_by_tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"crossPackageRef\",\"notNull\":false,\"unique\":false}},\"indexes\":[{\"name\":\"_smrt_credit_grants_slug_context_idx\",\"columns\":[\"tenant_id\",\"slug\",\"context\"],\"unique\":true},{\"name\":\"_smrt_credit_grants_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]},{\"name\":\"_smrt_credit_grants_spending_policy_id_idx\",\"columns\":[\"spending_policy_id\"]},{\"name\":\"_smrt_credit_grants_granted_by_tenant_id_idx\",\"columns\":[\"granted_by_tenant_id\"]}],\"version\":\"602c4e02\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:PriceBookCollection\":{\"name\":\"pricebookcollection\",\"className\":\"PriceBookCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:PriceBookCollection\",\"collection\":\"pricebooks\",\"filePath\":\"/home/runner/work/smrt/smrt/packages/subscriptions/src/models/reseller.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{},\"methods\":{},\"decoratorConfig\":{\"tableName\":\"_smrt_price_books\",\"api\":false,\"mcp\":false,\"cli\":false},\"extends\":\"SmrtCollection\",\"extendsTypeArg\":\"PriceBook\",\"exportName\":\"PriceBookCollection\",\"collectionExportName\":\"PriceBookCollectionCollection\",\"schema\":{\"tableName\":\"_smrt_price_books\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_price_books\\\" (\\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 \\\"book_key\\\" TEXT DEFAULT '',\\n \\\"name\\\" TEXT DEFAULT '',\\n \\\"kind\\\" TEXT DEFAULT 'retail',\\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},\"book_key\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"name\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"kind\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"retail\"},\"active\":{\"type\":\"BOOLEAN\",\"notNull\":false,\"unique\":false,\"default\":true}},\"indexes\":[{\"name\":\"_smrt_price_books_tenant_id_book_key_idx\",\"columns\":[\"tenant_id\",\"book_key\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_price_books_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_price_books_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]}],\"version\":\"c7e5f5e0\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:PriceBookAssignmentCollection\":{\"name\":\"pricebookassignmentcollection\",\"className\":\"PriceBookAssignmentCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:PriceBookAssignmentCollection\",\"collection\":\"pricebookassignments\",\"filePath\":\"/home/runner/work/smrt/smrt/packages/subscriptions/src/models/reseller.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{},\"methods\":{},\"decoratorConfig\":{\"tableName\":\"_smrt_price_book_assignments\",\"api\":false,\"mcp\":false,\"cli\":false},\"extends\":\"SmrtCollection\",\"extendsTypeArg\":\"PriceBookAssignment\",\"exportName\":\"PriceBookAssignmentCollection\",\"collectionExportName\":\"PriceBookAssignmentCollectionCollection\",\"schema\":{\"tableName\":\"_smrt_price_book_assignments\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_price_book_assignments\\\" (\\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 \\\"child_tenant_id\\\" UUID NOT NULL,\\n \\\"reseller_tenant_id\\\" UUID NOT NULL,\\n \\\"wholesale_price_book_id\\\" UUID,\\n \\\"wholesale_currency\\\" TEXT DEFAULT '',\\n \\\"retail_price_book_id\\\" UUID,\\n \\\"retail_currency\\\" 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\"},\"child_tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"crossPackageRef\",\"notNull\":true,\"unique\":false},\"reseller_tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"crossPackageRef\",\"notNull\":true,\"unique\":false},\"wholesale_price_book_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false,\"foreignKey\":{\"table\":\"_smrt_price_books\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"wholesale_currency\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"},\"retail_price_book_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false,\"foreignKey\":{\"table\":\"_smrt_price_books\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"retail_currency\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"\"}},\"indexes\":[{\"name\":\"_smrt_price_book_assignments_child_tenant_id_idx\",\"columns\":[\"child_tenant_id\"],\"unique\":true},{\"name\":\"_smrt_price_book_assignments_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_price_book_assignments_created_at_idx\",\"columns\":[\"created_at\"]},{\"name\":\"_smrt_price_book_assignments_reseller_tenant_id_idx\",\"columns\":[\"reseller_tenant_id\"]},{\"name\":\"_smrt_price_book_assignments_wholesale_price_book_id_idx\",\"columns\":[\"wholesale_price_book_id\"]},{\"name\":\"_smrt_price_book_assignments_retail_price_book_id_idx\",\"columns\":[\"retail_price_book_id\"]}],\"version\":\"f24f020e\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:RetailChargeCollection\":{\"name\":\"retailchargecollection\",\"className\":\"RetailChargeCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:RetailChargeCollection\",\"collection\":\"retailcharges\",\"filePath\":\"/home/runner/work/smrt/smrt/packages/subscriptions/src/models/reseller.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{},\"methods\":{},\"decoratorConfig\":{\"tableName\":\"_smrt_retail_charges\"},\"extends\":\"SmrtCollection\",\"extendsTypeArg\":\"RetailCharge\",\"exportName\":\"RetailChargeCollection\",\"collectionExportName\":\"RetailChargeCollectionCollection\",\"schema\":{\"tableName\":\"_smrt_retail_charges\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_retail_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 \\\"reseller_tenant_id\\\" UUID,\\n \\\"usage_event_id\\\" UUID,\\n \\\"client_charge_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\\\" INTEGER DEFAULT 0,\\n \\\"currency\\\" TEXT DEFAULT 'USD',\\n \\\"price_book_id\\\" UUID,\\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},\"reseller_tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"crossPackageRef\",\"notNull\":false,\"unique\":false},\"usage_event_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false,\"foreignKey\":{\"table\":\"_smrt_tenant_usage_metrics\",\"column\":\"id\",\"onDelete\":\"CASCADE\",\"onUpdate\":\"CASCADE\"}},\"client_charge_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false,\"foreignKey\":{\"table\":\"_smrt_client_charges\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"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\":\"INTEGER\",\"notNull\":false,\"unique\":false,\"default\":0},\"currency\":{\"type\":\"TEXT\",\"notNull\":false,\"unique\":false,\"default\":\"USD\"},\"price_book_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false,\"foreignKey\":{\"table\":\"_smrt_price_books\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"pricing_rule_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false,\"foreignKey\":{\"table\":\"_smrt_pricing_rules\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"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_retail_charges_usage_event_id_idx\",\"columns\":[\"usage_event_id\"],\"unique\":true,\"nullsNotDistinct\":true},{\"name\":\"_smrt_retail_charges_slug_context_idx\",\"columns\":[\"slug\",\"context\"]},{\"name\":\"_smrt_retail_charges_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]},{\"name\":\"_smrt_retail_charges_reseller_tenant_id_idx\",\"columns\":[\"reseller_tenant_id\"]},{\"name\":\"_smrt_retail_charges_client_charge_id_idx\",\"columns\":[\"client_charge_id\"]},{\"name\":\"_smrt_retail_charges_price_book_id_idx\",\"columns\":[\"price_book_id\"]},{\"name\":\"_smrt_retail_charges_pricing_rule_id_idx\",\"columns\":[\"pricing_rule_id\"]}],\"version\":\"1c1ae3c8\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"},\"@happyvertical/smrt-subscriptions:CreditGrantCollection\":{\"name\":\"creditgrantcollection\",\"className\":\"CreditGrantCollection\",\"qualifiedName\":\"@happyvertical/smrt-subscriptions:CreditGrantCollection\",\"collection\":\"creditgrants\",\"filePath\":\"/home/runner/work/smrt/smrt/packages/subscriptions/src/models/reseller.ts\",\"packageName\":\"@happyvertical/smrt-subscriptions\",\"fields\":{},\"methods\":{},\"decoratorConfig\":{\"tableName\":\"_smrt_credit_grants\"},\"extends\":\"SmrtCollection\",\"extendsTypeArg\":\"CreditGrant\",\"exportName\":\"CreditGrantCollection\",\"collectionExportName\":\"CreditGrantCollectionCollection\",\"schema\":{\"tableName\":\"_smrt_credit_grants\",\"ddl\":\"CREATE TABLE IF NOT EXISTS \\\"_smrt_credit_grants\\\" (\\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 \\\"spending_policy_id\\\" UUID,\\n \\\"amount\\\" INTEGER DEFAULT 0,\\n \\\"currency\\\" TEXT DEFAULT 'USD',\\n \\\"reason\\\" TEXT DEFAULT '',\\n \\\"source\\\" TEXT DEFAULT '',\\n \\\"source_id\\\" TEXT DEFAULT '',\\n \\\"granted_by_tenant_id\\\" UUID\\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},\"spending_policy_id\":{\"type\":\"UUID\",\"referenceKind\":\"foreignKey\",\"notNull\":false,\"unique\":false,\"foreignKey\":{\"table\":\"_smrt_spending_policies\",\"column\":\"id\",\"onDelete\":\"NO ACTION\",\"onUpdate\":\"CASCADE\"}},\"amount\":{\"type\":\"INTEGER\",\"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\":\"\"},\"granted_by_tenant_id\":{\"type\":\"UUID\",\"referenceKind\":\"crossPackageRef\",\"notNull\":false,\"unique\":false}},\"indexes\":[{\"name\":\"_smrt_credit_grants_slug_context_idx\",\"columns\":[\"tenant_id\",\"slug\",\"context\"],\"unique\":true},{\"name\":\"_smrt_credit_grants_tenant_id_created_at_idx\",\"columns\":[\"tenant_id\",\"created_at\"]},{\"name\":\"_smrt_credit_grants_spending_policy_id_idx\",\"columns\":[\"spending_policy_id\"]},{\"name\":\"_smrt_credit_grants_granted_by_tenant_id_idx\",\"columns\":[\"granted_by_tenant_id\"]}],\"version\":\"602c4e02\"},\"importPath\":\"@happyvertical/smrt-subscriptions\"}},\"moduleType\":\"smrt\",\"smrtDependencies\":[\"@happyvertical/smrt-core\",\"@happyvertical/smrt-tenancy\"]}"));
|
|
6
6
|
//#endregion
|
|
7
7
|
//#region src/utils.ts
|
|
8
8
|
var THRESHOLD_WINDOWS = [
|
|
@@ -155,14 +155,17 @@ function utcWindow(now, unit) {
|
|
|
155
155
|
end
|
|
156
156
|
};
|
|
157
157
|
}
|
|
158
|
+
function tenantKey(value) {
|
|
159
|
+
return String(value ?? "").toLowerCase();
|
|
160
|
+
}
|
|
158
161
|
//#endregion
|
|
159
162
|
//#region src/models/SubscriptionPlan.ts
|
|
160
|
-
var __defProp$
|
|
161
|
-
var __getOwnPropDesc$
|
|
162
|
-
var __decorateClass$
|
|
163
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$
|
|
163
|
+
var __defProp$4 = Object.defineProperty;
|
|
164
|
+
var __getOwnPropDesc$4 = Object.getOwnPropertyDescriptor;
|
|
165
|
+
var __decorateClass$4 = (decorators, target, key, kind) => {
|
|
166
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$4(target, key) : target;
|
|
164
167
|
for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
165
|
-
if (kind && result) __defProp$
|
|
168
|
+
if (kind && result) __defProp$4(target, key, result);
|
|
166
169
|
return result;
|
|
167
170
|
};
|
|
168
171
|
var SubscriptionPlan = class extends SmrtObject {
|
|
@@ -229,8 +232,8 @@ var SubscriptionPlan = class extends SmrtObject {
|
|
|
229
232
|
this.metadata = stringifyJson(metadata);
|
|
230
233
|
}
|
|
231
234
|
};
|
|
232
|
-
__decorateClass$
|
|
233
|
-
SubscriptionPlan = __decorateClass$
|
|
235
|
+
__decorateClass$4([tenantId({ nullable: true })], SubscriptionPlan.prototype, "tenantId", 2);
|
|
236
|
+
SubscriptionPlan = __decorateClass$4([TenantScoped({ mode: "optional" }), smrt({
|
|
234
237
|
tableName: "_smrt_subscription_plans",
|
|
235
238
|
api: { include: [
|
|
236
239
|
"list",
|
|
@@ -267,12 +270,12 @@ var SubscriptionPlanCollection = class extends SmrtCollection {
|
|
|
267
270
|
};
|
|
268
271
|
//#endregion
|
|
269
272
|
//#region src/models/TenantSubscription.ts
|
|
270
|
-
var __defProp$
|
|
271
|
-
var __getOwnPropDesc$
|
|
272
|
-
var __decorateClass$
|
|
273
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$
|
|
273
|
+
var __defProp$3 = Object.defineProperty;
|
|
274
|
+
var __getOwnPropDesc$3 = Object.getOwnPropertyDescriptor;
|
|
275
|
+
var __decorateClass$3 = (decorators, target, key, kind) => {
|
|
276
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$3(target, key) : target;
|
|
274
277
|
for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
275
|
-
if (kind && result) __defProp$
|
|
278
|
+
if (kind && result) __defProp$3(target, key, result);
|
|
276
279
|
return result;
|
|
277
280
|
};
|
|
278
281
|
var TenantSubscription = class extends SmrtObject {
|
|
@@ -380,9 +383,9 @@ var TenantSubscription = class extends SmrtObject {
|
|
|
380
383
|
this.metadata = stringifyJson(metadata);
|
|
381
384
|
}
|
|
382
385
|
};
|
|
383
|
-
__decorateClass$
|
|
384
|
-
__decorateClass$
|
|
385
|
-
TenantSubscription = __decorateClass$
|
|
386
|
+
__decorateClass$3([tenantId()], TenantSubscription.prototype, "tenantId", 2);
|
|
387
|
+
__decorateClass$3([foreignKey("SubscriptionPlan")], TenantSubscription.prototype, "planId", 2);
|
|
388
|
+
TenantSubscription = __decorateClass$3([TenantScoped({ mode: "required" }), smrt({
|
|
386
389
|
tableName: "_smrt_tenant_subscriptions",
|
|
387
390
|
api: { include: [
|
|
388
391
|
"list",
|
|
@@ -453,12 +456,12 @@ var TenantSubscriptionCollection = class extends SmrtCollection {
|
|
|
453
456
|
};
|
|
454
457
|
//#endregion
|
|
455
458
|
//#region src/models/TenantUsageMetric.ts
|
|
456
|
-
var __defProp$
|
|
457
|
-
var __getOwnPropDesc$
|
|
458
|
-
var __decorateClass$
|
|
459
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$
|
|
459
|
+
var __defProp$2 = Object.defineProperty;
|
|
460
|
+
var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
|
|
461
|
+
var __decorateClass$2 = (decorators, target, key, kind) => {
|
|
462
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target;
|
|
460
463
|
for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
461
|
-
if (kind && result) __defProp$
|
|
464
|
+
if (kind && result) __defProp$2(target, key, result);
|
|
462
465
|
return result;
|
|
463
466
|
};
|
|
464
467
|
var TenantUsageMetric = class extends SmrtObject {
|
|
@@ -578,8 +581,8 @@ var TenantUsageMetric = class extends SmrtObject {
|
|
|
578
581
|
this.dimensions = stringifyJson(dimensions);
|
|
579
582
|
}
|
|
580
583
|
};
|
|
581
|
-
__decorateClass$
|
|
582
|
-
TenantUsageMetric = __decorateClass$
|
|
584
|
+
__decorateClass$2([tenantId()], TenantUsageMetric.prototype, "tenantId", 2);
|
|
585
|
+
TenantUsageMetric = __decorateClass$2([TenantScoped({ mode: "required" }), smrt({
|
|
583
586
|
tableName: "_smrt_tenant_usage_metrics",
|
|
584
587
|
api: { include: [
|
|
585
588
|
"list",
|
|
@@ -830,12 +833,12 @@ function migrateSubscriptionsMoneyToMinorUnits(db, options = {}) {
|
|
|
830
833
|
}
|
|
831
834
|
//#endregion
|
|
832
835
|
//#region src/models/commercial.ts
|
|
833
|
-
var __defProp = Object.defineProperty;
|
|
834
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
835
|
-
var __decorateClass = (decorators, target, key, kind) => {
|
|
836
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
836
|
+
var __defProp$1 = Object.defineProperty;
|
|
837
|
+
var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
|
|
838
|
+
var __decorateClass$1 = (decorators, target, key, kind) => {
|
|
839
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
|
|
837
840
|
for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
838
|
-
if (kind && result) __defProp(target, key, result);
|
|
841
|
+
if (kind && result) __defProp$1(target, key, result);
|
|
839
842
|
return result;
|
|
840
843
|
};
|
|
841
844
|
var PricingRule = class extends SmrtObject {
|
|
@@ -850,6 +853,7 @@ var PricingRule = class extends SmrtObject {
|
|
|
850
853
|
priority = 0;
|
|
851
854
|
terms = "{}";
|
|
852
855
|
active = true;
|
|
856
|
+
priceBookId = "";
|
|
853
857
|
getTerms() {
|
|
854
858
|
try {
|
|
855
859
|
return JSON.parse(this.terms);
|
|
@@ -861,8 +865,9 @@ var PricingRule = class extends SmrtObject {
|
|
|
861
865
|
this.terms = JSON.stringify(value);
|
|
862
866
|
}
|
|
863
867
|
};
|
|
864
|
-
__decorateClass([tenantId()], PricingRule.prototype, "tenantId", 2);
|
|
865
|
-
|
|
868
|
+
__decorateClass$1([tenantId()], PricingRule.prototype, "tenantId", 2);
|
|
869
|
+
__decorateClass$1([foreignKey("PriceBook")], PricingRule.prototype, "priceBookId", 2);
|
|
870
|
+
PricingRule = __decorateClass$1([TenantScoped({ mode: "required" }), smrt({
|
|
866
871
|
tableName: "_smrt_pricing_rules",
|
|
867
872
|
api: true,
|
|
868
873
|
cli: true,
|
|
@@ -871,6 +876,7 @@ PricingRule = __decorateClass([TenantScoped({ mode: "required" }), smrt({
|
|
|
871
876
|
var ClientCharge = class extends SmrtObject {
|
|
872
877
|
tenantId;
|
|
873
878
|
usageEventId = "";
|
|
879
|
+
usageTenantId = "";
|
|
874
880
|
subscriberKind = "tenant";
|
|
875
881
|
subscriberExternalId = "";
|
|
876
882
|
projectId = "";
|
|
@@ -895,6 +901,7 @@ var ClientCharge = class extends SmrtObject {
|
|
|
895
901
|
amount = 0;
|
|
896
902
|
currency = "USD";
|
|
897
903
|
pricingRuleId = "";
|
|
904
|
+
priceBookId = "";
|
|
898
905
|
pricingSnapshot = "{}";
|
|
899
906
|
status = "draft";
|
|
900
907
|
approvedAt = null;
|
|
@@ -927,7 +934,9 @@ var ClientCharge = class extends SmrtObject {
|
|
|
927
934
|
row.currency,
|
|
928
935
|
row.pricing_rule_id,
|
|
929
936
|
row.pricing_snapshot,
|
|
930
|
-
row.approved_at
|
|
937
|
+
row.approved_at,
|
|
938
|
+
row.usage_tenant_id,
|
|
939
|
+
row.price_book_id
|
|
931
940
|
];
|
|
932
941
|
const current = [
|
|
933
942
|
this.tenantId,
|
|
@@ -945,15 +954,19 @@ var ClientCharge = class extends SmrtObject {
|
|
|
945
954
|
this.currency,
|
|
946
955
|
this.pricingRuleId,
|
|
947
956
|
this.pricingSnapshot,
|
|
948
|
-
this.approvedAt
|
|
957
|
+
this.approvedAt,
|
|
958
|
+
this.usageTenantId,
|
|
959
|
+
this.priceBookId
|
|
949
960
|
];
|
|
950
961
|
if (persisted.some((value, index) => normalizeSnapshot(value) !== normalizeSnapshot(current[index]))) throw new Error("Approved client charges are immutable; append a BillingAdjustment instead.");
|
|
951
962
|
}
|
|
952
963
|
};
|
|
953
|
-
__decorateClass([tenantId()], ClientCharge.prototype, "tenantId", 2);
|
|
954
|
-
__decorateClass([foreignKey("TenantUsageMetric")], ClientCharge.prototype, "usageEventId", 2);
|
|
955
|
-
__decorateClass([
|
|
956
|
-
|
|
964
|
+
__decorateClass$1([tenantId()], ClientCharge.prototype, "tenantId", 2);
|
|
965
|
+
__decorateClass$1([foreignKey("TenantUsageMetric")], ClientCharge.prototype, "usageEventId", 2);
|
|
966
|
+
__decorateClass$1([crossPackageRef("@happyvertical/smrt-users:Tenant")], ClientCharge.prototype, "usageTenantId", 2);
|
|
967
|
+
__decorateClass$1([foreignKey("PricingRule")], ClientCharge.prototype, "pricingRuleId", 2);
|
|
968
|
+
__decorateClass$1([foreignKey("PriceBook")], ClientCharge.prototype, "priceBookId", 2);
|
|
969
|
+
ClientCharge = __decorateClass$1([TenantScoped({ mode: "required" }), smrt({
|
|
957
970
|
tableName: "_smrt_client_charges",
|
|
958
971
|
api: { include: ["list", "get"] },
|
|
959
972
|
cli: { include: ["list", "get"] },
|
|
@@ -981,9 +994,9 @@ var BillingAdjustment = class extends SmrtObject {
|
|
|
981
994
|
if (await this.db.get(this.tableName, { id: this.id })) throw new Error("Billing adjustments are append-only; create a new adjustment instead.");
|
|
982
995
|
}
|
|
983
996
|
};
|
|
984
|
-
__decorateClass([tenantId()], BillingAdjustment.prototype, "tenantId", 2);
|
|
985
|
-
__decorateClass([foreignKey("ClientCharge")], BillingAdjustment.prototype, "clientChargeId", 2);
|
|
986
|
-
BillingAdjustment = __decorateClass([TenantScoped({ mode: "required" }), smrt({
|
|
997
|
+
__decorateClass$1([tenantId()], BillingAdjustment.prototype, "tenantId", 2);
|
|
998
|
+
__decorateClass$1([foreignKey("ClientCharge")], BillingAdjustment.prototype, "clientChargeId", 2);
|
|
999
|
+
BillingAdjustment = __decorateClass$1([TenantScoped({ mode: "required" }), smrt({
|
|
987
1000
|
tableName: "_smrt_billing_adjustments",
|
|
988
1001
|
api: { include: ["list", "get"] },
|
|
989
1002
|
cli: { include: ["list", "get"] },
|
|
@@ -1003,20 +1016,87 @@ var SpendingPolicy = class extends SmrtObject {
|
|
|
1003
1016
|
* Spending cap in **integer minor units** of {@link currency}. Compared
|
|
1004
1017
|
* directly against the sum of `ClientCharge.amount` + `BillingAdjustment`s
|
|
1005
1018
|
* plus the caller's estimate, so it must carry the same unit (#2401).
|
|
1019
|
+
* Must be zero for a `balance` policy, whose limit is its credit grants.
|
|
1006
1020
|
*/
|
|
1007
1021
|
limitAmount = 0;
|
|
1008
1022
|
currency = "USD";
|
|
1009
1023
|
behavior = "observe";
|
|
1010
1024
|
priority = 0;
|
|
1011
1025
|
active = true;
|
|
1026
|
+
/** Which charges count toward the policy; see {@link SpendingBasis}. */
|
|
1027
|
+
basis = "billed";
|
|
1028
|
+
setByTenantId = "";
|
|
1029
|
+
/** Start of the spend window for a `balance` policy; defaults to creation. */
|
|
1030
|
+
balanceFrom = null;
|
|
1012
1031
|
async validateBeforeSave() {
|
|
1013
1032
|
await super.validateBeforeSave();
|
|
1014
1033
|
if (this.subscriberExternalId && !this.subscriberKind) throw new Error("Spending policies with subscriberExternalId require subscriberKind.");
|
|
1015
1034
|
if (this.period === "rolling" && (!Number.isFinite(this.rollingSeconds) || this.rollingSeconds <= 0)) throw new Error("Rolling spending policies require rollingSeconds greater than zero.");
|
|
1035
|
+
if (this.basis !== "billed" && this.basis !== "retail" && this.basis !== "wholesale") throw new Error("Spending policy basis must be billed, retail, or wholesale.");
|
|
1036
|
+
if (this.basis === "wholesale" && !this.setByTenantId) throw new Error("Wholesale spending policies must be delegated by a parent (setByTenantId).");
|
|
1037
|
+
if (this.period === "balance") {
|
|
1038
|
+
if (this.limitAmount !== 0) throw new Error("Balance spending policies take their limit from credit grants; limitAmount must be 0.");
|
|
1039
|
+
if (!this.balanceFrom) this.balanceFrom = /* @__PURE__ */ new Date();
|
|
1040
|
+
}
|
|
1041
|
+
const targets = await this.persistedTargets();
|
|
1042
|
+
await this.assertBalanceLedgerStable(targets);
|
|
1043
|
+
await this.assertDelegationAuthority(targets);
|
|
1044
|
+
}
|
|
1045
|
+
/**
|
|
1046
|
+
* A balance policy's credit grants are scoped to its currency and period;
|
|
1047
|
+
* changing either would silently detach the ledger, so create a new
|
|
1048
|
+
* balance instead.
|
|
1049
|
+
*/
|
|
1050
|
+
async assertBalanceLedgerStable(rows) {
|
|
1051
|
+
for (const row of rows) {
|
|
1052
|
+
if (row?.period !== "balance") continue;
|
|
1053
|
+
if (this.period !== "balance" || row.currency !== this.currency) throw new Error("A balance policy cannot change currency or period; create a new balance policy.");
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
/**
|
|
1057
|
+
* The rows this save can overwrite: by id and, because a new object may
|
|
1058
|
+
* already carry a generated id, by conflict key (an upsert target).
|
|
1059
|
+
*/
|
|
1060
|
+
async persistedTargets() {
|
|
1061
|
+
return [this.id ? await this.getCanonicalPersistedRow({ id: this.id }) : null, this.tenantId ? await this.getCanonicalPersistedRow({
|
|
1062
|
+
tenant_id: this.tenantId,
|
|
1063
|
+
subscriber_kind: this.subscriberKind,
|
|
1064
|
+
subscriber_external_id: this.subscriberExternalId,
|
|
1065
|
+
project_id: this.projectId,
|
|
1066
|
+
service_key: this.serviceKey,
|
|
1067
|
+
metric_key: this.metricKey,
|
|
1068
|
+
period: this.period,
|
|
1069
|
+
name: this.name
|
|
1070
|
+
}) : null];
|
|
1071
|
+
}
|
|
1072
|
+
/**
|
|
1073
|
+
* A delegated policy belongs to the parent that set it: the constrained
|
|
1074
|
+
* child cannot create one in a parent's name, loosen it, or delete it.
|
|
1075
|
+
* The parent's-own-context allowance applies only where no tenancy
|
|
1076
|
+
* interceptor is registered; with one, the interceptor refuses a parent
|
|
1077
|
+
* writing the child's row, so parents change delegated policies through
|
|
1078
|
+
* `ResellerBillingService.setDelegatedSpendingPolicy()` (set
|
|
1079
|
+
* `active: false` to retire one).
|
|
1080
|
+
* Checks both the persisted row (by id, or by conflict key for an upsert)
|
|
1081
|
+
* and the incoming value.
|
|
1082
|
+
*/
|
|
1083
|
+
async assertDelegationAuthority(targets) {
|
|
1084
|
+
const [byId, byKey] = targets ?? await this.persistedTargets();
|
|
1085
|
+
const owners = new Set([
|
|
1086
|
+
byId?.set_by_tenant_id,
|
|
1087
|
+
byKey?.set_by_tenant_id,
|
|
1088
|
+
this.setByTenantId
|
|
1089
|
+
].filter((value) => Boolean(value)).map((value) => String(value).toLowerCase()));
|
|
1090
|
+
if (owners.size === 0) return;
|
|
1091
|
+
if (isSystemContext() || isSuperAdminBypass()) return;
|
|
1092
|
+
const current = getTenantId()?.toLowerCase();
|
|
1093
|
+
if (owners.size === 1 && current && owners.has(current)) return;
|
|
1094
|
+
throw new TenantIsolationError("Delegated spending policies can be changed only by the parent that set them.");
|
|
1016
1095
|
}
|
|
1017
1096
|
};
|
|
1018
|
-
__decorateClass([tenantId()], SpendingPolicy.prototype, "tenantId", 2);
|
|
1019
|
-
|
|
1097
|
+
__decorateClass$1([tenantId()], SpendingPolicy.prototype, "tenantId", 2);
|
|
1098
|
+
__decorateClass$1([crossPackageRef("@happyvertical/smrt-users:Tenant")], SpendingPolicy.prototype, "setByTenantId", 2);
|
|
1099
|
+
SpendingPolicy = __decorateClass$1([TenantScoped({ mode: "required" }), smrt({
|
|
1020
1100
|
tableName: "_smrt_spending_policies",
|
|
1021
1101
|
conflictColumns: [
|
|
1022
1102
|
"tenant_id",
|
|
@@ -1030,7 +1110,8 @@ SpendingPolicy = __decorateClass([TenantScoped({ mode: "required" }), smrt({
|
|
|
1030
1110
|
],
|
|
1031
1111
|
api: true,
|
|
1032
1112
|
cli: true,
|
|
1033
|
-
mcp: true
|
|
1113
|
+
mcp: true,
|
|
1114
|
+
hooks: { beforeDelete: "assertDelegationAuthority" }
|
|
1034
1115
|
})], SpendingPolicy);
|
|
1035
1116
|
var PricingRuleCollection = class extends SmrtCollection {
|
|
1036
1117
|
static _itemClass = PricingRule;
|
|
@@ -1053,6 +1134,227 @@ function normalizeSnapshot(value) {
|
|
|
1053
1134
|
return String(value ?? "");
|
|
1054
1135
|
}
|
|
1055
1136
|
//#endregion
|
|
1137
|
+
//#region src/models/reseller.ts
|
|
1138
|
+
var __defProp = Object.defineProperty;
|
|
1139
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
1140
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
1141
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
1142
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
1143
|
+
if (kind && result) __defProp(target, key, result);
|
|
1144
|
+
return result;
|
|
1145
|
+
};
|
|
1146
|
+
var PRICE_BOOK_KINDS = ["wholesale", "retail"];
|
|
1147
|
+
var CURRENCY_PATTERN = /^[A-Z]{3}$/;
|
|
1148
|
+
function isPriceBookKind(value) {
|
|
1149
|
+
return PRICE_BOOK_KINDS.includes(value);
|
|
1150
|
+
}
|
|
1151
|
+
function isCurrencyCode(value) {
|
|
1152
|
+
return typeof value === "string" && CURRENCY_PATTERN.test(value);
|
|
1153
|
+
}
|
|
1154
|
+
var PriceBook = class extends SmrtObject {
|
|
1155
|
+
tenantId;
|
|
1156
|
+
bookKey = "";
|
|
1157
|
+
name = "";
|
|
1158
|
+
kind = "retail";
|
|
1159
|
+
active = true;
|
|
1160
|
+
async validateBeforeSave() {
|
|
1161
|
+
await super.validateBeforeSave();
|
|
1162
|
+
if (!this.bookKey.trim()) throw new Error("Price books require a bookKey.");
|
|
1163
|
+
if (!isPriceBookKind(this.kind)) throw new Error("Price book kind must be wholesale or retail.");
|
|
1164
|
+
}
|
|
1165
|
+
};
|
|
1166
|
+
__decorateClass([tenantId()], PriceBook.prototype, "tenantId", 2);
|
|
1167
|
+
PriceBook = __decorateClass([TenantScoped({ mode: "required" }), smrt({
|
|
1168
|
+
tableName: "_smrt_price_books",
|
|
1169
|
+
conflictColumns: ["tenant_id", "book_key"],
|
|
1170
|
+
api: false,
|
|
1171
|
+
cli: false,
|
|
1172
|
+
mcp: false
|
|
1173
|
+
})], PriceBook);
|
|
1174
|
+
var PriceBookAssignment = class extends SmrtObject {
|
|
1175
|
+
childTenantId = "";
|
|
1176
|
+
resellerTenantId = "";
|
|
1177
|
+
wholesalePriceBookId = "";
|
|
1178
|
+
wholesaleCurrency = "";
|
|
1179
|
+
retailPriceBookId = "";
|
|
1180
|
+
retailCurrency = "";
|
|
1181
|
+
};
|
|
1182
|
+
__decorateClass([crossPackageRef("@happyvertical/smrt-users:Tenant"), field({ required: true })], PriceBookAssignment.prototype, "childTenantId", 2);
|
|
1183
|
+
__decorateClass([crossPackageRef("@happyvertical/smrt-users:Tenant"), field({ required: true })], PriceBookAssignment.prototype, "resellerTenantId", 2);
|
|
1184
|
+
__decorateClass([foreignKey("PriceBook")], PriceBookAssignment.prototype, "wholesalePriceBookId", 2);
|
|
1185
|
+
__decorateClass([foreignKey("PriceBook")], PriceBookAssignment.prototype, "retailPriceBookId", 2);
|
|
1186
|
+
PriceBookAssignment = __decorateClass([smrt({
|
|
1187
|
+
tableName: "_smrt_price_book_assignments",
|
|
1188
|
+
conflictColumns: ["child_tenant_id"],
|
|
1189
|
+
api: false,
|
|
1190
|
+
cli: false,
|
|
1191
|
+
mcp: false
|
|
1192
|
+
})], PriceBookAssignment);
|
|
1193
|
+
var RetailCharge = class extends SmrtObject {
|
|
1194
|
+
tenantId;
|
|
1195
|
+
resellerTenantId = "";
|
|
1196
|
+
usageEventId = "";
|
|
1197
|
+
clientChargeId = "";
|
|
1198
|
+
subscriberKind = "tenant";
|
|
1199
|
+
subscriberExternalId = "";
|
|
1200
|
+
projectId = "";
|
|
1201
|
+
workRefType = "";
|
|
1202
|
+
workRefId = "";
|
|
1203
|
+
provider = "";
|
|
1204
|
+
serviceKey = "";
|
|
1205
|
+
metricKey = "";
|
|
1206
|
+
/** Metered quantity; fractional, like `ClientCharge.quantity`. */
|
|
1207
|
+
quantity = 0;
|
|
1208
|
+
/** Charge in integer minor units of {@link currency}. */
|
|
1209
|
+
amount = 0;
|
|
1210
|
+
currency = "USD";
|
|
1211
|
+
priceBookId = "";
|
|
1212
|
+
pricingRuleId = "";
|
|
1213
|
+
pricingSnapshot = "{}";
|
|
1214
|
+
status = "draft";
|
|
1215
|
+
approvedAt = null;
|
|
1216
|
+
getPricingSnapshot() {
|
|
1217
|
+
try {
|
|
1218
|
+
return JSON.parse(this.pricingSnapshot);
|
|
1219
|
+
} catch {
|
|
1220
|
+
return {};
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
async validateBeforeSave() {
|
|
1224
|
+
await super.validateBeforeSave();
|
|
1225
|
+
if (!this.id) return;
|
|
1226
|
+
const row = await this.getCanonicalPersistedRow({ id: this.id });
|
|
1227
|
+
if (row?.status !== "approved") return;
|
|
1228
|
+
const persisted = [
|
|
1229
|
+
row.tenant_id,
|
|
1230
|
+
row.reseller_tenant_id,
|
|
1231
|
+
row.usage_event_id,
|
|
1232
|
+
row.client_charge_id,
|
|
1233
|
+
row.subscriber_kind,
|
|
1234
|
+
row.subscriber_external_id,
|
|
1235
|
+
row.project_id,
|
|
1236
|
+
row.work_ref_type,
|
|
1237
|
+
row.work_ref_id,
|
|
1238
|
+
row.provider,
|
|
1239
|
+
row.service_key,
|
|
1240
|
+
row.metric_key,
|
|
1241
|
+
row.quantity,
|
|
1242
|
+
row.amount,
|
|
1243
|
+
row.currency,
|
|
1244
|
+
row.price_book_id,
|
|
1245
|
+
row.pricing_rule_id,
|
|
1246
|
+
row.pricing_snapshot,
|
|
1247
|
+
row.status,
|
|
1248
|
+
row.approved_at
|
|
1249
|
+
];
|
|
1250
|
+
const current = [
|
|
1251
|
+
this.tenantId,
|
|
1252
|
+
this.resellerTenantId,
|
|
1253
|
+
this.usageEventId,
|
|
1254
|
+
this.clientChargeId,
|
|
1255
|
+
this.subscriberKind,
|
|
1256
|
+
this.subscriberExternalId,
|
|
1257
|
+
this.projectId,
|
|
1258
|
+
this.workRefType,
|
|
1259
|
+
this.workRefId,
|
|
1260
|
+
this.provider,
|
|
1261
|
+
this.serviceKey,
|
|
1262
|
+
this.metricKey,
|
|
1263
|
+
this.quantity,
|
|
1264
|
+
this.amount,
|
|
1265
|
+
this.currency,
|
|
1266
|
+
this.priceBookId,
|
|
1267
|
+
this.pricingRuleId,
|
|
1268
|
+
this.pricingSnapshot,
|
|
1269
|
+
this.status,
|
|
1270
|
+
this.approvedAt
|
|
1271
|
+
];
|
|
1272
|
+
if (persisted.some((value, index) => normalizeLedgerValue(value) !== normalizeLedgerValue(current[index]))) throw new Error("Approved retail charges are immutable.");
|
|
1273
|
+
}
|
|
1274
|
+
};
|
|
1275
|
+
__decorateClass([tenantId()], RetailCharge.prototype, "tenantId", 2);
|
|
1276
|
+
__decorateClass([crossPackageRef("@happyvertical/smrt-users:Tenant")], RetailCharge.prototype, "resellerTenantId", 2);
|
|
1277
|
+
__decorateClass([foreignKey("TenantUsageMetric")], RetailCharge.prototype, "usageEventId", 2);
|
|
1278
|
+
__decorateClass([foreignKey("ClientCharge")], RetailCharge.prototype, "clientChargeId", 2);
|
|
1279
|
+
__decorateClass([foreignKey("PriceBook")], RetailCharge.prototype, "priceBookId", 2);
|
|
1280
|
+
__decorateClass([foreignKey("PricingRule")], RetailCharge.prototype, "pricingRuleId", 2);
|
|
1281
|
+
RetailCharge = __decorateClass([TenantScoped({ mode: "required" }), smrt({
|
|
1282
|
+
tableName: "_smrt_retail_charges",
|
|
1283
|
+
api: { include: ["list", "get"] },
|
|
1284
|
+
cli: { include: ["list", "get"] },
|
|
1285
|
+
mcp: { include: ["list", "get"] },
|
|
1286
|
+
conflictColumns: ["usage_event_id"]
|
|
1287
|
+
})], RetailCharge);
|
|
1288
|
+
var CreditGrant = class extends SmrtObject {
|
|
1289
|
+
tenantId;
|
|
1290
|
+
spendingPolicyId = "";
|
|
1291
|
+
/** Signed credit in integer minor units of {@link currency}. */
|
|
1292
|
+
amount = 0;
|
|
1293
|
+
currency = "USD";
|
|
1294
|
+
reason = "";
|
|
1295
|
+
source = "";
|
|
1296
|
+
sourceId = "";
|
|
1297
|
+
grantedByTenantId = "";
|
|
1298
|
+
/** Append-only: history is corrected by a reversing grant, never removed. */
|
|
1299
|
+
refuseDelete() {
|
|
1300
|
+
throw new Error("Credit grants are append-only; record a reversing grant instead of deleting.");
|
|
1301
|
+
}
|
|
1302
|
+
async validateBeforeSave() {
|
|
1303
|
+
await super.validateBeforeSave();
|
|
1304
|
+
if (!Number.isSafeInteger(this.amount) || this.amount === 0) throw new Error("Credit grant amounts must be nonzero integer minor units (cents).");
|
|
1305
|
+
if (this.id) {
|
|
1306
|
+
if (await this.db.get(this.tableName, { id: this.id })) throw new Error("Credit grants are append-only; record a reversing grant instead.");
|
|
1307
|
+
}
|
|
1308
|
+
const policy = this.spendingPolicyId ? await this.db.get("_smrt_spending_policies", { id: this.spendingPolicyId }) : null;
|
|
1309
|
+
if (policy?.period !== "balance" || tenantKey(policy.tenant_id) !== tenantKey(this.tenantId) || policy.currency !== this.currency) throw new Error("Credit grants must credit a balance policy of the same tenant and currency.");
|
|
1310
|
+
const setBy = tenantKey(policy.set_by_tenant_id);
|
|
1311
|
+
if (!setBy) return;
|
|
1312
|
+
if (tenantKey(this.grantedByTenantId) !== setBy) throw new TenantIsolationError("Delegated balance credit must be granted by the parent that set it.");
|
|
1313
|
+
if (!isSystemContext() && !isSuperAdminBypass() && tenantKey(getTenantId()) !== setBy) throw new TenantIsolationError("Only the parent that set a delegated policy can grant it credit.");
|
|
1314
|
+
}
|
|
1315
|
+
};
|
|
1316
|
+
__decorateClass([tenantId()], CreditGrant.prototype, "tenantId", 2);
|
|
1317
|
+
__decorateClass([foreignKey("SpendingPolicy")], CreditGrant.prototype, "spendingPolicyId", 2);
|
|
1318
|
+
__decorateClass([crossPackageRef("@happyvertical/smrt-users:Tenant")], CreditGrant.prototype, "grantedByTenantId", 2);
|
|
1319
|
+
CreditGrant = __decorateClass([TenantScoped({ mode: "required" }), smrt({
|
|
1320
|
+
tableName: "_smrt_credit_grants",
|
|
1321
|
+
api: { include: ["list", "get"] },
|
|
1322
|
+
cli: { include: ["list", "get"] },
|
|
1323
|
+
mcp: { include: ["list", "get"] },
|
|
1324
|
+
hooks: { beforeDelete: "refuseDelete" }
|
|
1325
|
+
})], CreditGrant);
|
|
1326
|
+
var PriceBookCollection = class extends SmrtCollection {
|
|
1327
|
+
static _itemClass = PriceBook;
|
|
1328
|
+
};
|
|
1329
|
+
var PriceBookAssignmentCollection = class extends SmrtCollection {
|
|
1330
|
+
static _itemClass = PriceBookAssignment;
|
|
1331
|
+
};
|
|
1332
|
+
var RetailChargeCollection = class extends SmrtCollection {
|
|
1333
|
+
static _itemClass = RetailCharge;
|
|
1334
|
+
};
|
|
1335
|
+
var CreditGrantCollection = class extends SmrtCollection {
|
|
1336
|
+
static _itemClass = CreditGrant;
|
|
1337
|
+
};
|
|
1338
|
+
function normalizeLedgerValue(value) {
|
|
1339
|
+
if (value instanceof Date) return value.toISOString();
|
|
1340
|
+
if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}[T ]/.test(value)) {
|
|
1341
|
+
const timestamp = Date.parse(value);
|
|
1342
|
+
if (Number.isFinite(timestamp)) return new Date(timestamp).toISOString();
|
|
1343
|
+
}
|
|
1344
|
+
if (typeof value === "boolean") return value ? "1" : "0";
|
|
1345
|
+
return String(value ?? "");
|
|
1346
|
+
}
|
|
1347
|
+
//#endregion
|
|
1348
|
+
//#region src/services/reseller-errors.ts
|
|
1349
|
+
var ResellerBillingError = class extends Error {
|
|
1350
|
+
constructor(message, code) {
|
|
1351
|
+
super(message);
|
|
1352
|
+
this.code = code;
|
|
1353
|
+
this.name = "ResellerBillingError";
|
|
1354
|
+
}
|
|
1355
|
+
code;
|
|
1356
|
+
};
|
|
1357
|
+
//#endregion
|
|
1056
1358
|
//#region src/services/commercial.ts
|
|
1057
1359
|
var embeddedAdjustmentLocks = /* @__PURE__ */ new Map();
|
|
1058
1360
|
async function withEmbeddedSourcedAdjustmentLock(db, storage, sourced, operation) {
|
|
@@ -1213,6 +1515,7 @@ var CommercialUsageService = class CommercialUsageService {
|
|
|
1213
1515
|
adjustments;
|
|
1214
1516
|
billingStorage;
|
|
1215
1517
|
customStrategies = /* @__PURE__ */ new Map();
|
|
1518
|
+
resellerCollections;
|
|
1216
1519
|
static async create(options = {}) {
|
|
1217
1520
|
const optionSnapshot = snapshotCommercialUsageServiceOptions(options);
|
|
1218
1521
|
const billingStorage = resolveCommercialBillingStorage(optionSnapshot);
|
|
@@ -1241,11 +1544,11 @@ var CommercialUsageService = class CommercialUsageService {
|
|
|
1241
1544
|
if (!usage) throw new Error(`Usage event ${options.usageEventId} was not found.`);
|
|
1242
1545
|
const at = options.at ?? usage.windowStart;
|
|
1243
1546
|
const dimensions = usage.getDimensions();
|
|
1244
|
-
const rule = selectRule(await this.rules.list({ where: {
|
|
1547
|
+
const rule = selectRule((await this.rules.list({ where: {
|
|
1245
1548
|
tenantId: usage.tenantId,
|
|
1246
1549
|
metricKey: usage.metricKey,
|
|
1247
1550
|
active: true
|
|
1248
|
-
} }), at, String(dimensions.serviceKey ?? ""));
|
|
1551
|
+
} })).filter((candidate) => !candidate.priceBookId), at, String(dimensions.serviceKey ?? ""));
|
|
1249
1552
|
if (!rule) throw new Error(`No effective pricing rule for metric '${usage.metricKey}'.`);
|
|
1250
1553
|
if (!usage.id) throw new Error(`Usage event ${options.usageEventId} has no persisted id.`);
|
|
1251
1554
|
if (!rule.id) throw new Error(`Pricing rule '${rule.ruleKey}' has no persisted id.`);
|
|
@@ -1260,6 +1563,7 @@ var CommercialUsageService = class CommercialUsageService {
|
|
|
1260
1563
|
id: chargeId,
|
|
1261
1564
|
tenantId: usage.tenantId,
|
|
1262
1565
|
usageEventId: String(usage.id),
|
|
1566
|
+
usageTenantId: usage.tenantId,
|
|
1263
1567
|
subscriberKind: usage.subscriberKind,
|
|
1264
1568
|
subscriberExternalId: usage.subscriberExternalId,
|
|
1265
1569
|
projectId: usage.projectId,
|
|
@@ -1288,6 +1592,217 @@ var CommercialUsageService = class CommercialUsageService {
|
|
|
1288
1592
|
return this.approveCharge(concurrent, options.approved);
|
|
1289
1593
|
}
|
|
1290
1594
|
}
|
|
1595
|
+
/**
|
|
1596
|
+
* Rate one usage event under its billing owner's price books (#3059).
|
|
1597
|
+
*
|
|
1598
|
+
* - No reseller relationship, or a `self`-billed one: the usage tenant pays
|
|
1599
|
+
* the provider directly, priced exactly as {@link price} prices it.
|
|
1600
|
+
* - `reseller`-billed: the reseller pays the provider from the child's
|
|
1601
|
+
* assigned wholesale book (a {@link ClientCharge} with `tenantId` = the
|
|
1602
|
+
* reseller and `usageTenantId` = the child) and, when the child has a
|
|
1603
|
+
* retail book assigned, the child owes the reseller a
|
|
1604
|
+
* {@link RetailCharge}. Both records commit in one transaction.
|
|
1605
|
+
*
|
|
1606
|
+
* Rating is idempotent per usage event and frozen at first rating: a later
|
|
1607
|
+
* billing-owner change never re-prices or double-charges an event that
|
|
1608
|
+
* already has a provider charge, because `ClientCharge` holds exactly one
|
|
1609
|
+
* row per usage event.
|
|
1610
|
+
*
|
|
1611
|
+
* Rating reads the seller's books across tenants; run it where the host's
|
|
1612
|
+
* tenancy rules allow that (typically a system context).
|
|
1613
|
+
*/
|
|
1614
|
+
async rateUsage(options) {
|
|
1615
|
+
const { retailCharges } = await this.getResellerCollections();
|
|
1616
|
+
const existing = await this.charges.list({
|
|
1617
|
+
where: { usageEventId: options.usageEventId },
|
|
1618
|
+
limit: 1
|
|
1619
|
+
});
|
|
1620
|
+
if (existing[0]) return this.frozenRating(existing[0], retailCharges, options.approved);
|
|
1621
|
+
const usage = await this.usage.get(options.usageEventId);
|
|
1622
|
+
if (!usage) throw new Error(`Usage event ${options.usageEventId} was not found.`);
|
|
1623
|
+
if (!usage.id || !usage.tenantId) throw new Error(`Usage event ${options.usageEventId} has no persisted tenant id.`);
|
|
1624
|
+
const relationship = await options.billingRelationships.getRelationship(usage.tenantId);
|
|
1625
|
+
if (relationship?.billingOwnerMode !== "reseller") {
|
|
1626
|
+
const charge = await this.price(options);
|
|
1627
|
+
return this.frozenRating(charge, retailCharges, options.approved);
|
|
1628
|
+
}
|
|
1629
|
+
let failure;
|
|
1630
|
+
try {
|
|
1631
|
+
await this.rateResellerBilled(usage, relationship, options);
|
|
1632
|
+
} catch (error) {
|
|
1633
|
+
failure = error;
|
|
1634
|
+
}
|
|
1635
|
+
const rated = await this.charges.list({
|
|
1636
|
+
where: { usageEventId: String(usage.id) },
|
|
1637
|
+
limit: 1
|
|
1638
|
+
});
|
|
1639
|
+
if (!rated[0]) throw failure ?? /* @__PURE__ */ new Error("Rating was not persisted.");
|
|
1640
|
+
return this.frozenRating(rated[0], retailCharges, options.approved);
|
|
1641
|
+
}
|
|
1642
|
+
async rateResellerBilled(usage, relationship, options) {
|
|
1643
|
+
const { books, assignments } = await this.getResellerCollections();
|
|
1644
|
+
const childTenantId = relationship.childTenantId;
|
|
1645
|
+
const resellerTenantId = relationship.resellerTenantId;
|
|
1646
|
+
const assignment = await assignments.get({ childTenantId });
|
|
1647
|
+
if (!assignment?.wholesalePriceBookId || tenantKey(assignment.resellerTenantId) !== resellerTenantId) throw new ResellerBillingError(`No wholesale price book is assigned to tenant ${childTenantId} under reseller ${resellerTenantId}.`, "PRICE_BOOK_NOT_ASSIGNED");
|
|
1648
|
+
const at = options.at ?? usage.windowStart;
|
|
1649
|
+
const dimensions = usage.getDimensions();
|
|
1650
|
+
const serviceKey = String(dimensions.serviceKey ?? "");
|
|
1651
|
+
const wholesaleBook = await loadBook(books, assignment.wholesalePriceBookId, "wholesale");
|
|
1652
|
+
assertWholesalePublisher(wholesaleBook, resellerTenantId, childTenantId);
|
|
1653
|
+
const wholesaleRule = await this.selectBookRule(wholesaleBook, usage.metricKey, serviceKey, assignment.wholesaleCurrency, at);
|
|
1654
|
+
let retail = null;
|
|
1655
|
+
if (assignment.retailPriceBookId) {
|
|
1656
|
+
const retailBook = await loadBook(books, assignment.retailPriceBookId, "retail");
|
|
1657
|
+
if (tenantKey(retailBook.tenantId) !== resellerTenantId) throw new ResellerBillingError(`Retail price book '${retailBook.bookKey}' is not published by reseller ${resellerTenantId}.`, "PRICE_BOOK_OWNER_MISMATCH");
|
|
1658
|
+
retail = {
|
|
1659
|
+
book: retailBook,
|
|
1660
|
+
rule: await this.selectBookRule(retailBook, usage.metricKey, serviceKey, assignment.retailCurrency, at)
|
|
1661
|
+
};
|
|
1662
|
+
}
|
|
1663
|
+
const wholesaleAmount = await this.calculateAmount(wholesaleRule, usage.quantity, dimensions);
|
|
1664
|
+
const retailAmount = retail ? await this.calculateAmount(retail.rule, usage.quantity, dimensions) : 0;
|
|
1665
|
+
const usageEventId = String(usage.id);
|
|
1666
|
+
const chargeId = await deterministicUuid([
|
|
1667
|
+
"client-charge",
|
|
1668
|
+
String(usage.tenantId),
|
|
1669
|
+
usageEventId
|
|
1670
|
+
]);
|
|
1671
|
+
const retailChargeId = await deterministicUuid([
|
|
1672
|
+
"retail-charge",
|
|
1673
|
+
String(usage.tenantId),
|
|
1674
|
+
usageEventId
|
|
1675
|
+
]);
|
|
1676
|
+
const approvedAt = options.approved ? /* @__PURE__ */ new Date() : null;
|
|
1677
|
+
const status = options.approved ? "approved" : "draft";
|
|
1678
|
+
const usageColumns = {
|
|
1679
|
+
usageEventId,
|
|
1680
|
+
subscriberKind: usage.subscriberKind,
|
|
1681
|
+
subscriberExternalId: usage.subscriberExternalId,
|
|
1682
|
+
projectId: usage.projectId,
|
|
1683
|
+
workRefType: usage.workRefType,
|
|
1684
|
+
workRefId: usage.workRefId,
|
|
1685
|
+
provider: usage.provider,
|
|
1686
|
+
serviceKey,
|
|
1687
|
+
metricKey: usage.metricKey,
|
|
1688
|
+
quantity: usage.quantity
|
|
1689
|
+
};
|
|
1690
|
+
const snapshot = (book, rule) => JSON.stringify({
|
|
1691
|
+
ruleKey: rule.ruleKey,
|
|
1692
|
+
strategy: rule.strategy,
|
|
1693
|
+
terms: rule.getTerms(),
|
|
1694
|
+
effectiveFrom: rule.effectiveFrom,
|
|
1695
|
+
priceBookKey: book.bookKey,
|
|
1696
|
+
priceBookKind: book.kind,
|
|
1697
|
+
usageTenantId: childTenantId,
|
|
1698
|
+
billingOwnerTenantId: resellerTenantId
|
|
1699
|
+
});
|
|
1700
|
+
const db = this.charges.db;
|
|
1701
|
+
return withEmbeddedWriteTransaction(db, isEmbeddedDatabase(db), async (transaction) => {
|
|
1702
|
+
const charges = await ClientChargeCollection.create({ db: transaction });
|
|
1703
|
+
const retailCharges = await RetailChargeCollection.create({ db: transaction });
|
|
1704
|
+
const charge = await charges.create({
|
|
1705
|
+
id: chargeId,
|
|
1706
|
+
tenantId: resellerTenantId,
|
|
1707
|
+
usageTenantId: childTenantId,
|
|
1708
|
+
...usageColumns,
|
|
1709
|
+
amount: wholesaleAmount,
|
|
1710
|
+
currency: wholesaleRule.currency,
|
|
1711
|
+
pricingRuleId: String(wholesaleRule.id),
|
|
1712
|
+
priceBookId: String(wholesaleBook.id),
|
|
1713
|
+
pricingSnapshot: snapshot(wholesaleBook, wholesaleRule),
|
|
1714
|
+
status,
|
|
1715
|
+
approvedAt,
|
|
1716
|
+
_insertOnly: true
|
|
1717
|
+
});
|
|
1718
|
+
const retailCharge = retail ? await retailCharges.create({
|
|
1719
|
+
id: retailChargeId,
|
|
1720
|
+
tenantId: childTenantId,
|
|
1721
|
+
resellerTenantId,
|
|
1722
|
+
clientChargeId: chargeId,
|
|
1723
|
+
...usageColumns,
|
|
1724
|
+
amount: retailAmount,
|
|
1725
|
+
currency: retail.rule.currency,
|
|
1726
|
+
priceBookId: String(retail.book.id),
|
|
1727
|
+
pricingRuleId: String(retail.rule.id),
|
|
1728
|
+
pricingSnapshot: snapshot(retail.book, retail.rule),
|
|
1729
|
+
status,
|
|
1730
|
+
approvedAt,
|
|
1731
|
+
_insertOnly: true
|
|
1732
|
+
}) : null;
|
|
1733
|
+
return {
|
|
1734
|
+
usageTenantId: childTenantId,
|
|
1735
|
+
billingOwnerTenantId: resellerTenantId,
|
|
1736
|
+
mode: "wholesale",
|
|
1737
|
+
charge,
|
|
1738
|
+
retailCharge
|
|
1739
|
+
};
|
|
1740
|
+
});
|
|
1741
|
+
}
|
|
1742
|
+
async selectBookRule(book, metricKey, serviceKey, currency, at) {
|
|
1743
|
+
const rule = selectRule((await this.rules.list({ where: {
|
|
1744
|
+
tenantId: book.tenantId,
|
|
1745
|
+
priceBookId: book.id,
|
|
1746
|
+
metricKey,
|
|
1747
|
+
currency,
|
|
1748
|
+
active: true
|
|
1749
|
+
} })).filter((candidate) => candidate.priceBookId === book.id && candidate.tenantId === book.tenantId && candidate.currency === currency), at, serviceKey);
|
|
1750
|
+
if (!rule?.id) throw new ResellerBillingError(`Price book '${book.bookKey}' has no effective ${currency} price for metric '${metricKey}'.`, "NO_EFFECTIVE_PRICE");
|
|
1751
|
+
return rule;
|
|
1752
|
+
}
|
|
1753
|
+
async frozenRating(charge, retailCharges, approved = false) {
|
|
1754
|
+
const retail = await retailCharges.list({
|
|
1755
|
+
where: { usageEventId: charge.usageEventId },
|
|
1756
|
+
limit: 1
|
|
1757
|
+
});
|
|
1758
|
+
let providerCharge = charge;
|
|
1759
|
+
let retailCharge = retail[0] ?? null;
|
|
1760
|
+
if (approved && (providerCharge.status === "draft" || retailCharge?.status === "draft")) {
|
|
1761
|
+
const db = this.charges.db;
|
|
1762
|
+
[providerCharge, retailCharge] = await withEmbeddedWriteTransaction(db, isEmbeddedDatabase(db), async (transaction) => {
|
|
1763
|
+
const charges = await ClientChargeCollection.create({ db: transaction });
|
|
1764
|
+
const retails = await RetailChargeCollection.create({ db: transaction });
|
|
1765
|
+
const provider = await charges.get(String(charge.id));
|
|
1766
|
+
if (!provider) throw new Error(`Client charge ${charge.id} was not found.`);
|
|
1767
|
+
const leg = retailCharge ? await retails.get(String(retailCharge.id)) : null;
|
|
1768
|
+
const approvedAt = /* @__PURE__ */ new Date();
|
|
1769
|
+
if (provider.status === "draft") {
|
|
1770
|
+
provider.status = "approved";
|
|
1771
|
+
provider.approvedAt = approvedAt;
|
|
1772
|
+
await provider.save();
|
|
1773
|
+
}
|
|
1774
|
+
if (leg?.status === "draft") {
|
|
1775
|
+
leg.status = "approved";
|
|
1776
|
+
leg.approvedAt = approvedAt;
|
|
1777
|
+
await leg.save();
|
|
1778
|
+
}
|
|
1779
|
+
return [provider, leg ?? null];
|
|
1780
|
+
});
|
|
1781
|
+
providerCharge = await this.charges.get(String(charge.id)) ?? charge;
|
|
1782
|
+
retailCharge = retailCharge?.id ? await retailCharges.get(String(retailCharge.id)) ?? null : null;
|
|
1783
|
+
}
|
|
1784
|
+
return {
|
|
1785
|
+
usageTenantId: tenantKey(providerCharge.usageTenantId) || tenantKey(providerCharge.tenantId),
|
|
1786
|
+
billingOwnerTenantId: tenantKey(providerCharge.tenantId),
|
|
1787
|
+
mode: providerCharge.priceBookId ? "wholesale" : "direct",
|
|
1788
|
+
charge: providerCharge,
|
|
1789
|
+
retailCharge
|
|
1790
|
+
};
|
|
1791
|
+
}
|
|
1792
|
+
getResellerCollections() {
|
|
1793
|
+
this.resellerCollections ??= (async () => {
|
|
1794
|
+
const options = { db: this.charges.db };
|
|
1795
|
+
return {
|
|
1796
|
+
books: await PriceBookCollection.create(options),
|
|
1797
|
+
assignments: await PriceBookAssignmentCollection.create(options),
|
|
1798
|
+
retailCharges: await RetailChargeCollection.create(options)
|
|
1799
|
+
};
|
|
1800
|
+
})();
|
|
1801
|
+
this.resellerCollections.catch(() => {
|
|
1802
|
+
this.resellerCollections = void 0;
|
|
1803
|
+
});
|
|
1804
|
+
return this.resellerCollections;
|
|
1805
|
+
}
|
|
1291
1806
|
async approveCharge(charge, approved = false) {
|
|
1292
1807
|
if (approved && charge.status === "draft") {
|
|
1293
1808
|
charge.status = "approved";
|
|
@@ -1412,21 +1927,30 @@ var CommercialUsageService = class CommercialUsageService {
|
|
|
1412
1927
|
}
|
|
1413
1928
|
};
|
|
1414
1929
|
var SpendingPolicyEvaluator = class SpendingPolicyEvaluator {
|
|
1415
|
-
constructor(policies, charges, adjustments) {
|
|
1930
|
+
constructor(policies, charges, adjustments, extensions = {}) {
|
|
1416
1931
|
this.policies = policies;
|
|
1417
1932
|
this.charges = charges;
|
|
1418
1933
|
this.adjustments = adjustments;
|
|
1934
|
+
this.extensions = extensions;
|
|
1419
1935
|
}
|
|
1420
1936
|
policies;
|
|
1421
1937
|
charges;
|
|
1422
1938
|
adjustments;
|
|
1939
|
+
extensions;
|
|
1940
|
+
ledgers;
|
|
1423
1941
|
static async create(options = {}) {
|
|
1424
|
-
const
|
|
1942
|
+
const { autoTopUp, billingRelationships, ...classOptions } = options;
|
|
1943
|
+
const policies = await SpendingPolicyCollection.create(classOptions);
|
|
1425
1944
|
const sharedOptions = {
|
|
1426
|
-
...
|
|
1945
|
+
...classOptions,
|
|
1427
1946
|
db: policies.db
|
|
1428
1947
|
};
|
|
1429
|
-
return new SpendingPolicyEvaluator(policies, await ClientChargeCollection.create(sharedOptions), await BillingAdjustmentCollection.create(sharedOptions)
|
|
1948
|
+
return new SpendingPolicyEvaluator(policies, await ClientChargeCollection.create(sharedOptions), await BillingAdjustmentCollection.create(sharedOptions), {
|
|
1949
|
+
retailCharges: await RetailChargeCollection.create(sharedOptions),
|
|
1950
|
+
credits: await CreditGrantCollection.create(sharedOptions),
|
|
1951
|
+
autoTopUp,
|
|
1952
|
+
billingRelationships
|
|
1953
|
+
});
|
|
1430
1954
|
}
|
|
1431
1955
|
async evaluate(input) {
|
|
1432
1956
|
const at = input.at ?? /* @__PURE__ */ new Date();
|
|
@@ -1438,11 +1962,12 @@ var SpendingPolicyEvaluator = class SpendingPolicyEvaluator {
|
|
|
1438
1962
|
subscriberExternalId: input.subscriberExternalId
|
|
1439
1963
|
}))
|
|
1440
1964
|
};
|
|
1441
|
-
const
|
|
1965
|
+
const candidates = await this.policies.list({ where: {
|
|
1442
1966
|
tenantId: input.tenantId,
|
|
1443
1967
|
currency: input.currency,
|
|
1444
1968
|
active: true
|
|
1445
|
-
} })
|
|
1969
|
+
} });
|
|
1970
|
+
const matchingPolicies = await this.withoutStaleDelegations(input.tenantId, selectPolicies(candidates, normalizedInput));
|
|
1446
1971
|
if (matchingPolicies.length === 0) return {
|
|
1447
1972
|
allowed: true,
|
|
1448
1973
|
approvalRequired: false,
|
|
@@ -1452,60 +1977,221 @@ var SpendingPolicyEvaluator = class SpendingPolicyEvaluator {
|
|
|
1452
1977
|
};
|
|
1453
1978
|
return (await Promise.all(matchingPolicies.map((policy) => this.evaluatePolicy(policy, normalizedInput, at)))).reduce((mostRestrictive, decision) => decisionRank(decision) > decisionRank(mostRestrictive) ? decision : mostRestrictive);
|
|
1454
1979
|
}
|
|
1980
|
+
/**
|
|
1981
|
+
* Drop delegated policies whose parent is no longer the tenant's reseller,
|
|
1982
|
+
* when a relationship reader is configured.
|
|
1983
|
+
*/
|
|
1984
|
+
async withoutStaleDelegations(tenantId, policies) {
|
|
1985
|
+
const reader = this.extensions.billingRelationships;
|
|
1986
|
+
if (!reader || !policies.some((policy) => tenantKey(policy.setByTenantId))) return policies;
|
|
1987
|
+
const currentParent = tenantKey((await reader.getRelationship(tenantId))?.resellerTenantId);
|
|
1988
|
+
return policies.filter((policy) => {
|
|
1989
|
+
const setBy = tenantKey(policy.setByTenantId);
|
|
1990
|
+
return !setBy || setBy === currentParent;
|
|
1991
|
+
});
|
|
1992
|
+
}
|
|
1993
|
+
/**
|
|
1994
|
+
* Credit a prepaid `balance` policy. A delegated policy accepts grants only
|
|
1995
|
+
* from the parent that set it (or a system context / super-admin bypass).
|
|
1996
|
+
*/
|
|
1997
|
+
async grantCredit(input) {
|
|
1998
|
+
const policy = await this.policies.get(input.spendingPolicyId);
|
|
1999
|
+
if (!policy?.id) throw new ResellerBillingError(`Spending policy ${input.spendingPolicyId} was not found.`, "POLICY_NOT_FOUND");
|
|
2000
|
+
const setBy = tenantKey(policy.setByTenantId);
|
|
2001
|
+
if (setBy && !isSystemContext() && !isSuperAdminBypass() && getTenantId()?.toLowerCase() !== setBy) throw new TenantIsolationError("Only the parent that set a delegated policy can grant it credit.");
|
|
2002
|
+
if (input.grantedByTenantId && setBy && tenantKey(input.grantedByTenantId) !== setBy) throw new TenantIsolationError("Delegated policy credit must be granted by the parent that set it.");
|
|
2003
|
+
return this.recordGrant(policy, {
|
|
2004
|
+
...input,
|
|
2005
|
+
grantedByTenantId: input.grantedByTenantId || setBy
|
|
2006
|
+
});
|
|
2007
|
+
}
|
|
2008
|
+
async recordGrant(policy, input) {
|
|
2009
|
+
if (policy.period !== "balance") throw new ResellerBillingError(`Spending policy '${policy.name}' is not a balance policy.`, "POLICY_NOT_BALANCE");
|
|
2010
|
+
if (!Number.isSafeInteger(input.amount) || input.amount === 0) throw new ResellerBillingError(`Credit amount must be a nonzero integer number of minor units \u2014 got ${input.amount}.`, "INVALID_AMOUNT");
|
|
2011
|
+
const { credits } = await this.getLedgers();
|
|
2012
|
+
const source = input.source ?? "";
|
|
2013
|
+
const sourceId = input.sourceId ?? "";
|
|
2014
|
+
const id = source && sourceId ? await deterministicUuid([
|
|
2015
|
+
"credit-grant",
|
|
2016
|
+
String(policy.tenantId),
|
|
2017
|
+
String(policy.id),
|
|
2018
|
+
source,
|
|
2019
|
+
sourceId
|
|
2020
|
+
]) : void 0;
|
|
2021
|
+
if (id) {
|
|
2022
|
+
const existing = await credits.get(id);
|
|
2023
|
+
if (existing) return existing;
|
|
2024
|
+
}
|
|
2025
|
+
try {
|
|
2026
|
+
return await credits.create({
|
|
2027
|
+
...id ? { id } : {},
|
|
2028
|
+
tenantId: policy.tenantId,
|
|
2029
|
+
spendingPolicyId: String(policy.id),
|
|
2030
|
+
amount: input.amount,
|
|
2031
|
+
currency: policy.currency,
|
|
2032
|
+
reason: input.reason ?? "",
|
|
2033
|
+
source,
|
|
2034
|
+
sourceId,
|
|
2035
|
+
grantedByTenantId: input.grantedByTenantId ?? "",
|
|
2036
|
+
_insertOnly: Boolean(id)
|
|
2037
|
+
});
|
|
2038
|
+
} catch (error) {
|
|
2039
|
+
const concurrent = id ? await credits.get(id) : void 0;
|
|
2040
|
+
if (concurrent) return concurrent;
|
|
2041
|
+
throw error;
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
1455
2044
|
async evaluatePolicy(policy, input, at) {
|
|
2045
|
+
const estimatedAmount = input.estimatedAmounts?.[policy.basis] ?? input.estimatedAmount;
|
|
1456
2046
|
const [start, end] = policyWindow(policy, at);
|
|
1457
|
-
const
|
|
1458
|
-
|
|
2047
|
+
const spent = await this.spentFor(policy, input.tenantId, start, end);
|
|
2048
|
+
if (policy.period !== "balance") return decide(policy, spent + estimatedAmount, policy.limitAmount);
|
|
2049
|
+
let credit = await this.creditFor(policy);
|
|
2050
|
+
const projectedAmount = spent + estimatedAmount;
|
|
2051
|
+
const policyId = policy.id;
|
|
2052
|
+
if (projectedAmount > credit && this.extensions.autoTopUp && policyId) {
|
|
2053
|
+
const grant = await this.extensions.autoTopUp({
|
|
2054
|
+
policyId,
|
|
2055
|
+
tenantId: String(policy.tenantId),
|
|
2056
|
+
setByTenantId: tenantKey(policy.setByTenantId),
|
|
2057
|
+
currency: policy.currency,
|
|
2058
|
+
balanceAmount: credit - spent,
|
|
2059
|
+
estimatedAmount,
|
|
2060
|
+
shortfall: projectedAmount - credit
|
|
2061
|
+
});
|
|
2062
|
+
if (grant) {
|
|
2063
|
+
await withSystemContext(() => this.recordGrant(policy, {
|
|
2064
|
+
spendingPolicyId: policyId,
|
|
2065
|
+
amount: grant.amount,
|
|
2066
|
+
reason: grant.reason ?? "auto top-up",
|
|
2067
|
+
source: grant.source ?? "auto_top_up",
|
|
2068
|
+
sourceId: grant.sourceId,
|
|
2069
|
+
grantedByTenantId: tenantKey(policy.setByTenantId)
|
|
2070
|
+
}));
|
|
2071
|
+
credit = await this.creditFor(policy);
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
return {
|
|
2075
|
+
...decide(policy, projectedAmount, credit),
|
|
2076
|
+
balanceAmount: credit - spent
|
|
2077
|
+
};
|
|
2078
|
+
}
|
|
2079
|
+
/** Approved spend in the policy's window, currency, scope, and basis. */
|
|
2080
|
+
async spentFor(policy, tenantId, start, end) {
|
|
2081
|
+
const scope = {
|
|
1459
2082
|
currency: policy.currency,
|
|
1460
|
-
status: ["approved", "adjusted"],
|
|
1461
2083
|
"approvedAt >=": start.toISOString(),
|
|
1462
2084
|
"approvedAt <": end.toISOString()
|
|
1463
2085
|
};
|
|
1464
|
-
if (policy.metricKey)
|
|
1465
|
-
if (policy.projectId)
|
|
1466
|
-
if (policy.serviceKey)
|
|
1467
|
-
if (policy.subscriberKind)
|
|
1468
|
-
if (policy.subscriberExternalId)
|
|
1469
|
-
const
|
|
2086
|
+
if (policy.metricKey) scope.metricKey = policy.metricKey;
|
|
2087
|
+
if (policy.projectId) scope.projectId = policy.projectId;
|
|
2088
|
+
if (policy.serviceKey) scope.serviceKey = policy.serviceKey;
|
|
2089
|
+
if (policy.subscriberKind) scope.subscriberKind = policy.subscriberKind;
|
|
2090
|
+
if (policy.subscriberExternalId) scope.subscriberExternalId = policy.subscriberExternalId;
|
|
2091
|
+
const setBy = tenantKey(policy.setByTenantId);
|
|
2092
|
+
if (policy.basis === "retail") {
|
|
2093
|
+
const { retailCharges } = await this.getLedgers();
|
|
2094
|
+
const where = {
|
|
2095
|
+
...scope,
|
|
2096
|
+
tenantId,
|
|
2097
|
+
status: "approved"
|
|
2098
|
+
};
|
|
2099
|
+
if (setBy) where.resellerTenantId = setBy;
|
|
2100
|
+
return sumScoped(policy, (await retailCharges.list({ where })).filter((row) => !setBy || tenantKey(row.resellerTenantId) === setBy), ["approved"]);
|
|
2101
|
+
}
|
|
2102
|
+
if (policy.basis === "wholesale") {
|
|
2103
|
+
if (!setBy) return 0;
|
|
2104
|
+
return withSystemContext(() => this.sumProviderCharges(policy, scope, setBy, tenantId));
|
|
2105
|
+
}
|
|
2106
|
+
return this.sumProviderCharges(policy, scope, tenantId);
|
|
2107
|
+
}
|
|
2108
|
+
async sumProviderCharges(policy, scope, payer, usageTenantId) {
|
|
2109
|
+
const where = {
|
|
2110
|
+
...scope,
|
|
2111
|
+
tenantId: payer,
|
|
2112
|
+
status: ["approved", "adjusted"]
|
|
2113
|
+
};
|
|
2114
|
+
if (usageTenantId) where.usageTenantId = usageTenantId;
|
|
2115
|
+
const scopedCharges = (await this.charges.list({ where })).filter((charge) => (!usageTenantId || tenantKey(charge.usageTenantId) === tenantKey(usageTenantId)) && (charge.status === "approved" || charge.status === "adjusted") && matchesChargeScope(policy, charge));
|
|
1470
2116
|
const chargeIds = scopedCharges.map((charge) => charge.id).filter((id) => Boolean(id));
|
|
1471
2117
|
const chargeIdSet = new Set(chargeIds);
|
|
1472
2118
|
const adjustmentRows = chargeIds.length > 0 ? await this.adjustments.list({ where: {
|
|
1473
|
-
tenantId:
|
|
2119
|
+
tenantId: payer,
|
|
1474
2120
|
currency: policy.currency,
|
|
1475
2121
|
clientChargeId: chargeIds
|
|
1476
2122
|
} }) : [];
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
};
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
};
|
|
1500
|
-
return
|
|
1501
|
-
allowed: false,
|
|
1502
|
-
approvalRequired: false,
|
|
1503
|
-
state: "blocked",
|
|
1504
|
-
projectedAmount,
|
|
1505
|
-
matchedPolicyId: policy.id ?? null
|
|
1506
|
-
};
|
|
2123
|
+
return scopedCharges.reduce((sum, charge) => sum + charge.amount, 0) + adjustmentRows.filter((adjustment) => chargeIdSet.has(adjustment.clientChargeId)).reduce((sum, adjustment) => sum + adjustment.amount, 0);
|
|
2124
|
+
}
|
|
2125
|
+
async creditFor(policy) {
|
|
2126
|
+
const { credits } = await this.getLedgers();
|
|
2127
|
+
const grants = await credits.list({ where: {
|
|
2128
|
+
tenantId: policy.tenantId,
|
|
2129
|
+
spendingPolicyId: policy.id,
|
|
2130
|
+
currency: policy.currency
|
|
2131
|
+
} });
|
|
2132
|
+
const setBy = tenantKey(policy.setByTenantId);
|
|
2133
|
+
return grants.filter((grant) => grant.spendingPolicyId === policy.id && (!setBy || tenantKey(grant.grantedByTenantId) === setBy)).reduce((sum, grant) => sum + grant.amount, 0);
|
|
2134
|
+
}
|
|
2135
|
+
getLedgers() {
|
|
2136
|
+
this.ledgers ??= (async () => {
|
|
2137
|
+
const options = { db: this.policies.db };
|
|
2138
|
+
return {
|
|
2139
|
+
retailCharges: this.extensions.retailCharges ?? await RetailChargeCollection.create(options),
|
|
2140
|
+
credits: this.extensions.credits ?? await CreditGrantCollection.create(options)
|
|
2141
|
+
};
|
|
2142
|
+
})();
|
|
2143
|
+
this.ledgers.catch(() => {
|
|
2144
|
+
this.ledgers = void 0;
|
|
2145
|
+
});
|
|
2146
|
+
return this.ledgers;
|
|
1507
2147
|
}
|
|
1508
2148
|
};
|
|
2149
|
+
function decide(policy, projectedAmount, limitAmount) {
|
|
2150
|
+
const exceeded = projectedAmount > limitAmount;
|
|
2151
|
+
const matchedPolicyId = policy.id ?? null;
|
|
2152
|
+
if (!exceeded || policy.behavior === "observe") return {
|
|
2153
|
+
allowed: true,
|
|
2154
|
+
approvalRequired: false,
|
|
2155
|
+
state: exceeded ? "observed" : "ok",
|
|
2156
|
+
projectedAmount,
|
|
2157
|
+
matchedPolicyId
|
|
2158
|
+
};
|
|
2159
|
+
if (policy.behavior === "warn") return {
|
|
2160
|
+
allowed: true,
|
|
2161
|
+
approvalRequired: false,
|
|
2162
|
+
state: "warned",
|
|
2163
|
+
projectedAmount,
|
|
2164
|
+
matchedPolicyId
|
|
2165
|
+
};
|
|
2166
|
+
if (policy.behavior === "approval_required") return {
|
|
2167
|
+
allowed: false,
|
|
2168
|
+
approvalRequired: true,
|
|
2169
|
+
state: "approval_required",
|
|
2170
|
+
projectedAmount,
|
|
2171
|
+
matchedPolicyId
|
|
2172
|
+
};
|
|
2173
|
+
return {
|
|
2174
|
+
allowed: false,
|
|
2175
|
+
approvalRequired: false,
|
|
2176
|
+
state: "blocked",
|
|
2177
|
+
projectedAmount,
|
|
2178
|
+
matchedPolicyId
|
|
2179
|
+
};
|
|
2180
|
+
}
|
|
2181
|
+
function sumScoped(policy, rows, statuses) {
|
|
2182
|
+
return rows.filter((row) => statuses.includes(row.status) && matchesChargeScope(policy, row)).reduce((sum, row) => sum + row.amount, 0);
|
|
2183
|
+
}
|
|
2184
|
+
function assertWholesalePublisher(book, resellerTenantId, childTenantId) {
|
|
2185
|
+
const publisher = tenantKey(book.tenantId);
|
|
2186
|
+
if (publisher === resellerTenantId || publisher === childTenantId) throw new ResellerBillingError(`Wholesale price book '${book.bookKey}' is published by the tenant it would charge.`, "PRICE_BOOK_OWNER_MISMATCH");
|
|
2187
|
+
}
|
|
2188
|
+
async function loadBook(books, id, kind) {
|
|
2189
|
+
const book = await books.get(id);
|
|
2190
|
+
if (!book?.id) throw new ResellerBillingError(`Price book ${id} was not found.`, "PRICE_BOOK_NOT_FOUND");
|
|
2191
|
+
if (book.kind !== kind) throw new ResellerBillingError(`Price book '${book.bookKey}' is a ${book.kind} book, not ${kind}.`, "PRICE_BOOK_KIND_MISMATCH");
|
|
2192
|
+
if (!book.active) throw new ResellerBillingError(`Price book '${book.bookKey}' is inactive.`, "PRICE_BOOK_INACTIVE");
|
|
2193
|
+
return book;
|
|
2194
|
+
}
|
|
1509
2195
|
function selectRule(rules, at, serviceKey) {
|
|
1510
2196
|
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];
|
|
1511
2197
|
}
|
|
@@ -1545,7 +2231,8 @@ function hasValidSubscriberScope(p) {
|
|
|
1545
2231
|
function policyWindow(policy, at) {
|
|
1546
2232
|
const end = new Date(at);
|
|
1547
2233
|
const start = new Date(at);
|
|
1548
|
-
if (policy.period === "
|
|
2234
|
+
if (policy.period === "balance") start.setTime(new Date(policy.balanceFrom ?? policy.created_at ?? 0).getTime());
|
|
2235
|
+
else if (policy.period === "rolling") start.setTime(at.getTime() - policy.rollingSeconds * 1e3);
|
|
1549
2236
|
else if (policy.period === "day") start.setUTCHours(0, 0, 0, 0);
|
|
1550
2237
|
else if (policy.period === "week") {
|
|
1551
2238
|
start.setUTCHours(0, 0, 0, 0);
|
|
@@ -1560,6 +2247,292 @@ function policyWindow(policy, at) {
|
|
|
1560
2247
|
return [start, end];
|
|
1561
2248
|
}
|
|
1562
2249
|
//#endregion
|
|
2250
|
+
//#region src/services/reseller.ts
|
|
2251
|
+
var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
2252
|
+
function canonicalTenantId(id) {
|
|
2253
|
+
if (typeof id !== "string" || !UUID_PATTERN.test(id)) throw new ResellerBillingError("Tenant IDs must be UUIDs.", "INVALID_TENANT");
|
|
2254
|
+
return id.toLowerCase();
|
|
2255
|
+
}
|
|
2256
|
+
function assertCurrency(currency) {
|
|
2257
|
+
if (!isCurrencyCode(currency)) throw new ResellerBillingError(`Currency '${currency}' must be a three-letter upper-case code.`, "INVALID_CURRENCY");
|
|
2258
|
+
}
|
|
2259
|
+
function legView(priceBookId, currency) {
|
|
2260
|
+
return priceBookId ? {
|
|
2261
|
+
priceBookId: String(priceBookId),
|
|
2262
|
+
currency
|
|
2263
|
+
} : null;
|
|
2264
|
+
}
|
|
2265
|
+
function assignmentView(row) {
|
|
2266
|
+
return {
|
|
2267
|
+
childTenantId: tenantKey(row.childTenantId),
|
|
2268
|
+
resellerTenantId: tenantKey(row.resellerTenantId),
|
|
2269
|
+
wholesale: legView(row.wholesalePriceBookId, row.wholesaleCurrency),
|
|
2270
|
+
retail: legView(row.retailPriceBookId, row.retailCurrency)
|
|
2271
|
+
};
|
|
2272
|
+
}
|
|
2273
|
+
function authorized(operation) {
|
|
2274
|
+
return withSystemContext(operation);
|
|
2275
|
+
}
|
|
2276
|
+
var ResellerBillingService = class ResellerBillingService {
|
|
2277
|
+
constructor(options, books, assignments, rules, policies, evaluator) {
|
|
2278
|
+
this.options = options;
|
|
2279
|
+
this.books = books;
|
|
2280
|
+
this.assignments = assignments;
|
|
2281
|
+
this.rules = rules;
|
|
2282
|
+
this.policies = policies;
|
|
2283
|
+
this.evaluator = evaluator;
|
|
2284
|
+
}
|
|
2285
|
+
options;
|
|
2286
|
+
books;
|
|
2287
|
+
assignments;
|
|
2288
|
+
rules;
|
|
2289
|
+
policies;
|
|
2290
|
+
evaluator;
|
|
2291
|
+
static async create(options) {
|
|
2292
|
+
if (typeof options.billingRelationships?.getRelationship !== "function") throw new Error("Reseller billing requires a billingRelationships reader from smrt-tenancy.");
|
|
2293
|
+
const { billingRelationships: _reader, authorize: _authorize, ...rest } = options;
|
|
2294
|
+
const books = await PriceBookCollection.create(rest);
|
|
2295
|
+
const shared = {
|
|
2296
|
+
...rest,
|
|
2297
|
+
db: books.db
|
|
2298
|
+
};
|
|
2299
|
+
const policies = await SpendingPolicyCollection.create(shared);
|
|
2300
|
+
const evaluator = new SpendingPolicyEvaluator(policies, await ClientChargeCollection.create(shared), await BillingAdjustmentCollection.create(shared), {
|
|
2301
|
+
retailCharges: await RetailChargeCollection.create(shared),
|
|
2302
|
+
credits: await CreditGrantCollection.create(shared)
|
|
2303
|
+
});
|
|
2304
|
+
return new ResellerBillingService(options, books, await PriceBookAssignmentCollection.create(shared), await PricingRuleCollection.create(shared), policies, evaluator);
|
|
2305
|
+
}
|
|
2306
|
+
/**
|
|
2307
|
+
* Publish one price in a book, in one or more currencies. Each currency is
|
|
2308
|
+
* a `PricingRule` owned by the book's seller; re-defining the same rule key,
|
|
2309
|
+
* currency, and effective date replaces that rule's terms.
|
|
2310
|
+
*/
|
|
2311
|
+
async definePrice(input) {
|
|
2312
|
+
const book = await this.readBook(input.priceBookId);
|
|
2313
|
+
const sellerTenantId = canonicalTenantId(String(book.tenantId));
|
|
2314
|
+
await this.assertManage("define_prices", sellerTenantId, void 0, true);
|
|
2315
|
+
if (!input.ruleKey.trim() || !input.metricKey.trim()) throw new Error("Price book prices require a ruleKey and metricKey.");
|
|
2316
|
+
if (input.prices.length === 0) throw new ResellerBillingError("A price needs at least one currency.", "INVALID_CURRENCY");
|
|
2317
|
+
const currencies = /* @__PURE__ */ new Set();
|
|
2318
|
+
for (const { currency } of input.prices) {
|
|
2319
|
+
assertCurrency(currency);
|
|
2320
|
+
if (currencies.has(currency)) throw new ResellerBillingError(`Currency ${currency} is listed twice for one price.`, "INVALID_CURRENCY");
|
|
2321
|
+
currencies.add(currency);
|
|
2322
|
+
}
|
|
2323
|
+
const effectiveFrom = input.effectiveFrom ?? /* @__PURE__ */ new Date();
|
|
2324
|
+
return authorized(async () => {
|
|
2325
|
+
const saved = [];
|
|
2326
|
+
for (const { currency, terms } of input.prices) {
|
|
2327
|
+
const id = await deterministicUuid([
|
|
2328
|
+
"price-book-rule",
|
|
2329
|
+
String(book.id),
|
|
2330
|
+
input.ruleKey,
|
|
2331
|
+
input.metricKey,
|
|
2332
|
+
input.serviceKey ?? "",
|
|
2333
|
+
currency,
|
|
2334
|
+
effectiveFrom.toISOString()
|
|
2335
|
+
]);
|
|
2336
|
+
const values = {
|
|
2337
|
+
tenantId: book.tenantId,
|
|
2338
|
+
priceBookId: String(book.id),
|
|
2339
|
+
ruleKey: input.ruleKey,
|
|
2340
|
+
metricKey: input.metricKey,
|
|
2341
|
+
serviceKey: input.serviceKey ?? "",
|
|
2342
|
+
strategy: input.strategy,
|
|
2343
|
+
currency,
|
|
2344
|
+
effectiveFrom,
|
|
2345
|
+
effectiveTo: input.effectiveTo ?? null,
|
|
2346
|
+
priority: input.priority ?? 0,
|
|
2347
|
+
terms: JSON.stringify(terms),
|
|
2348
|
+
active: true
|
|
2349
|
+
};
|
|
2350
|
+
const existing = await this.rules.get(id);
|
|
2351
|
+
if (existing) {
|
|
2352
|
+
Object.assign(existing, values);
|
|
2353
|
+
await existing.save();
|
|
2354
|
+
saved.push(existing);
|
|
2355
|
+
} else saved.push(await this.rules.create({
|
|
2356
|
+
id,
|
|
2357
|
+
...values
|
|
2358
|
+
}));
|
|
2359
|
+
}
|
|
2360
|
+
return saved;
|
|
2361
|
+
});
|
|
2362
|
+
}
|
|
2363
|
+
/**
|
|
2364
|
+
* Select the wholesale and/or retail book that rates a child's usage under
|
|
2365
|
+
* its current reseller relationship. The retail book must be published by
|
|
2366
|
+
* that reseller; the wholesale book must be published by someone other
|
|
2367
|
+
* than the reseller or child it charges. Each leg is authorized separately:
|
|
2368
|
+
* the wholesale leg by its publisher (`assign_wholesale_price_book`), the
|
|
2369
|
+
* retail leg by the reseller (`assign_retail_price_book`).
|
|
2370
|
+
*/
|
|
2371
|
+
async assignPriceBooks(input) {
|
|
2372
|
+
const { childTenantId, resellerTenantId } = await this.requireRelationship(input.childTenantId);
|
|
2373
|
+
const existing = await authorized(() => this.assignments.get({ childTenantId }));
|
|
2374
|
+
const current = existing && tenantKey(existing.resellerTenantId) === resellerTenantId ? assignmentView(existing) : null;
|
|
2375
|
+
if (input.wholesale !== void 0) {
|
|
2376
|
+
let publisher = resellerTenantId;
|
|
2377
|
+
if (input.wholesale) {
|
|
2378
|
+
const book = await this.requireLeg(input.wholesale, "wholesale");
|
|
2379
|
+
assertWholesalePublisher(book, resellerTenantId, childTenantId);
|
|
2380
|
+
publisher = tenantKey(book.tenantId);
|
|
2381
|
+
} else if (current?.wholesale) publisher = tenantKey((await this.readBook(current.wholesale.priceBookId)).tenantId);
|
|
2382
|
+
await this.assertManage("assign_wholesale_price_book", publisher, childTenantId, false, resellerTenantId);
|
|
2383
|
+
}
|
|
2384
|
+
if (input.retail) {
|
|
2385
|
+
const book = await this.requireLeg(input.retail, "retail");
|
|
2386
|
+
if (tenantKey(book.tenantId) !== resellerTenantId) throw new ResellerBillingError(`Retail price book '${book.bookKey}' is not published by the child's reseller.`, "PRICE_BOOK_OWNER_MISMATCH");
|
|
2387
|
+
}
|
|
2388
|
+
if (input.retail !== void 0 || input.wholesale === void 0) await this.assertManage("assign_retail_price_book", resellerTenantId, childTenantId, false, resellerTenantId);
|
|
2389
|
+
const db = this.assignments.db;
|
|
2390
|
+
return authorized(() => withEmbeddedWriteTransaction(db, isEmbeddedDatabase(db), async (transaction) => {
|
|
2391
|
+
if (isPostgresDatabase(transaction)) await transaction.query("SELECT pg_advisory_xact_lock(hashtext('smrt-price-book-assignments'))");
|
|
2392
|
+
const assignments = await PriceBookAssignmentCollection.create({ db: transaction });
|
|
2393
|
+
const row = await assignments.get({ childTenantId });
|
|
2394
|
+
const fresh = row && tenantKey(row.resellerTenantId) === resellerTenantId ? assignmentView(row) : null;
|
|
2395
|
+
if (input.wholesale === null && fresh?.wholesale?.priceBookId !== current?.wholesale?.priceBookId) throw new ResellerBillingError("The wholesale assignment changed concurrently; retry.", "ASSIGNMENT_CONFLICT");
|
|
2396
|
+
const wholesale = input.wholesale === void 0 ? fresh?.wholesale ?? null : input.wholesale;
|
|
2397
|
+
const retail = input.retail === void 0 ? fresh?.retail ?? null : input.retail;
|
|
2398
|
+
const values = {
|
|
2399
|
+
childTenantId,
|
|
2400
|
+
resellerTenantId,
|
|
2401
|
+
wholesalePriceBookId: wholesale?.priceBookId ?? "",
|
|
2402
|
+
wholesaleCurrency: wholesale?.currency ?? "",
|
|
2403
|
+
retailPriceBookId: retail?.priceBookId ?? "",
|
|
2404
|
+
retailCurrency: retail?.currency ?? ""
|
|
2405
|
+
};
|
|
2406
|
+
if (row) {
|
|
2407
|
+
Object.assign(row, values);
|
|
2408
|
+
await row.save();
|
|
2409
|
+
return assignmentView(row);
|
|
2410
|
+
}
|
|
2411
|
+
return assignmentView(await assignments.create(values));
|
|
2412
|
+
}));
|
|
2413
|
+
}
|
|
2414
|
+
/** The child's assignment under its current reseller, if any. */
|
|
2415
|
+
async getPriceBookAssignment(childTenantId) {
|
|
2416
|
+
const relationship = await this.options.billingRelationships.getRelationship(canonicalTenantId(childTenantId));
|
|
2417
|
+
if (!relationship) return null;
|
|
2418
|
+
const row = await this.assignments.get({ childTenantId: relationship.childTenantId });
|
|
2419
|
+
if (!row || tenantKey(row.resellerTenantId) !== relationship.resellerTenantId) return null;
|
|
2420
|
+
return assignmentView(row);
|
|
2421
|
+
}
|
|
2422
|
+
/**
|
|
2423
|
+
* Create or replace a spending policy that a parent sets on its child. The
|
|
2424
|
+
* row belongs to the child (so the ordinary evaluator enforces it for the
|
|
2425
|
+
* child) and records the parent in `setByTenantId`, which locks it against
|
|
2426
|
+
* changes by the child. A delegated limit left by a former parent may be
|
|
2427
|
+
* replaced (not a former parent's prepaid balance, which keeps its credit
|
|
2428
|
+
* ledger); one the child set for itself may not. Use `period: 'balance'`
|
|
2429
|
+
* for a prepaid credit balance and fund it with {@link grantChildCredit}.
|
|
2430
|
+
*/
|
|
2431
|
+
async setDelegatedSpendingPolicy(input) {
|
|
2432
|
+
const parentTenantId = canonicalTenantId(input.parentTenantId);
|
|
2433
|
+
const relationship = await this.requireChildOf(input.childTenantId, parentTenantId);
|
|
2434
|
+
await this.assertManage("manage_child_spending", parentTenantId, relationship.childTenantId, false, relationship.resellerTenantId);
|
|
2435
|
+
assertCurrency(input.currency);
|
|
2436
|
+
if (input.limitAmount !== void 0 && !Number.isSafeInteger(input.limitAmount)) throw new ResellerBillingError(`Spending limits must be integer minor units \u2014 got ${input.limitAmount}.`, "INVALID_AMOUNT");
|
|
2437
|
+
const values = {
|
|
2438
|
+
tenantId: relationship.childTenantId,
|
|
2439
|
+
name: input.name,
|
|
2440
|
+
subscriberKind: input.subscriberKind ?? "",
|
|
2441
|
+
subscriberExternalId: input.subscriberExternalId ?? "",
|
|
2442
|
+
projectId: input.projectId ?? "",
|
|
2443
|
+
serviceKey: input.serviceKey ?? "",
|
|
2444
|
+
metricKey: input.metricKey ?? "",
|
|
2445
|
+
period: input.period ?? "month",
|
|
2446
|
+
rollingSeconds: input.rollingSeconds ?? 0,
|
|
2447
|
+
limitAmount: input.limitAmount ?? 0,
|
|
2448
|
+
currency: input.currency,
|
|
2449
|
+
behavior: input.behavior,
|
|
2450
|
+
priority: input.priority ?? 0,
|
|
2451
|
+
active: input.active ?? true,
|
|
2452
|
+
basis: input.basis,
|
|
2453
|
+
setByTenantId: parentTenantId,
|
|
2454
|
+
...input.balanceFrom ? { balanceFrom: input.balanceFrom } : {}
|
|
2455
|
+
};
|
|
2456
|
+
return authorized(async () => {
|
|
2457
|
+
const existing = (await this.policies.list({
|
|
2458
|
+
where: {
|
|
2459
|
+
tenantId: values.tenantId,
|
|
2460
|
+
subscriberKind: values.subscriberKind,
|
|
2461
|
+
subscriberExternalId: values.subscriberExternalId,
|
|
2462
|
+
projectId: values.projectId,
|
|
2463
|
+
serviceKey: values.serviceKey,
|
|
2464
|
+
metricKey: values.metricKey,
|
|
2465
|
+
period: values.period,
|
|
2466
|
+
name: values.name
|
|
2467
|
+
},
|
|
2468
|
+
limit: 1
|
|
2469
|
+
}))[0];
|
|
2470
|
+
if (existing) {
|
|
2471
|
+
const owner = tenantKey(existing.setByTenantId);
|
|
2472
|
+
if (!owner) throw new ResellerBillingError(`Spending policy '${input.name}' already exists for this child and was set by the child.`, "POLICY_CONFLICT");
|
|
2473
|
+
if (owner !== parentTenantId && existing.period === "balance") throw new ResellerBillingError(`Balance policy '${input.name}' belongs to a former parent; choose another name.`, "POLICY_CONFLICT");
|
|
2474
|
+
Object.assign(existing, values);
|
|
2475
|
+
await existing.save();
|
|
2476
|
+
return existing;
|
|
2477
|
+
}
|
|
2478
|
+
return this.policies.create(values);
|
|
2479
|
+
});
|
|
2480
|
+
}
|
|
2481
|
+
/** Credit a prepaid balance policy the parent set on its child. */
|
|
2482
|
+
async grantChildCredit(input) {
|
|
2483
|
+
const parentTenantId = canonicalTenantId(input.parentTenantId);
|
|
2484
|
+
const relationship = await this.requireChildOf(input.childTenantId, parentTenantId);
|
|
2485
|
+
await this.assertManage("manage_child_spending", parentTenantId, relationship.childTenantId, false, relationship.resellerTenantId);
|
|
2486
|
+
return authorized(async () => {
|
|
2487
|
+
const policy = await this.policies.get(input.spendingPolicyId);
|
|
2488
|
+
if (!policy || tenantKey(policy.tenantId) !== relationship.childTenantId || tenantKey(policy.setByTenantId) !== parentTenantId) throw new ResellerBillingError(`Spending policy ${input.spendingPolicyId} is not a policy this parent set on the child.`, "POLICY_NOT_FOUND");
|
|
2489
|
+
return this.evaluator.grantCredit({
|
|
2490
|
+
spendingPolicyId: input.spendingPolicyId,
|
|
2491
|
+
amount: input.amount,
|
|
2492
|
+
reason: input.reason,
|
|
2493
|
+
source: input.source,
|
|
2494
|
+
sourceId: input.sourceId,
|
|
2495
|
+
grantedByTenantId: parentTenantId
|
|
2496
|
+
});
|
|
2497
|
+
});
|
|
2498
|
+
}
|
|
2499
|
+
async requireRelationship(childTenantId) {
|
|
2500
|
+
const relationship = await this.options.billingRelationships.getRelationship(canonicalTenantId(childTenantId));
|
|
2501
|
+
if (!relationship) throw new ResellerBillingError(`Tenant ${childTenantId} has no reseller relationship.`, "RELATIONSHIP_REQUIRED");
|
|
2502
|
+
return relationship;
|
|
2503
|
+
}
|
|
2504
|
+
async requireChildOf(childTenantId, parentTenantId) {
|
|
2505
|
+
const relationship = await this.requireRelationship(childTenantId);
|
|
2506
|
+
if (relationship.resellerTenantId !== parentTenantId) throw new ResellerBillingError(`Tenant ${childTenantId} is not a child of ${parentTenantId}.`, "RELATIONSHIP_REQUIRED");
|
|
2507
|
+
return relationship;
|
|
2508
|
+
}
|
|
2509
|
+
/**
|
|
2510
|
+
* Read a book's metadata to learn its publisher and kind before deciding
|
|
2511
|
+
* authorization. Books belong to their seller, so the read is not scoped to
|
|
2512
|
+
* the caller; nothing beyond a validation error is returned on denial.
|
|
2513
|
+
*/
|
|
2514
|
+
async readBook(id) {
|
|
2515
|
+
const book = await authorized(() => this.books.get(id));
|
|
2516
|
+
if (!book?.id) throw new ResellerBillingError(`Price book ${id} was not found.`, "PRICE_BOOK_NOT_FOUND");
|
|
2517
|
+
return book;
|
|
2518
|
+
}
|
|
2519
|
+
async requireLeg(leg, kind) {
|
|
2520
|
+
assertCurrency(leg.currency);
|
|
2521
|
+
const book = await this.readBook(leg.priceBookId);
|
|
2522
|
+
if (book.kind !== kind) throw new ResellerBillingError(`Price book '${book.bookKey}' is a ${book.kind} book, not ${kind}.`, "PRICE_BOOK_KIND_MISMATCH");
|
|
2523
|
+
return book;
|
|
2524
|
+
}
|
|
2525
|
+
async assertManage(action, tenantId, childTenantId, allowOwnTenant = false, resellerTenantId) {
|
|
2526
|
+
if (isSystemContext() || isSuperAdminBypass() || allowOwnTenant && getTenantId()?.toLowerCase() === tenantId || await this.options.authorize?.({
|
|
2527
|
+
action,
|
|
2528
|
+
tenantId,
|
|
2529
|
+
childTenantId,
|
|
2530
|
+
...resellerTenantId ? { resellerTenantId } : {}
|
|
2531
|
+
})) return;
|
|
2532
|
+
throw new TenantIsolationError("Reseller billing mutation denied.");
|
|
2533
|
+
}
|
|
2534
|
+
};
|
|
2535
|
+
//#endregion
|
|
1563
2536
|
//#region src/services/threshold-evaluator.ts
|
|
1564
2537
|
function evaluateThreshold(threshold, usage) {
|
|
1565
2538
|
const ratio = threshold.limit === 0 ? usage.quantity > 0 ? Infinity : 0 : usage.quantity / threshold.limit;
|
|
@@ -1984,6 +2957,6 @@ function emptyUsageSummary(subscriber, metricKey, window) {
|
|
|
1984
2957
|
return summary;
|
|
1985
2958
|
}
|
|
1986
2959
|
//#endregion
|
|
1987
|
-
export { BillingAdjustment, BillingAdjustmentCollection, ClientCharge, ClientChargeCollection, CommercialBillingStorageConfigurationError, CommercialUsageService, PricingRule, PricingRuleCollection, SUBSCRIPTIONS_MONEY_COLUMNS, SUBSCRIPTIONS_MONEY_MINOR_UNITS_BACKFILL, SpendingPolicy, SpendingPolicyCollection, SpendingPolicyEvaluator, SubscriptionPlan, SubscriptionPlanCollection, SubscriptionResolver, TenantSubscription, TenantSubscriptionCollection, TenantUsageMeter, TenantUsageMetric, TenantUsageMetricCollection, UnsupportedCommercialBillingStorageError, assertCommercialBillingStorageSupported, assertSubscriberInvariant, evaluateThreshold, evaluateThresholds, getWindowForThreshold, getWindowKey, isValidThreshold, migrateSubscriptionsMoneyToMinorUnits, normalizeFeatureGrants, normalizeSubscriber, preflightSubscriptionsMoneyMinorUnits, subscriberToColumns };
|
|
2960
|
+
export { BillingAdjustment, BillingAdjustmentCollection, ClientCharge, ClientChargeCollection, CommercialBillingStorageConfigurationError, CommercialUsageService, CreditGrant, CreditGrantCollection, PriceBook, PriceBookAssignment, PriceBookCollection, PricingRule, PricingRuleCollection, ResellerBillingError, ResellerBillingService, RetailCharge, RetailChargeCollection, SUBSCRIPTIONS_MONEY_COLUMNS, SUBSCRIPTIONS_MONEY_MINOR_UNITS_BACKFILL, SpendingPolicy, SpendingPolicyCollection, SpendingPolicyEvaluator, SubscriptionPlan, SubscriptionPlanCollection, SubscriptionResolver, TenantSubscription, TenantSubscriptionCollection, TenantUsageMeter, TenantUsageMetric, TenantUsageMetricCollection, UnsupportedCommercialBillingStorageError, assertCommercialBillingStorageSupported, assertSubscriberInvariant, evaluateThreshold, evaluateThresholds, getWindowForThreshold, getWindowKey, isCurrencyCode, isPriceBookKind, isValidThreshold, migrateSubscriptionsMoneyToMinorUnits, normalizeFeatureGrants, normalizeSubscriber, preflightSubscriptionsMoneyMinorUnits, subscriberToColumns };
|
|
1988
2961
|
|
|
1989
2962
|
//# sourceMappingURL=index.js.map
|