@infuro/cms-core 1.0.58 → 1.0.60

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 (35) hide show
  1. package/dist/admin.cjs +442 -37
  2. package/dist/admin.js +443 -38
  3. package/dist/api.cjs +41 -37
  4. package/dist/api.d.cts +2 -1
  5. package/dist/api.d.ts +2 -1
  6. package/dist/api.js +5 -5
  7. package/dist/auth.cjs +51 -51
  8. package/dist/auth.js +3 -3
  9. package/dist/{chunk-3EOM4V2M.cjs → chunk-4U6DATGZ.cjs} +7 -7
  10. package/dist/{chunk-BNKZNLEX.js → chunk-6DBDJ4VD.js} +2 -2
  11. package/dist/{chunk-UQWZUZ5X.cjs → chunk-73WVHINE.cjs} +30 -6
  12. package/dist/{chunk-UCKN4BBY.cjs → chunk-77I3KS7V.cjs} +4 -1
  13. package/dist/{chunk-BHUEXLD2.cjs → chunk-BSLNXKV2.cjs} +415 -131
  14. package/dist/{chunk-77NUXO6A.cjs → chunk-J7FMZK66.cjs} +10 -2
  15. package/dist/{chunk-AGU3B5JW.js → chunk-JAEUYYGA.js} +335 -52
  16. package/dist/{chunk-BC22I7C7.cjs → chunk-KM2I6AFP.cjs} +9 -9
  17. package/dist/{chunk-JIWUVQ6B.js → chunk-MVHDC3XF.js} +10 -2
  18. package/dist/{chunk-RK5ETF2I.js → chunk-NR44CK5E.js} +1 -1
  19. package/dist/{chunk-MXIWUFBP.js → chunk-O2642WVS.js} +28 -4
  20. package/dist/{chunk-HCIRL37O.js → chunk-T3HPSF7K.js} +4 -1
  21. package/dist/{chunk-HYW3MUXT.js → chunk-URN7GS23.js} +30 -16
  22. package/dist/{chunk-HXLC56ZK.cjs → chunk-YSYX4GUD.cjs} +32 -18
  23. package/dist/{emit-order-notification-trigger-HZQPPSFB.js → emit-order-notification-trigger-CZU3V2WE.js} +2 -2
  24. package/dist/{emit-order-notification-trigger-NR3VN6C6.cjs → emit-order-notification-trigger-TNEZOYEE.cjs} +4 -4
  25. package/dist/index.cjs +342 -300
  26. package/dist/index.d.cts +33 -1
  27. package/dist/index.d.ts +33 -1
  28. package/dist/index.js +54 -16
  29. package/dist/migrations/1782800000000-AddPaymentSuccessFailedRefundTriggers.ts +32 -0
  30. package/dist/migrations/1782900000000-AddEnableTurnstileToForms.ts +29 -0
  31. package/dist/{order-notification-dispatcher-2FCZFZUD.cjs → order-notification-dispatcher-KJVGLK5E.cjs} +5 -5
  32. package/dist/{order-notification-dispatcher-64WDCHHG.js → order-notification-dispatcher-ZSFKEYMP.js} +2 -2
  33. package/dist/{rbac-debug-db-6EMIVMGF.js → rbac-debug-db-5R6XFPSV.js} +1 -1
  34. package/dist/{rbac-debug-db-6PWTLBEL.cjs → rbac-debug-db-JKK2MCWF.cjs} +2 -2
  35. package/package.json +1 -1
@@ -1,15 +1,15 @@
1
1
  import { JOB_RUNNER_QUEUE } from './chunk-GO7PPYNU.js';
2
2
  import { validateInventoryForConfirmedOrderLines, orderStatusHoldsStock, reconcileOrderInventoryBetweenSnapshots, orderInventorySnapshotFromRow, validateInventoryForOrderBecomingConfirmed } from './chunk-3K5AIEIZ.js';
3
- import { resolveChatEmailToolSettings, CHAT_EMAIL_LOG, detectChatLeadIntent, parseIntentRecipientEmails, sendChatLeadEmail, buildTranscriptForLeadEmail, buildChatbotSystemPromptWithEmailTool, validateFcmCredentials, sendFcmPushNotification, parseEmailRecipientsFromConfig, isWhatsAppPluginEnabled, mergeWhatsAppConfigLayers, whatsAppConfigured, WhatsAppService, registerWhatsAppQueueProcessor, emailPlugin, initWhatsappTriggerDispatcher } from './chunk-HYW3MUXT.js';
3
+ import { resolveChatEmailToolSettings, CHAT_EMAIL_LOG, detectChatLeadIntent, parseIntentRecipientEmails, sendChatLeadEmail, buildTranscriptForLeadEmail, buildChatbotSystemPromptWithEmailTool, validateFcmCredentials, sendFcmPushNotification, parseEmailRecipientsFromConfig, isWhatsAppPluginEnabled, mergeWhatsAppConfigLayers, whatsAppConfigured, WhatsAppService, registerWhatsAppQueueProcessor, emailPlugin, initWhatsappTriggerDispatcher } from './chunk-URN7GS23.js';
4
4
  import { inviteStatusForActivation } from './chunk-JXF23MPG.js';
5
5
  import { queueEmail, queueVendorOnboardEmails, registerEmailQueueProcessor } from './chunk-L3525VXI.js';
6
6
  import { mergeEmailLayoutCompanyDetails, unwrapErpReadData, mapErpPayloadToFulfillment, extractChildOrderRefsFromSalePayload, mapErpPayloadToInvoiceNumber, streamOrderInvoicePdf } from './chunk-2KUCQVAQ.js';
7
7
  import { isErpIntegrationEnabled } from './chunk-JC6DLWTE.js';
8
8
  import { getSmsTemplateDefault, SMS_MESSAGE_TEMPLATE_DEFAULTS } from './chunk-MQBT33IV.js';
9
9
  import { EVENT_ORDER_MESSAGE_TEMPLATE_DEFAULTS, EVENT_ORDER_TEMPLATE_KEY, EVENT_ORDER_TEMPLATE_VARIABLES } from './chunk-AYERBA7I.js';
10
- import { ensureCustomerRecord, linkUnclaimedContactToUser, ensureCustomerForUser, canManageRoles, sessionHasEntityAccess } from './chunk-RK5ETF2I.js';
10
+ import { ensureCustomerRecord, linkUnclaimedContactToUser, ensureCustomerForUser, canManageRoles, sessionHasEntityAccess } from './chunk-NR44CK5E.js';
11
11
  import { retireSoftDeletedUniqueValue, activeUniqueValueExists } from './chunk-DBPSJYLZ.js';
