@infuro/cms-core 1.0.62 → 1.0.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/admin.cjs +183 -65
  2. package/dist/admin.js +183 -65
  3. package/dist/api.cjs +38 -38
  4. package/dist/api.d.cts +2 -0
  5. package/dist/api.d.ts +2 -0
  6. package/dist/api.js +6 -6
  7. package/dist/{chunk-GZGFNVTK.js → chunk-6YOQ7G5O.js} +105 -49
  8. package/dist/{chunk-6XAVZE4I.js → chunk-DXERXWBR.js} +1 -1
  9. package/dist/{chunk-QA5C477U.cjs → chunk-FF45VZMM.cjs} +99 -73
  10. package/dist/{chunk-AXMP2U43.cjs → chunk-GLD263KW.cjs} +3 -3
  11. package/dist/{chunk-R6Q67HAS.js → chunk-K6C3ZSBZ.js} +56 -30
  12. package/dist/{chunk-TWTISTZB.cjs → chunk-M25DGZ5J.cjs} +114 -53
  13. package/dist/{chunk-6LV36PCL.js → chunk-OJAYCNE5.js} +107 -46
  14. package/dist/{chunk-HMLVPIJR.js → chunk-OPJEV44S.js} +2 -2
  15. package/dist/{chunk-LVQSG25Y.cjs → chunk-PX3BSCIG.cjs} +1 -1
  16. package/dist/{chunk-YW7EF7K7.js → chunk-TU23GJPJ.js} +2 -2
  17. package/dist/{chunk-CTIEAHQL.cjs → chunk-TZEMLHSP.cjs} +30 -11
  18. package/dist/{chunk-ZPAPCGCR.cjs → chunk-VM6OVUUM.cjs} +106 -50
  19. package/dist/{chunk-LRD4CGOG.cjs → chunk-XFDIIVZB.cjs} +4 -4
  20. package/dist/{chunk-NMYGQWHV.js → chunk-YRCKEGL2.js} +30 -11
  21. package/dist/{email-queue-J7DXYNCE.cjs → email-queue-4OY45JIU.cjs} +7 -7
  22. package/dist/{email-queue-65PQAG4C.js → email-queue-HGXB2FIS.js} +3 -3
  23. package/dist/{email-service-RDOTY3CO.cjs → email-service-5O24BSFR.cjs} +7 -7
  24. package/dist/{email-service-F7HA4X63.js → email-service-ADDF52PJ.js} +2 -2
  25. package/dist/{emit-order-notification-trigger-MD7EBODC.js → emit-order-notification-trigger-MFCBAE7L.js} +1 -1
  26. package/dist/{emit-order-notification-trigger-K7URAZHJ.cjs → emit-order-notification-trigger-ZRRGCQGB.cjs} +3 -3
  27. package/dist/{erp-order-invoice-MYFCXOCY.js → erp-order-invoice-H6HCJ7YS.js} +2 -2
  28. package/dist/{erp-order-invoice-C5GZCOBM.cjs → erp-order-invoice-YUSPZ7CE.cjs} +6 -6
  29. package/dist/index.cjs +275 -260
  30. package/dist/index.d.cts +42 -17
  31. package/dist/index.d.ts +42 -17
  32. package/dist/index.js +44 -29
  33. package/dist/migrations/1783000000000-AddOrderPendingProcessingCompletedTriggers.ts +15 -39
  34. package/dist/migrations/1783300000000-SeedOrderNotificationTriggersAndTemplates.ts +155 -0
  35. package/dist/{order-completion-otp-handlers-3NTOGEA5.js → order-completion-otp-handlers-3W5I3LON.js} +4 -4
  36. package/dist/{order-completion-otp-handlers-4EOLYLAP.cjs → order-completion-otp-handlers-RF3DLNV7.cjs} +6 -6
  37. package/dist/{order-notification-dispatcher-IYMOS4VY.js → order-notification-dispatcher-ID2PDEXD.js} +5 -5
  38. package/dist/{order-notification-dispatcher-X2XM5VUY.cjs → order-notification-dispatcher-RNEQB3V7.cjs} +10 -10
  39. package/package.json +1 -1
