@infuro/cms-core 1.0.64 → 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 (32) hide show
  1. package/dist/admin.cjs +1 -1
  2. package/dist/admin.js +1 -1
  3. package/dist/api.cjs +36 -36
  4. package/dist/api.js +4 -4
  5. package/dist/{chunk-OJAYCNE5.js → chunk-ACBN6UWZ.js} +218 -39
  6. package/dist/chunk-BXAKL2TF.cjs +84 -0
  7. package/dist/{chunk-M25DGZ5J.cjs → chunk-NIRYYJIJ.cjs} +220 -41
  8. package/dist/{chunk-DXERXWBR.js → chunk-RDEVZMO5.js} +36 -20
  9. package/dist/{chunk-K6C3ZSBZ.js → chunk-SANKKGB3.js} +28 -18
  10. package/dist/chunk-THL5JDWJ.cjs +101 -0
  11. package/dist/{chunk-PX3BSCIG.cjs → chunk-V6EYAC7X.cjs} +38 -22
  12. package/dist/chunk-XJNNOSJR.js +98 -0
  13. package/dist/chunk-YEAXE4U2.js +77 -0
  14. package/dist/{chunk-FF45VZMM.cjs → chunk-YHEITFHR.cjs} +56 -46
  15. package/dist/{emit-order-notification-trigger-ZRRGCQGB.cjs → emit-order-notification-trigger-DR74TQXN.cjs} +4 -4
  16. package/dist/{emit-order-notification-trigger-MFCBAE7L.js → emit-order-notification-trigger-UCKJHDQK.js} +2 -2
  17. package/dist/index.cjs +224 -224
  18. package/dist/index.d.cts +8 -3
  19. package/dist/index.d.ts +8 -3
  20. package/dist/index.js +8 -8
  21. package/dist/{order-completion-otp-handlers-3W5I3LON.js → order-completion-otp-handlers-CH22ZRAI.js} +2 -2
  22. package/dist/{order-completion-otp-handlers-RF3DLNV7.cjs → order-completion-otp-handlers-RW5RSXH3.cjs} +3 -3
  23. package/dist/{order-notification-dispatcher-ID2PDEXD.js → order-notification-dispatcher-3TXUAJ7L.js} +2 -2
  24. package/dist/{order-notification-dispatcher-RNEQB3V7.cjs → order-notification-dispatcher-Y7NZAALH.cjs} +7 -7
  25. package/dist/{pg-boss-service-L6MTF4EQ.cjs → pg-boss-service-BDGOKM2T.cjs} +3 -3
  26. package/dist/pg-boss-service-WCBJD4JB.js +2 -0
  27. package/package.json +1 -1
  28. package/dist/chunk-AYWDQFJZ.js +0 -27
  29. package/dist/chunk-GO7PPYNU.js +0 -76
  30. package/dist/chunk-UEE4PTTB.cjs +0 -30
  31. package/dist/chunk-XQ3QUHWR.cjs +0 -83
  32. package/dist/pg-boss-service-4XF2TQ2E.js +0 -2
