@infuro/cms-core 1.0.63 → 1.0.65

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 (50) hide show
  1. package/dist/admin.cjs +183 -65
  2. package/dist/admin.js +183 -65
  3. package/dist/api.cjs +40 -40
  4. package/dist/api.d.cts +2 -0
  5. package/dist/api.d.ts +2 -0
  6. package/dist/api.js +8 -8
  7. package/dist/{chunk-KAOHOHCA.js → chunk-6YOQ7G5O.js} +92 -51
  8. package/dist/{chunk-BWOITUNI.js → chunk-ACBN6UWZ.js} +320 -81
  9. package/dist/chunk-BXAKL2TF.cjs +84 -0
  10. package/dist/{chunk-7L556RGL.cjs → chunk-GLD263KW.cjs} +3 -3
  11. package/dist/{chunk-EWXG4E74.cjs → chunk-NIRYYJIJ.cjs} +330 -91
  12. package/dist/{chunk-MWEK7N3F.js → chunk-OPJEV44S.js} +2 -2
  13. package/dist/{chunk-DTUL3Q5L.js → chunk-RDEVZMO5.js} +36 -20
  14. package/dist/{chunk-77YWLP4X.js → chunk-SANKKGB3.js} +68 -32
  15. package/dist/chunk-THL5JDWJ.cjs +101 -0
  16. package/dist/{chunk-RXTUSF3R.js → chunk-TU23GJPJ.js} +2 -2
  17. package/dist/{chunk-JLDHK2QE.cjs → chunk-TZEMLHSP.cjs} +20 -14
  18. package/dist/{chunk-RHYVNRYG.cjs → chunk-V6EYAC7X.cjs} +38 -22
  19. package/dist/{chunk-YVP4NQII.cjs → chunk-VM6OVUUM.cjs} +93 -52
  20. package/dist/{chunk-MXABMVF7.cjs → chunk-XFDIIVZB.cjs} +4 -4
  21. package/dist/chunk-XJNNOSJR.js +98 -0
  22. package/dist/chunk-YEAXE4U2.js +77 -0
  23. package/dist/{chunk-CJEOH6QC.cjs → chunk-YHEITFHR.cjs} +112 -76
  24. package/dist/{chunk-3VZAAQUV.js → chunk-YRCKEGL2.js} +20 -14
  25. package/dist/{email-queue-VTYL2KFA.cjs → email-queue-4OY45JIU.cjs} +7 -7
  26. package/dist/{email-queue-YPRSVG56.js → email-queue-HGXB2FIS.js} +3 -3
  27. package/dist/{email-service-ATCPJFWG.cjs → email-service-5O24BSFR.cjs} +7 -7
  28. package/dist/{email-service-DPKVQOKP.js → email-service-ADDF52PJ.js} +2 -2
  29. package/dist/{emit-order-notification-trigger-WI4HGMKH.cjs → emit-order-notification-trigger-DR74TQXN.cjs} +4 -4
  30. package/dist/{emit-order-notification-trigger-XVG2B5ZF.js → emit-order-notification-trigger-UCKJHDQK.js} +2 -2
  31. package/dist/{erp-order-invoice-3UGWLICU.js → erp-order-invoice-H6HCJ7YS.js} +2 -2
  32. package/dist/{erp-order-invoice-KJYJNWMG.cjs → erp-order-invoice-YUSPZ7CE.cjs} +6 -6
  33. package/dist/index.cjs +279 -265
  34. package/dist/index.d.cts +46 -22
  35. package/dist/index.d.ts +46 -22
  36. package/dist/index.js +43 -29
  37. package/dist/migrations/1783000000000-AddOrderPendingProcessingCompletedTriggers.ts +15 -39
  38. package/dist/migrations/1783300000000-SeedOrderNotificationTriggersAndTemplates.ts +155 -0
  39. package/dist/{order-completion-otp-handlers-WGM7HWG4.js → order-completion-otp-handlers-CH22ZRAI.js} +5 -5
  40. package/dist/{order-completion-otp-handlers-IMMQGHDR.cjs → order-completion-otp-handlers-RW5RSXH3.cjs} +7 -7
  41. package/dist/{order-notification-dispatcher-JKFQJYGG.js → order-notification-dispatcher-3TXUAJ7L.js} +6 -6
  42. package/dist/{order-notification-dispatcher-5TUFCDU7.cjs → order-notification-dispatcher-Y7NZAALH.cjs} +11 -11
  43. package/dist/{pg-boss-service-L6MTF4EQ.cjs → pg-boss-service-BDGOKM2T.cjs} +3 -3
  44. package/dist/pg-boss-service-WCBJD4JB.js +2 -0
  45. package/package.json +1 -1
  46. package/dist/chunk-AYWDQFJZ.js +0 -27
  47. package/dist/chunk-GO7PPYNU.js +0 -76
  48. package/dist/chunk-UEE4PTTB.cjs +0 -30
  49. package/dist/chunk-XQ3QUHWR.cjs +0 -83
  50. package/dist/pg-boss-service-4XF2TQ2E.js +0 -2
@@ -1,5 +1,5 @@
1
1
  import { isErpIntegrationEnabled } from './chunk-JC6DLWTE.js';
2
- import { mergeEmailLayoutCompanyDetails, getCompanyDetailsFromSettings } from './chunk-3VZAAQUV.js';
2
+ import { mergeEmailLayoutCompanyDetails, getCompanyDetailsFromSettings } from './chunk-YRCKEGL2.js';
3
3
  import { __name } from './chunk-SHUYVCID.js';
