@infuro/cms-core 1.0.64 → 1.0.66

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 +4 -4
  2. package/dist/admin.js +4 -4
  3. package/dist/api.cjs +36 -36
  4. package/dist/api.js +4 -4
  5. package/dist/{chunk-M25DGZ5J.cjs → chunk-5MZFQRDW.cjs} +242 -45
  6. package/dist/chunk-FLUF2GZH.js +71 -0
  7. package/dist/{chunk-OJAYCNE5.js → chunk-NV5IRHI3.js} +240 -43
  8. package/dist/chunk-PA6YDMFZ.cjs +78 -0
  9. package/dist/{chunk-FF45VZMM.cjs → chunk-QYRXLURF.cjs} +109 -67
  10. package/dist/{chunk-DXERXWBR.js → chunk-RCE5SJBA.js} +36 -20
  11. package/dist/{chunk-K6C3ZSBZ.js → chunk-T33KU5G5.js} +81 -39
  12. package/dist/chunk-THL5JDWJ.cjs +101 -0
  13. package/dist/{chunk-PX3BSCIG.cjs → chunk-WMMZZRDJ.cjs} +38 -22
  14. package/dist/chunk-XJNNOSJR.js +98 -0
  15. package/dist/{emit-order-notification-trigger-MFCBAE7L.js → emit-order-notification-trigger-EJJZ6XTS.js} +2 -2
  16. package/dist/{emit-order-notification-trigger-ZRRGCQGB.cjs → emit-order-notification-trigger-ZD5YN3JM.cjs} +4 -4
  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-LFRHXWK4.js} +2 -2
  22. package/dist/{order-completion-otp-handlers-RF3DLNV7.cjs → order-completion-otp-handlers-NK65LOLV.cjs} +3 -3
  23. package/dist/{order-notification-dispatcher-ID2PDEXD.js → order-notification-dispatcher-ECPFI7CD.js} +2 -2
  24. package/dist/{order-notification-dispatcher-RNEQB3V7.cjs → order-notification-dispatcher-LL7ETKLU.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
@@ -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 chunkPA6YDMFZ_cjs = require('./chunk-PA6YDMFZ.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');
@@ -239,7 +239,8 @@ async function loadOrderNotificationContexts(orderId, deps) {
239
239
  const contact = {
240
240
  name: metaBuyerName || rawContact.name,
241
241
  email: metaBuyerEmail || metaCheckoutEmail || rawContact.email,
242
- phone: rawContact.phone
242
+ phone: rawContact.phone,
243
+ userId: rawContact.userId ?? null
243
244
  };
244
245
  const currency = String(o.currency ?? "INR");
245
246
  const siteUrl = resolvePublicSiteUrl();
@@ -1422,12 +1423,6 @@ var ORDER_NOTIFICATION_DEFAULTS = {
1422
1423
 
1423
1424
  // src/lib/order-notification-dispatcher.ts
1424
1425
  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
1426
  async function getSettingsGroup(dataSource, entityMap, group) {
1432
1427
  if (!entityMap.configs) return {};
1433
1428
  const rows = await dataSource.getRepository(entityMap.configs).find({
@@ -1530,7 +1525,17 @@ async function loadBoundTemplate(triggerKey, channel, audienceType = "customers"
1530
1525
  enabled: true
1531
1526
  }
1532
1527
  }).catch(() => null);
1533
- if (!template) {
1528
+ let resolvedTemplate = template;
1529
+ if (!resolvedTemplate && (channel === "mobile" || channel === "push")) {
1530
+ resolvedTemplate = await dataSource.getRepository(entityMap.message_templates).findOne({
1531
+ where: {
1532
+ id: templateId,
1533
+ deleted: false,
1534
+ enabled: true
1535
+ }
1536
+ }).catch(() => null);
1537
+ }
1538
+ if (!resolvedTemplate) {
1534
1539
  const defChannel = ORDER_NOTIFICATION_DEFAULTS[channel];
1535
1540
  const def = defChannel ? defChannel[triggerKey] : null;
1536
1541
  if (def) {
@@ -1555,7 +1560,7 @@ async function loadBoundTemplate(triggerKey, channel, audienceType = "customers"
1555
1560
  });
1556
1561
  return null;
1557
1562
  }
1558
- return template;
1563
+ return resolvedTemplate;
1559
1564
  } catch (err) {
1560
1565
  const defChannel = ORDER_NOTIFICATION_DEFAULTS[channel];
1561
1566
  const def = defChannel ? defChannel[triggerKey] : null;
@@ -1637,11 +1642,26 @@ async function sendPushNotificationForTrigger(triggerKey, orderId, audienceType,
1637
1642
  if (!template) {
1638
1643
  template = await loadBoundTemplate(triggerKey, "push", audienceType, dataSource, entityMap);
1639
1644
  }
1640
- if (!template || !template.body) return;
1645
+ if (!template || !template.body) {
1646
+ chunkPA6YDMFZ_cjs.notifyLog.skip("PUSH", "no mobile/push template or empty body", {
1647
+ triggerKey,
1648
+ orderId,
1649
+ audienceType,
1650
+ targetId
1651
+ });
1652
+ return;
1653
+ }
1641
1654
  const rawTitle = template.subject?.trim() || "Order Notification";
1642
1655
  const title = chunkOOTLNH63_cjs.applyTemplateVars(rawTitle, variables);
1643
1656
  const body = chunkOOTLNH63_cjs.applyTemplateVars(template.body, variables);
1644
- if (!entityMap.user_device_tokens) return;
1657
+ if (!entityMap.user_device_tokens) {
1658
+ chunkPA6YDMFZ_cjs.notifyLog.skip("PUSH", "user_device_tokens entity not registered", {
1659
+ triggerKey,
1660
+ orderId,
1661
+ audienceType
1662
+ });
1663
+ return;
1664
+ }
1645
1665
  const tokenRepo = dataSource.getRepository(entityMap.user_device_tokens);
1646
1666
  let targetTokens = [];
1647
1667
  try {
@@ -1676,19 +1696,67 @@ async function sendPushNotificationForTrigger(triggerKey, orderId, audienceType,
1676
1696
  });
1677
1697
  }
1678
1698
  } catch (err) {
1679
- console.error("[order-notifications] Error querying device tokens for push", err);
1699
+ chunkPA6YDMFZ_cjs.notifyLog.error("PUSH", "device token query failed", {
1700
+ triggerKey,
1701
+ orderId,
1702
+ audienceType,
1703
+ targetId,
1704
+ error: err instanceof Error ? err.message : String(err)
1705
+ });
1680
1706
  return;
1681
1707
  }
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
- }
1708
+ const tokens = targetTokens.map((t) => t.token?.trim()).filter(Boolean);
1709
+ chunkPA6YDMFZ_cjs.notifyLog.push("sending", {
1710
+ triggerKey,
1711
+ orderId,
1712
+ audienceType,
1713
+ targetId,
1714
+ title,
1715
+ tokenCount: tokens.length,
1716
+ fcmTokens: tokens.map((t) => chunkPA6YDMFZ_cjs.logFcmToken(t))
1717
+ });
1718
+ if (tokens.length === 0) {
1719
+ chunkPA6YDMFZ_cjs.notifyLog.skip("PUSH", "no active FCM tokens for target", {
1720
+ triggerKey,
1721
+ orderId,
1722
+ audienceType,
1723
+ targetId,
1724
+ hint: "App must POST /api/user-device-tokens after login"
1725
+ });
1726
+ return;
1727
+ }
1728
+ for (const token of tokens) {
1729
+ chunkPA6YDMFZ_cjs.notifyLog.push("FCM target", {
1730
+ triggerKey,
1731
+ orderId,
1732
+ audienceType,
1733
+ targetId,
1734
+ fcmToken: chunkPA6YDMFZ_cjs.logFcmToken(token)
1735
+ });
1736
+ const res = await sendFcmPushNotification(dataSource, entityMap, {
1737
+ token,
1738
+ title,
1739
+ body,
1740
+ data: {
1741
+ orderId: String(orderId),
1742
+ triggerKey
1743
+ }
1744
+ });
1745
+ if (res.success) {
1746
+ chunkPA6YDMFZ_cjs.notifyLog.push("FCM sent", {
1747
+ triggerKey,
1748
+ orderId,
1749
+ audienceType,
1750
+ fcmToken: chunkPA6YDMFZ_cjs.logFcmToken(token),
1751
+ messageId: res.messageId ?? null
1752
+ });
1753
+ } else {
1754
+ chunkPA6YDMFZ_cjs.notifyLog.error("PUSH", "FCM send failed", {
1755
+ triggerKey,
1756
+ orderId,
1757
+ audienceType,
1758
+ fcmToken: chunkPA6YDMFZ_cjs.logFcmToken(token),
1759
+ error: res.error ?? "unknown"
1692
1760
  });
1693
1761
  }
1694
1762
  }
@@ -1832,7 +1900,15 @@ function formatBodyForEmailHtml(body) {
1832
1900
  chunkUSNT2KNT_cjs.__name(formatBodyForEmailHtml, "formatBodyForEmailHtml");
1833
1901
  async function sendEmailForTrigger(triggerKey, orderId, audienceType, variables, contactEmail, dataSource, entityMap, getCms) {
1834
1902
  const template = await loadBoundTemplate(triggerKey, "email", audienceType, dataSource, entityMap);
1835
- if (!template) return;
1903
+ if (!template) {
1904
+ chunkPA6YDMFZ_cjs.notifyLog.skip("EMAIL", "no bound/default email template", {
1905
+ triggerKey,
1906
+ orderId,
1907
+ audienceType,
1908
+ to: chunkPA6YDMFZ_cjs.maskNotifyEmail(contactEmail)
1909
+ });
1910
+ return;
1911
+ }
1836
1912
  const [branding, emailSettings, storeSettings] = await Promise.all([
1837
1913
  getSettingsGroup(dataSource, entityMap, "branding"),
1838
1914
  getSettingsGroup(dataSource, entityMap, "email"),
@@ -1867,22 +1943,31 @@ async function sendEmailForTrigger(triggerKey, orderId, audienceType, variables,
1867
1943
  attachInvoice: true
1868
1944
  } : {}
1869
1945
  });
1870
- console.log("[order-notifications] email queued", {
1946
+ chunkPA6YDMFZ_cjs.notifyLog.email("queued", {
1871
1947
  triggerKey,
1872
1948
  audienceType,
1873
1949
  orderId,
1874
- to: contactEmail,
1950
+ to: chunkPA6YDMFZ_cjs.maskNotifyEmail(contactEmail),
1951
+ subject,
1875
1952
  attachInvoice: shouldAttachInvoice
1876
1953
  });
1877
1954
  }
1878
1955
  chunkUSNT2KNT_cjs.__name(sendEmailForTrigger, "sendEmailForTrigger");
1879
1956
  async function sendWhatsAppForTrigger(triggerKey, orderId, phone, variables, dataSource, entityMap, getCms) {
1880
1957
  const template = await loadBoundTemplate(triggerKey, "whatsapp", "customers", dataSource, entityMap);
1881
- if (!template) return;
1958
+ if (!template) {
1959
+ chunkPA6YDMFZ_cjs.notifyLog.skip("WHATSAPP", "no bound/default WhatsApp template", {
1960
+ triggerKey,
1961
+ orderId,
1962
+ phone: chunkPA6YDMFZ_cjs.maskNotifyPhone(phone)
1963
+ });
1964
+ return;
1965
+ }
1882
1966
  const paramOrder = template.providerMeta?.paramOrder ?? [];
1883
1967
  if (paramOrder.length === 0) {
1884
- console.warn("[order-notifications] WhatsApp template has no paramOrder set \u2014 variables may send blank/wrong", {
1885
- triggerKey
1968
+ chunkPA6YDMFZ_cjs.notifyLog.skip("WHATSAPP", "template has no paramOrder \u2014 variables may send blank/wrong", {
1969
+ triggerKey,
1970
+ orderId
1886
1971
  });
1887
1972
  }
1888
1973
  const cms = await getCms();
@@ -1891,8 +1976,10 @@ async function sendWhatsAppForTrigger(triggerKey, orderId, phone, variables, dat
1891
1976
  name: template.name
1892
1977
  });
1893
1978
  if (!metaTemplateName) {
1894
- console.warn("[order-notifications] bound WhatsApp template has no Meta template name", {
1979
+ chunkPA6YDMFZ_cjs.notifyLog.skip("WHATSAPP", "template has no Meta template name", {
1895
1980
  triggerKey,
1981
+ orderId,
1982
+ phone: chunkPA6YDMFZ_cjs.maskNotifyPhone(phone),
1896
1983
  templateId: template.id
1897
1984
  });
1898
1985
  return;
@@ -1907,37 +1994,57 @@ async function sendWhatsAppForTrigger(triggerKey, orderId, phone, variables, dat
1907
1994
  templateParamOrder: paramOrder
1908
1995
  });
1909
1996
  if (!sent) {
1910
- console.warn("[order-notifications] WhatsApp send failed", {
1997
+ chunkPA6YDMFZ_cjs.notifyLog.error("WHATSAPP", "send failed / not queued", {
1911
1998
  triggerKey,
1912
1999
  orderId,
2000
+ phone: chunkPA6YDMFZ_cjs.maskNotifyPhone(phone),
1913
2001
  hint: "Register whatsappPlugin() + queuePlugin() in getCms(), or set WHATSAPP_ACCESS_TOKEN and WHATSAPP_PHONE_NUMBER_ID"
1914
2002
  });
1915
2003
  } else {
1916
- console.log("[order-notifications] WhatsApp queued/sent", {
2004
+ chunkPA6YDMFZ_cjs.notifyLog.whatsapp("queued/sent", {
1917
2005
  triggerKey,
1918
2006
  orderId,
1919
- phone: maskPhone2(phone)
2007
+ phone: chunkPA6YDMFZ_cjs.maskNotifyPhone(phone),
2008
+ metaTemplateName
1920
2009
  });
1921
2010
  }
1922
2011
  }
1923
2012
  chunkUSNT2KNT_cjs.__name(sendWhatsAppForTrigger, "sendWhatsAppForTrigger");
1924
2013
  async function handleTrigger(triggerKey, payload, dataSource, entityMap, getCms) {
1925
- console.log("[order-notifications] received", {
2014
+ chunkPA6YDMFZ_cjs.notifyLog.trigger("dispatcher received", {
1926
2015
  triggerKey,
1927
2016
  orderId: payload.orderId,
1928
- phone: maskPhone2(payload.customerPhone)
2017
+ orderNumber: payload.orderNumber,
2018
+ phone: chunkPA6YDMFZ_cjs.maskNotifyPhone(payload.customerPhone),
2019
+ vendorId: payload.vendorId ?? null
1929
2020
  });
1930
2021
  const [emailChannelEnabled, whatsappChannelEnabled, pushChannelEnabled] = await Promise.all([
1931
2022
  isEmailNotificationsEnabled(dataSource, entityMap),
1932
2023
  isWhatsappNotificationsEnabled(dataSource, entityMap),
1933
2024
  isPushNotificationsEnabled(dataSource, entityMap)
1934
2025
  ]);
2026
+ chunkPA6YDMFZ_cjs.notifyLog.trigger("channel switches", {
2027
+ triggerKey,
2028
+ orderId: payload.orderId,
2029
+ email: emailChannelEnabled,
2030
+ whatsapp: whatsappChannelEnabled,
2031
+ push: pushChannelEnabled
2032
+ });
1935
2033
  if (!emailChannelEnabled && !whatsappChannelEnabled && !pushChannelEnabled) {
1936
- console.warn("[order-notifications] skip: Email, WhatsApp, and Mobile Push notifications are disabled");
2034
+ chunkPA6YDMFZ_cjs.notifyLog.skip("ALL", "Email, WhatsApp, and Mobile Push are disabled in event_notifications", {
2035
+ triggerKey,
2036
+ orderId: payload.orderId
2037
+ });
1937
2038
  return;
1938
2039
  }
1939
2040
  const triggerEnabled = await isTriggerCatalogEnabled(triggerKey, dataSource, entityMap);
1940
- if (!triggerEnabled) return;
2041
+ if (!triggerEnabled) {
2042
+ chunkPA6YDMFZ_cjs.notifyLog.skip("TRIGGER", "trigger catalog disabled", {
2043
+ triggerKey,
2044
+ orderId: payload.orderId
2045
+ });
2046
+ return;
2047
+ }
1941
2048
  const context = await loadOrderNotificationContexts(payload.orderId, {
1942
2049
  dataSource,
1943
2050
  entityMap
@@ -1945,37 +2052,86 @@ async function handleTrigger(triggerKey, payload, dataSource, entityMap, getCms)
1945
2052
  const variables = mergeTriggerVariables(payload, context?.variables);
1946
2053
  const contactEmail = context?.contact.email?.trim() || "";
1947
2054
  const contactPhone = context?.contact.phone?.trim() || payload.customerPhone?.trim() || "";
2055
+ chunkPA6YDMFZ_cjs.notifyLog.trigger("recipients resolved", {
2056
+ triggerKey,
2057
+ orderId: payload.orderId,
2058
+ contactEmail: chunkPA6YDMFZ_cjs.maskNotifyEmail(contactEmail),
2059
+ contactPhone: chunkPA6YDMFZ_cjs.maskNotifyPhone(contactPhone)
2060
+ });
1948
2061
  if (emailChannelEnabled) {
1949
2062
  const [customerEnabled, vendorEnabled, adminEnabled] = await Promise.all([
1950
2063
  isAudienceEmailEnabled(dataSource, entityMap, "customer"),
1951
2064
  isAudienceEmailEnabled(dataSource, entityMap, "vendor"),
1952
2065
  isAudienceEmailEnabled(dataSource, entityMap, "admin")
1953
2066
  ]);
2067
+ chunkPA6YDMFZ_cjs.notifyLog.email("audience switches", {
2068
+ triggerKey,
2069
+ orderId: payload.orderId,
2070
+ customer: customerEnabled,
2071
+ vendor: vendorEnabled,
2072
+ admin: adminEnabled
2073
+ });
1954
2074
  if (triggerKey === "order_assigned_assignee") {
1955
2075
  const assigneeEmail = context?.order?.assignedUser?.email?.trim();
1956
2076
  if (assigneeEmail) {
1957
2077
  await sendEmailForTrigger(triggerKey, payload.orderId, "customers", variables, assigneeEmail, dataSource, entityMap, getCms);
2078
+ } else {
2079
+ chunkPA6YDMFZ_cjs.notifyLog.skip("EMAIL", "order_assigned_assignee has no assignee email", {
2080
+ triggerKey,
2081
+ orderId: payload.orderId
2082
+ });
1958
2083
  }
1959
2084
  } else if (customerEnabled && contactEmail) {
1960
2085
  await sendEmailForTrigger(triggerKey, payload.orderId, "customers", variables, contactEmail, dataSource, entityMap, getCms);
2086
+ } else if (!customerEnabled) {
2087
+ chunkPA6YDMFZ_cjs.notifyLog.skip("EMAIL", "customer email audience disabled", {
2088
+ triggerKey,
2089
+ orderId: payload.orderId
2090
+ });
2091
+ } else {
2092
+ chunkPA6YDMFZ_cjs.notifyLog.skip("EMAIL", "no customer email on order contact", {
2093
+ triggerKey,
2094
+ orderId: payload.orderId
2095
+ });
1961
2096
  }
1962
2097
  if (vendorEnabled && triggerKey !== "order_assigned_assignee") {
1963
2098
  const multiVendorSettings = await getSettingsGroup(dataSource, entityMap, "multi_vendor");
1964
2099
  if (multiVendorSettings.enabled !== "false" && multiVendorSettings.enabled !== "0") {
1965
2100
  const vendorEmails = await getOrderVendorEmails(payload.orderId, payload.vendorId, dataSource, entityMap);
2101
+ if (vendorEmails.length === 0) {
2102
+ chunkPA6YDMFZ_cjs.notifyLog.skip("EMAIL", "no vendor emails for order", {
2103
+ triggerKey,
2104
+ orderId: payload.orderId,
2105
+ vendorId: payload.vendorId ?? null
2106
+ });
2107
+ }
1966
2108
  for (const vEmail of vendorEmails) {
1967
2109
  await sendEmailForTrigger(triggerKey, payload.orderId, "vendors", variables, vEmail, dataSource, entityMap, getCms);
1968
2110
  }
2111
+ } else {
2112
+ chunkPA6YDMFZ_cjs.notifyLog.skip("EMAIL", "multi-vendor off \u2014 skip vendor email", {
2113
+ triggerKey,
2114
+ orderId: payload.orderId
2115
+ });
1969
2116
  }
1970
2117
  }
1971
2118
  if (adminEnabled && triggerKey !== "order_assigned_assignee") {
1972
2119
  const adminEmails = await getAdminRecipientEmails(dataSource, entityMap);
2120
+ if (adminEmails.length === 0) {
2121
+ chunkPA6YDMFZ_cjs.notifyLog.skip("EMAIL", "no admin recipient emails", {
2122
+ triggerKey,
2123
+ orderId: payload.orderId
2124
+ });
2125
+ }
1973
2126
  for (const aEmail of adminEmails) {
1974
2127
  await sendEmailForTrigger(triggerKey, payload.orderId, "admin", variables, aEmail, dataSource, entityMap, getCms);
1975
2128
  }
1976
2129
  }
1977
2130
  } else {
1978
- console.log("[order-notifications] skip email: Email notifications channel is disabled");
2131
+ chunkPA6YDMFZ_cjs.notifyLog.skip("EMAIL", "email channel disabled", {
2132
+ triggerKey,
2133
+ orderId: payload.orderId
2134
+ });
1979
2135
  }
1980
2136
  if (pushChannelEnabled) {
1981
2137
  const [pushCustomerEnabled, pushVendorEnabled, pushAdminEnabled] = await Promise.all([
@@ -1983,29 +2139,59 @@ async function handleTrigger(triggerKey, payload, dataSource, entityMap, getCms)
1983
2139
  isAudiencePushEnabled(dataSource, entityMap, "vendor"),
1984
2140
  isAudiencePushEnabled(dataSource, entityMap, "admin")
1985
2141
  ]);
1986
- const targetCustomerId = triggerKey === "order_assigned_assignee" ? context?.order?.assignedUser?.id : context?.order?.customerContactId || context?.order?.contactId || context?.order?.userId || context?.order?.id;
2142
+ chunkPA6YDMFZ_cjs.notifyLog.push("audience switches", {
2143
+ triggerKey,
2144
+ orderId: payload.orderId,
2145
+ customer: pushCustomerEnabled,
2146
+ vendor: pushVendorEnabled,
2147
+ admin: pushAdminEnabled
2148
+ });
2149
+ const targetCustomerId = triggerKey === "order_assigned_assignee" ? context?.order?.assignedUser?.id : context?.contact?.userId;
1987
2150
  if (pushCustomerEnabled && targetCustomerId) {
1988
2151
  await sendPushNotificationForTrigger(triggerKey, payload.orderId, "customers", String(targetCustomerId), variables, dataSource, entityMap);
2152
+ } else if (!pushCustomerEnabled) {
2153
+ chunkPA6YDMFZ_cjs.notifyLog.skip("PUSH", "customer push audience disabled", {
2154
+ triggerKey,
2155
+ orderId: payload.orderId
2156
+ });
2157
+ } else {
2158
+ chunkPA6YDMFZ_cjs.notifyLog.skip("PUSH", "no customer user/contact id for push", {
2159
+ triggerKey,
2160
+ orderId: payload.orderId
2161
+ });
1989
2162
  }
1990
2163
  if (pushVendorEnabled && payload.vendorId && triggerKey !== "order_assigned_assignee") {
1991
2164
  await sendPushNotificationForTrigger(triggerKey, payload.orderId, "vendors", String(payload.vendorId), variables, dataSource, entityMap);
2165
+ } else if (pushVendorEnabled && triggerKey !== "order_assigned_assignee" && !payload.vendorId) {
2166
+ chunkPA6YDMFZ_cjs.notifyLog.skip("PUSH", "no vendorId on order \u2014 skip vendor push", {
2167
+ triggerKey,
2168
+ orderId: payload.orderId
2169
+ });
1992
2170
  }
1993
2171
  if (pushAdminEnabled && triggerKey !== "order_assigned_assignee") {
1994
2172
  await sendPushNotificationForTrigger(triggerKey, payload.orderId, "admin", "admin", variables, dataSource, entityMap);
1995
2173
  }
2174
+ } else {
2175
+ chunkPA6YDMFZ_cjs.notifyLog.skip("PUSH", "push channel disabled", {
2176
+ triggerKey,
2177
+ orderId: payload.orderId
2178
+ });
1996
2179
  }
1997
2180
  if (whatsappChannelEnabled) {
1998
2181
  const targetPhone = triggerKey === "order_assigned_assignee" ? context?.order?.assignedUser?.phone?.trim() : contactPhone;
1999
2182
  if (targetPhone) {
2000
2183
  await sendWhatsAppForTrigger(triggerKey, payload.orderId, targetPhone, variables, dataSource, entityMap, getCms);
2001
2184
  } else {
2002
- console.warn("[order-notifications] skip WhatsApp: no recipient phone", {
2185
+ chunkPA6YDMFZ_cjs.notifyLog.skip("WHATSAPP", "no recipient phone", {
2003
2186
  triggerKey,
2004
2187
  orderId: payload.orderId
2005
2188
  });
2006
2189
  }
2007
2190
  } else {
2008
- console.log("[order-notifications] skip WhatsApp: WhatsApp notifications channel is disabled");
2191
+ chunkPA6YDMFZ_cjs.notifyLog.skip("WHATSAPP", "WhatsApp channel disabled", {
2192
+ triggerKey,
2193
+ orderId: payload.orderId
2194
+ });
2009
2195
  }
2010
2196
  }
2011
2197
  chunkUSNT2KNT_cjs.__name(handleTrigger, "handleTrigger");
@@ -2017,12 +2203,23 @@ function initWhatsappTriggerDispatcher(deps) {
2017
2203
  const { dataSource, entityMap, getCms } = deps;
2018
2204
  void dataSource.query(`ALTER TYPE "order_notification_bindings_channel_enum" ADD VALUE IF NOT EXISTS 'mobile'`).catch(() => {
2019
2205
  });
2020
- chunkUEE4PTTB_cjs.notificationTriggerEmitter.onAnyTrigger((triggerKey, payload) => {
2206
+ chunkPA6YDMFZ_cjs.notificationTriggerEmitter.onAnyTrigger((triggerKey, payload) => {
2021
2207
  void handleTrigger(triggerKey, payload, dataSource, entityMap, getCms).catch((err) => {
2022
- console.error("[order-notifications]", triggerKey, err);
2208
+ chunkPA6YDMFZ_cjs.notifyLog.error("TRIGGER", "dispatcher handleTrigger failed", {
2209
+ triggerKey,
2210
+ orderId: payload.orderId,
2211
+ error: err instanceof Error ? err.message : String(err),
2212
+ stack: err instanceof Error ? err.stack : void 0
2213
+ });
2023
2214
  });
2024
2215
  });
2025
- console.log("[order-notifications] dispatcher initialized (email + WhatsApp, unified via order_notification_bindings)");
2216
+ chunkPA6YDMFZ_cjs.notifyLog.trigger("dispatcher initialized", {
2217
+ channels: [
2218
+ "email",
2219
+ "whatsapp",
2220
+ "push"
2221
+ ]
2222
+ });
2026
2223
  }
2027
2224
  chunkUSNT2KNT_cjs.__name(initWhatsappTriggerDispatcher, "initWhatsappTriggerDispatcher");
2028
2225
  async function dispatchOrderNotificationDirectly(triggerKey, payload, dataSource, entityMap, getCms) {
@@ -2090,7 +2287,7 @@ async function emitOrderNotificationTrigger(dataSource, entityMap, triggerKey, p
2090
2287
  if (settings.whatsapp_enabled !== "false" && settings.whatsapp_enabled !== "0") enabledChannels.push("whatsapp");
2091
2288
  if (settings.sms_enabled !== "false" && settings.sms_enabled !== "0") enabledChannels.push("sms");
2092
2289
  if (settings.push_enabled !== "false" && settings.push_enabled !== "0") enabledChannels.push("push");
2093
- chunkUEE4PTTB_cjs.notificationTriggerEmitter.emitTrigger(triggerKey, payload);
2290
+ chunkPA6YDMFZ_cjs.notificationTriggerEmitter.emitTrigger(triggerKey, payload);
2094
2291
  return {
2095
2292
  ok: true,
2096
2293
  channels: enabledChannels
@@ -0,0 +1,71 @@
1
+ import { __name } from './chunk-SHUYVCID.js';
2
+ import { EventEmitter } from 'events';
3
+
4
+ var KNOWN_NOTIFICATION_TRIGGERS = {
5
+ ORDER_PENDING: "order_pending",
6
+ ORDER_PROCESSING: "order_processing",
7
+ ORDER_COMPLETED: "order_completed",
8
+ ORDER_PLACED: "order_placed",
9
+ ORDER_CANCELLED: "order_cancelled",
10
+ PAYMENT_SUCCESS: "payment_success",
11
+ PAYMENT_FAILED: "payment_failed",
12
+ PAYMENT_REFUND_INITIATED: "payment_refund_initiated"
13
+ };
14
+ var NotificationTriggerEmitter = class NotificationTriggerEmitter2 extends EventEmitter {
15
+ static {
16
+ __name(this, "NotificationTriggerEmitter");
17
+ }
18
+ emitTrigger(triggerKey, payload) {
19
+ this.emit("__any__", triggerKey, payload);
20
+ }
21
+ onAnyTrigger(listener) {
22
+ this.on("__any__", listener);
23
+ }
24
+ };
25
+ var notificationTriggerEmitter = new NotificationTriggerEmitter();
26
+
27
+ // src/lib/notify-log.ts
28
+ function maskNotifyPhone(raw) {
29
+ const digits = String(raw ?? "").replace(/\D/g, "");
30
+ if (digits.length <= 4) return "(none)";
31
+ return `***${digits.slice(-4)}`;
32
+ }
33
+ __name(maskNotifyPhone, "maskNotifyPhone");
34
+ function maskNotifyEmail(raw) {
35
+ const e = String(raw ?? "").trim();
36
+ if (!e || !e.includes("@")) return "(none)";
37
+ const [user, domain] = e.split("@");
38
+ const u = user.length <= 2 ? "**" : `${user.slice(0, 2)}***`;
39
+ return `${u}@${domain}`;
40
+ }
41
+ __name(maskNotifyEmail, "maskNotifyEmail");
42
+ function logFcmToken(raw) {
43
+ const s = String(raw ?? "").trim();
44
+ return s || "(none)";
45
+ }
46
+ __name(logFcmToken, "logFcmToken");
47
+ function write(level, channel, message, data) {
48
+ const banner = `========== [NOTIFY] ${channel} | ${message} ==========`;
49
+ const payload = data ?? {};
50
+ if (level === "error") {
51
+ console.error(`
52
+ ${banner}`, payload);
53
+ } else if (level === "warn") {
54
+ console.warn(`
55
+ ${banner}`, payload);
56
+ } else {
57
+ console.info(`
58
+ ${banner}`, payload);
59
+ }
60
+ }
61
+ __name(write, "write");
62
+ var notifyLog = {
63
+ trigger: /* @__PURE__ */ __name((message, data) => write("info", "TRIGGER", message, data), "trigger"),
64
+ email: /* @__PURE__ */ __name((message, data) => write("info", "EMAIL", message, data), "email"),
65
+ whatsapp: /* @__PURE__ */ __name((message, data) => write("info", "WHATSAPP", message, data), "whatsapp"),
66
+ push: /* @__PURE__ */ __name((message, data) => write("info", "PUSH", message, data), "push"),
67
+ skip: /* @__PURE__ */ __name((channel, message, data) => write("warn", `SKIP ${channel}`, message, data), "skip"),
68
+ error: /* @__PURE__ */ __name((channel, message, data) => write("error", channel, message, data), "error")
69
+ };
70
+
71
+ export { KNOWN_NOTIFICATION_TRIGGERS, logFcmToken, maskNotifyEmail, maskNotifyPhone, notificationTriggerEmitter, notifyLog };