12
- import { permissionRowsToRecord, logRbac, isSuperAdmin, vendorPortalFlagsFromUser, VENDOR_SCOPED_STORE_ENTITIES, isVendorPortalUser, getPermissionableEntityKeys, VENDOR_STORE_RBAC_ENTITIES, isSuperAdminGroupName, VENDOR_RBAC_ENTITIES, VENDOR_VIEWER_ROLE_NAME, DEFAULT_VENDOR_ROLE_DEFS, VENDOR_GROUP_NAME, resolveVendorScopeFromSessionUser, canManageVendorRoles, isPlatformAdministrator, canManageVendorTeam, resolveDisabledMultiVendorScope, logEntityAccessDecision, explainSessionEntityAccess } from './chunk-JIWUVQ6B.js';
12
+ import { permissionRowsToRecord, logRbac, isSuperAdmin, vendorPortalFlagsFromUser, VENDOR_SCOPED_STORE_ENTITIES, isVendorPortalUser, getPermissionableEntityKeys, VENDOR_STORE_RBAC_ENTITIES, isSuperAdminGroupName, VENDOR_RBAC_ENTITIES, VENDOR_VIEWER_ROLE_NAME, DEFAULT_VENDOR_ROLE_DEFS, VENDOR_GROUP_NAME, resolveVendorScopeFromSessionUser, canManageVendorRoles, isPlatformAdministrator, canManageVendorTeam, resolveDisabledMultiVendorScope, logEntityAccessDecision, explainSessionEntityAccess } from './chunk-MVHDC3XF.js';
13
13
  import { queueErp } from './chunk-SYBOCAWB.js';
14
14
  import { __name } from './chunk-SHUYVCID.js';
15
15
  import { PrimaryGeneratedColumn, Column, Entity, ManyToOne, JoinColumn, CreateDateColumn, UpdateDateColumn, Unique, OneToMany, Index, ManyToMany, JoinTable, In, ILike, Between, MoreThanOrEqual, LessThanOrEqual, Not, MoreThan, IsNull } from 'typeorm';