4
4
  import { rgb, PDFDocument, StandardFonts } from 'pdf-lib';
5
5
 
@@ -664,7 +664,7 @@ async function buildLocalInvoicePdfForOrder(ds, entityMap, orderId) {
664
664
  loadSettingsGroup(ds, entityMap, "branding"),
665
665
  loadSettingsGroup(ds, entityMap, "email")
666
666
  ]);
667
- const companyDetails = mergeEmailLayoutCompanyDetails(branding, email);
667
+ const companyDetails = mergeEmailLayoutCompanyDetails(branding, email, store);
668
668
  const fromBranding = getCompanyDetailsFromSettings(branding);
669
669
  const rawLogo = store.invoiceLogoUrl || store.companyLogo || store.logo || companyDetails.logoUrl || fromBranding.logoUrl || null;
670
670
  const logoUrl = resolveInvoiceAssetUrl(rawLogo);
@@ -1,16 +1,10 @@
1
- import { notificationTriggerEmitter } from './chunk-AYWDQFJZ.js';
1
+ import { notifyLog, notificationTriggerEmitter, maskNotifyPhone } from './chunk-YEAXE4U2.js';
2
2
  import { __name } from './chunk-SHUYVCID.js';
3
3
 
4
4
  // src/lib/emit-order-notification-trigger.ts