package/dist/index.d.cts CHANGED
@@ -236,6 +236,8 @@ interface CompanyDetails {
236
236
  companyName?: string;
237
237
  supportEmail?: string;
238
238
  supportPhone?: string;
239
+ /** From Store → Invoice Header & Store Details (`companyAddress`). */
240
+ companyAddress?: string;
239
241
  socialLinks?: SocialLinkItem[];
240
242
  /** Shown below footer rows; from email plugin settings */
241
243
  footerDisclaimer?: string;
@@ -252,8 +254,15 @@ interface OrderPlacedLineItem {
252
254
  tax?: number | string | null;
253
255
  hsn?: string | null;
254
256
  }
255
- /** Merge branding + email plugin settings for layout (email overrides when set). */
256
- declare function mergeEmailLayoutCompanyDetails(branding: Record<string, string>, emailSettings: Record<string, string>): CompanyDetails;
257
+ /**
258
+ * Build email layout company details.
259
+ *
260
+ * Primary source: **Settings → Store → Invoice Header & Store Details**
261
+ * (`companyLogo` / `invoiceLogoUrl`, `companyName`, `companyEmail`, `companyPhone`, `companyAddress`).
262
+ * Email plugin fields override only when set (optional email-specific tweaks).
263
+ * Branding is last-resort fallback.
264
+ */
265
+ declare function mergeEmailLayoutCompanyDetails(branding: Record<string, string>, emailSettings: Record<string, string>, storeSettings?: Record<string, string>): CompanyDetails;
257
266
  interface EmailTemplateResult {
258
267
  subject: string;
259
268
  bodyHtml: string;
@@ -361,6 +370,10 @@ declare const emailTemplates: {
361
370
  };
362
371
  };
363
372
 
373
+ /**
374
+ * Branded HTML shell for transactional email.
375
+ * Company logo/name/contact/address come from Store → Invoice Header & Store Details.
376
+ */
364
377
  declare function renderLayout(options: {
365
378
  bodyHtml: string;
366
379
  companyDetails: CompanyDetails;
@@ -2863,27 +2876,27 @@ declare function resendOrderNotification(triggerKey: string, orderId: number, de
2863
2876
 
2864
2877
  /** Default order lifecycle triggers — seeded by migration, not tied to the `events` table. */
2865
2878
  declare const DEFAULT_ORDER_NOTIFICATION_TRIGGER_SEEDS: readonly [{
2866
- readonly triggerKey: "order_pending";
2867
- readonly label: "Order pending";
2868
- readonly description: "Fires when an order is created and pending confirmation or payment.";
2879
+ readonly triggerKey: "order_placed";
2880
+ readonly label: "Order placed";
2881
+ readonly description: "Fires when a new order is created (storefront checkout or admin).";
2869
2882
  readonly category: "order";
2870
2883
  readonly sortOrder: 1;
2871
2884
  }, {
2872
- readonly triggerKey: "order_processing";
2873
- readonly label: "Order processing";
2874
- readonly description: "Fires when an order moves to processing after being assigned.";
2885
+ readonly triggerKey: "order_pending";
2886
+ readonly label: "Order pending";
2887
+ readonly description: "Fires when an order is in pending status (awaiting payment or review).";
2875
2888
  readonly category: "order";
2876
2889
  readonly sortOrder: 2;
2877
2890
  }, {
2878
- readonly triggerKey: "order_completed";
2879
- readonly label: "Order completed";
2880
- readonly description: "Fires when an order is completed after customer OTP validation.";
2891
+ readonly triggerKey: "order_assigned";
2892
+ readonly label: "Order assigned (Customer)";
2893
+ readonly description: "Fires when a teammate is assigned to the order (notifies customer with assignee details and scheduled time slot).";
2881
2894
  readonly category: "order";
2882
2895
  readonly sortOrder: 3;
2883
2896
  }, {
2884
- readonly triggerKey: "order_placed";
2885
- readonly label: "Order placed";
2886
- readonly description: "Fires when a new order is created (storefront checkout or admin).";
2897
+ readonly triggerKey: "order_assigned_assignee";
2898
+ readonly label: "Task assigned (Assignee)";
2899
+ readonly description: "Fires when a task is assigned to a teammate (notifies assignee with task description and customer details).";
2887
2900
  readonly category: "order";
2888
2901
  readonly sortOrder: 4;
2889
2902
  }, {
@@ -2892,24 +2905,36 @@ declare const DEFAULT_ORDER_NOTIFICATION_TRIGGER_SEEDS: readonly [{
2892
2905
  readonly description: "Fires when an order is cancelled (includes refund amount when applicable).";
2893
2906
  readonly category: "order";
2894
2907
  readonly sortOrder: 5;
2908
+ }, {
2909
+ readonly triggerKey: "order_processing";
2910
+ readonly label: "Order processing";
2911
+ readonly description: "Fires when an order status changes to processing.";
2912
+ readonly category: "order";
2913
+ readonly sortOrder: 6;
2895
2914
  }, {
2896
2915
  readonly triggerKey: "payment_success";
2897
2916
  readonly label: "Payment success";
2898
2917
  readonly description: "Fires when order is placed and payment status is paid.";
2899
2918
  readonly category: "order";
2900
- readonly sortOrder: 6;
2919
+ readonly sortOrder: 7;
2920
+ }, {
2921
+ readonly triggerKey: "order_completed";
2922
+ readonly label: "Order completed";
2923
+ readonly description: "Fires when an order status changes to completed / fulfilled.";
2924
+ readonly category: "order";
2925
+ readonly sortOrder: 8;
2901
2926
  }, {
2902
2927
  readonly triggerKey: "payment_failed";
2903
2928
  readonly label: "Payment failed";
2904
2929
  readonly description: "Fires when payment status is pending, unpaid, or failed, or when order is cancelled without payment.";
2905
2930
  readonly category: "order";
2906
- readonly sortOrder: 7;
2931
+ readonly sortOrder: 9;
2907
2932
  }, {
2908
2933
  readonly triggerKey: "payment_refund_initiated";
2909
2934
  readonly label: "Payment refund initiated";
2910
2935
  readonly description: "Fires when order is cancelled and its payment status is paid (refund initiated).";
2911
2936
  readonly category: "order";
2912
- readonly sortOrder: 8;
2937
+ readonly sortOrder: 10;
2913
2938
  }];
2914
2939
 
2915
2940
  /** @deprecated Use DB catalog `order_notification_triggers`; kept for type hints. */
package/dist/index.d.ts CHANGED
@@ -236,6 +236,8 @@ interface CompanyDetails {
236
236
  companyName?: string;
237
237
  supportEmail?: string;
238
238
  supportPhone?: string;
239
+ /** From Store → Invoice Header & Store Details (`companyAddress`). */
240
+ companyAddress?: string;
239
241
  socialLinks?: SocialLinkItem[];
240
242
  /** Shown below footer rows; from email plugin settings */
241
243
  footerDisclaimer?: string;
@@ -252,8 +254,15 @@ interface OrderPlacedLineItem {
252
254
  tax?: number | string | null;
253
255
  hsn?: string | null;
254
256
  }
255
- /** Merge branding + email plugin settings for layout (email overrides when set). */
256
- declare function mergeEmailLayoutCompanyDetails(branding: Record<string, string>, emailSettings: Record<string, string>): CompanyDetails;
257
+ /**
258
+ * Build email layout company details.
259
+ *
260
+ * Primary source: **Settings → Store → Invoice Header & Store Details**
261
+ * (`companyLogo` / `invoiceLogoUrl`, `companyName`, `companyEmail`, `companyPhone`, `companyAddress`).
262
+ * Email plugin fields override only when set (optional email-specific tweaks).
263
+ * Branding is last-resort fallback.
264
+ */
265
+ declare function mergeEmailLayoutCompanyDetails(branding: Record<string, string>, emailSettings: Record<string, string>, storeSettings?: Record<string, string>): CompanyDetails;
257
266
  interface EmailTemplateResult {
258
267
  subject: string;
259
268
  bodyHtml: string;
@@ -361,6 +370,10 @@ declare const emailTemplates: {
361
370
  };
362
371
  };
363
372
 
373
+ /**
374
+ * Branded HTML shell for transactional email.
375
+ * Company logo/name/contact/address come from Store → Invoice Header & Store Details.
376
+ */
364
377
  declare function renderLayout(options: {
365
378
  bodyHtml: string;
366
379
  companyDetails: CompanyDetails;
@@ -2863,27 +2876,27 @@ declare function resendOrderNotification(triggerKey: string, orderId: number, de
2863
2876
 
2864
2877
  /** Default order lifecycle triggers — seeded by migration, not tied to the `events` table. */
2865
2878
  declare const DEFAULT_ORDER_NOTIFICATION_TRIGGER_SEEDS: readonly [{
2866
- readonly triggerKey: "order_pending";
2867
- readonly label: "Order pending";
2868
- readonly description: "Fires when an order is created and pending confirmation or payment.";
2879
+ readonly triggerKey: "order_placed";
2880
+ readonly label: "Order placed";
2881
+ readonly description: "Fires when a new order is created (storefront checkout or admin).";
2869
2882
  readonly category: "order";
2870
2883
  readonly sortOrder: 1;
2871
2884
  }, {
2872
- readonly triggerKey: "order_processing";
2873
- readonly label: "Order processing";
2874
- readonly description: "Fires when an order moves to processing after being assigned.";
2885
+ readonly triggerKey: "order_pending";
2886
+ readonly label: "Order pending";
2887
+ readonly description: "Fires when an order is in pending status (awaiting payment or review).";
2875
2888
  readonly category: "order";
2876
2889
  readonly sortOrder: 2;
2877
2890
  }, {
2878
- readonly triggerKey: "order_completed";
2879
- readonly label: "Order completed";
2880
- readonly description: "Fires when an order is completed after customer OTP validation.";
2891
+ readonly triggerKey: "order_assigned";
2892
+ readonly label: "Order assigned (Customer)";
2893
+ readonly description: "Fires when a teammate is assigned to the order (notifies customer with assignee details and scheduled time slot).";
2881
2894
  readonly category: "order";
2882
2895
  readonly sortOrder: 3;
2883
2896
  }, {
2884
- readonly triggerKey: "order_placed";
2885
- readonly label: "Order placed";
2886
- readonly description: "Fires when a new order is created (storefront checkout or admin).";
2897
+ readonly triggerKey: "order_assigned_assignee";
2898
+ readonly label: "Task assigned (Assignee)";
2899
+ readonly description: "Fires when a task is assigned to a teammate (notifies assignee with task description and customer details).";
2887
2900
  readonly category: "order";
2888
2901
  readonly sortOrder: 4;
2889
2902
  }, {
@@ -2892,24 +2905,36 @@ declare const DEFAULT_ORDER_NOTIFICATION_TRIGGER_SEEDS: readonly [{
2892
2905
  readonly description: "Fires when an order is cancelled (includes refund amount when applicable).";
2893
2906
  readonly category: "order";
2894
2907
  readonly sortOrder: 5;
2908
+ }, {
2909
+ readonly triggerKey: "order_processing";
2910
+ readonly label: "Order processing";
2911
+ readonly description: "Fires when an order status changes to processing.";
2912
+ readonly category: "order";
2913
+ readonly sortOrder: 6;
2895
2914
  }, {
2896
2915
  readonly triggerKey: "payment_success";
2897
2916
  readonly label: "Payment success";
2898
2917
  readonly description: "Fires when order is placed and payment status is paid.";
2899
2918
  readonly category: "order";
2900
- readonly sortOrder: 6;
2919
+ readonly sortOrder: 7;
2920
+ }, {
2921
+ readonly triggerKey: "order_completed";
2922
+ readonly label: "Order completed";
2923
+ readonly description: "Fires when an order status changes to completed / fulfilled.";
2924
+ readonly category: "order";
2925
+ readonly sortOrder: 8;
2901
2926
  }, {
2902
2927
  readonly triggerKey: "payment_failed";
2903
2928
  readonly label: "Payment failed";
2904
2929
  readonly description: "Fires when payment status is pending, unpaid, or failed, or when order is cancelled without payment.";
2905
2930
  readonly category: "order";
2906
- readonly sortOrder: 7;
2931
+ readonly sortOrder: 9;
2907
2932
  }, {
2908
2933
  readonly triggerKey: "payment_refund_initiated";
2909
2934
  readonly label: "Payment refund initiated";
2910
2935
  readonly description: "Fires when order is cancelled and its payment status is paid (refund initiated).";
2911
2936
  readonly category: "order";
2912
- readonly sortOrder: 8;
2937
+ readonly sortOrder: 10;
2913
2938
  }];
2914
2939
 
2915
2940
  /** @deprecated Use DB catalog `order_notification_triggers`; kept for type hints. */
package/dist/index.js CHANGED
@@ -1,22 +1,22 @@
1
- export { emitOrderNotificationTrigger, fireOrderNotificationTrigger } from './chunk-6XAVZE4I.js';
2
- import { checkMultiVendorEnabled, loadUserVendorContext, getPublicSettingsGroup, BlogGeneratorService } from './chunk-R6Q67HAS.js';
3
- export { Address, Attendee, Attribute, BLOG_GENERATOR_AGENT_NAME, BLOG_GENERATOR_DEFAULT_SYSTEM_INSTRUCTION, BLOG_GENERATOR_DEFAULT_VALIDATION_RULES, BLOG_GENERATOR_LLM_AGENT_SLUG, BLOG_GENERATOR_MARKDOWN_ARTICLE_SEPARATOR, BLOG_METADATA_ENRICHER_AGENT_NAME, BLOG_METADATA_ENRICHER_DEFAULT_SYSTEM_INSTRUCTION, BLOG_METADATA_ENRICHER_DEFAULT_VALIDATION_RULES, BLOG_METADATA_ENRICHER_LLM_AGENT_SLUG, Blog, BlogGeneratorService, Brand, CMS_ENTITY_MAP, Cart, CartItem, Category, ChatConversation, ChatMessage, Collection, Combo, ComboItem, Comment, Config, Contact, Currency, CurrencyExchange, Customer, Customer_Contacts, Discount, DiscountRules, Event, EventProduct, Form, FormField, FormSubmission, JobSchedule, JobScheduleRun, KnowledgeBaseChunk, KnowledgeBaseDocument, LlmAgent, LlmAgentKnowledgeDocument, Media, MessageTemplate, Order, OrderAddresses, OrderDiscounts, OrderItem, OrderNotificationBinding, OrderNotificationTrigger, OtpChallenge, Page, PasswordResetToken, Payment, Permission, Product, ProductAttribute, ProductCategory, ProductConfig, ProductVariant, RefundPolicy, RefundRequest, RssArticle, RssFeed, Seo, Tag, Tax, User, UserDeviceToken, UserGroup, Vendor, VendorCustomer, VendorRole, VendorRolePermission, VendorUser, VendorUserProfile, Wishlist, WishlistItem, ZIP_MIME_TYPES, applyApprovalStatusSideEffects, applyEventApprovalStatusSideEffects, applyRotatingVendorInvite, applyVendorCustomersContactFilter, applyVendorEventCreateApproval, applyVendorProductCreateApproval, assertCaptchaOk, assertContactAllowedForVendorOrder, assertEventApprovalUpdate, assertProductApprovalUpdate, autoExpireOrderIfPaymentTimeExceeded, buildBlogMetadataUserPrompt, buildCronFromSchedule, buildRssUserPromptFromFeeds, buildUserInviteLink, buildVendorInviteLink, calculateOrderRefundPreview, calculateRefundFromPolicy, checkAndIncrementDiscountUsage, checkEventsEnabled, checkMultiVendorEnabled, completeUserInviteAccept, consumeAppliedDiscountUsages, contactIsVendorCustomer, countDiscountOrdersForContact, createAnalyticsHandlers, createBlogBySlugHandler, createChangePasswordHandler, createCmsApiHandler, createCmsApp, createCmsAppWithMessaging, createCrudByIdHandler, createCrudHandler, createDashboardStatsHandler, createEcommerceAnalyticsHandler, createEventOrderMessageTemplateHandlers, createForgotPasswordHandler, createFormBySlugHandler, createInviteAcceptHandler, createJobScheduleHandlers, createLlmAgentKnowledgeHandlers, createMediaZipExtractHandler, createMessageTemplateRowLoader, createSetPasswordHandler, createSettingsApiHandlers, createSocialMediaHandlers, createStorefrontApiHandler, createUploadHandler, createUserAuthApiRouter, createUserAvatarHandler, createUserProfileHandler, createUsersApiHandlers, createVendorDashboardHandler, createVendorOnboardHandlers, daysBeforeEventStart, decrementDiscountUsage, describeEventTierPolicy, ensureMessagingPluginsOnCms, ensureScheduleQueueWorker, ensureVendorCustomerForOrderContact, ensureVendorCustomersForOrder, findActiveRefundPolicyForVendor, findUserByInviteToken, findVendorByInviteToken, formatTierRange, getPublicSettingsGroup, getRequireEventApproval, getRequireProductApproval, getRssArticleSummaryFromItem, getVendorCatalogCreateFlags, hydrateVendorSessionUser, invalidateEventsCache, invalidateMultiVendorCache, invalidateRequireEventApprovalCache, invalidateRequireProductApprovalCache, invalidateVendorCatalogCreateFlagsCache, isCustomerTypeContact, isMaxPerUserUsageReached, isMaxTotalUsageReached, isZipMedia, llmAgentToChatAgentOptions, loadSettingsGroupFromDb, loadUserVendorContext, mergeGuardrailsIntoSystemPrompt, messagingPlugins, metaFetchUserManagedPages, metaPostPageFeed, metaPostPagePhoto, metaResolvePageAccessToken, newUserInviteToken, normalizeRefundTiers, overlayCmsPlugins, parseBlogGeneratorAgentContent, parseBlogGeneratorModelOutput, parseBlogMetadataEnrichmentJson, parseLlmAgentValidationRules, pgBossScheduleNameForId, queueErpCreateContactIfEnabled, queueJobScheduleNow, queuePlugin, recordDiscountUsage, registerJobRunnerWorker, registerMessagingQueueProcessors, relativePathFromMediaParentId, resolveBlogCategoryIdByName, resolveSettingsEncryptionKey, resolveVendorIdForContactCheck, sanitizeMediaFolderPath, sanitizeStorageSegment, sendVendorOnboardEmails, simpleDecrypt, simpleEncrypt, syncJobScheduleToPgBoss, validateRefundTiers, validateScheduleInput, validateUserMessageAgainstAgentRules, validateUserMessageAgainstStructuredRules, whatsappPlugin, wrapGetCmsWithMessaging } from './chunk-R6Q67HAS.js';
1
+ export { emitOrderNotificationTrigger, fireOrderNotificationTrigger } from './chunk-DXERXWBR.js';
2
+ import { checkMultiVendorEnabled, loadUserVendorContext, getPublicSettingsGroup, BlogGeneratorService } from './chunk-K6C3ZSBZ.js';
3
+ export { Address, Attendee, Attribute, BLOG_GENERATOR_AGENT_NAME, BLOG_GENERATOR_DEFAULT_SYSTEM_INSTRUCTION, BLOG_GENERATOR_DEFAULT_VALIDATION_RULES, BLOG_GENERATOR_LLM_AGENT_SLUG, BLOG_GENERATOR_MARKDOWN_ARTICLE_SEPARATOR, BLOG_METADATA_ENRICHER_AGENT_NAME, BLOG_METADATA_ENRICHER_DEFAULT_SYSTEM_INSTRUCTION, BLOG_METADATA_ENRICHER_DEFAULT_VALIDATION_RULES, BLOG_METADATA_ENRICHER_LLM_AGENT_SLUG, Blog, BlogGeneratorService, Brand, CMS_ENTITY_MAP, Cart, CartItem, Category, ChatConversation, ChatMessage, Collection, Combo, ComboItem, Comment, Config, Contact, Currency, CurrencyExchange, Customer, Customer_Contacts, Discount, DiscountRules, Event, EventProduct, Form, FormField, FormSubmission, JobSchedule, JobScheduleRun, KnowledgeBaseChunk, KnowledgeBaseDocument, LlmAgent, LlmAgentKnowledgeDocument, Media, MessageTemplate, Order, OrderAddresses, OrderDiscounts, OrderItem, OrderNotificationBinding, OrderNotificationTrigger, OtpChallenge, Page, PasswordResetToken, Payment, Permission, Product, ProductAttribute, ProductCategory, ProductConfig, ProductVariant, RefundPolicy, RefundRequest, RssArticle, RssFeed, Seo, Tag, Tax, User, UserDeviceToken, UserGroup, Vendor, VendorCustomer, VendorRole, VendorRolePermission, VendorUser, VendorUserProfile, Wishlist, WishlistItem, ZIP_MIME_TYPES, applyApprovalStatusSideEffects, applyEventApprovalStatusSideEffects, applyRotatingVendorInvite, applyVendorCustomersContactFilter, applyVendorEventCreateApproval, applyVendorProductCreateApproval, assertCaptchaOk, assertContactAllowedForVendorOrder, assertEventApprovalUpdate, assertProductApprovalUpdate, autoExpireOrderIfPaymentTimeExceeded, buildBlogMetadataUserPrompt, buildCronFromSchedule, buildRssUserPromptFromFeeds, buildUserInviteLink, buildVendorInviteLink, calculateOrderRefundPreview, calculateRefundFromPolicy, checkAndIncrementDiscountUsage, checkEventsEnabled, checkMultiVendorEnabled, completeUserInviteAccept, consumeAppliedDiscountUsages, contactIsVendorCustomer, countDiscountOrdersForContact, createAnalyticsHandlers, createBlogBySlugHandler, createChangePasswordHandler, createCmsApiHandler, createCmsApp, createCmsAppWithMessaging, createCrudByIdHandler, createCrudHandler, createDashboardStatsHandler, createEcommerceAnalyticsHandler, createEventOrderMessageTemplateHandlers, createForgotPasswordHandler, createFormBySlugHandler, createInviteAcceptHandler, createJobScheduleHandlers, createLlmAgentKnowledgeHandlers, createMediaZipExtractHandler, createMessageTemplateRowLoader, createSetPasswordHandler, createSettingsApiHandlers, createSocialMediaHandlers, createStorefrontApiHandler, createUploadHandler, createUserAuthApiRouter, createUserAvatarHandler, createUserProfileHandler, createUsersApiHandlers, createVendorDashboardHandler, createVendorOnboardHandlers, daysBeforeEventStart, decrementDiscountUsage, describeEventTierPolicy, ensureMessagingPluginsOnCms, ensureScheduleQueueWorker, ensureVendorCustomerForOrderContact, ensureVendorCustomersForOrder, findActiveRefundPolicyForVendor, findUserByInviteToken, findVendorByInviteToken, formatTierRange, getPublicSettingsGroup, getRequireEventApproval, getRequireProductApproval, getRssArticleSummaryFromItem, getVendorCatalogCreateFlags, hydrateVendorSessionUser, invalidateEventsCache, invalidateMultiVendorCache, invalidateRequireEventApprovalCache, invalidateRequireProductApprovalCache, invalidateVendorCatalogCreateFlagsCache, isCustomerTypeContact, isMaxPerUserUsageReached, isMaxTotalUsageReached, isZipMedia, llmAgentToChatAgentOptions, loadSettingsGroupFromDb, loadUserVendorContext, mergeGuardrailsIntoSystemPrompt, messagingPlugins, metaFetchUserManagedPages, metaPostPageFeed, metaPostPagePhoto, metaResolvePageAccessToken, newUserInviteToken, normalizeRefundTiers, overlayCmsPlugins, parseBlogGeneratorAgentContent, parseBlogGeneratorModelOutput, parseBlogMetadataEnrichmentJson, parseLlmAgentValidationRules, pgBossScheduleNameForId, queueErpCreateContactIfEnabled, queueJobScheduleNow, queuePlugin, recordDiscountUsage, registerJobRunnerWorker, registerMessagingQueueProcessors, relativePathFromMediaParentId, resolveBlogCategoryIdByName, resolveSettingsEncryptionKey, resolveVendorIdForContactCheck, sanitizeMediaFolderPath, sanitizeStorageSegment, sendVendorOnboardEmails, simpleDecrypt, simpleEncrypt, syncJobScheduleToPgBoss, validateRefundTiers, validateScheduleInput, validateUserMessageAgainstAgentRules, validateUserMessageAgainstStructuredRules, whatsappPlugin, wrapGetCmsWithMessaging } from './chunk-K6C3ZSBZ.js';
4
4
  export { countRecentOtpSends, createOtpChallenge, generateNumericOtp, hashOtpCode, normalizePhoneE164, queueSms, registerSmsQueueProcessor, verifyAndConsumeOtpChallenge, verifyOtpCodeHash } from './chunk-OVTOP42W.js';
5
5
  import { PgBossService } from './chunk-GO7PPYNU.js';
6
6
  export { JOB_RUNNER_QUEUE, PgBossService } from './chunk-GO7PPYNU.js';
7
7
  export { deductInventoryForConfirmedOrder, mergeInventoryLines, orderInventorySnapshotFromRow, orderStatusHoldsStock, reconcileOrderInventoryBetweenSnapshots, restoreInventoryForCancelledOrder, validateInventoryForConfirmedOrderLines, validateInventoryForOrderBecomingConfirmed } from './chunk-3K5AIEIZ.js';
8
- import { parseEmailRecipientsFromConfig } from './chunk-6LV36PCL.js';
9
- export { buildEventOrderTemplateVariables, emailPlugin, initWhatsappTriggerDispatcher, joinRecipientsForSend, parseEmailRecipientsFromConfig, resendOrderNotification, serializeEmailRecipients } from './chunk-6LV36PCL.js';
8
+ import { parseEmailRecipientsFromConfig } from './chunk-OJAYCNE5.js';
9
+ export { buildEventOrderTemplateVariables, emailPlugin, initWhatsappTriggerDispatcher, joinRecipientsForSend, parseEmailRecipientsFromConfig, resendOrderNotification, serializeEmailRecipients } from './chunk-OJAYCNE5.js';
10
10
  export { queueWhatsApp, registerWhatsAppQueueProcessor } from './chunk-GWDI752Q.js';
11
11
  export { KNOWN_NOTIFICATION_TRIGGERS, notificationTriggerEmitter } from './chunk-AYWDQFJZ.js';
12
12
  import './chunk-JXF23MPG.js';
13
- export { EmailService, emailTemplates, renderEmail, renderLayout } from './chunk-GZGFNVTK.js';
14
- import { queueOrderPlacedEmails } from './chunk-YW7EF7K7.js';
15
- export { queueEmail, queueOrderPlacedEmails, queueVendorOnboardEmails, registerEmailQueueProcessor } from './chunk-YW7EF7K7.js';
16
- export { INVOICE_TEMPLATE_IDS, INVOICE_TEMPLATE_OPTIONS, buildLocalInvoicePdfForOrder, generateLocalInvoicePdf, isOrderEligibleForInvoiceEmail, normalizeInvoiceTemplateId, resolveInvoiceAssetUrl, resolveOrderInvoicePdfBytes, streamOrderInvoicePdf } from './chunk-HMLVPIJR.js';
13
+ export { EmailService, emailTemplates, renderEmail, renderLayout } from './chunk-6YOQ7G5O.js';
14
+ import { queueOrderPlacedEmails } from './chunk-TU23GJPJ.js';
15
+ export { queueEmail, queueOrderPlacedEmails, queueVendorOnboardEmails, registerEmailQueueProcessor } from './chunk-TU23GJPJ.js';
16
+ export { INVOICE_TEMPLATE_IDS, INVOICE_TEMPLATE_OPTIONS, buildLocalInvoicePdfForOrder, generateLocalInvoicePdf, isOrderEligibleForInvoiceEmail, normalizeInvoiceTemplateId, resolveInvoiceAssetUrl, resolveOrderInvoicePdfBytes, streamOrderInvoicePdf } from './chunk-OPJEV44S.js';
17
17
  import './chunk-JC6DLWTE.js';
18
- import { mergeEmailLayoutCompanyDetails } from './chunk-NMYGQWHV.js';
19
- export { getCompanyDetailsFromSettings, mergeEmailLayoutCompanyDetails } from './chunk-NMYGQWHV.js';
18
+ import { mergeEmailLayoutCompanyDetails } from './chunk-YRCKEGL2.js';
19
+ export { getCompanyDetailsFromSettings, mergeEmailLayoutCompanyDetails } from './chunk-YRCKEGL2.js';
20
20
  import './chunk-MQBT33IV.js';
21
21
  import './chunk-CRFV5WJK.js';
22
22
  export { EVENT_ORDER_MESSAGE_TEMPLATE_DEFAULTS, EVENT_ORDER_TEMPLATE_KEY, EVENT_ORDER_TEMPLATE_VARIABLES, resolveEventOrderTemplate } from './chunk-AYERBA7I.js';
@@ -2689,11 +2689,12 @@ async function sendOrderPlacedEmailsAfterConfirmation(orderId, deps) {
2689
2689
  }
2690
2690
  } catch {
2691
2691
  }
2692
- const [branding, emailSettings] = await Promise.all([
2692
+ const [branding, emailSettings, storeSettings] = await Promise.all([
2693
2693
  getSettingsGroup(deps, "branding"),
2694
- getSettingsGroup(deps, "email")
2694
+ getSettingsGroup(deps, "email"),
2695
+ getSettingsGroup(deps, "store")
2695
2696
  ]);
2696
- const companyDetails = mergeEmailLayoutCompanyDetails(branding, emailSettings);
2697
+ const companyDetails = mergeEmailLayoutCompanyDetails(branding, emailSettings, storeSettings);
2697
2698
  const salesTeamEmails = parseEmailRecipientsFromConfig(emailSettings.salesTeamEmails ?? emailSettings.salesTeamEmail);
2698
2699
  const cms = await deps.getCms();
2699
2700
  if (customerEmail) {
@@ -2738,30 +2739,30 @@ __name(sendOrderPlacedEmailsAfterConfirmation, "sendOrderPlacedEmailsAfterConfir
2738
2739
  // src/lib/order-notification-trigger-seeds.ts
2739
2740
  var DEFAULT_ORDER_NOTIFICATION_TRIGGER_SEEDS = [
2740
2741
  {
2741
- triggerKey: "order_pending",
2742
- label: "Order pending",
2743
- description: "Fires when an order is created and pending confirmation or payment.",
2742
+ triggerKey: "order_placed",
2743
+ label: "Order placed",
2744
+ description: "Fires when a new order is created (storefront checkout or admin).",
2744
2745
  category: "order",
2745
2746
  sortOrder: 1
2746
2747
  },
2747
2748
  {
2748
- triggerKey: "order_processing",
2749
- label: "Order processing",
2750
- description: "Fires when an order moves to processing after being assigned.",
2749
+ triggerKey: "order_pending",
2750
+ label: "Order pending",
2751
+ description: "Fires when an order is in pending status (awaiting payment or review).",
2751
2752
  category: "order",
2752
2753
  sortOrder: 2
2753
2754
  },
2754
2755
  {
2755
- triggerKey: "order_completed",
2756
- label: "Order completed",
2757
- description: "Fires when an order is completed after customer OTP validation.",
2756
+ triggerKey: "order_assigned",
2757
+ label: "Order assigned (Customer)",
2758
+ description: "Fires when a teammate is assigned to the order (notifies customer with assignee details and scheduled time slot).",
2758
2759
  category: "order",
2759
2760
  sortOrder: 3
2760
2761
  },
2761
2762
  {
2762
- triggerKey: "order_placed",
2763
- label: "Order placed",
2764
- description: "Fires when a new order is created (storefront checkout or admin).",
2763
+ triggerKey: "order_assigned_assignee",
2764
+ label: "Task assigned (Assignee)",
2765
+ description: "Fires when a task is assigned to a teammate (notifies assignee with task description and customer details).",
2765
2766
  category: "order",
2766
2767
  sortOrder: 4
2767
2768
  },
@@ -2772,26 +2773,40 @@ var DEFAULT_ORDER_NOTIFICATION_TRIGGER_SEEDS = [
2772
2773
  category: "order",
2773
2774
  sortOrder: 5
2774
2775
  },
2776
+ {
2777
+ triggerKey: "order_processing",
2778
+ label: "Order processing",
2779
+ description: "Fires when an order status changes to processing.",
2780
+ category: "order",
2781
+ sortOrder: 6
2782
+ },
2775
2783
  {
2776
2784
  triggerKey: "payment_success",
2777
2785
  label: "Payment success",
2778
2786
  description: "Fires when order is placed and payment status is paid.",
2779
2787
  category: "order",
2780
- sortOrder: 6
2788
+ sortOrder: 7
2789
+ },
2790
+ {
2791
+ triggerKey: "order_completed",
2792
+ label: "Order completed",
2793
+ description: "Fires when an order status changes to completed / fulfilled.",
2794
+ category: "order",
2795
+ sortOrder: 8
2781
2796
  },
2782
2797
  {
2783
2798
  triggerKey: "payment_failed",
2784
2799
  label: "Payment failed",
2785
2800
  description: "Fires when payment status is pending, unpaid, or failed, or when order is cancelled without payment.",
2786
2801
  category: "order",
2787
- sortOrder: 7
2802
+ sortOrder: 9
2788
2803
  },
2789
2804
  {
2790
2805
  triggerKey: "payment_refund_initiated",
2791
2806
  label: "Payment refund initiated",
2792
2807
  description: "Fires when order is cancelled and its payment status is paid (refund initiated).",
2793
2808
  category: "order",
2794
- sortOrder: 8
2809
+ sortOrder: 10
2795
2810
  }
2796
2811
  ];
2797
2812
 
@@ -4,53 +4,29 @@ export class AddOrderPendingProcessingCompletedTriggers1783000000000 implements
4
4
  name = "AddOrderPendingProcessingCompletedTriggers1783000000000";
5
5
 
6
6
  public async up(queryRunner: QueryRunner): Promise<void> {
7
- const tableExists = await queryRunner.hasTable("notification_triggers");
7
+ const tableExists = await queryRunner.hasTable("order_notification_triggers");
8
8
  if (!tableExists) return;
9
9
 
10
- const triggers = [
11
- {
12
- id: "order.pending",
13
- name: "Order Pending",
14
- description: "Triggered when a customer places an order and it is pending confirmation or payment.",
15
- category: "orders",
16
- enabled: true,
17
- },
18
- {
19
- id: "order.processing",
20
- name: "Order Processing",
21
- description: "Triggered when an order transitions to processing status after being assigned to a team member.",
22
- category: "orders",
23
- enabled: true,
24
- },
25
- {
26
- id: "order.completed",
27
- name: "Order Completed",
28
- description: "Triggered when an order is completed after customer OTP validation.",
29
- category: "orders",
30
- enabled: true,
31
- },
32
- ];
33
-
34
- for (const t of triggers) {
35
- await queryRunner.query(
36
- `INSERT INTO "notification_triggers" ("id", "name", "description", "category", "enabled")
37
- VALUES ($1, $2, $3, $4, $5)
38
- ON CONFLICT ("id") DO UPDATE
39
- SET "name" = EXCLUDED."name",
40
- "description" = EXCLUDED."description",
41
- "category" = EXCLUDED."category",
42
- "enabled" = EXCLUDED."enabled"`,
43
- [t.id, t.name, t.description, t.category, t.enabled]
44
- );
45
- }
10
+ await queryRunner.query(`
11
+ INSERT INTO "order_notification_triggers" ("triggerKey", "label", "description", "category", "sortOrder")
12
+ VALUES
13
+ ('order_pending', 'Order pending', 'Fires when an order is created and pending confirmation or payment.', 'order', 1),
14
+ ('order_processing', 'Order processing', 'Fires when an order moves to processing after being assigned.', 'order', 2),
15
+ ('order_completed', 'Order completed', 'Fires when an order is completed after customer OTP validation.', 'order', 3)
16
+ ON CONFLICT ("triggerKey") DO UPDATE SET
17
+ "label" = EXCLUDED."label",
18
+ "description" = EXCLUDED."description",
19
+ "sortOrder" = EXCLUDED."sortOrder",
20
+ "updatedAt" = now();
21
+ `);
46
22
  }
47
23
 
48
24
  public async down(queryRunner: QueryRunner): Promise<void> {
49
- const tableExists = await queryRunner.hasTable("notification_triggers");
25
+ const tableExists = await queryRunner.hasTable("order_notification_triggers");
50
26
  if (!tableExists) return;
51
27
 
52
28
  await queryRunner.query(
53
- `DELETE FROM "notification_triggers" WHERE "id" IN ('order.pending', 'order.processing', 'order.completed')`
29
+ `DELETE FROM "order_notification_triggers" WHERE "triggerKey" IN ('order_pending', 'order_processing', 'order_completed')`
54
30
  );
55
31
  }
56
32
  }
@@ -0,0 +1,155 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+
3
+ /**
4
+ * Seeds and syncs all default order notification triggers, starter email templates,
5
+ * and default bindings so notification channels work out-of-the-box across all stores.
6
+ */
7
+ export class SeedOrderNotificationTriggersAndTemplates1783300000000 implements MigrationInterface {
8
+ name = 'SeedOrderNotificationTriggersAndTemplates1783300000000';
9
+
10
+ public async up(queryRunner: QueryRunner): Promise<void> {
11
+ const hasTriggersTable = await queryRunner.hasTable('order_notification_triggers');
12
+ if (!hasTriggersTable) return;
13
+
14
+ // 1. Seed or update all 10 order notification triggers
15
+ await queryRunner.query(`
16
+ INSERT INTO "order_notification_triggers" ("triggerKey", "label", "description", "category", "sortOrder")
17
+ VALUES
18
+ ('order_placed', 'Order placed', 'Fires when a new order is created (storefront checkout or admin).', 'order', 1),
19
+ ('order_pending', 'Order pending', 'Fires when an order is in pending status (awaiting payment or review).', 'order', 2),
20
+ ('order_assigned', 'Order assigned (Customer)', 'Fires when a teammate is assigned to the order (notifies customer with assignee details and scheduled time slot).', 'order', 3),
21
+ ('order_assigned_assignee', 'Task assigned (Assignee)', 'Fires when a task is assigned to a teammate (notifies assignee with task description and customer details).', 'order', 4),
22
+ ('order_cancelled', 'Order cancelled', 'Fires when an order is cancelled (includes refund amount when applicable).', 'order', 5),
23
+ ('order_processing', 'Order processing', 'Fires when an order status changes to processing.', 'order', 6),
24
+ ('payment_success', 'Payment success', 'Fires when order is placed and payment status is paid.', 'order', 7),
25
+ ('order_completed', 'Order completed', 'Fires when an order status changes to completed / fulfilled.', 'order', 8),
26
+ ('payment_failed', 'Payment failed', 'Fires when payment status is pending, unpaid, or failed, or when order is cancelled without payment.', 'order', 9),
27
+ ('payment_refund_initiated', 'Payment refund initiated', 'Fires when order is cancelled and its payment status is paid (refund initiated).', 'order', 10)
28
+ ON CONFLICT ("triggerKey") DO UPDATE SET
29
+ "label" = EXCLUDED."label",
30
+ "description" = EXCLUDED."description",
31
+ "category" = EXCLUDED."category",
32
+ "sortOrder" = EXCLUDED."sortOrder",
33
+ "updatedAt" = now();
34
+ `);
35
+
36
+ // 2. Seed starter message templates and bindings if tables exist
37
+ const hasTemplates = await queryRunner.hasTable('message_templates');
38
+ const hasBindings = await queryRunner.hasTable('order_notification_bindings');
39
+ if (hasTemplates && hasBindings) {
40
+ const templates = [
41
+ {
42
+ triggerKey: 'order_placed',
43
+ templateKey: 'order_notification_customer_order_placed',
44
+ name: 'Order placed email',
45
+ subject: 'Your order {{orderNumber}} is confirmed',
46
+ body: `Hi {{customerName}},\n\nThank you for your order! Your order {{orderNumber}} for {{total}} {{currency}} has been confirmed.\n\nOrder Details:\n{{orderDetails}}\n\nYour Tax Invoice PDF is attached to this email for your records.\n\nThank you!`,
47
+ },
48
+ {
49
+ triggerKey: 'order_pending',
50
+ templateKey: 'order_notification_customer_order_pending',
51
+ name: 'Order pending email',
52
+ subject: 'Your order {{orderNumber}} is Pending',
53
+ body: `Hi {{customerName}},\n\nYour order {{orderNumber}} for {{total}} {{currency}} is currently pending.\n\nOrder Details:\n{{orderDetails}}\n\nWe will update you as soon as your order status changes.\n\nThank you!`,
54
+ },
55
+ {
56
+ triggerKey: 'order_assigned',
57
+ templateKey: 'order_notification_customer_order_assigned',
58
+ name: 'Order assigned email (Customer)',
59
+ subject: 'Your service expert has been assigned for order {{orderNumber}}',
60
+ body: `Hi {{customerName}},\n\nA service expert has been assigned to your order {{orderNumber}}.\n\nAssignee Details:\n• Name: {{assigneeName}}\n• Phone: {{assigneePhone}}\n\nYour expert will reach you by your scheduled time slot:\n• Date: {{serviceDate}}\n• Slot: {{timeSlot}}\n\nOrder Details:\n{{orderDetails}}\n\nThank you!`,
61
+ },
62
+ {
63
+ triggerKey: 'order_assigned_assignee',
64
+ templateKey: 'order_notification_assignee_order_assigned',
65
+ name: 'Task assigned email (Assignee)',
66
+ subject: 'New task assigned: Order {{orderNumber}}',
67
+ body: `Hi {{assigneeName}},\n\nA new task has been assigned to you for order {{orderNumber}}.\n\nTask Details:\n{{taskDescription}}\n\nCustomer Details:\n• Name: {{customerName}}\n• Phone: {{customerPhone}}\n• Address: {{customerAddress}}\n\nSchedule:\n• Date: {{serviceDate}}\n• Slot: {{timeSlot}}\n\nPlease arrive promptly within the scheduled time slot.`,
68
+ },
69
+ {
70
+ triggerKey: 'order_cancelled',
71
+ templateKey: 'order_notification_customer_order_cancelled',
72
+ name: 'Order cancelled email',
73
+ subject: 'Your order {{orderNumber}} has been cancelled',
74
+ body: `Hi {{customerName}},\n\nYour order {{orderNumber}} for {{total}} {{currency}} has been cancelled.\n\nIf a refund is due, you will receive {{refundAmount}} {{currency}} back to your original payment method.\n\nIf you have any questions, please contact us.\n\nThank you!`,
75
+ },
76
+ {
77
+ triggerKey: 'order_processing',
78
+ templateKey: 'order_notification_customer_order_processing',
79
+ name: 'Order processing email',
80
+ subject: 'Your order {{orderNumber}} is now Processing',
81
+ body: `Hi {{customerName}},\n\nYour order {{orderNumber}} for {{total}} {{currency}} is currently being processed.\n\nOrder Details:\n{{orderDetails}}\n\nWe will notify you once it is completed.\n\nThank you!`,
82
+ },
83
+ {
84
+ triggerKey: 'payment_success',
85
+ templateKey: 'order_notification_customer_payment_success',
86
+ name: 'Payment success email',
87
+ subject: 'Payment Successful for Order {{orderNumber}}',
88
+ body: `Hi {{customerName}},\n\nWe have received your payment for order {{orderNumber}} of {{total}} {{currency}}.\n\nOrder Details:\n{{orderDetails}}\n\nThank you!`,
89
+ },
90
+ {
91
+ triggerKey: 'order_completed',
92
+ templateKey: 'order_notification_customer_order_completed',
93
+ name: 'Order completed email',
94
+ subject: 'Your order {{orderNumber}} is Completed',
95
+ body: `Hi {{customerName}},\n\nYour order {{orderNumber}} for {{total}} {{currency}} has been completed.\n\nOrder Details:\n{{orderDetails}}\n\nThank you for choosing us!`,
96
+ },
97
+ {
98
+ triggerKey: 'payment_failed',
99
+ templateKey: 'order_notification_customer_payment_failed',
100
+ name: 'Payment failed email',
101
+ subject: 'Payment Failed for Order {{orderNumber}}',
102
+ body: `Hi {{customerName}},\n\nYour payment for order {{orderNumber}} of {{total}} {{currency}} could not be completed or remains unpaid.\n\nIf you were charged, please contact us with your order number {{orderNumber}}.\n\nThank you!`,
103
+ },
104
+ {
105
+ triggerKey: 'payment_refund_initiated',
106
+ templateKey: 'order_notification_customer_payment_refund_initiated',
107
+ name: 'Payment refund initiated email',
108
+ subject: 'Refund Initiated for Order {{orderNumber}}',
109
+ body: `Hi {{customerName}},\n\nYour order {{orderNumber}} has been cancelled and a refund of {{refundAmount}} {{currency}} has been initiated.\n\nThe amount will be credited back to your original payment method.\n\nThank you!`,
110
+ },
111
+ ];
112
+
113
+ for (const t of templates) {
114
+ const insertedRows = await queryRunner.query(
115
+ `INSERT INTO "message_templates" ("channel", "template_key", "name", "subject", "body", "enabled")
116
+ VALUES ('email', $1, $2, $3, $4, true)
117
+ ON CONFLICT ("channel", "template_key") WHERE "deleted" = false
118
+ DO UPDATE SET "name" = EXCLUDED."name", "subject" = EXCLUDED."subject", "body" = EXCLUDED."body", "updatedAt" = now()
119
+ RETURNING "id"`,
120
+ [t.templateKey, t.name, t.subject, t.body]
121
+ );
122
+ const templateId = insertedRows?.[0]?.id;
123
+
124
+ if (templateId) {
125
+ await queryRunner.query(
126
+ `INSERT INTO "order_notification_bindings" ("triggerKey", "channel", "type", "messageTemplateId", "enabled")
127
+ VALUES ($1, 'email', 'customers', $2, true)
128
+ ON CONFLICT ("triggerKey", "channel", "type")
129
+ DO UPDATE SET "messageTemplateId" = EXCLUDED."messageTemplateId"
130
+ WHERE "order_notification_bindings"."messageTemplateId" IS NULL`,
131
+ [t.triggerKey, templateId]
132
+ );
133
+ }
134
+ }
135
+ }
136
+ }
137
+
138
+ public async down(queryRunner: QueryRunner): Promise<void> {
139
+ const hasTriggersTable = await queryRunner.hasTable('order_notification_triggers');
140
+ if (hasTriggersTable) {
141
+ await queryRunner.query(`
142
+ DELETE FROM "order_notification_triggers"
143
+ WHERE "triggerKey" IN ('order_assigned', 'order_assigned_assignee');
144
+ `);
145
+ }
146
+
147
+ const hasTemplates = await queryRunner.hasTable('message_templates');
148
+ if (hasTemplates) {
149
+ await queryRunner.query(`
150
+ DELETE FROM "message_templates"
151
+ WHERE "template_key" LIKE 'order_notification_%';
152
+ `);
153
+ }
154
+ }
155
+ }
@@ -1,11 +1,11 @@
1
- import { fireOrderNotificationTrigger } from './chunk-6XAVZE4I.js';
1
+ import { fireOrderNotificationTrigger } from './chunk-DXERXWBR.js';
2
2
  import { verifyAndConsumeOtpChallenge, generateNumericOtp, createOtpChallenge, queueSms } from './chunk-OVTOP42W.js';
3
3
  import { queueWhatsApp } from './chunk-GWDI752Q.js';
4
4
  import './chunk-AYWDQFJZ.js';
5
- import { queueEmail } from './chunk-YW7EF7K7.js';
6
- import './chunk-HMLVPIJR.js';
5
+ import { queueEmail } from './chunk-TU23GJPJ.js';
6
+ import './chunk-OPJEV44S.js';
7
7
  import './chunk-JC6DLWTE.js';
8
- import './chunk-NMYGQWHV.js';
8
+ import './chunk-YRCKEGL2.js';
9
9
  import { __name } from './chunk-SHUYVCID.js';
10
10
 
11
11
  // src/api/order-completion-otp-handlers.ts