@@ -1510,6 +1510,36 @@ async function validateLlmAgentScopeForWrite(dataSource, entityMap, scope, exclu
1510
1510
  __name(validateLlmAgentScopeForWrite, "validateLlmAgentScopeForWrite");
1511
1511
 
1512
1512
  // src/api/crud.ts
1513
+ async function autoExpireOrderIfPaymentTimeExceeded(dataSource, entityMap, order) {
1514
+ if (!order || typeof order !== "object") return order;
1515
+ const status = String(order.status ?? "").toLowerCase();
1516
+ if (status !== "pending") return order;
1517
+ const meta = typeof order.metadata === "object" && order.metadata ? order.metadata : {};
1518
+ const expiresAtStr = meta.paymentExpiresAt ? String(meta.paymentExpiresAt) : null;
1519
+ if (!expiresAtStr) return order;
1520
+ const expiresMs = new Date(expiresAtStr).getTime();
1521
+ if (Number.isNaN(expiresMs) || Date.now() <= expiresMs) return order;
1522
+ try {
1523
+ const orderId = Number(order.id);
1524
+ if (orderId && entityMap.orders) {
1525
+ const orderRepo = dataSource.getRepository(entityMap.orders);
1526
+ const updatedMeta = {
1527
+ ...meta,
1528
+ cancelReason: "Payment window expired (10 minutes)"
1529
+ };
1530
+ await orderRepo.update(orderId, {
1531
+ status: "cancelled",
1532
+ metadata: updatedMeta
1533
+ });
1534
+ order.status = "cancelled";
1535
+ order.metadata = updatedMeta;
1536
+ }
1537
+ } catch (err) {
1538
+ console.error("[payment-expiry] Auto-cancelling expired order failed", err);
1539
+ }
1540
+ return order;
1541
+ }
1542
+ __name(autoExpireOrderIfPaymentTimeExceeded, "autoExpireOrderIfPaymentTimeExceeded");
1513
1543
  var CRUD_LOG = "[cms-crud]";
1514
1544
  function logCrudClientError(op, detail) {
1515
1545
  console.warn(CRUD_LOG, op, detail);
@@ -2414,13 +2444,46 @@ function discountCompare(cartValue, op, ruleValue) {
2414
2444
  }
2415
2445
  }
2416
2446
  __name(discountCompare, "discountCompare");
2417
- function discountEvaluateRule(rule, cartLines, cartTotal) {
2418
- if (rule.conditionType === "group") return discountEvaluateGroup(rule, cartLines, cartTotal);
2447
+ async function getExchangeRate(dataSource, entityMap, fromCurrency, toCurrency) {
2448
+ const from = (fromCurrency || "INR").trim().toUpperCase();
2449
+ const to = (toCurrency || "INR").trim().toUpperCase();
2450
+ if (from === to) return 1;
2451
+ if (entityMap["currency_exchange"]) {
2452
+ try {
2453
+ const exchangeRepo = dataSource.getRepository(entityMap["currency_exchange"]);
2454
+ const direct = await exchangeRepo.findOne({
2455
+ where: {
2456
+ fromCurrency: from,
2457
+ toCurrency: to
2458
+ }
2459
+ });
2460
+ if (direct && Number(direct.rate) > 0) {
2461
+ return Number(direct.rate);
2462
+ }
2463
+ const inverse = await exchangeRepo.findOne({
2464
+ where: {
2465
+ fromCurrency: to,
2466
+ toCurrency: from
2467
+ }
2468
+ });
2469
+ if (inverse && Number(inverse.rate) > 0) {
2470
+ return 1 / Number(inverse.rate);
2471
+ }
2472
+ } catch {
2473
+ }
2474
+ }
2475
+ return 1;
2476
+ }
2477
+ __name(getExchangeRate, "getExchangeRate");
2478
+ function discountEvaluateRule(rule, cartLines, cartTotal, exchangeRate = 1) {
2479
+ if (rule.conditionType === "group") return discountEvaluateGroup(rule, cartLines, cartTotal, exchangeRate);
2419
2480
  if (rule.type === "reward") return true;
2420
- const ruleValue = discountExtractValue(rule.value);
2481
+ const rawRuleValue = discountExtractValue(rule.value);
2421
2482
  switch (rule.type) {
2422
- case "minAmount":
2423
- return discountCompare(cartTotal, rule.comparisonOperator, ruleValue);
2483
+ case "minAmount": {
2484
+ const convertedValue = typeof rawRuleValue === "number" ? rawRuleValue * exchangeRate : !isNaN(Number(rawRuleValue)) ? Number(rawRuleValue) * exchangeRate : rawRuleValue;
2485
+ return discountCompare(cartTotal, rule.comparisonOperator, convertedValue);
2486
+ }
2424
2487
  case "quantity": {
2425
2488
  if (rule.subType === "productId" && rule.value?.productId) {
2426
2489
  const targetProductId = Number(rule.value.productId);
@@ -2429,11 +2492,11 @@ function discountEvaluateRule(rule, cartLines, cartTotal) {
2429
2492
  return discountCompare(productQty, rule.comparisonOperator, requiredQty);
2430
2493
  }
2431
2494
  const totalQty = cartLines.reduce((s, l) => s + l.quantity, 0);
2432
- return discountCompare(totalQty, rule.comparisonOperator, ruleValue);
2495
+ return discountCompare(totalQty, rule.comparisonOperator, rawRuleValue);
2433
2496
  }
2434
2497
  case "product":
2435
2498
  if (rule.subType === "productId") {
2436
- return cartLines.some((l) => discountCompare(l.productId, rule.comparisonOperator, ruleValue));
2499
+ return cartLines.some((l) => discountCompare(l.productId, rule.comparisonOperator, rawRuleValue));
2437
2500
  }
2438
2501
  return false;
2439
2502
  // These require external context (user session, payment method, time) —
@@ -2457,11 +2520,11 @@ function discountEvaluateRule(rule, cartLines, cartTotal) {
2457
2520
  }
2458
2521
  }
2459
2522
  __name(discountEvaluateRule, "discountEvaluateRule");
2460
- function discountEvaluateGroup(group, cartLines, cartTotal) {
2523
+ function discountEvaluateGroup(group, cartLines, cartTotal, exchangeRate = 1) {
2461
2524
  if (!group.children?.length) return true;
2462
2525
  const op = (group.conditionOperator ?? "and").toLowerCase();
2463
- if (op === "and") return group.children.every((child) => discountEvaluateRule(child, cartLines, cartTotal));
2464
- if (op === "or") return group.children.some((child) => discountEvaluateRule(child, cartLines, cartTotal));
2526
+ if (op === "and") return group.children.every((child) => discountEvaluateRule(child, cartLines, cartTotal, exchangeRate));
2527
+ if (op === "or") return group.children.some((child) => discountEvaluateRule(child, cartLines, cartTotal, exchangeRate));
2465
2528
  return true;
2466
2529
  }
2467
2530
  __name(discountEvaluateGroup, "discountEvaluateGroup");
@@ -2508,19 +2571,19 @@ function discountExtractBuyProductId(nodes) {
2508
2571
  return null;
2509
2572
  }
2510
2573
  __name(discountExtractBuyProductId, "discountExtractBuyProductId");
2511
- function discountBuildUniversalResult(discount, cartLines) {
2574
+ function discountBuildUniversalResult(discount, cartLines, effectiveValue) {
2512
2575
  return {
2513
2576
  rewardLines: cartLines.map((l) => ({
2514
2577
  productId: l.productId,
2515
2578
  quantity: l.quantity,
2516
- discountRate: Number(discount.value),
2579
+ discountRate: effectiveValue,
2517
2580
  discountType: discount.discountType
2518
2581
  })),
2519
2582
  conditionsMet: true
2520
2583
  };
2521
2584
  }
2522
2585
  __name(discountBuildUniversalResult, "discountBuildUniversalResult");
2523
- function evaluateDiscount(discount, cartLines) {
2586
+ function evaluateDiscount(discount, cartLines, exchangeRate = 1) {
2524
2587
  const empty = {
2525
2588
  rewardLines: [],
2526
2589
  conditionsMet: false
@@ -2544,16 +2607,17 @@ function evaluateDiscount(discount, cartLines) {
2544
2607
  reason: "discount usage limit reached"
2545
2608
  };
2546
2609
  }
2610
+ const effectiveValue = discount.discountType === "FLAT" ? Number(discount.value) * exchangeRate : Number(discount.value);
2547
2611
  const cartTotal = cartLines.reduce((s, l) => s + l.subtotal, 0);
2548
2612
  const tree = discountBuildTree(discount.rules ?? []);
2549
- if (tree.length === 0) return discountBuildUniversalResult(discount, cartLines);
2550
- const conditionsMet = tree.every((node) => discountEvaluateRule(node, cartLines, cartTotal));
2613
+ if (tree.length === 0) return discountBuildUniversalResult(discount, cartLines, effectiveValue);
2614
+ const conditionsMet = tree.every((node) => discountEvaluateRule(node, cartLines, cartTotal, exchangeRate));
2551
2615
  if (!conditionsMet) return {
2552
2616
  ...empty,
2553
2617
  reason: "conditions not met"
2554
2618
  };
2555
2619
  const rewardRules = discountCollectRewardRules(tree);
2556
- if (rewardRules.length === 0) return discountBuildUniversalResult(discount, cartLines);
2620
+ if (rewardRules.length === 0) return discountBuildUniversalResult(discount, cartLines, effectiveValue);
2557
2621
  const requiredBuyQty = discountExtractRequiredBuyQty(tree);
2558
2622
  const buyProductId = discountExtractBuyProductId(tree);
2559
2623
  let dealMultiplier = 1;
@@ -2571,7 +2635,7 @@ function evaluateDiscount(discount, cartLines) {
2571
2635
  rewardLines.push({
2572
2636
  productId: rewardProductId,
2573
2637
  quantity: dealMultiplier,
2574
- discountRate: Number(discount.value),
2638
+ discountRate: effectiveValue,
2575
2639
  discountType: discount.discountType
2576
2640
  });
2577
2641
  } else {
@@ -2580,7 +2644,7 @@ function evaluateDiscount(discount, cartLines) {
2580
2644
  rewardLines.push({
2581
2645
  productId: rewardProductId,
2582
2646
  quantity: rewardQty,
2583
- discountRate: Number(discount.value),
2647
+ discountRate: effectiveValue,
2584
2648
  discountType: discount.discountType
2585
2649
  });
2586
2650
  }
@@ -2591,8 +2655,9 @@ function evaluateDiscount(discount, cartLines) {
2591
2655
  };
2592
2656
  }
2593
2657
  __name(evaluateDiscount, "evaluateDiscount");
2594
- function applyDiscountToOrderLines(lines, evalResult, maxDiscountAmount) {
2658
+ function applyDiscountToOrderLines(lines, evalResult, maxDiscountAmount, exchangeRate = 1) {
2595
2659
  if (!evalResult.conditionsMet || evalResult.rewardLines.length === 0) return 0;
2660
+ const effectiveMaxDiscountAmount = maxDiscountAmount != null ? Number(maxDiscountAmount) * exchangeRate : null;
2596
2661
  let totalDiscountApplied = 0;
2597
2662
  for (const reward of evalResult.rewardLines) {
2598
2663
  const line = lines.find((l) => l.productId === reward.productId);
@@ -2609,8 +2674,8 @@ function applyDiscountToOrderLines(lines, evalResult, maxDiscountAmount) {
2609
2674
  line.subtotal = line.unitPrice * line.quantity;
2610
2675
  line.total = Math.max(0, line.subtotal - (line.discount ?? 0));
2611
2676
  }
2612
- if (maxDiscountAmount != null && totalDiscountApplied > maxDiscountAmount) {
2613
- const excess = totalDiscountApplied - maxDiscountAmount;
2677
+ if (effectiveMaxDiscountAmount != null && totalDiscountApplied > effectiveMaxDiscountAmount) {
2678
+ const excess = totalDiscountApplied - effectiveMaxDiscountAmount;
2614
2679
  for (let i = evalResult.rewardLines.length - 1; i >= 0; i--) {
2615
2680
  const reward = evalResult.rewardLines[i];
2616
2681
  const line = lines.find((l) => l.productId === reward.productId);
@@ -2620,7 +2685,7 @@ function applyDiscountToOrderLines(lines, evalResult, maxDiscountAmount) {
2620
2685
  line.total = Math.max(0, line.total + rollback);
2621
2686
  if (rollback > 0) break;
2622
2687
  }
2623
- totalDiscountApplied = maxDiscountAmount;
2688
+ totalDiscountApplied = effectiveMaxDiscountAmount;
2624
2689
  }
2625
2690
  return totalDiscountApplied;
2626
2691
  }
@@ -2726,7 +2791,9 @@ async function validateCoupon(dataSource, entityMap, couponCode, orderLines, cur
2726
2791
  unitPrice: l.unitPrice,
2727
2792
  subtotal: l.subtotal
2728
2793
  }));
2729
- const evalResult = evaluateDiscount(discountForEval, cartLines);
2794
+ const dCurrency = d.currency || "INR";
2795
+ const exchangeRate = await getExchangeRate(dataSource, entityMap, dCurrency, currency);
2796
+ const evalResult = evaluateDiscount(discountForEval, cartLines, exchangeRate);
2730
2797
  if (!evalResult.conditionsMet) {
2731
2798
  return {
2732
2799
  valid: false,
@@ -2736,7 +2803,7 @@ async function validateCoupon(dataSource, entityMap, couponCode, orderLines, cur
2736
2803
  const clonedLines = lines.map((l) => ({
2737
2804
  ...l
2738
2805
  }));
2739
- const calculatedDiscount = applyDiscountToOrderLines(clonedLines, evalResult, d.maxDiscountAmount);
2806
+ const calculatedDiscount = applyDiscountToOrderLines(clonedLines, evalResult, d.maxDiscountAmount, exchangeRate);
2740
2807
  const rewardProductIds = evalResult.rewardLines.map((r) => r.productId);
2741
2808
  return {
2742
2809
  valid: true,
@@ -3021,9 +3088,11 @@ async function calculateOrderTotalsFromLines(dataSource, entityMap, lineInputs,
3021
3088
  unitPrice: l.unitPrice,
3022
3089
  subtotal: l.subtotal
3023
3090
  }));
3024
- const evalResult = evaluateDiscount(discountForEval, cartLines);
3091
+ const dCurrency = discountRow.currency || "INR";
3092
+ const exchangeRate2 = await getExchangeRate(dataSource, entityMap, dCurrency, currency);
3093
+ const evalResult = evaluateDiscount(discountForEval, cartLines, exchangeRate2);
3025
3094
  if (evalResult.conditionsMet) {
3026
- const totalDiscountApplied = applyDiscountToOrderLines(lines, evalResult, discountRow.maxDiscountAmount);
3095
+ const totalDiscountApplied = applyDiscountToOrderLines(lines, evalResult, discountRow.maxDiscountAmount, exchangeRate2);
3027
3096
  orderDiscount += totalDiscountApplied;
3028
3097
  }
3029
3098
  }
@@ -3136,9 +3205,25 @@ async function calculateOrderTotals(dataSource, entityMap, itemsSummary, discoun
3136
3205
  unitPrice: l.unitPrice,
3137
3206
  subtotal: l.subtotal
3138
3207
  }));
3139
- const evalResult = evaluateDiscount(discountForEval, cartLines);
3208
+ const dCurrency = discountRow.currency || "INR";
3209
+ let storeCurrency = "INR";
3210
+ if (entityMap["configs"]) {
3211
+ try {
3212
+ const configRepo = dataSource.getRepository(entityMap["configs"]);
3213
+ const curr = await configRepo.findOne({
3214
+ where: {
3215
+ settings: "store",
3216
+ key: "currency"
3217
+ }
3218
+ });
3219
+ storeCurrency = curr?.value?.toUpperCase() ?? "INR";
3220
+ } catch {
3221
+ }
3222
+ }
3223
+ const exchangeRate = await getExchangeRate(dataSource, entityMap, dCurrency, storeCurrency);
3224
+ const evalResult = evaluateDiscount(discountForEval, cartLines, exchangeRate);
3140
3225
  if (evalResult.conditionsMet) {
3141
- const totalDiscountApplied = applyDiscountToOrderLines(lines, evalResult, discountRow.maxDiscountAmount);
3226
+ const totalDiscountApplied = applyDiscountToOrderLines(lines, evalResult, discountRow.maxDiscountAmount, exchangeRate);
3142
3227
  for (const line of lines) {
3143
3228
  if (!line.found || line.taxRate === 0) continue;
3144
3229
  const discountedAmount = line.subtotal - (line.discount ?? 0);
@@ -3554,6 +3639,12 @@ function createCrudHandler(dataSource, entityMap, options) {
3554
3639
  }
3555
3640
  const itemsSummary = parts.join(", ") || "\u2014";
3556
3641
  const { payments: _payments, ...orderWithoutPayments } = order;
3642
+ const rawPayStatus = String(orderPayments[0]?.status ?? "unpaid").toLowerCase();
3643
+ const orderStatus = String(order.status ?? "").toLowerCase();
3644
+ let paymentStatus2 = rawPayStatus;
3645
+ if (orderStatus === "cancelled" && rawPayStatus !== "paid" && rawPayStatus !== "captured" && rawPayStatus !== "refunded") {
3646
+ paymentStatus2 = "unpaid";
3647
+ }
3557
3648
  return {
3558
3649
  ...orderWithoutPayments,
3559
3650
  contact: contact ? {
@@ -3563,7 +3654,7 @@ function createCrudHandler(dataSource, entityMap, options) {
3563
3654
  phone: contact.phone
3564
3655
  } : null,
3565
3656
  itemsSummary,
3566
- paymentStatus: orderPayments[0]?.status ?? "unpaid"
3657
+ paymentStatus: paymentStatus2
3567
3658
  };
3568
3659
  }));
3569
3660
  return json({
@@ -5081,11 +5172,18 @@ function createCrudHandler(dataSource, entityMap, options) {
5081
5172
  await recordDiscountUsage2(dataSource, entityMap, created.id, orderDiscountId, persistBody.contactId, discount);
5082
5173
  }
5083
5174
  const orderIdForNotify = created.id;
5084
- void import('./emit-order-notification-trigger-HZQPPSFB.js').then(({ fireOrderNotificationTrigger }) => {
5175
+ const initialPayStatus = String(persistBody.paymentStatus ?? "unpaid").toLowerCase();
5176
+ void import('./emit-order-notification-trigger-CZU3V2WE.js').then(({ fireOrderNotificationTrigger }) => {
5085
5177
  fireOrderNotificationTrigger("order_placed", orderIdForNotify, {
5086
5178
  dataSource,
5087
5179
  entityMap
5088
5180
  });
5181
+ if (initialPayStatus === "paid" || initialPayStatus === "captured") {
5182
+ fireOrderNotificationTrigger("payment_success", orderIdForNotify, {
5183
+ dataSource,
5184
+ entityMap
5185
+ });
5186
+ }
5089
5187
  });
5090
5188
  }
5091
5189
  } catch (err) {
@@ -5448,6 +5546,9 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
5448
5546
  "payments"
5449
5547
  ]
5450
5548
  });
5549
+ if (order) {
5550
+ await autoExpireOrderIfPaymentTimeExceeded(dataSource, entityMap, order);
5551
+ }
5451
5552
  const orderDenied = await vendorScopeAccessJson(order, scope2, resource);
5452
5553
  if (orderDenied) return orderDenied;
5453
5554
  const relatedOrders = await repo.find({
@@ -6549,6 +6650,43 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6549
6650
  await retireSoftDeletedUniquesFromBody(repo, updatePayload);
6550
6651
  try {
6551
6652
  await repo.update(numericId, updatePayload);
6653
+ if (resource === "payments" && updatePayload.status) {
6654
+ const updatedPay = await repo.findOne({
6655
+ where: {
6656
+ id: numericId
6657
+ }
6658
+ });
6659
+ const pOrder = updatedPay?.orderId;
6660
+ const newPayStatus = String(updatePayload.status).toLowerCase();
6661
+ if (pOrder && Number.isFinite(pOrder)) {
6662
+ if (newPayStatus === "paid" || newPayStatus === "captured") {
6663
+ if (entityMap.orders) {
6664
+ await dataSource.getRepository(entityMap.orders).update(pOrder, {
6665
+ status: "confirmed"
6666
+ });
6667
+ }
6668
+ void import('./emit-order-notification-trigger-CZU3V2WE.js').then(({ fireOrderNotificationTrigger }) => {
6669
+ fireOrderNotificationTrigger("order_placed", pOrder, {
6670
+ dataSource,
6671
+ entityMap
6672
+ });
6673
+ fireOrderNotificationTrigger("payment_success", pOrder, {
6674
+ dataSource,
6675
+ entityMap
6676
+ });
6677
+ }).catch(() => {
6678
+ });
6679
+ } else if (newPayStatus === "failed") {
6680
+ void import('./emit-order-notification-trigger-CZU3V2WE.js').then(({ fireOrderNotificationTrigger }) => {
6681
+ fireOrderNotificationTrigger("payment_failed", pOrder, {
6682
+ dataSource,
6683
+ entityMap
6684
+ });
6685
+ }).catch(() => {
6686
+ });
6687
+ }
6688
+ }
6689
+ }
6552
6690
  } catch (err) {
6553
6691
  if (resource === "events" && isSlugUniqueViolation(err)) {
6554
6692
  return json({
@@ -9103,7 +9241,9 @@ function createFormSaveHandlers(config) {
9103
9241
  "description",
9104
9242
  "campaign",
9105
9243
  "slug",
9106
- "published"
9244
+ "published",
9245
+ "enableTurnstile",
9246
+ "enable_turnstile"
9107
9247
  ]) {
9108
9248
  if (body[key] !== void 0) formRow[key] = body[key];
9109
9249
  }
@@ -16999,6 +17139,7 @@ var Form = class {
16999
17139
  campaign;
17000
17140
  slug;
17001
17141
  published;
17142
+ enableTurnstile;
17002
17143
  createdAt;
17003
17144
  updatedAt;
17004
17145
  deletedAt;
@@ -17041,6 +17182,14 @@ _ts_decorate14([
17041
17182
  }),
17042
17183
  _ts_metadata14("design:type", Boolean)
17043
17184
  ], Form.prototype, "published", void 0);
17185
+ _ts_decorate14([
17186
+ Column("boolean", {
17187
+ default: false,
17188
+ name: "enable_turnstile",
17189
+ nullable: true
17190
+ }),
17191
+ _ts_metadata14("design:type", Boolean)
17192
+ ], Form.prototype, "enableTurnstile", void 0);
17044
17193
  _ts_decorate14([
17045
17194
  Column({
17046
17195
  type: "timestamp",
@@ -29178,7 +29327,7 @@ function createCmsApiHandler(config) {
29178
29327
  }
29179
29328
  if (path2[0] === "settings" && path2.length === 2 && settingsHandlers) {
29180
29329
  const group = path2[1];
29181
- const isPublic = group === "multi_vendor" || settingsConfig?.publicGetGroups?.includes(group);
29330
+ const isPublic = group === "multi_vendor" || group === "turnstile" || group === "auth_providers" || settingsConfig?.publicGetGroups?.includes(group);
29182
29331
  if (m === "GET") {
29183
29332
  if (!isPublic) {
29184
29333
  const a = await config.requireAuth(req);
@@ -29836,14 +29985,21 @@ function createCmsApiHandler(config) {
29836
29985
  body = {};
29837
29986
  }
29838
29987
  const triggerKey = String(body.triggerKey ?? "order_placed").trim() || "order_placed";
29839
- if (triggerKey !== "order_placed" && triggerKey !== "order_cancelled") {
29988
+ const validTriggers = [
29989
+ "order_placed",
29990
+ "order_cancelled",
29991
+ "payment_success",
29992
+ "payment_failed",
29993
+ "payment_refund_initiated"
29994
+ ];
29995
+ if (!validTriggers.includes(triggerKey)) {
29840
29996
  return config.json({
29841
- error: "Invalid triggerKey; use order_placed or order_cancelled"
29997
+ error: `Invalid triggerKey; use one of: ${validTriggers.join(", ")}`
29842
29998
  }, {
29843
29999
  status: 400
29844
30000
  });
29845
30001
  }
29846
- const { resendOrderNotification } = await import('./order-notification-dispatcher-64WDCHHG.js');
30002
+ const { resendOrderNotification } = await import('./order-notification-dispatcher-ZSFKEYMP.js');
29847
30003
  const result = await resendOrderNotification(triggerKey, orderId, {
29848
30004
  dataSource,
29849
30005
  entityMap,
@@ -29865,11 +30021,9 @@ function createCmsApiHandler(config) {
29865
30021
  if (path2[0] === "orders" && path2.length === 3 && path2[2] === "cancel" && m === "POST") {
29866
30022
  const a = await config.requireAuth(req);
29867
30023
  if (a) return a;
29868
- const pe = await requireEntityPermissionEffective(req, "orders", "update");
29869
- if (pe) return pe;
29870
- const orderId = Number(path2[1]);
29871
- if (!Number.isFinite(orderId)) return config.json({
29872
- error: "Invalid id"
30024
+ const orderId = parseInt(path2[1], 10);
30025
+ if (Number.isNaN(orderId)) return config.json({
30026
+ error: "Invalid order ID"
29873
30027
  }, {
29874
30028
  status: 400
29875
30029
  });
@@ -29886,9 +30040,10 @@ function createCmsApiHandler(config) {
29886
30040
  status: 404
29887
30041
  });
29888
30042
  const o = order;
29889
- if (o.status !== "confirmed" && o.status !== "completed") {
30043
+ const currentStatus = (o.status || "").toLowerCase();
30044
+ if (currentStatus === "cancelled") {
29890
30045
  return config.json({
29891
- error: "Only confirmed or completed orders can be cancelled"
30046
+ error: "Order is already cancelled"
29892
30047
  }, {
29893
30048
  status: 400
29894
30049
  });
@@ -29911,7 +30066,7 @@ function createCmsApiHandler(config) {
29911
30066
  }
29912
30067
  });
29913
30068
  if (payment) {
29914
- paymentStatus = String(payment.status ?? "unpaid");
30069
+ paymentStatus = String(payment.status ?? "unpaid").toLowerCase();
29915
30070
  paymentId = Number(payment.id);
29916
30071
  }
29917
30072
  }
@@ -29943,13 +30098,26 @@ function createCmsApiHandler(config) {
29943
30098
  status: "cancelled"
29944
30099
  });
29945
30100
  const fireOrderCancelledNotification = /* @__PURE__ */ __name((refundAmount) => {
29946
- void import('./emit-order-notification-trigger-HZQPPSFB.js').then(({ fireOrderNotificationTrigger }) => {
30101
+ void import('./emit-order-notification-trigger-CZU3V2WE.js').then(({ fireOrderNotificationTrigger }) => {
29947
30102
  fireOrderNotificationTrigger("order_cancelled", orderId, {
29948
30103
  dataSource,
29949
30104
  entityMap
29950
30105
  }, refundAmount != null && refundAmount > 0 ? {
29951
30106
  refundAmount
29952
30107
  } : void 0);
30108
+ if (paymentStatus === "paid" || paymentStatus === "captured") {
30109
+ fireOrderNotificationTrigger("payment_refund_initiated", orderId, {
30110
+ dataSource,
30111
+ entityMap
30112
+ }, refundAmount != null && refundAmount > 0 ? {
30113
+ refundAmount
30114
+ } : void 0);
30115
+ } else {
30116
+ fireOrderNotificationTrigger("payment_failed", orderId, {
30117
+ dataSource,
30118
+ entityMap
30119
+ });
30120
+ }
29953
30121
  });
29954
30122
  }, "fireOrderCancelledNotification");
29955
30123
  if (paymentStatus === "paid" && entityMap.payments && paymentId) {
@@ -30975,12 +31143,23 @@ function createStorefrontApiHandler(config) {
30975
31143
  const otpFlags = config.otpFlags;
30976
31144
  const otpPepper = config.otpPepper;
30977
31145
  const defaultPhoneCc = config.defaultPhoneCountryCode;
30978
- function fireOrderPlacedNotification(orderId) {
30979
- void import('./emit-order-notification-trigger-HZQPPSFB.js').then(({ fireOrderNotificationTrigger }) => {
31146
+ function fireOrderPlacedNotification(orderId, isPaid) {
31147
+ void import('./emit-order-notification-trigger-CZU3V2WE.js').then(({ fireOrderNotificationTrigger }) => {
30980
31148
  fireOrderNotificationTrigger("order_placed", orderId, {
30981
31149
  dataSource,
30982
31150
  entityMap
30983
31151
  });
31152
+ if (isPaid) {
31153
+ fireOrderNotificationTrigger("payment_success", orderId, {
31154
+ dataSource,
31155
+ entityMap
31156
+ });
31157
+ } else {
31158
+ fireOrderNotificationTrigger("payment_failed", orderId, {
31159
+ dataSource,
31160
+ entityMap
31161
+ });
31162
+ }
30984
31163
  }).catch((err) => console.error("[notification-triggers] import failed", err));
30985
31164
  }
30986
31165
  __name(fireOrderPlacedNotification, "fireOrderPlacedNotification");
@@ -32884,6 +33063,23 @@ function createStorefrontApiHandler(config) {
32884
33063
  });
32885
33064
  return json(body);
32886
33065
  }
33066
+ if (path2[0] === "cart" && path2.length === 1 && method === "DELETE") {
33067
+ const { cart, err } = await getOrCreateCart(req);
33068
+ if (err) return err;
33069
+ const cartId = cart?.id;
33070
+ if (cartId && Number.isFinite(cartId) && cartId > 0) {
33071
+ await cartItemRepo().delete({
33072
+ cartId
33073
+ });
33074
+ await cartRepo().update(cartId, {
33075
+ updatedAt: /* @__PURE__ */ new Date()
33076
+ });
33077
+ }
33078
+ return json({
33079
+ ok: true,
33080
+ message: "Cart cleared"
33081
+ });
33082
+ }
32887
33083
  if (path2[0] === "cart" && path2[1] === "items" && path2.length === 2 && method === "POST") {
32888
33084
  const body = await req.json().catch(() => ({}));
32889
33085
  const capCart = await assertCaptchaOk(getCms, body, req, json);
@@ -33403,7 +33599,8 @@ function createStorefrontApiHandler(config) {
33403
33599
  total: prepOrd.orderTotal,
33404
33600
  currency: cart.currency || "INR",
33405
33601
  metadata: {
33406
- cartId
33602
+ cartId,
33603
+ paymentExpiresAt: new Date(Date.now() + 10 * 60 * 1e3).toISOString()
33407
33604
  }
33408
33605
  }));
33409
33606
  const oid = ord.id;
@@ -33476,7 +33673,11 @@ function createStorefrontApiHandler(config) {
33476
33673
  tax: prepChk.orderTax,
33477
33674
  discount: 0,
33478
33675
  total: prepChk.orderTotal,
33479
- currency: cart.currency || "INR"
33676
+ currency: cart.currency || "INR",
33677
+ metadata: {
33678
+ cartId: cart.id,
33679
+ paymentExpiresAt: new Date(Date.now() + 10 * 60 * 1e3).toISOString()
33680
+ }
33480
33681
  }));
33481
33682
  const oid = ord.id;
33482
33683
  await orderRepo().update(oid, {
@@ -33722,6 +33923,7 @@ function createStorefrontApiHandler(config) {
33722
33923
  status: 404
33723
33924
  });
33724
33925
  const o = order;
33926
+ await autoExpireOrderIfPaymentTimeExceeded(dataSource, entityMap, o);
33725
33927
  const lines = (o.items || []).map((line) => {
33726
33928
  const p = line.product;
33727
33929
  return {
@@ -33782,6 +33984,87 @@ function createStorefrontApiHandler(config) {
33782
33984
  fulfillmentPreview: fulfillmentPreview || void 0
33783
33985
  });
33784
33986
  }
33987
+ if (path2[0] === "orders" && path2.length === 3 && path2[2] === "cancel" && method === "POST") {
33988
+ const orderId = parseInt(path2[1], 10);
33989
+ if (!Number.isFinite(orderId)) return json({
33990
+ error: "Invalid order id"
33991
+ }, {
33992
+ status: 400
33993
+ });
33994
+ const order = await orderRepo().findOne({
33995
+ where: {
33996
+ id: orderId,
33997
+ deleted: false
33998
+ }
33999
+ });
34000
+ if (!order) return json({
34001
+ error: "Not found"
34002
+ }, {
34003
+ status: 404
34004
+ });
34005
+ const o = order;
34006
+ const status = String(o.status || "").toLowerCase();
34007
+ if (status === "pending") {
34008
+ const meta = typeof o.metadata === "object" && o.metadata ? o.metadata : {};
34009
+ const updatedMeta = {
34010
+ ...meta,
34011
+ cancelReason: "Cancelled by user during payment window"
34012
+ };
34013
+ await orderRepo().update(orderId, {
34014
+ status: "cancelled",
34015
+ metadata: updatedMeta
34016
+ });
34017
+ try {
34018
+ if (entityMap.payments) {
34019
+ const payRepo = dataSource.getRepository(entityMap.payments);
34020
+ const pendingPayment = await payRepo.findOne({
34021
+ where: {
34022
+ orderId,
34023
+ status: "pending"
34024
+ }
34025
+ });
34026
+ if (pendingPayment) {
34027
+ await payRepo.update(pendingPayment.id, {
34028
+ status: "unpaid"
34029
+ });
34030
+ }
34031
+ }
34032
+ } catch {
34033
+ }
34034
+ try {
34035
+ const { cart } = await getOrCreateCart(req);
34036
+ const cartId = cart?.id;
34037
+ if (cartId && Number.isFinite(cartId) && cartId > 0) {
34038
+ await cartItemRepo().delete({
34039
+ cartId
34040
+ });
34041
+ await cartRepo().update(cartId, {
34042
+ updatedAt: /* @__PURE__ */ new Date()
34043
+ });
34044
+ }
34045
+ } catch {
34046
+ }
34047
+ try {
34048
+ void import('./emit-order-notification-trigger-CZU3V2WE.js').then(({ fireOrderNotificationTrigger }) => {
34049
+ fireOrderNotificationTrigger("order_cancelled", orderId, {
34050
+ dataSource,
34051
+ entityMap
34052
+ });
34053
+ fireOrderNotificationTrigger("payment_failed", orderId, {
34054
+ dataSource,
34055
+ entityMap
34056
+ });
34057
+ }).catch(() => {
34058
+ });
34059
+ } catch {
34060
+ }
34061
+ }
34062
+ return json({
34063
+ ok: true,
34064
+ orderId,
34065
+ status: "cancelled"
34066
+ });
34067
+ }
33785
34068
  return json({
33786
34069
  error: "Not found"
33787
34070
  }, {
@@ -33799,4 +34082,4 @@ function createStorefrontApiHandler(config) {
33799
34082
  }
33800
34083
  __name(createStorefrontApiHandler, "createStorefrontApiHandler");
33801
34084
 
33802
- export { Address, Attendee, Attribute, BLOG_GENERATOR_AGENT_NAME, BLOG_GENERATOR_DEFAULT_SYSTEM_INSTRUCTION, BLOG_GENERATOR_DEFAULT_VALIDATION_RULES, BLOG_GENERATOR_LLM_AGENT_SLUG, BLOG_GENERATOR_MARKDOWN_ARTICLE_SEPARATOR, BLOG_METADATA_ENRICHER_AGENT_NAME, BLOG_METADATA_ENRICHER_DEFAULT_SYSTEM_INSTRUCTION, BLOG_METADATA_ENRICHER_DEFAULT_VALIDATION_RULES, BLOG_METADATA_ENRICHER_LLM_AGENT_SLUG, Blog, BlogGeneratorService, Brand, CMS_ENTITY_MAP, Cart, CartItem, Category, ChatConversation, ChatMessage, Collection, Combo, ComboItem, Comment, Config, Contact, Currency, CurrencyExchange, Customer, Customer_Contacts, Discount, DiscountRules, Event, EventProduct, Form, FormField, FormSubmission, JobSchedule, JobScheduleRun, KnowledgeBaseChunk, KnowledgeBaseDocument, LlmAgent, LlmAgentKnowledgeDocument, Media, MessageTemplate, Order, OrderAddresses, OrderDiscounts, OrderItem, OrderNotificationBinding, OrderNotificationTrigger, OtpChallenge, Page, PasswordResetToken, Payment, Permission, Product, ProductAttribute, ProductCategory, ProductConfig, ProductVariant, RefundPolicy, RefundRequest, RssArticle, RssFeed, Seo, Tag, Tax, User, UserDeviceToken, UserGroup, Vendor, VendorCustomer, VendorRole, VendorRolePermission, VendorUser, VendorUserProfile, Wishlist, WishlistItem, ZIP_MIME_TYPES, applyApprovalStatusSideEffects, applyEventApprovalStatusSideEffects, applyRotatingVendorInvite, applyVendorCustomersContactFilter, applyVendorEventCreateApproval, applyVendorProductCreateApproval, assertCaptchaOk, assertContactAllowedForVendorOrder, assertEventApprovalUpdate, assertProductApprovalUpdate, buildBlogMetadataUserPrompt, buildCronFromSchedule, buildRssUserPromptFromFeeds, buildUserInviteLink, buildVendorInviteLink, calculateOrderRefundPreview, calculateRefundFromPolicy, checkAndIncrementDiscountUsage, checkEventsEnabled, checkMultiVendorEnabled, completeUserInviteAccept, consumeAppliedDiscountUsages, contactIsVendorCustomer, countDiscountOrdersForContact, countRecentOtpSends, createAnalyticsHandlers, createBlogBySlugHandler, createChangePasswordHandler, createCmsApiHandler, createCmsApp, createCmsAppWithMessaging, createCrudByIdHandler, createCrudHandler, createDashboardStatsHandler, createEcommerceAnalyticsHandler, createEventOrderMessageTemplateHandlers, createForgotPasswordHandler, createFormBySlugHandler, createInviteAcceptHandler, createJobScheduleHandlers, createLlmAgentKnowledgeHandlers, createMediaZipExtractHandler, createMessageTemplateRowLoader, createOtpChallenge, createSetPasswordHandler, createSettingsApiHandlers, createSocialMediaHandlers, createStorefrontApiHandler, createUploadHandler, createUserAuthApiRouter, createUserAvatarHandler, createUserProfileHandler, createUsersApiHandlers, createVendorDashboardHandler, createVendorOnboardHandlers, daysBeforeEventStart, decrementDiscountUsage, describeEventTierPolicy, ensureMessagingPluginsOnCms, ensureScheduleQueueWorker, ensureVendorCustomerForOrderContact, ensureVendorCustomersForOrder, findActiveRefundPolicyForVendor, findUserByInviteToken, findVendorByInviteToken, formatTierRange, generateNumericOtp, getPublicSettingsGroup, getRequireEventApproval, getRequireProductApproval, getRssArticleSummaryFromItem, getVendorCatalogCreateFlags, hashOtpCode, hydrateVendorSessionUser, invalidateEventsCache, invalidateMultiVendorCache, invalidateRequireEventApprovalCache, invalidateRequireProductApprovalCache, invalidateVendorCatalogCreateFlagsCache, isCustomerTypeContact, isMaxPerUserUsageReached, isMaxTotalUsageReached, isZipMedia, llmAgentToChatAgentOptions, loadSettingsGroupFromDb, loadUserVendorContext, mergeGuardrailsIntoSystemPrompt, messagingPlugins, metaFetchUserManagedPages, metaPostPageFeed, metaPostPagePhoto, metaResolvePageAccessToken, newUserInviteToken, normalizePhoneE164, normalizeRefundTiers, overlayCmsPlugins, parseBlogGeneratorAgentContent, parseBlogGeneratorModelOutput, parseBlogMetadataEnrichmentJson, parseLlmAgentValidationRules, pgBossScheduleNameForId, queueErpCreateContactIfEnabled, queueJobScheduleNow, queuePlugin, queueSms, recordDiscountUsage, registerJobRunnerWorker, registerMessagingQueueProcessors, registerSmsQueueProcessor, relativePathFromMediaParentId, resolveBlogCategoryIdByName, resolveSettingsEncryptionKey, resolveVendorIdForContactCheck, sanitizeMediaFolderPath, sanitizeStorageSegment, sendVendorOnboardEmails, simpleDecrypt, simpleEncrypt, syncJobScheduleToPgBoss, validateRefundTiers, validateScheduleInput, validateUserMessageAgainstAgentRules, validateUserMessageAgainstStructuredRules, verifyAndConsumeOtpChallenge, verifyOtpCodeHash, whatsappPlugin, wrapGetCmsWithMessaging };
34085
+ export { Address, Attendee, Attribute, BLOG_GENERATOR_AGENT_NAME, BLOG_GENERATOR_DEFAULT_SYSTEM_INSTRUCTION, BLOG_GENERATOR_DEFAULT_VALIDATION_RULES, BLOG_GENERATOR_LLM_AGENT_SLUG, BLOG_GENERATOR_MARKDOWN_ARTICLE_SEPARATOR, BLOG_METADATA_ENRICHER_AGENT_NAME, BLOG_METADATA_ENRICHER_DEFAULT_SYSTEM_INSTRUCTION, BLOG_METADATA_ENRICHER_DEFAULT_VALIDATION_RULES, BLOG_METADATA_ENRICHER_LLM_AGENT_SLUG, Blog, BlogGeneratorService, Brand, CMS_ENTITY_MAP, Cart, CartItem, Category, ChatConversation, ChatMessage, Collection, Combo, ComboItem, Comment, Config, Contact, Currency, CurrencyExchange, Customer, Customer_Contacts, Discount, DiscountRules, Event, EventProduct, Form, FormField, FormSubmission, JobSchedule, JobScheduleRun, KnowledgeBaseChunk, KnowledgeBaseDocument, LlmAgent, LlmAgentKnowledgeDocument, Media, MessageTemplate, Order, OrderAddresses, OrderDiscounts, OrderItem, OrderNotificationBinding, OrderNotificationTrigger, OtpChallenge, Page, PasswordResetToken, Payment, Permission, Product, ProductAttribute, ProductCategory, ProductConfig, ProductVariant, RefundPolicy, RefundRequest, RssArticle, RssFeed, Seo, Tag, Tax, User, UserDeviceToken, UserGroup, Vendor, VendorCustomer, VendorRole, VendorRolePermission, VendorUser, VendorUserProfile, Wishlist, WishlistItem, ZIP_MIME_TYPES, applyApprovalStatusSideEffects, applyEventApprovalStatusSideEffects, applyRotatingVendorInvite, applyVendorCustomersContactFilter, applyVendorEventCreateApproval, applyVendorProductCreateApproval, assertCaptchaOk, assertContactAllowedForVendorOrder, assertEventApprovalUpdate, assertProductApprovalUpdate, autoExpireOrderIfPaymentTimeExceeded, buildBlogMetadataUserPrompt, buildCronFromSchedule, buildRssUserPromptFromFeeds, buildUserInviteLink, buildVendorInviteLink, calculateOrderRefundPreview, calculateRefundFromPolicy, checkAndIncrementDiscountUsage, checkEventsEnabled, checkMultiVendorEnabled, completeUserInviteAccept, consumeAppliedDiscountUsages, contactIsVendorCustomer, countDiscountOrdersForContact, countRecentOtpSends, createAnalyticsHandlers, createBlogBySlugHandler, createChangePasswordHandler, createCmsApiHandler, createCmsApp, createCmsAppWithMessaging, createCrudByIdHandler, createCrudHandler, createDashboardStatsHandler, createEcommerceAnalyticsHandler, createEventOrderMessageTemplateHandlers, createForgotPasswordHandler, createFormBySlugHandler, createInviteAcceptHandler, createJobScheduleHandlers, createLlmAgentKnowledgeHandlers, createMediaZipExtractHandler, createMessageTemplateRowLoader, createOtpChallenge, createSetPasswordHandler, createSettingsApiHandlers, createSocialMediaHandlers, createStorefrontApiHandler, createUploadHandler, createUserAuthApiRouter, createUserAvatarHandler, createUserProfileHandler, createUsersApiHandlers, createVendorDashboardHandler, createVendorOnboardHandlers, daysBeforeEventStart, decrementDiscountUsage, describeEventTierPolicy, ensureMessagingPluginsOnCms, ensureScheduleQueueWorker, ensureVendorCustomerForOrderContact, ensureVendorCustomersForOrder, findActiveRefundPolicyForVendor, findUserByInviteToken, findVendorByInviteToken, formatTierRange, generateNumericOtp, getPublicSettingsGroup, getRequireEventApproval, getRequireProductApproval, getRssArticleSummaryFromItem, getVendorCatalogCreateFlags, hashOtpCode, hydrateVendorSessionUser, invalidateEventsCache, invalidateMultiVendorCache, invalidateRequireEventApprovalCache, invalidateRequireProductApprovalCache, invalidateVendorCatalogCreateFlagsCache, isCustomerTypeContact, isMaxPerUserUsageReached, isMaxTotalUsageReached, isZipMedia, llmAgentToChatAgentOptions, loadSettingsGroupFromDb, loadUserVendorContext, mergeGuardrailsIntoSystemPrompt, messagingPlugins, metaFetchUserManagedPages, metaPostPageFeed, metaPostPagePhoto, metaResolvePageAccessToken, newUserInviteToken, normalizePhoneE164, normalizeRefundTiers, overlayCmsPlugins, parseBlogGeneratorAgentContent, parseBlogGeneratorModelOutput, parseBlogMetadataEnrichmentJson, parseLlmAgentValidationRules, pgBossScheduleNameForId, queueErpCreateContactIfEnabled, queueJobScheduleNow, queuePlugin, queueSms, recordDiscountUsage, registerJobRunnerWorker, registerMessagingQueueProcessors, registerSmsQueueProcessor, relativePathFromMediaParentId, resolveBlogCategoryIdByName, resolveSettingsEncryptionKey, resolveVendorIdForContactCheck, sanitizeMediaFolderPath, sanitizeStorageSegment, sendVendorOnboardEmails, simpleDecrypt, simpleEncrypt, syncJobScheduleToPgBoss, validateRefundTiers, validateScheduleInput, validateUserMessageAgainstAgentRules, validateUserMessageAgainstStructuredRules, verifyAndConsumeOtpChallenge, verifyOtpCodeHash, whatsappPlugin, wrapGetCmsWithMessaging };