5
- function maskPhone(raw) {
6
- const digits = String(raw ?? "").replace(/\D/g, "");
7
- if (digits.length <= 4) return "(none)";
8
- return `***${digits.slice(-4)}`;
9
- }
10
- __name(maskPhone, "maskPhone");
11
5
  async function emitOrderNotificationTrigger(triggerKey, orderId, deps, extra) {
12
6
  if (!deps.entityMap.orders) {
13
- console.warn("[notification-triggers] skip emit: orders entity missing from entityMap", {
7
+ notifyLog.skip("TRIGGER", "orders entity missing from entityMap", {
14
8
  triggerKey,
15
9
  orderId
16
10
  });
@@ -18,7 +12,10 @@ async function emitOrderNotificationTrigger(triggerKey, orderId, deps, extra) {
18
12
  }
19
13
  const listenerCount = notificationTriggerEmitter.listenerCount("__any__");
20
14
  if (listenerCount === 0) {
21
- console.warn("[notification-triggers] no WhatsApp dispatcher listener \u2014 ensure createCmsApiHandler passes getCms (initWhatsappTriggerDispatcher)");
15
+ notifyLog.skip("TRIGGER", "no dispatcher listener \u2014 will try direct dispatch (pass getCms to createCmsApiHandler)", {
16
+ triggerKey,
17
+ orderId
18
+ });
22
19
  }
23
20
  const orderRepo = deps.dataSource.getRepository(deps.entityMap.orders);
24
21
  const fullOrder = await orderRepo.findOne({
@@ -31,7 +28,7 @@ async function emitOrderNotificationTrigger(triggerKey, orderId, deps, extra) {
31
28
  ]
32
29
  });
33
30
  if (!fullOrder) {
34
- console.warn("[notification-triggers] skip emit: order not found", {
31
+ notifyLog.skip("TRIGGER", "order not found", {
35
32
  triggerKey,
36
33
  orderId
37
34
  });
@@ -39,15 +36,18 @@ async function emitOrderNotificationTrigger(triggerKey, orderId, deps, extra) {
39
36
  }
40
37
  const fo = fullOrder;
41
38
  const phone = fo.contact?.phone ?? null;
42
- console.log("[notification-triggers] emit", {
39
+ notifyLog.trigger("emit", {
43
40
  triggerKey,
44
41
  orderId,
45
42
  orderNumber: fo.orderNumber ?? null,
46
- phone: maskPhone(phone),
47
- listeners: listenerCount
43
+ phone: maskNotifyPhone(phone),
44
+ listeners: listenerCount,
45
+ vendorId: fo.vendorId ?? null,
46
+ source: extra?.source ?? "api"
48
47
  });
49
48
  if (!phone?.trim()) {
50
- console.warn("[notification-triggers] order contact has no phone \u2014 WhatsApp will be skipped", {
49
+ notifyLog.skip("WHATSAPP", "order contact has no phone", {
50
+ triggerKey,
51
51
  orderId
52
52
  });
53
53
  }
@@ -89,28 +89,44 @@ async function emitOrderNotificationTrigger(triggerKey, orderId, deps, extra) {
89
89
  refundAmount: resolvedRefundAmount
90
90
  };
91
91
  if (listenerCount === 0) {
92
+ notifyLog.trigger("direct dispatch (no in-process listener)", {
93
+ triggerKey,
94
+ orderId
95
+ });
92
96
  try {
93
- const { dispatchOrderNotificationDirectly } = await import('./order-notification-dispatcher-JKFQJYGG.js');
97
+ const { dispatchOrderNotificationDirectly } = await import('./order-notification-dispatcher-3TXUAJ7L.js');
94
98
  await dispatchOrderNotificationDirectly(triggerKey, triggerPayload, deps.dataSource, deps.entityMap);
95
99
  } catch (err) {
96
- console.error("[notification-triggers] direct dispatch failed", {
100
+ notifyLog.error("TRIGGER", "direct dispatch failed", {
97
101
  triggerKey,
98
102
  orderId,
99
- err
103
+ error: err instanceof Error ? err.message : String(err),
104
+ stack: err instanceof Error ? err.stack : void 0
100
105
  });
101
106
  }
102
107
  } else {
108
+ notifyLog.trigger("emit to dispatcher listener", {
109
+ triggerKey,
110
+ orderId,
111
+ listeners: listenerCount
112
+ });
103
113
  notificationTriggerEmitter.emitTrigger(triggerKey, triggerPayload);
104
114
  }
105
115
  }
106
116
  __name(emitOrderNotificationTrigger, "emitOrderNotificationTrigger");
107
117
  function fireOrderNotificationTrigger(triggerKey, orderId, deps, extra) {
108
- console.log("[notification-triggers] fire", {
118
+ notifyLog.trigger("FIRE", {
109
119
  triggerKey,
110
- orderId
120
+ orderId,
121
+ source: extra?.source ?? "api"
111
122
  });
112
123
  void emitOrderNotificationTrigger(triggerKey, orderId, deps, extra).catch((err) => {
113
- console.error("[notification-triggers]", triggerKey, orderId, err);
124
+ notifyLog.error("TRIGGER", "fire failed", {
125
+ triggerKey,
126
+ orderId,
127
+ error: err instanceof Error ? err.message : String(err),
128
+ stack: err instanceof Error ? err.stack : void 0
129
+ });
114
130
  });
115
131
  }
116
132
  __name(fireOrderNotificationTrigger, "fireOrderNotificationTrigger");
@@ -1,13 +1,13 @@
1
1
  import { normalizePhoneE164, generateNumericOtp, createOtpChallenge, queueSms, verifyAndConsumeOtpChallenge } from './chunk-OVTOP42W.js';
2
- import { JOB_RUNNER_QUEUE } from './chunk-GO7PPYNU.js';
2
+ import { JOB_RUNNER_QUEUE } from './chunk-XJNNOSJR.js';
3
3
  import { validateInventoryForConfirmedOrderLines, orderStatusHoldsStock, reconcileOrderInventoryBetweenSnapshots, orderInventorySnapshotFromRow, validateInventoryForOrderBecomingConfirmed } from './chunk-3K5AIEIZ.js';
4
- import { resolveChatEmailToolSettings, CHAT_EMAIL_LOG, detectChatLeadIntent, parseIntentRecipientEmails, sendChatLeadEmail, buildTranscriptForLeadEmail, buildChatbotSystemPromptWithEmailTool, validateFcmCredentials, sendFcmPushNotification, parseEmailRecipientsFromConfig, isWhatsAppPluginEnabled, WhatsAppService, emailPlugin, initWhatsappTriggerDispatcher } from './chunk-BWOITUNI.js';
4
+ import { resolveChatEmailToolSettings, CHAT_EMAIL_LOG, detectChatLeadIntent, parseIntentRecipientEmails, sendChatLeadEmail, buildTranscriptForLeadEmail, buildChatbotSystemPromptWithEmailTool, validateFcmCredentials, sendFcmPushNotification, parseEmailRecipientsFromConfig, isWhatsAppPluginEnabled, WhatsAppService, emailPlugin, initWhatsappTriggerDispatcher } from './chunk-ACBN6UWZ.js';
5
5
  import { registerWhatsAppQueueProcessor } from './chunk-GWDI752Q.js';
6
6
  import { inviteStatusForActivation } from './chunk-JXF23MPG.js';
7
- import { queueEmail, queueVendorOnboardEmails, registerEmailQueueProcessor } from './chunk-RXTUSF3R.js';
8
- import { unwrapErpReadData, mapErpPayloadToFulfillment, extractChildOrderRefsFromSalePayload, mapErpPayloadToInvoiceNumber, streamOrderInvoicePdf } from './chunk-MWEK7N3F.js';
7
+ import { queueEmail, queueVendorOnboardEmails, registerEmailQueueProcessor } from './chunk-TU23GJPJ.js';
8
+ import { unwrapErpReadData, mapErpPayloadToFulfillment, extractChildOrderRefsFromSalePayload, mapErpPayloadToInvoiceNumber, streamOrderInvoicePdf } from './chunk-OPJEV44S.js';
9
9
  import { isErpIntegrationEnabled } from './chunk-JC6DLWTE.js';
10
- import { mergeEmailLayoutCompanyDetails } from './chunk-3VZAAQUV.js';
10
+ import { mergeEmailLayoutCompanyDetails } from './chunk-YRCKEGL2.js';
11
11
  import { getSmsTemplateDefault, SMS_MESSAGE_TEMPLATE_DEFAULTS } from './chunk-MQBT33IV.js';
12
12
  import { EVENT_ORDER_MESSAGE_TEMPLATE_DEFAULTS, EVENT_ORDER_TEMPLATE_KEY, EVENT_ORDER_TEMPLATE_VARIABLES } from './chunk-AYERBA7I.js';
13
13
  import { ensureCustomerRecord, linkUnclaimedContactToUser, ensureCustomerForUser, canManageRoles, sessionHasEntityAccess } from './chunk-NR44CK5E.js';
@@ -5229,7 +5229,7 @@ function createCrudHandler(dataSource, entityMap, options) {
5229
5229
  const orderIdForNotify = created.id;
5230
5230
  const finalCreatedStatus = String(created.status ?? createdStatus ?? "pending").toLowerCase();
5231
5231
  const initialPayStatus = String(persistBody.paymentStatus ?? body.paymentStatus ?? "unpaid").toLowerCase();
5232
- void import('./emit-order-notification-trigger-XVG2B5ZF.js').then(({ fireOrderNotificationTrigger }) => {
5232
+ void import('./emit-order-notification-trigger-UCKJHDQK.js').then(({ fireOrderNotificationTrigger }) => {
5233
5233
  if (finalCreatedStatus === "pending") {
5234
5234
  if (initialPayStatus === "failed") {
5235
5235
  fireOrderNotificationTrigger("payment_failed", orderIdForNotify, {
@@ -5885,6 +5885,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
5885
5885
  const repo = dataSource.getRepository(entity);
5886
5886
  const numericId = Number(id);
5887
5887
  let orderInvPrev = null;
5888
+ let existingOrderRow = null;
5888
5889
  if (resource === "blogs" && rawBody && typeof rawBody === "object" && entityMap.categories && entityMap.seos && entityMap.tags) {
5889
5890
  const existing = await repo.findOne({
5890
5891
  where: {
@@ -6021,6 +6022,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6021
6022
  status: 404
6022
6023
  });
6023
6024
  if (resource === "orders") {
6025
+ existingOrderRow = cur;
6024
6026
  orderInvPrev = orderInventorySnapshotFromRow(cur);
6025
6027
  }
6026
6028
  }
@@ -6052,16 +6054,13 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6052
6054
  if (Number.isFinite(aId) && aId > 0) {
6053
6055
  scalarUpdate.assignedUserId = aId;
6054
6056
  scalarUpdate.assignedAt = /* @__PURE__ */ new Date();
6055
- if (!scalarUpdate.status && (orderInvPrev?.status === "confirmed" || orderInvPrev?.status === "pending")) {
6056
- scalarUpdate.status = "processing";
6057
- }
6058
6057
  } else {
6059
6058
  scalarUpdate.assignedUserId = null;
6060
6059
  scalarUpdate.assignedAt = null;
6061
6060
  }
6062
6061
  }
6063
6062
  if (scalarUpdate.status === "processing") {
6064
- const effectiveAssignee = scalarUpdate.assignedUserId !== void 0 ? scalarUpdate.assignedUserId : orderInvPrev?.assignedUserId;
6063
+ const effectiveAssignee = scalarUpdate.assignedUserId !== void 0 ? scalarUpdate.assignedUserId : existingOrderRow?.assignedUserId ?? null;
6065
6064
  if (!effectiveAssignee) {
6066
6065
  return json({
6067
6066
  error: "Cannot start processing without assigning a teammate. Please assign a teammate first."
@@ -6308,12 +6307,26 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6308
6307
  }
6309
6308
  const statusUpdated = Boolean(scalarUpdate.status || rawBody.status);
6310
6309
  const paymentUpdated = Boolean(rawBody && typeof rawBody === "object" && rawBody.paymentStatus != null);
6310
+ const assigneeUpdated = Boolean(rawBody && typeof rawBody === "object" && "assignedUserId" in rawBody && rawBody.assignedUserId !== void 0 && Number(rawBody.assignedUserId) > 0 && Number(rawBody.assignedUserId) !== Number(existingOrderRow?.assignedUserId));
6311
+ if (assigneeUpdated) {
6312
+ void import('./emit-order-notification-trigger-UCKJHDQK.js').then(({ fireOrderNotificationTrigger }) => {
6313
+ fireOrderNotificationTrigger("order_assigned", updatedOrder.id, {
6314
+ dataSource,
6315
+ entityMap
6316
+ });
6317
+ fireOrderNotificationTrigger("order_assigned_assignee", updatedOrder.id, {
6318
+ dataSource,
6319
+ entityMap
6320
+ });
6321
+ }).catch(() => {
6322
+ });
6323
+ }
6311
6324
  if (statusUpdated || paymentUpdated) {
6312
6325
  const newStatus = scalarUpdate.status ? String(scalarUpdate.status).toLowerCase() : rawBody.status ? String(rawBody.status).toLowerCase() : String(updatedOrder.status || "pending").toLowerCase();
6313
6326
  const payments = Array.isArray(updatedOrder.payments) ? updatedOrder.payments : [];
6314
6327
  const bodyPayStatus = rawBody && typeof rawBody === "object" && rawBody.paymentStatus != null ? String(rawBody.paymentStatus).toLowerCase() : null;
6315
6328
  const curPayStatus = bodyPayStatus || String(payments[0]?.status || "unpaid").toLowerCase();
6316
- void import('./emit-order-notification-trigger-XVG2B5ZF.js').then(({ fireOrderNotificationTrigger }) => {
6329
+ void import('./emit-order-notification-trigger-UCKJHDQK.js').then(({ fireOrderNotificationTrigger }) => {
6317
6330
  if (newStatus === "pending") {
6318
6331
  if (curPayStatus === "failed") {
6319
6332
  fireOrderNotificationTrigger("payment_failed", updatedOrder.id, {
@@ -6868,16 +6881,13 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6868
6881
  if (Number.isFinite(aId) && aId > 0) {
6869
6882
  updatePayload.assignedUserId = aId;
6870
6883
  updatePayload.assignedAt = /* @__PURE__ */ new Date();
6871
- if (!updatePayload.status && (orderInvPrev.status === "confirmed" || orderInvPrev.status === "pending")) {
6872
- updatePayload.status = "processing";
6873
- }
6874
6884
  } else {
6875
6885
  updatePayload.assignedUserId = null;
6876
6886
  updatePayload.assignedAt = null;
6877
6887
  }
6878
6888
  }
6879
6889
  if (updatePayload.status === "processing") {
6880
- const effectiveAssignee = updatePayload.assignedUserId !== void 0 ? updatePayload.assignedUserId : orderInvPrev?.assignedUserId;
6890
+ const effectiveAssignee = updatePayload.assignedUserId !== void 0 ? updatePayload.assignedUserId : existingOrderRow?.assignedUserId ?? null;
6881
6891
  if (!effectiveAssignee) {
6882
6892
  return json({
6883
6893
  error: "Cannot start processing without assigning a teammate. Please assign a teammate first."
@@ -6970,7 +6980,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6970
6980
  });
6971
6981
  }
6972
6982
  if (ordStatus === "pending" || ordStatus === "confirmed") {
6973
- void import('./emit-order-notification-trigger-XVG2B5ZF.js').then(({ fireOrderNotificationTrigger }) => {
6983
+ void import('./emit-order-notification-trigger-UCKJHDQK.js').then(({ fireOrderNotificationTrigger }) => {
6974
6984
  fireOrderNotificationTrigger("order_placed", pOrder, {
6975
6985
  dataSource,
6976
6986
  entityMap
@@ -6984,7 +6994,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6984
6994
  }
6985
6995
  }
6986
6996
  } else if (newPayStatus === "failed") {
6987
- void import('./emit-order-notification-trigger-XVG2B5ZF.js').then(({ fireOrderNotificationTrigger }) => {
6997
+ void import('./emit-order-notification-trigger-UCKJHDQK.js').then(({ fireOrderNotificationTrigger }) => {
6988
6998
  fireOrderNotificationTrigger("payment_failed", pOrder, {
6989
6999
  dataSource,
6990
7000
  entityMap
@@ -6992,7 +7002,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6992
7002
  }).catch(() => {
6993
7003
  });
6994
7004
  } else if (newPayStatus === "refunded") {
6995
- void import('./emit-order-notification-trigger-XVG2B5ZF.js').then(({ fireOrderNotificationTrigger }) => {
7005
+ void import('./emit-order-notification-trigger-UCKJHDQK.js').then(({ fireOrderNotificationTrigger }) => {
6996
7006
  fireOrderNotificationTrigger("payment_refund_initiated", pOrder, {
6997
7007
  dataSource,
6998
7008
  entityMap
@@ -7117,12 +7127,26 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
7117
7127
  const ord = updated;
7118
7128
  const statusUpdated = Boolean(updatePayload.status);
7119
7129
  const paymentUpdated = Boolean(rawBody && typeof rawBody === "object" && rawBody.paymentStatus != null);
7130
+ const assigneeUpdated = Boolean(rawBody && typeof rawBody === "object" && "assignedUserId" in rawBody && rawBody.assignedUserId !== void 0 && Number(rawBody.assignedUserId) > 0 && Number(rawBody.assignedUserId) !== Number(existingOrderRow?.assignedUserId));
7131
+ if (assigneeUpdated) {
7132
+ void import('./emit-order-notification-trigger-UCKJHDQK.js').then(({ fireOrderNotificationTrigger }) => {
7133
+ fireOrderNotificationTrigger("order_assigned", ord.id, {
7134
+ dataSource,
7135
+ entityMap
7136
+ });
7137
+ fireOrderNotificationTrigger("order_assigned_assignee", ord.id, {
7138
+ dataSource,
7139
+ entityMap
7140
+ });
7141
+ }).catch(() => {
7142
+ });
7143
+ }
7120
7144
  if (statusUpdated || paymentUpdated) {
7121
7145
  const newStatus = updatePayload.status ? String(updatePayload.status).toLowerCase() : String(ord.status || "pending").toLowerCase();
7122
7146
  const payments = Array.isArray(ord.payments) ? ord.payments : [];
7123
7147
  const bodyPayStatus = rawBody && typeof rawBody === "object" && rawBody.paymentStatus != null ? String(rawBody.paymentStatus).toLowerCase() : null;
7124
7148
  const curPayStatus = bodyPayStatus || String(payments[0]?.status || "unpaid").toLowerCase();
7125
- void import('./emit-order-notification-trigger-XVG2B5ZF.js').then(({ fireOrderNotificationTrigger }) => {
7149
+ void import('./emit-order-notification-trigger-UCKJHDQK.js').then(({ fireOrderNotificationTrigger }) => {
7126
7150
  if (newStatus === "pending") {
7127
7151
  if (curPayStatus === "failed") {
7128
7152
  fireOrderNotificationTrigger("payment_failed", ord.id, {
@@ -11664,7 +11688,8 @@ function createChatHandlers(config) {
11664
11688
  });
11665
11689
  const emailSettings = await loadSettingsGroupMap(dataSource, entityMap, "email");
11666
11690
  const brandingSettings = await loadSettingsGroupMap(dataSource, entityMap, "branding");
11667
- const companyDetails = mergeEmailLayoutCompanyDetails(brandingSettings, emailSettings);
11691
+ const storeSettings = await loadSettingsGroupMap(dataSource, entityMap, "store");
11692
+ const companyDetails = mergeEmailLayoutCompanyDetails(brandingSettings, emailSettings, storeSettings);
11668
11693
  const leadResult = await sendChatLeadEmail(cms, emailSettings, brandingSettings, {
11669
11694
  contactName: String(c.name ?? "").trim() || "Visitor",
11670
11695
  contactEmail: String(c.email ?? "").trim(),
@@ -13994,13 +14019,14 @@ __name(getVendorEmails, "getVendorEmails");
13994
14019
  async function sendVendorOnboardEmails(input, deps) {
13995
14020
  let ownerEmailSent = false;
13996
14021
  try {
13997
- const [branding, emailSettings, superAdminEmails, vendorEmailSet] = await Promise.all([
14022
+ const [branding, emailSettings, storeSettings, superAdminEmails, vendorEmailSet] = await Promise.all([
13998
14023
  getSettingsGroup(deps, "branding"),
13999
14024
  getSettingsGroup(deps, "email"),
14025
+ getSettingsGroup(deps, "store"),
14000
14026
  getSuperAdminEmails(deps),
14001
14027
  getVendorEmails(deps)
14002
14028
  ]);
14003
- const companyDetails = mergeEmailLayoutCompanyDetails(branding, emailSettings);
14029
+ const companyDetails = mergeEmailLayoutCompanyDetails(branding, emailSettings, storeSettings);
14004
14030
  const configuredNotify = parseEmailRecipientsFromConfig(emailSettings.salesTeamEmails ?? emailSettings.salesTeamEmail);
14005
14031
  const ownerEmail = input.ownerEmail?.trim() || "";
14006
14032
  const ownerEmailLower = ownerEmail.toLowerCase();
@@ -27459,7 +27485,7 @@ async function queueJobScheduleNow(cms, scheduleId) {
27459
27485
  if (!boss) {
27460
27486
  throw new Error("pg-boss is not configured (DATABASE_URL required)");
27461
27487
  }
27462
- const { JOB_RUNNER_QUEUE: JOB_RUNNER_QUEUE2 } = await import('./pg-boss-service-4XF2TQ2E.js');
27488
+ const { JOB_RUNNER_QUEUE: JOB_RUNNER_QUEUE2 } = await import('./pg-boss-service-WCBJD4JB.js');
27463
27489
  await boss.send(JOB_RUNNER_QUEUE2, {
27464
27490
  scheduleId,
27465
27491
  triggeredBy: "manual"
@@ -29005,7 +29031,7 @@ function createCmsApiHandler(config) {
29005
29031
  companyDetails
29006
29032
  };
29007
29033
  if (queue) {
29008
- const { queueEmail: queueEmail2 } = await import('./email-queue-YPRSVG56.js');
29034
+ const { queueEmail: queueEmail2 } = await import('./email-queue-HGXB2FIS.js');
29009
29035
  await queueEmail2(cms, {
29010
29036
  to: opts.to,
29011
29037
  templateName: "passwordReset",
@@ -30305,7 +30331,7 @@ function createCmsApiHandler(config) {
30305
30331
  const pe = await requireEntityPermissionEffective(req, "orders", "read");
30306
30332
  if (pe) return pe;
30307
30333
  const cms = await getCms();
30308
- const { streamOrderInvoicePdf: streamOrderInvoicePdf2 } = await import('./erp-order-invoice-3UGWLICU.js');
30334
+ const { streamOrderInvoicePdf: streamOrderInvoicePdf2 } = await import('./erp-order-invoice-H6HCJ7YS.js');
30309
30335
  const oid = Number(path2[1]);
30310
30336
  if (!Number.isFinite(oid)) return config.json({
30311
30337
  error: "Invalid id"
@@ -30687,7 +30713,7 @@ function createCmsApiHandler(config) {
30687
30713
  status: 400
30688
30714
  });
30689
30715
  }
30690
- const { resendOrderNotification } = await import('./order-notification-dispatcher-JKFQJYGG.js');
30716
+ const { resendOrderNotification } = await import('./order-notification-dispatcher-3TXUAJ7L.js');
30691
30717
  const result = await resendOrderNotification(triggerKey, orderId, {
30692
30718
  dataSource,
30693
30719
  entityMap,
@@ -30786,7 +30812,7 @@ function createCmsApiHandler(config) {
30786
30812
  status: "cancelled"
30787
30813
  });
30788
30814
  const fireOrderCancelledNotification = /* @__PURE__ */ __name((refundAmount) => {
30789
- void import('./emit-order-notification-trigger-XVG2B5ZF.js').then(({ fireOrderNotificationTrigger }) => {
30815
+ void import('./emit-order-notification-trigger-UCKJHDQK.js').then(({ fireOrderNotificationTrigger }) => {
30790
30816
  fireOrderNotificationTrigger("order_cancelled", orderId, {
30791
30817
  dataSource,
30792
30818
  entityMap
@@ -31031,7 +31057,7 @@ function createCmsApiHandler(config) {
31031
31057
  }, {
31032
31058
  status: 400
31033
31059
  });
31034
- const { createOrderCompletionOtpHandlers } = await import('./order-completion-otp-handlers-WGM7HWG4.js');
31060
+ const { createOrderCompletionOtpHandlers } = await import('./order-completion-otp-handlers-CH22ZRAI.js');
31035
31061
  const handlers = createOrderCompletionOtpHandlers(dataSource, entityMap, getCms);
31036
31062
  return handlers.getChannels(req, orderId);
31037
31063
  }
@@ -31046,7 +31072,7 @@ function createCmsApiHandler(config) {
31046
31072
  }, {
31047
31073
  status: 400
31048
31074
  });
31049
- const { createOrderCompletionOtpHandlers } = await import('./order-completion-otp-handlers-WGM7HWG4.js');
31075
+ const { createOrderCompletionOtpHandlers } = await import('./order-completion-otp-handlers-CH22ZRAI.js');
31050
31076
  const handlers = createOrderCompletionOtpHandlers(dataSource, entityMap, getCms);
31051
31077
  return handlers.sendOtp(req, orderId);
31052
31078
  }
@@ -31061,7 +31087,7 @@ function createCmsApiHandler(config) {
31061
31087
  }, {
31062
31088
  status: 400
31063
31089
  });
31064
- const { createOrderCompletionOtpHandlers } = await import('./order-completion-otp-handlers-WGM7HWG4.js');
31090
+ const { createOrderCompletionOtpHandlers } = await import('./order-completion-otp-handlers-CH22ZRAI.js');
31065
31091
  const handlers = createOrderCompletionOtpHandlers(dataSource, entityMap, getCms);
31066
31092
  return handlers.verifyOtp(req, orderId);
31067
31093
  }
@@ -31693,20 +31719,26 @@ function createStorefrontApiHandler(config) {
31693
31719
  const otpPepper = config.otpPepper;
31694
31720
  const defaultPhoneCc = config.defaultPhoneCountryCode;
31695
31721
  function fireOrderPlacedNotification(orderId, isPaid) {
31696
- void import('./emit-order-notification-trigger-XVG2B5ZF.js').then(({ fireOrderNotificationTrigger }) => {
31722
+ void import('./emit-order-notification-trigger-UCKJHDQK.js').then(({ fireOrderNotificationTrigger }) => {
31697
31723
  fireOrderNotificationTrigger("order_placed", orderId, {
31698
31724
  dataSource,
31699
31725
  entityMap
31726
+ }, {
31727
+ source: "storefront"
31700
31728
  });
31701
31729
  if (isPaid) {
31702
31730
  fireOrderNotificationTrigger("payment_success", orderId, {
31703
31731
  dataSource,
31704
31732
  entityMap
31733
+ }, {
31734
+ source: "storefront"
31705
31735
  });
31706
31736
  } else {
31707
31737
  fireOrderNotificationTrigger("payment_failed", orderId, {
31708
31738
  dataSource,
31709
31739
  entityMap
31740
+ }, {
31741
+ source: "storefront"
31710
31742
  });
31711
31743
  }
31712
31744
  }).catch((err) => console.error("[notification-triggers] import failed", err));
@@ -34630,14 +34662,18 @@ function createStorefrontApiHandler(config) {
34630
34662
  } catch {
34631
34663
  }
34632
34664
  try {
34633
- void import('./emit-order-notification-trigger-XVG2B5ZF.js').then(({ fireOrderNotificationTrigger }) => {
34665
+ void import('./emit-order-notification-trigger-UCKJHDQK.js').then(({ fireOrderNotificationTrigger }) => {
34634
34666
  fireOrderNotificationTrigger("order_cancelled", orderId, {
34635
34667
  dataSource,
34636
34668
  entityMap
34669
+ }, {
34670
+ source: "storefront"
34637
34671
  });
34638
34672
  fireOrderNotificationTrigger("payment_failed", orderId, {
34639
34673
  dataSource,
34640
34674
  entityMap
34675
+ }, {
34676
+ source: "storefront"
34641
34677
  });
34642
34678
  }).catch(() => {
34643
34679
  });
@@ -0,0 +1,101 @@
1
+ 'use strict';
2
+
3
+ var chunkUSNT2KNT_cjs = require('./chunk-USNT2KNT.cjs');
4
+
5
+ // src/plugins/pg-boss/pg-boss-service.ts
6
+ var JOB_RUNNER_QUEUE = "job-runner";
7
+ var PgBossService = class {
8
+ static {
9
+ chunkUSNT2KNT_cjs.__name(this, "PgBossService");
10
+ }
11
+ connectionString;
12
+ schema;
13
+ boss = null;
14
+ bossPromise = null;
15
+ started = false;
16
+ workRegistered = /* @__PURE__ */ new Set();
17
+ constructor(connectionString, schema) {
18
+ this.connectionString = connectionString;
19
+ this.schema = schema?.trim() ? schema.trim() : void 0;
20
+ }
21
+ async getBoss() {
22
+ if (this.boss) return this.boss;
23
+ if (this.bossPromise) return this.bossPromise;
24
+ this.bossPromise = (async () => {
25
+ const mod = await import('pg-boss');
26
+ const PgBossClass = mod?.PgBoss ?? mod?.default ?? mod;
27
+ const instance = new PgBossClass({
28
+ connectionString: this.connectionString,
29
+ ...this.schema ? {
30
+ schema: this.schema
31
+ } : {},
32
+ schedule: true
33
+ });
34
+ instance.on("error", (err) => {
35
+ console.error("[pg-boss]", err);
36
+ });
37
+ this.boss = instance;
38
+ return instance;
39
+ })();
40
+ return this.bossPromise;
41
+ }
42
+ async start() {
43
+ if (this.started) return;
44
+ const boss = await this.getBoss();
45
+ await boss.start();
46
+ await this.ensureQueue(JOB_RUNNER_QUEUE);
47
+ this.started = true;
48
+ }
49
+ async stop() {
50
+ if (!this.started || !this.boss) return;
51
+ await this.boss.stop({
52
+ graceful: true,
53
+ timeout: 1e4
54
+ });
55
+ this.started = false;
56
+ this.workRegistered.clear();
57
+ }
58
+ get raw() {
59
+ return this.boss;
60
+ }
61
+ async ensureQueue(name) {
62
+ const boss = await this.getBoss();
63
+ const existing = await boss.getQueue(name);
64
+ if (!existing) {
65
+ await boss.createQueue(name);
66
+ }
67
+ }
68
+ async send(queue, data) {
69
+ await this.ensureQueue(queue);
70
+ const boss = await this.getBoss();
71
+ return boss.send(queue, data, {
72
+ retryLimit: 2
73
+ });
74
+ }
75
+ async schedule(name, cron, data, options) {
76
+ await this.ensureQueue(name);
77
+ const boss = await this.getBoss();
78
+ await boss.schedule(name, cron, data, options);
79
+ }
80
+ async unschedule(name) {
81
+ try {
82
+ const boss = await this.getBoss();
83
+ await boss.unschedule(name);
84
+ } catch {
85
+ }
86
+ }
87
+ async registerWork(queue, handler) {
88
+ if (this.workRegistered.has(queue)) return;
89
+ await this.ensureQueue(queue);
90
+ const boss = await this.getBoss();
91
+ await boss.work(queue, async (jobs) => {
92
+ for (const job of jobs) {
93
+ await handler(job.data);
94
+ }
95
+ });
96
+ this.workRegistered.add(queue);
97
+ }
98
+ };
99
+
100
+ exports.JOB_RUNNER_QUEUE = JOB_RUNNER_QUEUE;
101
+ exports.PgBossService = PgBossService;
@@ -1,4 +1,4 @@
1
- import { isOrderEligibleForInvoiceEmail, resolveOrderInvoicePdfBytes } from './chunk-MWEK7N3F.js';
1
+ import { isOrderEligibleForInvoiceEmail, resolveOrderInvoicePdfBytes } from './chunk-OPJEV44S.js';
2
2
  import { __name } from './chunk-SHUYVCID.js';
3
3
 
4
4
  // src/plugins/email/email-queue.ts
@@ -131,7 +131,7 @@ async function queueEmail(cms, payload) {
131
131
  let email = cms && typeof cms.getPlugin === "function" ? cms.getPlugin("email") : void 0;
132
132
  if (!email) {
133
133
  try {
134
- const { EmailService } = await import('./email-service-DPKVQOKP.js');
134
+ const { EmailService } = await import('./email-service-ADDF52PJ.js');
135
135
  const env = typeof process !== "undefined" && process.env ? process.env : {};
136
136
  const type = String(env.SMTP_TYPE || "SMTP").toUpperCase();
137
137
  const port = env.SMTP_PORT ? parseInt(env.SMTP_PORT, 10) : void 0;
@@ -49,20 +49,25 @@ function absolutizeEmailAssetUrl(url) {
49
49
  chunkUSNT2KNT_cjs.__name(absolutizeEmailAssetUrl, "absolutizeEmailAssetUrl");
50
50
  function mergeEmailLayoutCompanyDetails(branding, emailSettings, storeSettings) {
51
51
  const fromBranding = getCompanyDetailsFromSettings(branding);
52
- const pick = /* @__PURE__ */ chunkUSNT2KNT_cjs.__name((emailVal, fallback) => {
53
- const t = emailVal?.trim();
54
- return t || fallback?.trim() || void 0;
55
- }, "pick");
56
- const storeLogo = storeSettings?.invoiceLogoUrl || storeSettings?.companyLogo || storeSettings?.logo || "";
57
- const storeName = storeSettings?.companyName || storeSettings?.storeName || "";
58
- const storeEmail = storeSettings?.companyEmail || "";
59
- const storePhone = storeSettings?.companyPhone || "";
60
- const logoUrl = absolutizeEmailAssetUrl(pick(emailSettings.logoUrl ?? emailSettings.emailLogoUrl, fromBranding.logoUrl || storeLogo));
61
- const companyName = pick(emailSettings.companyName ?? emailSettings.emailCompanyName, fromBranding.companyName || storeName);
62
- const supportEmail = pick(emailSettings.supportEmail ?? emailSettings.emailSupportEmail, fromBranding.supportEmail || storeEmail);
63
- const supportPhone = pick(emailSettings.supportPhone, storePhone || void 0);
64
- const footerDisclaimer = pick(emailSettings.footerDisclaimer, void 0);
65
- const followUsTitle = pick(emailSettings.followUsTitle, "Follow Us") || "Follow Us";
52
+ const first = /* @__PURE__ */ chunkUSNT2KNT_cjs.__name((...vals) => {
53
+ for (const v of vals) {
54
+ const t = v?.trim();
55
+ if (t) return t;
56
+ }
57
+ return void 0;
58
+ }, "first");
59
+ const storeLogo = first(storeSettings?.invoiceLogoUrl, storeSettings?.companyLogo, storeSettings?.logo);
60
+ const storeName = first(storeSettings?.companyName, storeSettings?.storeName);
61
+ const storeEmail = first(storeSettings?.companyEmail);
62
+ const storePhone = first(storeSettings?.companyPhone);
63
+ const storeAddress = first(storeSettings?.companyAddress);
64
+ const logoUrl = absolutizeEmailAssetUrl(first(storeLogo, emailSettings.logoUrl, emailSettings.emailLogoUrl, fromBranding.logoUrl));
65
+ const companyName = first(storeName, emailSettings.companyName, emailSettings.emailCompanyName, fromBranding.companyName);
66
+ const supportEmail = first(storeEmail, emailSettings.supportEmail, emailSettings.emailSupportEmail, fromBranding.supportEmail);
67
+ const supportPhone = first(storePhone, emailSettings.supportPhone);
68
+ const companyAddress = storeAddress;
69
+ const footerDisclaimer = first(emailSettings.footerDisclaimer);
70
+ const followUsTitle = first(emailSettings.followUsTitle, "Follow Us") || "Follow Us";
66
71
  const socialFromEmail = parseSocialLinksJson(emailSettings.socialLinks);
67
72
  const socialLinks = socialFromEmail?.length ? socialFromEmail : fromBranding.socialLinks;
68
73
  return {
@@ -70,6 +75,7 @@ function mergeEmailLayoutCompanyDetails(branding, emailSettings, storeSettings)
70
75
  companyName,
71
76
  supportEmail,
72
77
  supportPhone,
78
+ companyAddress,
73
79
  socialLinks,
74
80
  footerDisclaimer,
75
81
  followUsTitle