@@ -0,0 +1,84 @@
1
+ 'use strict';
2
+
3
+ var chunkUSNT2KNT_cjs = require('./chunk-USNT2KNT.cjs');
4
+ var events = require('events');
5
+
6
+ var KNOWN_NOTIFICATION_TRIGGERS = {
7
+ ORDER_PENDING: "order_pending",
8
+ ORDER_PROCESSING: "order_processing",
9
+ ORDER_COMPLETED: "order_completed",
10
+ ORDER_PLACED: "order_placed",
11
+ ORDER_CANCELLED: "order_cancelled",
12
+ PAYMENT_SUCCESS: "payment_success",
13
+ PAYMENT_FAILED: "payment_failed",
14
+ PAYMENT_REFUND_INITIATED: "payment_refund_initiated"
15
+ };
16
+ var NotificationTriggerEmitter = class NotificationTriggerEmitter2 extends events.EventEmitter {
17
+ static {
18
+ chunkUSNT2KNT_cjs.__name(this, "NotificationTriggerEmitter");
19
+ }
20
+ emitTrigger(triggerKey, payload) {
21
+ this.emit("__any__", triggerKey, payload);
22
+ }
23
+ onAnyTrigger(listener) {
24
+ this.on("__any__", listener);
25
+ }
26
+ };
27
+ var notificationTriggerEmitter = new NotificationTriggerEmitter();
28
+
29
+ // src/lib/notify-log.ts
30
+ function maskTail(raw, keep = 6) {
31
+ const s = String(raw ?? "").trim();
32
+ if (!s) return "(none)";
33
+ if (s.length <= keep) return "***";
34
+ return `***${s.slice(-keep)}`;
35
+ }
36
+ chunkUSNT2KNT_cjs.__name(maskTail, "maskTail");
37
+ function maskNotifyPhone(raw) {
38
+ const digits = String(raw ?? "").replace(/\D/g, "");
39
+ if (digits.length <= 4) return "(none)";
40
+ return `***${digits.slice(-4)}`;
41
+ }
42
+ chunkUSNT2KNT_cjs.__name(maskNotifyPhone, "maskNotifyPhone");
43
+ function maskNotifyEmail(raw) {
44
+ const e = String(raw ?? "").trim();
45
+ if (!e || !e.includes("@")) return "(none)";
46
+ const [user, domain] = e.split("@");
47
+ const u = user.length <= 2 ? "**" : `${user.slice(0, 2)}***`;
48
+ return `${u}@${domain}`;
49
+ }
50
+ chunkUSNT2KNT_cjs.__name(maskNotifyEmail, "maskNotifyEmail");
51
+ function maskNotifyToken(raw) {
52
+ return maskTail(raw, 8);
53
+ }
54
+ chunkUSNT2KNT_cjs.__name(maskNotifyToken, "maskNotifyToken");
55
+ function write(level, channel, message, data) {
56
+ const banner = `========== [NOTIFY] ${channel} | ${message} ==========`;
57
+ const payload = data ?? {};
58
+ if (level === "error") {
59
+ console.error(`
60
+ ${banner}`, payload);
61
+ } else if (level === "warn") {
62
+ console.warn(`
63
+ ${banner}`, payload);
64
+ } else {
65
+ console.info(`
66
+ ${banner}`, payload);
67
+ }
68
+ }
69
+ chunkUSNT2KNT_cjs.__name(write, "write");
70
+ var notifyLog = {
71
+ trigger: /* @__PURE__ */ chunkUSNT2KNT_cjs.__name((message, data) => write("info", "TRIGGER", message, data), "trigger"),
72
+ email: /* @__PURE__ */ chunkUSNT2KNT_cjs.__name((message, data) => write("info", "EMAIL", message, data), "email"),
73
+ whatsapp: /* @__PURE__ */ chunkUSNT2KNT_cjs.__name((message, data) => write("info", "WHATSAPP", message, data), "whatsapp"),
74
+ push: /* @__PURE__ */ chunkUSNT2KNT_cjs.__name((message, data) => write("info", "PUSH", message, data), "push"),
75
+ skip: /* @__PURE__ */ chunkUSNT2KNT_cjs.__name((channel, message, data) => write("warn", `SKIP ${channel}`, message, data), "skip"),
76
+ error: /* @__PURE__ */ chunkUSNT2KNT_cjs.__name((channel, message, data) => write("error", channel, message, data), "error")
77
+ };
78
+
79
+ exports.KNOWN_NOTIFICATION_TRIGGERS = KNOWN_NOTIFICATION_TRIGGERS;
80
+ exports.maskNotifyEmail = maskNotifyEmail;
81
+ exports.maskNotifyPhone = maskNotifyPhone;
82
+ exports.maskNotifyToken = maskNotifyToken;
83
+ exports.notificationTriggerEmitter = notificationTriggerEmitter;
84
+ exports.notifyLog = notifyLog;
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var chunkH3IVLIPR_cjs = require('./chunk-H3IVLIPR.cjs');
4
- var chunkUEE4PTTB_cjs = require('./chunk-UEE4PTTB.cjs');
4
+ var chunkBXAKL2TF_cjs = require('./chunk-BXAKL2TF.cjs');
5
5
  var chunkVM6OVUUM_cjs = require('./chunk-VM6OVUUM.cjs');
6
6
  var chunkXFDIIVZB_cjs = require('./chunk-XFDIIVZB.cjs');
7
7
  var chunkTZEMLHSP_cjs = require('./chunk-TZEMLHSP.cjs');
