@chatman-media/storage 1.21.0 → 1.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -35,10 +35,16 @@ __export(exports_schema, {
35
35
  skillOutcomes: () => skillOutcomes,
36
36
  shadowEvaluations: () => shadowEvaluations,
37
37
  sessions: () => sessions,
38
+ serviceOrders: () => serviceOrders,
39
+ serviceOrderPayments: () => serviceOrderPayments,
40
+ serviceOrderCommissions: () => serviceOrderCommissions,
38
41
  serviceCatalogItems: () => serviceCatalogItems,
39
42
  selfPlayMatches: () => selfPlayMatches,
40
43
  referralCodes: () => referralCodes,
41
44
  questionnaireTokens: () => questionnaireTokens,
45
+ providerServices: () => providerServices,
46
+ providerRequests: () => providerRequests,
47
+ providerProfiles: () => providerProfiles,
42
48
  passwordResets: () => passwordResets,
43
49
  partners: () => partners,
44
50
  partnerSettlements: () => partnerSettlements,
@@ -48,6 +54,7 @@ __export(exports_schema, {
48
54
  outreachCampaigns: () => outreachCampaigns,
49
55
  outreachCampaignLeads: () => outreachCampaignLeads,
50
56
  outboundQueue: () => outboundQueue,
57
+ orderEvents: () => orderEvents,
51
58
  operatorSettings: () => operatorSettings,
52
59
  notificationTemplates: () => notificationTemplates,
53
60
  notificationRules: () => notificationRules,
@@ -2605,6 +2612,11 @@ var kbDocuments = pgTable("kb_documents", {
2605
2612
  scopeType: text("scope_type").notNull().default("global"),
2606
2613
  funnelId: integer("funnel_id"),
2607
2614
  stageSlug: text("stage_slug"),
2615
+ fileStorageKey: text("file_storage_key"),
2616
+ fileName: text("file_name"),
2617
+ fileMimeType: text("file_mime_type"),
2618
+ fileSizeBytes: integer("file_size_bytes"),
2619
+ fileUploadedAt: integer("file_uploaded_at"),
2608
2620
  createdAt: integer("created_at").notNull().default(epochNow())
2609
2621
  }, (t) => [
2610
2622
  check("kb_documents_scope_type_check", sql`${t.scopeType} IN ('global','funnel','stage')`),
@@ -2613,7 +2625,9 @@ var kbDocuments = pgTable("kb_documents", {
2613
2625
  OR (${t.scopeType} = 'funnel' AND ${t.funnelId} IS NOT NULL AND ${t.stageSlug} IS NULL)
2614
2626
  OR (${t.scopeType} = 'stage' AND ${t.funnelId} IS NOT NULL AND ${t.stageSlug} IS NOT NULL)
2615
2627
  )`),
2628
+ check("kb_documents_file_size_check", sql`${t.fileSizeBytes} IS NULL OR ${t.fileSizeBytes} >= 0`),
2616
2629
  uniqueIndex("uniq_kb_source_hash").on(t.source, t.contentHash),
2630
+ uniqueIndex("uniq_kb_docs_file_storage_key").on(t.fileStorageKey).where(sql`file_storage_key IS NOT NULL`),
2617
2631
  index("idx_kb_docs_topic").on(t.topic).where(sql`topic IS NOT NULL`),
2618
2632
  index("idx_kb_docs_scope").on(t.tenantId, t.scopeType, t.funnelId, t.stageSlug)
2619
2633
  ]);
@@ -3064,12 +3078,18 @@ var shadowEvaluations = pgTable("shadow_evaluations", {
3064
3078
  status: text("status").notNull().default("running"),
3065
3079
  decision: text("decision"),
3066
3080
  errorMessage: text("error_message"),
3081
+ runConfigJson: text("run_config_json"),
3082
+ claimToken: text("claim_token"),
3083
+ claimedAt: integer("claimed_at"),
3084
+ leaseExpiresAt: integer("lease_expires_at"),
3085
+ attempts: integer("attempts").notNull().default(0),
3067
3086
  startedAt: integer("started_at").notNull().default(epochNow()),
3068
3087
  completedAt: integer("completed_at")
3069
3088
  }, (t) => [
3070
3089
  check("shadow_evaluations_status_check", sql`${t.status} IN ('running','complete','failed')`),
3071
3090
  check("shadow_evaluations_decision_check", sql`${t.decision} IS NULL OR ${t.decision} IN ('keep','rollback','inconclusive')`),
3072
- index("idx_shadow_evaluations_proposal").on(t.proposalId, sql`${t.startedAt} DESC`)
3091
+ index("idx_shadow_evaluations_proposal").on(t.proposalId, sql`${t.startedAt} DESC`),
3092
+ index("idx_shadow_evaluations_running_lease").on(t.tenantId, t.leaseExpiresAt, t.startedAt).where(sql`${t.status} = 'running'`)
3073
3093
  ]);
3074
3094
  var userbotSendQueue = pgTable("userbot_send_queue", {
3075
3095
  id: serial("id").primaryKey(),
@@ -3654,6 +3674,181 @@ var partnerSettlements = pgTable("partner_settlements", {
3654
3674
  check("partner_settlements_status_check", sql`${t.status} IN ('draft','issued','paid','cancelled')`),
3655
3675
  index("idx_partner_settlements_partner").on(t.tenantId, t.partnerId, t.periodStart)
3656
3676
  ]);
3677
+ var providerProfiles = pgTable("provider_profiles", {
3678
+ id: serial("id").primaryKey(),
3679
+ tenantId: integer("tenant_id").notNull().references(() => tenants.id, { onDelete: "cascade" }),
3680
+ contactId: integer("contact_id").notNull().references(() => contacts.id, { onDelete: "cascade" }),
3681
+ name: text("name").notNull(),
3682
+ category: text("category"),
3683
+ status: text("status").notNull().default("active"),
3684
+ serviceArea: text("service_area"),
3685
+ defaultCommissionPct: doublePrecision("default_commission_pct").notNull().default(0),
3686
+ notes: text("notes"),
3687
+ metadataJson: text("metadata_json").notNull().default("{}"),
3688
+ createdAt: integer("created_at").notNull().default(epochNow()),
3689
+ updatedAt: integer("updated_at").notNull().default(epochNow())
3690
+ }, (t) => [
3691
+ check("provider_profiles_status_check", sql`${t.status} IN ('active','paused','archived')`),
3692
+ uniqueIndex("uniq_provider_profiles_contact").on(t.tenantId, t.contactId),
3693
+ index("idx_provider_profiles_tenant_status").on(t.tenantId, t.status),
3694
+ index("idx_provider_profiles_category").on(t.tenantId, t.category)
3695
+ ]);
3696
+ var providerServices = pgTable("provider_services", {
3697
+ id: serial("id").primaryKey(),
3698
+ tenantId: integer("tenant_id").notNull().references(() => tenants.id, { onDelete: "cascade" }),
3699
+ providerId: integer("provider_id").notNull().references(() => providerProfiles.id, { onDelete: "cascade" }),
3700
+ serviceType: text("service_type").notNull(),
3701
+ name: text("name").notNull(),
3702
+ serviceArea: text("service_area"),
3703
+ pricingPolicyJson: text("pricing_policy_json").notNull().default("{}"),
3704
+ commissionPct: doublePrecision("commission_pct"),
3705
+ isActive: boolean("is_active").notNull().default(true),
3706
+ metadataJson: text("metadata_json").notNull().default("{}"),
3707
+ createdAt: integer("created_at").notNull().default(epochNow()),
3708
+ updatedAt: integer("updated_at").notNull().default(epochNow())
3709
+ }, (t) => [
3710
+ uniqueIndex("uniq_provider_services_name").on(t.tenantId, t.providerId, t.serviceType, t.name),
3711
+ index("idx_provider_services_tenant_active").on(t.tenantId, t.isActive),
3712
+ index("idx_provider_services_type").on(t.tenantId, t.serviceType, t.isActive)
3713
+ ]);
3714
+ var serviceOrders = pgTable("service_orders", {
3715
+ id: serial("id").primaryKey(),
3716
+ tenantId: integer("tenant_id").notNull().references(() => tenants.id, { onDelete: "cascade" }),
3717
+ customerContactId: integer("customer_contact_id").notNull().references(() => contacts.id, { onDelete: "cascade" }),
3718
+ customerConversationId: integer("customer_conversation_id").references(() => conversations.id, { onDelete: "set null" }),
3719
+ leadId: integer("lead_id").references(() => leads.id, { onDelete: "set null" }),
3720
+ assignedProviderId: integer("assigned_provider_id").references(() => providerProfiles.id, { onDelete: "set null" }),
3721
+ requestType: text("request_type").notNull(),
3722
+ status: text("status").notNull().default("intake"),
3723
+ summary: text("summary"),
3724
+ quotedAmount: doublePrecision("quoted_amount"),
3725
+ customerAmount: doublePrecision("customer_amount"),
3726
+ commissionPct: doublePrecision("commission_pct"),
3727
+ commissionAmount: doublePrecision("commission_amount"),
3728
+ currency: text("currency").notNull().default("THB"),
3729
+ paymentStatus: text("payment_status").notNull().default("unpaid"),
3730
+ paymentProvider: text("payment_provider"),
3731
+ paymentRef: text("payment_ref"),
3732
+ idempotencyKey: text("idempotency_key"),
3733
+ metadataJson: text("metadata_json").notNull().default("{}"),
3734
+ expiresAt: integer("expires_at"),
3735
+ confirmedAt: integer("confirmed_at"),
3736
+ completedAt: integer("completed_at"),
3737
+ cancelledAt: integer("cancelled_at"),
3738
+ createdAt: integer("created_at").notNull().default(epochNow()),
3739
+ updatedAt: integer("updated_at").notNull().default(epochNow())
3740
+ }, (t) => [
3741
+ check("service_orders_status_check", sql`${t.status} IN ('intake','matching','awaiting_provider','provider_declined','offer_ready','awaiting_customer_payment','paid','confirmed','fulfilled','cancelled','failed')`),
3742
+ check("service_orders_payment_status_check", sql`${t.paymentStatus} IN ('unpaid','pending','paid','refunded','failed')`),
3743
+ uniqueIndex("uniq_service_orders_idem").on(t.idempotencyKey).where(sql`idempotency_key IS NOT NULL`),
3744
+ index("idx_service_orders_tenant_status").on(t.tenantId, t.status),
3745
+ index("idx_service_orders_customer").on(t.tenantId, t.customerContactId),
3746
+ index("idx_service_orders_lead").on(t.tenantId, t.leadId),
3747
+ index("idx_service_orders_provider").on(t.tenantId, t.assignedProviderId),
3748
+ index("idx_service_orders_payment").on(t.tenantId, t.paymentStatus)
3749
+ ]);
3750
+ var providerRequests = pgTable("provider_requests", {
3751
+ id: serial("id").primaryKey(),
3752
+ tenantId: integer("tenant_id").notNull().references(() => tenants.id, { onDelete: "cascade" }),
3753
+ orderId: integer("order_id").notNull().references(() => serviceOrders.id, { onDelete: "cascade" }),
3754
+ providerId: integer("provider_id").references(() => providerProfiles.id, { onDelete: "set null" }),
3755
+ providerConversationId: integer("provider_conversation_id").references(() => conversations.id, { onDelete: "set null" }),
3756
+ channelId: integer("channel_id").references(() => channels.id, { onDelete: "set null" }),
3757
+ outboundQueueId: integer("outbound_queue_id").references(() => outboundQueue.id, { onDelete: "set null" }),
3758
+ status: text("status").notNull().default("draft"),
3759
+ quotedAmount: doublePrecision("quoted_amount"),
3760
+ customerAmount: doublePrecision("customer_amount"),
3761
+ commissionAmount: doublePrecision("commission_amount"),
3762
+ currency: text("currency").notNull().default("THB"),
3763
+ availableAt: integer("available_at"),
3764
+ quoteExpiresAt: integer("quote_expires_at"),
3765
+ responseText: text("response_text"),
3766
+ idempotencyKey: text("idempotency_key"),
3767
+ metadataJson: text("metadata_json").notNull().default("{}"),
3768
+ sentAt: integer("sent_at"),
3769
+ respondedAt: integer("responded_at"),
3770
+ expiredAt: integer("expired_at"),
3771
+ cancelledAt: integer("cancelled_at"),
3772
+ createdAt: integer("created_at").notNull().default(epochNow()),
3773
+ updatedAt: integer("updated_at").notNull().default(epochNow())
3774
+ }, (t) => [
3775
+ check("provider_requests_status_check", sql`${t.status} IN ('draft','sent','seen','quoted','accepted','declined','expired','cancelled')`),
3776
+ uniqueIndex("uniq_provider_requests_idem").on(t.idempotencyKey).where(sql`idempotency_key IS NOT NULL`),
3777
+ index("idx_provider_requests_order").on(t.tenantId, t.orderId),
3778
+ index("idx_provider_requests_provider_status").on(t.tenantId, t.providerId, t.status),
3779
+ index("idx_provider_requests_tenant_status").on(t.tenantId, t.status),
3780
+ index("idx_provider_requests_quote_ttl").on(t.status, t.quoteExpiresAt).where(sql`status = 'quoted'`)
3781
+ ]);
3782
+ var orderEvents = pgTable("order_events", {
3783
+ id: serial("id").primaryKey(),
3784
+ tenantId: integer("tenant_id").notNull().references(() => tenants.id, { onDelete: "cascade" }),
3785
+ orderId: integer("order_id").notNull().references(() => serviceOrders.id, { onDelete: "cascade" }),
3786
+ providerRequestId: integer("provider_request_id").references(() => providerRequests.id, { onDelete: "set null" }),
3787
+ conversationId: integer("conversation_id").references(() => conversations.id, { onDelete: "set null" }),
3788
+ messageId: integer("message_id").references(() => messages.id, { onDelete: "set null" }),
3789
+ actorType: text("actor_type").notNull().default("system"),
3790
+ eventType: text("event_type").notNull(),
3791
+ dataJson: text("data_json").notNull().default("{}"),
3792
+ createdAt: integer("created_at").notNull().default(epochNow())
3793
+ }, (t) => [
3794
+ check("order_events_actor_type_check", sql`${t.actorType} IN ('system','customer','provider','operator','payment')`),
3795
+ index("idx_order_events_order_created").on(t.tenantId, t.orderId, t.createdAt),
3796
+ index("idx_order_events_provider_request").on(t.tenantId, t.providerRequestId),
3797
+ index("idx_order_events_type").on(t.tenantId, t.eventType)
3798
+ ]);
3799
+ var serviceOrderPayments = pgTable("service_order_payments", {
3800
+ id: serial("id").primaryKey(),
3801
+ tenantId: integer("tenant_id").notNull().references(() => tenants.id, { onDelete: "cascade" }),
3802
+ orderId: integer("order_id").notNull().references(() => serviceOrders.id, { onDelete: "cascade" }),
3803
+ provider: text("provider").notNull(),
3804
+ externalIntentId: text("external_intent_id"),
3805
+ externalSessionId: text("external_session_id"),
3806
+ status: text("status").notNull().default("created"),
3807
+ amount: doublePrecision("amount").notNull(),
3808
+ currency: text("currency").notNull().default("THB"),
3809
+ idempotencyKey: text("idempotency_key"),
3810
+ metadataJson: text("metadata_json").notNull().default("{}"),
3811
+ createdAt: integer("created_at").notNull().default(epochNow()),
3812
+ updatedAt: integer("updated_at").notNull().default(epochNow()),
3813
+ paidAt: integer("paid_at"),
3814
+ failedAt: integer("failed_at"),
3815
+ cancelledAt: integer("cancelled_at"),
3816
+ refundedAt: integer("refunded_at")
3817
+ }, (t) => [
3818
+ check("service_order_payments_status_check", sql`${t.status} IN ('created','pending','paid','failed','cancelled','refunded')`),
3819
+ uniqueIndex("uniq_service_order_payments_idem").on(t.tenantId, t.idempotencyKey).where(sql`idempotency_key IS NOT NULL`),
3820
+ uniqueIndex("uniq_service_order_payments_provider_intent").on(t.tenantId, t.provider, t.externalIntentId).where(sql`external_intent_id IS NOT NULL`),
3821
+ uniqueIndex("uniq_service_order_payments_provider_session").on(t.tenantId, t.provider, t.externalSessionId).where(sql`external_session_id IS NOT NULL`),
3822
+ index("idx_service_order_payments_order").on(t.tenantId, t.orderId),
3823
+ index("idx_service_order_payments_status").on(t.tenantId, t.status)
3824
+ ]);
3825
+ var serviceOrderCommissions = pgTable("service_order_commissions", {
3826
+ id: serial("id").primaryKey(),
3827
+ tenantId: integer("tenant_id").notNull().references(() => tenants.id, { onDelete: "cascade" }),
3828
+ orderId: integer("order_id").notNull().references(() => serviceOrders.id, { onDelete: "cascade" }),
3829
+ providerId: integer("provider_id").references(() => providerProfiles.id, { onDelete: "set null" }),
3830
+ paymentId: integer("payment_id").references(() => serviceOrderPayments.id, { onDelete: "set null" }),
3831
+ status: text("status").notNull().default("pending"),
3832
+ grossAmount: doublePrecision("gross_amount").notNull(),
3833
+ commissionPct: doublePrecision("commission_pct").notNull().default(0),
3834
+ commissionAmount: doublePrecision("commission_amount").notNull().default(0),
3835
+ currency: text("currency").notNull().default("THB"),
3836
+ source: text("source").notNull().default("payment"),
3837
+ idempotencyKey: text("idempotency_key"),
3838
+ metadataJson: text("metadata_json").notNull().default("{}"),
3839
+ earnedAt: integer("earned_at"),
3840
+ refundedAt: integer("refunded_at"),
3841
+ paidOutAt: integer("paid_out_at"),
3842
+ createdAt: integer("created_at").notNull().default(epochNow()),
3843
+ updatedAt: integer("updated_at").notNull().default(epochNow())
3844
+ }, (t) => [
3845
+ check("service_order_commissions_status_check", sql`${t.status} IN ('pending','earned','void','refunded','paid_out')`),
3846
+ uniqueIndex("uniq_service_order_commissions_idem").on(t.tenantId, t.idempotencyKey).where(sql`idempotency_key IS NOT NULL`),
3847
+ index("idx_service_order_commissions_order").on(t.tenantId, t.orderId),
3848
+ index("idx_service_order_commissions_provider").on(t.tenantId, t.providerId),
3849
+ index("idx_service_order_commissions_payment").on(t.tenantId, t.paymentId),
3850
+ index("idx_service_order_commissions_status").on(t.tenantId, t.status)
3851
+ ]);
3657
3852
  // src/integration-helpers.ts
3658
3853
  import { readdirSync, readFileSync } from "node:fs";
3659
3854
  import { join } from "node:path";
@@ -5692,11 +5887,17 @@ export {
5692
5887
  skillOutcomes,
5693
5888
  shadowEvaluations,
5694
5889
  sessions,
5890
+ serviceOrders,
5891
+ serviceOrderPayments,
5892
+ serviceOrderCommissions,
5695
5893
  serviceCatalogItems,
5696
5894
  selfPlayMatches,
5697
5895
  exports_schema as schema,
5698
5896
  referralCodes,
5699
5897
  questionnaireTokens,
5898
+ providerServices,
5899
+ providerRequests,
5900
+ providerProfiles,
5700
5901
  passwordResets,
5701
5902
  partners,
5702
5903
  partnerSettlements,
@@ -5706,6 +5907,7 @@ export {
5706
5907
  outreachCampaigns,
5707
5908
  outreachCampaignLeads,
5708
5909
  outboundQueue,
5910
+ orderEvents,
5709
5911
  operatorSettings,
5710
5912
  notificationTemplates,
5711
5913
  notificationRules,
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=provider-relay.integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-relay.integration.test.d.ts","sourceRoot":"","sources":["../src/provider-relay.integration.test.ts"],"names":[],"mappings":""}