@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/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$3 = Object.defineProperty;
161
- var __getOwnPropDesc$3 = Object.getOwnPropertyDescriptor;
162
- var __decorateClass$3 = (decorators, target, key, kind) => {
163
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$3(target, key) : target;
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$3(target, key, result);
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$3([tenantId({ nullable: true })], SubscriptionPlan.prototype, "tenantId", 2);
233
- SubscriptionPlan = __decorateClass$3([TenantScoped({ mode: "optional" }), smrt({
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$2 = Object.defineProperty;
271
- var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
272
- var __decorateClass$2 = (decorators, target, key, kind) => {
273
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target;
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$2(target, key, result);
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$2([tenantId()], TenantSubscription.prototype, "tenantId", 2);
384
- __decorateClass$2([foreignKey("SubscriptionPlan")], TenantSubscription.prototype, "planId", 2);
385
- TenantSubscription = __decorateClass$2([TenantScoped({ mode: "required" }), smrt({
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$1 = Object.defineProperty;
457
- var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
458
- var __decorateClass$1 = (decorators, target, key, kind) => {
459
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
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$1(target, key, result);
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$1([tenantId()], TenantUsageMetric.prototype, "tenantId", 2);
582
- TenantUsageMetric = __decorateClass$1([TenantScoped({ mode: "required" }), smrt({
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
- PricingRule = __decorateClass([TenantScoped({ mode: "required" }), smrt({
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([foreignKey("PricingRule")], ClientCharge.prototype, "pricingRuleId", 2);
956
- ClientCharge = __decorateClass([TenantScoped({ mode: "required" }), smrt({
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
- SpendingPolicy = __decorateClass([TenantScoped({ mode: "required" }), smrt({
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 policies = await SpendingPolicyCollection.create(options);
1942
+ const { autoTopUp, billingRelationships, ...classOptions } = options;
1943
+ const policies = await SpendingPolicyCollection.create(classOptions);
1425
1944
  const sharedOptions = {
1426
- ...options,
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 matchingPolicies = selectPolicies(await this.policies.list({ where: {
1965
+ const candidates = await this.policies.list({ where: {
1442
1966
  tenantId: input.tenantId,
1443
1967
  currency: input.currency,
1444
1968
  active: true
1445
- } }), normalizedInput);
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 chargeWhere = {
1458
- tenantId: input.tenantId,
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) chargeWhere.metricKey = policy.metricKey;
1465
- if (policy.projectId) chargeWhere.projectId = policy.projectId;
1466
- if (policy.serviceKey) chargeWhere.serviceKey = policy.serviceKey;
1467
- if (policy.subscriberKind) chargeWhere.subscriberKind = policy.subscriberKind;
1468
- if (policy.subscriberExternalId) chargeWhere.subscriberExternalId = policy.subscriberExternalId;
1469
- const scopedCharges = (await this.charges.list({ where: chargeWhere })).filter((charge) => (charge.status === "approved" || charge.status === "adjusted") && matchesChargeScope(policy, charge));
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: input.tenantId,
2119
+ tenantId: payer,
1474
2120
  currency: policy.currency,
1475
2121
  clientChargeId: chargeIds
1476
2122
  } }) : [];
1477
- const projectedAmount = scopedCharges.reduce((sum, charge) => sum + charge.amount, 0) + adjustmentRows.filter((adjustment) => chargeIdSet.has(adjustment.clientChargeId)).reduce((sum, adjustment) => sum + adjustment.amount, 0) + input.estimatedAmount;
1478
- const exceeded = projectedAmount > policy.limitAmount;
1479
- if (!exceeded || policy.behavior === "observe") return {
1480
- allowed: true,
1481
- approvalRequired: false,
1482
- state: exceeded ? "observed" : "ok",
1483
- projectedAmount,
1484
- matchedPolicyId: policy.id ?? null
1485
- };
1486
- if (policy.behavior === "warn") return {
1487
- allowed: true,
1488
- approvalRequired: false,
1489
- state: "warned",
1490
- projectedAmount,
1491
- matchedPolicyId: policy.id ?? null
1492
- };
1493
- if (policy.behavior === "approval_required") return {
1494
- allowed: false,
1495
- approvalRequired: true,
1496
- state: "approval_required",
1497
- projectedAmount,
1498
- matchedPolicyId: policy.id ?? null
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 === "rolling") start.setTime(at.getTime() - policy.rollingSeconds * 1e3);
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