@@ -1422,12 +1422,6 @@ var ORDER_NOTIFICATION_DEFAULTS = {
1422
1422
 
1423
1423
  // src/lib/order-notification-dispatcher.ts
1424
1424
  var initialized = false;
1425
- function maskPhone2(raw) {
1426
- const digits = String(raw ?? "").replace(/\D/g, "");
1427
- if (digits.length <= 4) return "(none)";
1428
- return `***${digits.slice(-4)}`;
1429
- }
1430
- chunkUSNT2KNT_cjs.__name(maskPhone2, "maskPhone");
1431
1425
  async function getSettingsGroup(dataSource, entityMap, group) {
1432
1426
  if (!entityMap.configs) return {};
1433
1427
  const rows = await dataSource.getRepository(entityMap.configs).find({
@@ -1637,11 +1631,26 @@ async function sendPushNotificationForTrigger(triggerKey, orderId, audienceType,
1637
1631
  if (!template) {
1638
1632
  template = await loadBoundTemplate(triggerKey, "push", audienceType, dataSource, entityMap);
1639
1633
  }
1640
- if (!template || !template.body) return;
1634
+ if (!template || !template.body) {
1635
+ chunkBXAKL2TF_cjs.notifyLog.skip("PUSH", "no mobile/push template or empty body", {
1636
+ triggerKey,
1637
+ orderId,
1638
+ audienceType,
1639
+ targetId
1640
+ });
1641
+ return;
1642
+ }
1641
1643
  const rawTitle = template.subject?.trim() || "Order Notification";
1642
1644
  const title = chunkOOTLNH63_cjs.applyTemplateVars(rawTitle, variables);
1643
1645
  const body = chunkOOTLNH63_cjs.applyTemplateVars(template.body, variables);
1644
- if (!entityMap.user_device_tokens) return;
1646
+ if (!entityMap.user_device_tokens) {
1647
+ chunkBXAKL2TF_cjs.notifyLog.skip("PUSH", "user_device_tokens entity not registered", {
1648
+ triggerKey,
1649
+ orderId,
1650
+ audienceType
1651
+ });
1652
+ return;
1653
+ }
1645
1654
  const tokenRepo = dataSource.getRepository(entityMap.user_device_tokens);
1646
1655
  let targetTokens = [];
1647
1656
  try {
@@ -1676,19 +1685,60 @@ async function sendPushNotificationForTrigger(triggerKey, orderId, audienceType,
1676
1685
  });
1677
1686
  }
1678
1687
  } catch (err) {
1679
- console.error("[order-notifications] Error querying device tokens for push", err);
1688
+ chunkBXAKL2TF_cjs.notifyLog.error("PUSH", "device token query failed", {
1689
+ triggerKey,
1690
+ orderId,
1691
+ audienceType,
1692
+ targetId,
1693
+ error: err instanceof Error ? err.message : String(err)
1694
+ });
1680
1695
  return;
1681
1696
  }
1682
- for (const t of targetTokens) {
1683
- if (t.token?.trim()) {
1684
- await sendFcmPushNotification(dataSource, entityMap, {
1685
- token: t.token.trim(),
1686
- title,
1687
- body,
1688
- data: {
1689
- orderId: String(orderId),
1690
- triggerKey
1691
- }
1697
+ const tokens = targetTokens.map((t) => t.token?.trim()).filter(Boolean);
1698
+ chunkBXAKL2TF_cjs.notifyLog.push("sending", {
1699
+ triggerKey,
1700
+ orderId,
1701
+ audienceType,
1702
+ targetId,
1703
+ title,
1704
+ tokenCount: tokens.length,
1705
+ tokens: tokens.map((t) => chunkBXAKL2TF_cjs.maskNotifyToken(t))
1706
+ });
1707
+ if (tokens.length === 0) {
1708
+ chunkBXAKL2TF_cjs.notifyLog.skip("PUSH", "no active FCM tokens for target", {
1709
+ triggerKey,
1710
+ orderId,
1711
+ audienceType,
1712
+ targetId,
1713
+ hint: "App must POST /api/user-device-tokens after login"
1714
+ });
1715
+ return;
1716
+ }
1717
+ for (const token of tokens) {
1718
+ const res = await sendFcmPushNotification(dataSource, entityMap, {
1719
+ token,
1720
+ title,
1721
+ body,
1722
+ data: {
1723
+ orderId: String(orderId),
1724
+ triggerKey
1725
+ }
1726
+ });
1727
+ if (res.success) {
1728
+ chunkBXAKL2TF_cjs.notifyLog.push("FCM sent", {
1729
+ triggerKey,
1730
+ orderId,
1731
+ audienceType,
1732
+ token: chunkBXAKL2TF_cjs.maskNotifyToken(token),
1733
+ messageId: res.messageId ?? null
1734
+ });
1735
+ } else {
1736
+ chunkBXAKL2TF_cjs.notifyLog.error("PUSH", "FCM send failed", {
1737
+ triggerKey,
1738
+ orderId,
1739
+ audienceType,
1740
+ token: chunkBXAKL2TF_cjs.maskNotifyToken(token),
1741
+ error: res.error ?? "unknown"
1692
1742
  });
1693
1743
  }
1694
1744
  }
@@ -1832,7 +1882,15 @@ function formatBodyForEmailHtml(body) {
1832
1882
  chunkUSNT2KNT_cjs.__name(formatBodyForEmailHtml, "formatBodyForEmailHtml");
1833
1883
  async function sendEmailForTrigger(triggerKey, orderId, audienceType, variables, contactEmail, dataSource, entityMap, getCms) {
1834
1884
  const template = await loadBoundTemplate(triggerKey, "email", audienceType, dataSource, entityMap);
1835
- if (!template) return;
1885
+ if (!template) {
1886
+ chunkBXAKL2TF_cjs.notifyLog.skip("EMAIL", "no bound/default email template", {
1887
+ triggerKey,
1888
+ orderId,
1889
+ audienceType,
1890
+ to: chunkBXAKL2TF_cjs.maskNotifyEmail(contactEmail)
1891
+ });
1892
+ return;
1893
+ }
1836
1894
  const [branding, emailSettings, storeSettings] = await Promise.all([
1837
1895
  getSettingsGroup(dataSource, entityMap, "branding"),
1838
1896
  getSettingsGroup(dataSource, entityMap, "email"),
@@ -1867,22 +1925,31 @@ async function sendEmailForTrigger(triggerKey, orderId, audienceType, variables,
1867
1925
  attachInvoice: true
1868
1926
  } : {}
1869
1927
  });
1870
- console.log("[order-notifications] email queued", {
1928
+ chunkBXAKL2TF_cjs.notifyLog.email("queued", {
1871
1929
  triggerKey,
1872
1930
  audienceType,
1873
1931
  orderId,
1874
- to: contactEmail,
1932
+ to: chunkBXAKL2TF_cjs.maskNotifyEmail(contactEmail),
1933
+ subject,
1875
1934
  attachInvoice: shouldAttachInvoice
1876
1935
  });
1877
1936
  }
1878
1937
  chunkUSNT2KNT_cjs.__name(sendEmailForTrigger, "sendEmailForTrigger");
1879
1938
  async function sendWhatsAppForTrigger(triggerKey, orderId, phone, variables, dataSource, entityMap, getCms) {
1880
1939
  const template = await loadBoundTemplate(triggerKey, "whatsapp", "customers", dataSource, entityMap);
1881
- if (!template) return;
1940
+ if (!template) {
1941
+ chunkBXAKL2TF_cjs.notifyLog.skip("WHATSAPP", "no bound/default WhatsApp template", {
1942
+ triggerKey,
1943
+ orderId,
1944
+ phone: chunkBXAKL2TF_cjs.maskNotifyPhone(phone)
1945
+ });
1946
+ return;
1947
+ }
1882
1948
  const paramOrder = template.providerMeta?.paramOrder ?? [];
1883
1949
  if (paramOrder.length === 0) {
1884
- console.warn("[order-notifications] WhatsApp template has no paramOrder set \u2014 variables may send blank/wrong", {
1885
- triggerKey
1950
+ chunkBXAKL2TF_cjs.notifyLog.skip("WHATSAPP", "template has no paramOrder \u2014 variables may send blank/wrong", {
1951
+ triggerKey,
1952
+ orderId
1886
1953
  });
1887
1954
  }
1888
1955
  const cms = await getCms();
@@ -1891,8 +1958,10 @@ async function sendWhatsAppForTrigger(triggerKey, orderId, phone, variables, dat
1891
1958
  name: template.name
1892
1959
  });
1893
1960
  if (!metaTemplateName) {
1894
- console.warn("[order-notifications] bound WhatsApp template has no Meta template name", {
1961
+ chunkBXAKL2TF_cjs.notifyLog.skip("WHATSAPP", "template has no Meta template name", {
1895
1962
  triggerKey,
1963
+ orderId,
1964
+ phone: chunkBXAKL2TF_cjs.maskNotifyPhone(phone),
1896
1965
  templateId: template.id
1897
1966
  });
1898
1967
  return;
@@ -1907,37 +1976,57 @@ async function sendWhatsAppForTrigger(triggerKey, orderId, phone, variables, dat
1907
1976
  templateParamOrder: paramOrder
1908
1977
  });
1909
1978
  if (!sent) {
1910
- console.warn("[order-notifications] WhatsApp send failed", {
1979
+ chunkBXAKL2TF_cjs.notifyLog.error("WHATSAPP", "send failed / not queued", {
1911
1980
  triggerKey,
1912
1981
  orderId,
1982
+ phone: chunkBXAKL2TF_cjs.maskNotifyPhone(phone),
1913
1983
  hint: "Register whatsappPlugin() + queuePlugin() in getCms(), or set WHATSAPP_ACCESS_TOKEN and WHATSAPP_PHONE_NUMBER_ID"
1914
1984
  });
1915
1985
  } else {
1916
- console.log("[order-notifications] WhatsApp queued/sent", {
1986
+ chunkBXAKL2TF_cjs.notifyLog.whatsapp("queued/sent", {
1917
1987
  triggerKey,
1918
1988
  orderId,
1919
- phone: maskPhone2(phone)
1989
+ phone: chunkBXAKL2TF_cjs.maskNotifyPhone(phone),
1990
+ metaTemplateName
1920
1991
  });
1921
1992
  }
1922
1993
  }
1923
1994
  chunkUSNT2KNT_cjs.__name(sendWhatsAppForTrigger, "sendWhatsAppForTrigger");
1924
1995
  async function handleTrigger(triggerKey, payload, dataSource, entityMap, getCms) {
1925
- console.log("[order-notifications] received", {
1996
+ chunkBXAKL2TF_cjs.notifyLog.trigger("dispatcher received", {
1926
1997
  triggerKey,
1927
1998
  orderId: payload.orderId,
1928
- phone: maskPhone2(payload.customerPhone)
1999
+ orderNumber: payload.orderNumber,
2000
+ phone: chunkBXAKL2TF_cjs.maskNotifyPhone(payload.customerPhone),
2001
+ vendorId: payload.vendorId ?? null
1929
2002
  });
1930
2003
  const [emailChannelEnabled, whatsappChannelEnabled, pushChannelEnabled] = await Promise.all([
1931
2004
  isEmailNotificationsEnabled(dataSource, entityMap),
1932
2005
  isWhatsappNotificationsEnabled(dataSource, entityMap),
1933
2006
  isPushNotificationsEnabled(dataSource, entityMap)
1934
2007
  ]);
2008
+ chunkBXAKL2TF_cjs.notifyLog.trigger("channel switches", {
2009
+ triggerKey,
2010
+ orderId: payload.orderId,
2011
+ email: emailChannelEnabled,
2012
+ whatsapp: whatsappChannelEnabled,
2013
+ push: pushChannelEnabled
2014
+ });
1935
2015
  if (!emailChannelEnabled && !whatsappChannelEnabled && !pushChannelEnabled) {
1936
- console.warn("[order-notifications] skip: Email, WhatsApp, and Mobile Push notifications are disabled");
2016
+ chunkBXAKL2TF_cjs.notifyLog.skip("ALL", "Email, WhatsApp, and Mobile Push are disabled in event_notifications", {
2017
+ triggerKey,
2018
+ orderId: payload.orderId
2019
+ });
1937
2020
  return;
1938
2021
  }
1939
2022
  const triggerEnabled = await isTriggerCatalogEnabled(triggerKey, dataSource, entityMap);
1940
- if (!triggerEnabled) return;
2023
+ if (!triggerEnabled) {
2024
+ chunkBXAKL2TF_cjs.notifyLog.skip("TRIGGER", "trigger catalog disabled", {
2025
+ triggerKey,
2026
+ orderId: payload.orderId
2027
+ });
2028
+ return;
2029
+ }
1941
2030
  const context = await loadOrderNotificationContexts(payload.orderId, {
1942
2031
  dataSource,
1943
2032
  entityMap
@@ -1945,37 +2034,86 @@ async function handleTrigger(triggerKey, payload, dataSource, entityMap, getCms)
1945
2034
  const variables = mergeTriggerVariables(payload, context?.variables);
1946
2035
  const contactEmail = context?.contact.email?.trim() || "";
1947
2036
  const contactPhone = context?.contact.phone?.trim() || payload.customerPhone?.trim() || "";
2037
+ chunkBXAKL2TF_cjs.notifyLog.trigger("recipients resolved", {
2038
+ triggerKey,
2039
+ orderId: payload.orderId,
2040
+ contactEmail: chunkBXAKL2TF_cjs.maskNotifyEmail(contactEmail),
2041
+ contactPhone: chunkBXAKL2TF_cjs.maskNotifyPhone(contactPhone)
2042
+ });
1948
2043
  if (emailChannelEnabled) {
1949
2044
  const [customerEnabled, vendorEnabled, adminEnabled] = await Promise.all([
1950
2045
  isAudienceEmailEnabled(dataSource, entityMap, "customer"),
1951
2046
  isAudienceEmailEnabled(dataSource, entityMap, "vendor"),
1952
2047
  isAudienceEmailEnabled(dataSource, entityMap, "admin")
1953
2048
  ]);
2049
+ chunkBXAKL2TF_cjs.notifyLog.email("audience switches", {
2050
+ triggerKey,
2051
+ orderId: payload.orderId,
2052
+ customer: customerEnabled,
2053
+ vendor: vendorEnabled,
2054
+ admin: adminEnabled
2055
+ });
1954
2056
  if (triggerKey === "order_assigned_assignee") {
1955
2057
  const assigneeEmail = context?.order?.assignedUser?.email?.trim();
1956
2058
  if (assigneeEmail) {
1957
2059
  await sendEmailForTrigger(triggerKey, payload.orderId, "customers", variables, assigneeEmail, dataSource, entityMap, getCms);
2060
+ } else {
2061
+ chunkBXAKL2TF_cjs.notifyLog.skip("EMAIL", "order_assigned_assignee has no assignee email", {
2062
+ triggerKey,
2063
+ orderId: payload.orderId
2064
+ });
1958
2065
  }
1959
2066
  } else if (customerEnabled && contactEmail) {
1960
2067
  await sendEmailForTrigger(triggerKey, payload.orderId, "customers", variables, contactEmail, dataSource, entityMap, getCms);
2068
+ } else if (!customerEnabled) {
2069
+ chunkBXAKL2TF_cjs.notifyLog.skip("EMAIL", "customer email audience disabled", {
2070
+ triggerKey,
2071
+ orderId: payload.orderId
2072
+ });
2073
+ } else {
2074
+ chunkBXAKL2TF_cjs.notifyLog.skip("EMAIL", "no customer email on order contact", {
2075
+ triggerKey,
2076
+ orderId: payload.orderId
2077
+ });
1961
2078
  }
1962
2079
  if (vendorEnabled && triggerKey !== "order_assigned_assignee") {
1963
2080
  const multiVendorSettings = await getSettingsGroup(dataSource, entityMap, "multi_vendor");
1964
2081
  if (multiVendorSettings.enabled !== "false" && multiVendorSettings.enabled !== "0") {
1965
2082
  const vendorEmails = await getOrderVendorEmails(payload.orderId, payload.vendorId, dataSource, entityMap);
2083
+ if (vendorEmails.length === 0) {
2084
+ chunkBXAKL2TF_cjs.notifyLog.skip("EMAIL", "no vendor emails for order", {
2085
+ triggerKey,
2086
+ orderId: payload.orderId,
2087
+ vendorId: payload.vendorId ?? null
2088
+ });
2089
+ }
1966
2090
  for (const vEmail of vendorEmails) {
1967
2091
  await sendEmailForTrigger(triggerKey, payload.orderId, "vendors", variables, vEmail, dataSource, entityMap, getCms);
1968
2092
  }
2093
+ } else {
2094
+ chunkBXAKL2TF_cjs.notifyLog.skip("EMAIL", "multi-vendor off \u2014 skip vendor email", {
2095
+ triggerKey,
2096
+ orderId: payload.orderId
2097
+ });
1969
2098
  }
1970
2099
  }
1971
2100
  if (adminEnabled && triggerKey !== "order_assigned_assignee") {
1972
2101
  const adminEmails = await getAdminRecipientEmails(dataSource, entityMap);
2102
+ if (adminEmails.length === 0) {
2103
+ chunkBXAKL2TF_cjs.notifyLog.skip("EMAIL", "no admin recipient emails", {
2104
+ triggerKey,
2105
+ orderId: payload.orderId
2106
+ });
2107
+ }
1973
2108
  for (const aEmail of adminEmails) {
1974
2109
  await sendEmailForTrigger(triggerKey, payload.orderId, "admin", variables, aEmail, dataSource, entityMap, getCms);
1975
2110
  }
1976
2111
  }
1977
2112
  } else {
1978
- console.log("[order-notifications] skip email: Email notifications channel is disabled");
2113
+ chunkBXAKL2TF_cjs.notifyLog.skip("EMAIL", "email channel disabled", {
2114
+ triggerKey,
2115
+ orderId: payload.orderId
2116
+ });
1979
2117
  }
1980
2118
  if (pushChannelEnabled) {
1981
2119
  const [pushCustomerEnabled, pushVendorEnabled, pushAdminEnabled] = await Promise.all([
@@ -1983,29 +2121,59 @@ async function handleTrigger(triggerKey, payload, dataSource, entityMap, getCms)
1983
2121
  isAudiencePushEnabled(dataSource, entityMap, "vendor"),
1984
2122
  isAudiencePushEnabled(dataSource, entityMap, "admin")
1985
2123
  ]);
2124
+ chunkBXAKL2TF_cjs.notifyLog.push("audience switches", {
2125
+ triggerKey,
2126
+ orderId: payload.orderId,
2127
+ customer: pushCustomerEnabled,
2128
+ vendor: pushVendorEnabled,
2129
+ admin: pushAdminEnabled
2130
+ });
1986
2131
  const targetCustomerId = triggerKey === "order_assigned_assignee" ? context?.order?.assignedUser?.id : context?.order?.customerContactId || context?.order?.contactId || context?.order?.userId || context?.order?.id;
1987
2132
  if (pushCustomerEnabled && targetCustomerId) {
1988
2133
  await sendPushNotificationForTrigger(triggerKey, payload.orderId, "customers", String(targetCustomerId), variables, dataSource, entityMap);
2134
+ } else if (!pushCustomerEnabled) {
2135
+ chunkBXAKL2TF_cjs.notifyLog.skip("PUSH", "customer push audience disabled", {
2136
+ triggerKey,
2137
+ orderId: payload.orderId
2138
+ });
2139
+ } else {
2140
+ chunkBXAKL2TF_cjs.notifyLog.skip("PUSH", "no customer user/contact id for push", {
2141
+ triggerKey,
2142
+ orderId: payload.orderId
2143
+ });
1989
2144
  }
1990
2145
  if (pushVendorEnabled && payload.vendorId && triggerKey !== "order_assigned_assignee") {
1991
2146
  await sendPushNotificationForTrigger(triggerKey, payload.orderId, "vendors", String(payload.vendorId), variables, dataSource, entityMap);
2147
+ } else if (pushVendorEnabled && triggerKey !== "order_assigned_assignee" && !payload.vendorId) {
2148
+ chunkBXAKL2TF_cjs.notifyLog.skip("PUSH", "no vendorId on order \u2014 skip vendor push", {
2149
+ triggerKey,
2150
+ orderId: payload.orderId
2151
+ });
1992
2152
  }
1993
2153
  if (pushAdminEnabled && triggerKey !== "order_assigned_assignee") {
1994
2154
  await sendPushNotificationForTrigger(triggerKey, payload.orderId, "admin", "admin", variables, dataSource, entityMap);
1995
2155
  }
2156
+ } else {
2157
+ chunkBXAKL2TF_cjs.notifyLog.skip("PUSH", "push channel disabled", {
2158
+ triggerKey,
2159
+ orderId: payload.orderId
2160
+ });
1996
2161
  }
1997
2162
  if (whatsappChannelEnabled) {
1998
2163
  const targetPhone = triggerKey === "order_assigned_assignee" ? context?.order?.assignedUser?.phone?.trim() : contactPhone;
1999
2164
  if (targetPhone) {
2000
2165
  await sendWhatsAppForTrigger(triggerKey, payload.orderId, targetPhone, variables, dataSource, entityMap, getCms);
2001
2166
  } else {
2002
- console.warn("[order-notifications] skip WhatsApp: no recipient phone", {
2167
+ chunkBXAKL2TF_cjs.notifyLog.skip("WHATSAPP", "no recipient phone", {
2003
2168
  triggerKey,
2004
2169
  orderId: payload.orderId
2005
2170
  });
2006
2171
  }
2007
2172
  } else {
2008
- console.log("[order-notifications] skip WhatsApp: WhatsApp notifications channel is disabled");
2173
+ chunkBXAKL2TF_cjs.notifyLog.skip("WHATSAPP", "WhatsApp channel disabled", {
2174
+ triggerKey,
2175
+ orderId: payload.orderId
2176
+ });
2009
2177
  }
2010
2178
  }
2011
2179
  chunkUSNT2KNT_cjs.__name(handleTrigger, "handleTrigger");
@@ -2017,12 +2185,23 @@ function initWhatsappTriggerDispatcher(deps) {
2017
2185
  const { dataSource, entityMap, getCms } = deps;
2018
2186
  void dataSource.query(`ALTER TYPE "order_notification_bindings_channel_enum" ADD VALUE IF NOT EXISTS 'mobile'`).catch(() => {
2019
2187
  });
2020
- chunkUEE4PTTB_cjs.notificationTriggerEmitter.onAnyTrigger((triggerKey, payload) => {
2188
+ chunkBXAKL2TF_cjs.notificationTriggerEmitter.onAnyTrigger((triggerKey, payload) => {
2021
2189
  void handleTrigger(triggerKey, payload, dataSource, entityMap, getCms).catch((err) => {
2022
- console.error("[order-notifications]", triggerKey, err);
2190
+ chunkBXAKL2TF_cjs.notifyLog.error("TRIGGER", "dispatcher handleTrigger failed", {
2191
+ triggerKey,
2192
+ orderId: payload.orderId,
2193
+ error: err instanceof Error ? err.message : String(err),
2194
+ stack: err instanceof Error ? err.stack : void 0
2195
+ });
2023
2196
  });
2024
2197
  });
2025
- console.log("[order-notifications] dispatcher initialized (email + WhatsApp, unified via order_notification_bindings)");
2198
+ chunkBXAKL2TF_cjs.notifyLog.trigger("dispatcher initialized", {
2199
+ channels: [
2200
+ "email",
2201
+ "whatsapp",
2202
+ "push"
2203
+ ]
2204
+ });
2026
2205
  }
2027
2206
  chunkUSNT2KNT_cjs.__name(initWhatsappTriggerDispatcher, "initWhatsappTriggerDispatcher");
2028
2207
  async function dispatchOrderNotificationDirectly(triggerKey, payload, dataSource, entityMap, getCms) {
@@ -2090,7 +2269,7 @@ async function emitOrderNotificationTrigger(dataSource, entityMap, triggerKey, p
2090
2269
  if (settings.whatsapp_enabled !== "false" && settings.whatsapp_enabled !== "0") enabledChannels.push("whatsapp");
2091
2270
  if (settings.sms_enabled !== "false" && settings.sms_enabled !== "0") enabledChannels.push("sms");
2092
2271
  if (settings.push_enabled !== "false" && settings.push_enabled !== "0") enabledChannels.push("push");
2093
- chunkUEE4PTTB_cjs.notificationTriggerEmitter.emitTrigger(triggerKey, payload);
2272
+ chunkBXAKL2TF_cjs.notificationTriggerEmitter.emitTrigger(triggerKey, payload);
2094
2273
  return {
2095
2274
  ok: true,
2096
2275
  channels: enabledChannels
@@ -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-ID2PDEXD.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");