@infuro/cms-core 1.0.66 → 1.0.68

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 (57) hide show
  1. package/dist/admin.cjs +214 -32
  2. package/dist/admin.js +214 -32
  3. package/dist/api.cjs +45 -42
  4. package/dist/api.js +12 -9
  5. package/dist/auth.cjs +51 -51
  6. package/dist/auth.js +3 -3
  7. package/dist/{chunk-QYRXLURF.cjs → chunk-22XKONB5.cjs} +640 -145
  8. package/dist/{chunk-MVHDC3XF.js → chunk-5NOZSG6J.js} +22 -11
  9. package/dist/{chunk-TU23GJPJ.js → chunk-7JCCPQEF.js} +1 -1
  10. package/dist/{chunk-WMMZZRDJ.cjs → chunk-GN4LKG4V.cjs} +1 -1
  11. package/dist/{chunk-KM2I6AFP.cjs → chunk-HBUV73RB.cjs} +9 -9
  12. package/dist/chunk-IKTBZJHT.js +16 -0
  13. package/dist/chunk-M5GPOPGX.cjs +49 -0
  14. package/dist/{chunk-T33KU5G5.js → chunk-MYUGQHU4.js} +548 -53
  15. package/dist/{chunk-NV5IRHI3.js → chunk-N4LBZXBG.js} +2 -2
  16. package/dist/{chunk-J7FMZK66.cjs → chunk-O4AFPDQ4.cjs} +22 -11
  17. package/dist/{chunk-4U6DATGZ.cjs → chunk-OV5TRZET.cjs} +7 -7
  18. package/dist/chunk-P6S4XFZO.cjs +18 -0
  19. package/dist/{chunk-RCE5SJBA.js → chunk-SKJH7PX4.js} +1 -1
  20. package/dist/{chunk-5MZFQRDW.cjs → chunk-SMHQV3WL.cjs} +4 -4
  21. package/dist/chunk-SUUD7OUG.cjs +455 -0
  22. package/dist/{chunk-XFDIIVZB.cjs → chunk-UMC7W5G3.cjs} +3 -3
  23. package/dist/chunk-WKDBMDUX.js +45 -0
  24. package/dist/{chunk-6DBDJ4VD.js → chunk-Z5G54EGD.js} +2 -2
  25. package/dist/chunk-Z5OB5QGN.js +465 -0
  26. package/dist/chunk-ZIT4IP6N.js +445 -0
  27. package/dist/chunk-ZX5U3VCB.cjs +471 -0
  28. package/dist/{chunk-NR44CK5E.js → chunk-ZY64VJMS.js} +1 -1
  29. package/dist/email-queue-3QBQ63F7.js +8 -0
  30. package/dist/{email-queue-4OY45JIU.cjs → email-queue-K4E4OFI7.cjs} +9 -6
  31. package/dist/{emit-order-notification-trigger-ZD5YN3JM.cjs → emit-order-notification-trigger-ROASTYQP.cjs} +3 -3
  32. package/dist/{emit-order-notification-trigger-EJJZ6XTS.js → emit-order-notification-trigger-YUQTPELC.js} +1 -1
  33. package/dist/{erp-order-invoice-YUSPZ7CE.cjs → erp-order-invoice-AZ5MX2JB.cjs} +8 -5
  34. package/dist/{erp-order-invoice-H6HCJ7YS.js → erp-order-invoice-XSYHAMBS.js} +4 -1
  35. package/dist/generate-local-invoice-pdf-BQTCL5MW.cjs +12 -0
  36. package/dist/generate-local-invoice-pdf-OCFG47SE.js +3 -0
  37. package/dist/index.cjs +337 -330
  38. package/dist/index.d.cts +21 -2
  39. package/dist/index.d.ts +21 -2
  40. package/dist/index.js +18 -15
  41. package/dist/invoice-templates-GZ33OENC.js +2 -0
  42. package/dist/invoice-templates-RB462AQN.cjs +19 -0
  43. package/dist/migrations/1783300000000-CreateOrderAssigneesTable.ts +43 -0
  44. package/dist/{order-assignees-handlers-NPKD64P6.cjs → order-assignees-handlers-KF7RMTV5.cjs} +77 -8
  45. package/dist/{order-assignees-handlers-LKMAGLG6.js → order-assignees-handlers-L3RVKUBS.js} +77 -8
  46. package/dist/{order-completion-otp-handlers-NK65LOLV.cjs → order-completion-otp-handlers-DDQREULW.cjs} +75 -18
  47. package/dist/{order-completion-otp-handlers-LFRHXWK4.js → order-completion-otp-handlers-NROWBGXN.js} +73 -16
  48. package/dist/{order-notification-dispatcher-LL7ETKLU.cjs → order-notification-dispatcher-6HCJ6Q75.cjs} +12 -9
  49. package/dist/{order-notification-dispatcher-ECPFI7CD.js → order-notification-dispatcher-KM2SY7TX.js} +7 -4
  50. package/dist/{rbac-debug-db-5R6XFPSV.js → rbac-debug-db-DFZWZ6GV.js} +1 -1
  51. package/dist/{rbac-debug-db-JKK2MCWF.cjs → rbac-debug-db-KWV7D5PQ.cjs} +2 -2
  52. package/dist/resolve-invoice-asset-url-JEZRENJW.cjs +11 -0
  53. package/dist/resolve-invoice-asset-url-QZ2FRDHI.js +2 -0
  54. package/package.json +1 -1
  55. package/dist/chunk-GLD263KW.cjs +0 -862
  56. package/dist/chunk-OPJEV44S.js +0 -847
  57. package/dist/email-queue-HGXB2FIS.js +0 -5
@@ -1,18 +1,18 @@
1
+ import { inviteStatusForActivation } from './chunk-JXF23MPG.js';
1
2
  import { normalizePhoneE164, generateNumericOtp, createOtpChallenge, queueSms, verifyAndConsumeOtpChallenge } from './chunk-OVTOP42W.js';
3
+ import { EVENT_ORDER_MESSAGE_TEMPLATE_DEFAULTS, EVENT_ORDER_TEMPLATE_KEY, EVENT_ORDER_TEMPLATE_VARIABLES } from './chunk-AYERBA7I.js';
2
4
  import { JOB_RUNNER_QUEUE } from './chunk-XJNNOSJR.js';
3
5
  import { validateInventoryForConfirmedOrderLines, orderStatusHoldsStock, reconcileOrderInventoryBetweenSnapshots, orderInventorySnapshotFromRow, validateInventoryForOrderBecomingConfirmed } from './chunk-3K5AIEIZ.js';
4
- import { resolveChatEmailToolSettings, CHAT_EMAIL_LOG, detectChatLeadIntent, parseIntentRecipientEmails, sendChatLeadEmail, buildTranscriptForLeadEmail, buildChatbotSystemPromptWithEmailTool, validateFcmCredentials, sendFcmPushNotification, parseEmailRecipientsFromConfig, isWhatsAppPluginEnabled, WhatsAppService, emailPlugin, initWhatsappTriggerDispatcher } from './chunk-NV5IRHI3.js';
6
+ import { resolveChatEmailToolSettings, CHAT_EMAIL_LOG, detectChatLeadIntent, parseIntentRecipientEmails, sendChatLeadEmail, buildTranscriptForLeadEmail, buildChatbotSystemPromptWithEmailTool, validateFcmCredentials, sendFcmPushNotification, parseEmailRecipientsFromConfig, isWhatsAppPluginEnabled, WhatsAppService, emailPlugin, initWhatsappTriggerDispatcher } from './chunk-N4LBZXBG.js';
5
7
  import { registerWhatsAppQueueProcessor } from './chunk-GWDI752Q.js';
6
- import { inviteStatusForActivation } from './chunk-JXF23MPG.js';
7
- import { queueEmail, queueVendorOnboardEmails, registerEmailQueueProcessor } from './chunk-TU23GJPJ.js';
8
- import { unwrapErpReadData, mapErpPayloadToFulfillment, extractChildOrderRefsFromSalePayload, mapErpPayloadToInvoiceNumber, streamOrderInvoicePdf } from './chunk-OPJEV44S.js';
8
+ import { queueEmail, queueVendorOnboardEmails, registerEmailQueueProcessor } from './chunk-7JCCPQEF.js';
9
+ import { unwrapErpReadData, mapErpPayloadToFulfillment, extractChildOrderRefsFromSalePayload, mapErpPayloadToInvoiceNumber, streamOrderInvoicePdf } from './chunk-ZIT4IP6N.js';
9
10
  import { isErpIntegrationEnabled } from './chunk-JC6DLWTE.js';
10
11
  import { mergeEmailLayoutCompanyDetails } from './chunk-YRCKEGL2.js';
11
12
  import { getSmsTemplateDefault, SMS_MESSAGE_TEMPLATE_DEFAULTS } from './chunk-MQBT33IV.js';
12
- import { EVENT_ORDER_MESSAGE_TEMPLATE_DEFAULTS, EVENT_ORDER_TEMPLATE_KEY, EVENT_ORDER_TEMPLATE_VARIABLES } from './chunk-AYERBA7I.js';
13
- import { ensureCustomerRecord, linkUnclaimedContactToUser, ensureCustomerForUser, canManageRoles, sessionHasEntityAccess } from './chunk-NR44CK5E.js';
13
+ import { ensureCustomerRecord, linkUnclaimedContactToUser, ensureCustomerForUser, canManageRoles, sessionHasEntityAccess } from './chunk-ZY64VJMS.js';
14
+ 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-5NOZSG6J.js';
14
15
  import { retireSoftDeletedUniqueValue, activeUniqueValueExists } from './chunk-DBPSJYLZ.js';
15
- 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';
16
16
  import { queueErp } from './chunk-SYBOCAWB.js';
17
17
  import { __name } from './chunk-SHUYVCID.js';
18
18
  import { PrimaryGeneratedColumn, Column, Entity, ManyToOne, JoinColumn, CreateDateColumn, UpdateDateColumn, Unique, OneToMany, Index, ManyToMany, JoinTable, In, ILike, Between, MoreThanOrEqual, LessThanOrEqual, Not, MoreThan, IsNull } from 'typeorm';
@@ -1674,6 +1674,30 @@ function entityHasSoftDelete(repo) {
1674
1674
  return repo.metadata.columns.some((c) => c.propertyName === "deleted");
1675
1675
  }
1676
1676
  __name(entityHasSoftDelete, "entityHasSoftDelete");
1677
+ async function recordOrderAssigneeHistory(dataSource, entityMap, orderId, userId, vendorId) {
1678
+ if (!entityMap.order_assignees) return 1;
1679
+ const assigneeRepo = dataSource.getRepository(entityMap.order_assignees);
1680
+ const maxRow = await assigneeRepo.findOne({
1681
+ where: {
1682
+ orderId
1683
+ },
1684
+ order: {
1685
+ sortOrder: "DESC"
1686
+ }
1687
+ });
1688
+ const currentMax = Number(maxRow?.sortOrder ?? 0);
1689
+ const nextSortOrder = currentMax + 1;
1690
+ await assigneeRepo.save({
1691
+ orderId,
1692
+ userId,
1693
+ vendorId,
1694
+ sortOrder: nextSortOrder,
1695
+ assignedAt: /* @__PURE__ */ new Date()
1696
+ });
1697
+ console.log(`[ORDERS-DEBUG][ASSIGNEE_HISTORY] Recorded assignment for order ${orderId}: user ${userId}, vendor ${vendorId}, sortOrder ${nextSortOrder}`);
1698
+ return nextSortOrder;
1699
+ }
1700
+ __name(recordOrderAssigneeHistory, "recordOrderAssigneeHistory");
1677
1701
  var LIST_QUERY_RESERVED = /* @__PURE__ */ new Set([
1678
1702
  "page",
1679
1703
  "limit",
@@ -3556,10 +3580,38 @@ function createCrudHandler(dataSource, entityMap, options) {
3556
3580
  });
3557
3581
  }
3558
3582
  }
3559
- const qb = repo2.createQueryBuilder("order").leftJoinAndSelect("order.contact", "contact").leftJoinAndSelect("order.items", "items").leftJoinAndSelect("items.product", "product").leftJoinAndSelect("product.collection", "collection").leftJoinAndSelect("order.payments", "payments").leftJoinAndSelect("order.assignedUser", "assignedUser").andWhere("order.deleted = :orderDel", {
3583
+ const qb = repo2.createQueryBuilder("order").leftJoinAndSelect("order.contact", "contact").leftJoinAndSelect("order.items", "items").leftJoinAndSelect("items.product", "product").leftJoinAndSelect("product.collection", "collection").leftJoinAndSelect("order.payments", "payments").leftJoinAndSelect("order.assignedUser", "assignedUser").leftJoinAndSelect("order.vendor", "vendor").andWhere("order.deleted = :orderDel", {
3560
3584
  orderDel: false
3561
3585
  }).orderBy(`order.${sortField2}`, sortOrderOrders).skip(skip).take(limit);
3562
- applyVendorScopeToQueryBuilder(qb, "order", scope);
3586
+ const session = await getHydratedSessionUser?.() ?? null;
3587
+ console.log("[ORDERS-DEBUG][LIST] Querying orders. Session:", {
3588
+ id: session?.id,
3589
+ email: session?.email,
3590
+ role: session?.role,
3591
+ isRBACAdmin: session?.isRBACAdmin,
3592
+ isVendorPortal: session?.isVendorPortal,
3593
+ isVendorOwner: session?.isVendorOwner,
3594
+ isVendorRoleOwner: session?.isVendorRoleOwner,
3595
+ vendorIds: session?.vendorIds,
3596
+ activeVendorId: session?.activeVendorId
3597
+ }, "Scope:", scope);
3598
+ if (scope.type === "deny") {
3599
+ qb.andWhere("1 = 0");
3600
+ } else if (scope.type === "vendor") {
3601
+ const isOwner = Boolean(session?.isVendorOwner || session?.isVendorRoleOwner || session?.isRBACAdmin);
3602
+ console.log("[ORDERS-DEBUG][LIST] Vendor scope applied. isOwner:", isOwner, "vendorId:", scope.vendorId);
3603
+ if (isOwner) {
3604
+ qb.andWhere('(order.vendorId = :vendorScopeId OR order.assignedUserId IN (SELECT vu."userId" FROM vendor_users vu WHERE vu."vendorId" = :vendorScopeId))', {
3605
+ vendorScopeId: scope.vendorId
3606
+ });
3607
+ } else {
3608
+ const teamMemberId = Number(session?.id);
3609
+ console.log("[ORDERS-DEBUG][LIST] Team member scoping to teamMemberId:", teamMemberId);
3610
+ qb.andWhere("order.assignedUserId = :teamMemberId", {
3611
+ teamMemberId
3612
+ });
3613
+ }
3614
+ }
3563
3615
  const vendorIdFilter = searchParams.get("vendorId")?.trim();
3564
3616
  if (vendorIdFilter) {
3565
3617
  const n = Number(vendorIdFilter);
@@ -3612,7 +3664,15 @@ function createCrudHandler(dataSource, entityMap, options) {
3612
3664
  });
3613
3665
  }
3614
3666
  }
3667
+ console.log("[ORDERS-DEBUG][LIST] Executing SQL:", qb.getSql(), "Params:", qb.getParameters());
3615
3668
  const [rows, total2] = await qb.getManyAndCount();
3669
+ console.log("[ORDERS-DEBUG][LIST] Query result: total =", total2, "rows length =", rows.length, "Orders:", rows.map((r) => ({
3670
+ id: r.id,
3671
+ orderNumber: r.orderNumber,
3672
+ vendorId: r.vendorId,
3673
+ assignedUserId: r.assignedUserId,
3674
+ status: r.status
3675
+ })));
3616
3676
  const data2 = await Promise.all(rows.map(async (order) => {
3617
3677
  await autoExpireOrderIfPaymentTimeExceeded(dataSource, entityMap, order);
3618
3678
  const contact = order.contact;
@@ -3656,6 +3716,7 @@ function createCrudHandler(dataSource, entityMap, options) {
3656
3716
  if (orderStatus === "cancelled" && rawPayStatus !== "paid" && rawPayStatus !== "captured" && rawPayStatus !== "refunded") {
3657
3717
  paymentStatus2 = "unpaid";
3658
3718
  }
3719
+ const vendorObj = order.vendor;
3659
3720
  return {
3660
3721
  ...orderWithoutPayments,
3661
3722
  contact: contact ? {
@@ -3669,6 +3730,11 @@ function createCrudHandler(dataSource, entityMap, options) {
3669
3730
  name: assignedUserObj.name || assignedUserObj.email,
3670
3731
  email: assignedUserObj.email
3671
3732
  } : null,
3733
+ vendor: vendorObj ? {
3734
+ id: vendorObj.id,
3735
+ name: vendorObj.name || vendorObj.slug || `Vendor #${vendorObj.id}`,
3736
+ slug: vendorObj.slug
3737
+ } : null,
3672
3738
  itemsSummary,
3673
3739
  paymentStatus: paymentStatus2
3674
3740
  };
@@ -4201,6 +4267,18 @@ function createCrudHandler(dataSource, entityMap, options) {
4201
4267
  isCatalog: true
4202
4268
  });
4203
4269
  }
4270
+ } else if (resource === "orders" && scope.type === "vendor") {
4271
+ const session = await getHydratedSessionUser?.() ?? null;
4272
+ const isOwner = Boolean(session?.isVendorOwner || session?.isVendorRoleOwner || session?.isRBACAdmin);
4273
+ if (!isOwner) {
4274
+ const teamMemberId = Number(session?.id);
4275
+ where = mergeListWhereAnd(where, {
4276
+ vendorId: scope.vendorId,
4277
+ assignedUserId: teamMemberId
4278
+ });
4279
+ } else {
4280
+ where = mergeVendorScopeIntoWhere(where, scope, resource, catalogFlags);
4281
+ }
4204
4282
  } else {
4205
4283
  where = mergeVendorScopeIntoWhere(where, scope, resource, catalogFlags);
4206
4284
  }
@@ -5165,6 +5243,12 @@ function createCrudHandler(dataSource, entityMap, options) {
5165
5243
  shippingAddressId: savedShipping?.id ?? null
5166
5244
  });
5167
5245
  }
5246
+ if (persistBody.assignedUserId) {
5247
+ const initAssignee = Number(persistBody.assignedUserId);
5248
+ if (Number.isFinite(initAssignee) && initAssignee > 0) {
5249
+ await recordOrderAssigneeHistory(dataSource, entityMap, created.id, initAssignee, Number(created.vendorId) || null);
5250
+ }
5251
+ }
5168
5252
  const reloadedOrder = await repo.findOne({
5169
5253
  where: {
5170
5254
  id: created.id,
@@ -5229,7 +5313,7 @@ function createCrudHandler(dataSource, entityMap, options) {
5229
5313
  const orderIdForNotify = created.id;
5230
5314
  const finalCreatedStatus = String(created.status ?? createdStatus ?? "pending").toLowerCase();
5231
5315
  const initialPayStatus = String(persistBody.paymentStatus ?? body.paymentStatus ?? "unpaid").toLowerCase();
5232
- void import('./emit-order-notification-trigger-EJJZ6XTS.js').then(({ fireOrderNotificationTrigger }) => {
5316
+ void import('./emit-order-notification-trigger-YUQTPELC.js').then(({ fireOrderNotificationTrigger }) => {
5233
5317
  if (finalCreatedStatus === "pending") {
5234
5318
  if (initialPayStatus === "failed") {
5235
5319
  fireOrderNotificationTrigger("payment_failed", orderIdForNotify, {
@@ -5484,7 +5568,16 @@ function createCrudHandler(dataSource, entityMap, options) {
5484
5568
  const scope = await resolveScope();
5485
5569
  const flags = await getVendorCatalogCreateFlags(dataSource);
5486
5570
  if (scope.type !== "all") {
5487
- data = data.filter((row) => vendorScopeRowAccess(row, scope, resource, flags) === "ok");
5571
+ const session = await getHydratedSessionUser?.() ?? null;
5572
+ const isOwner = Boolean(session?.isVendorOwner || session?.isVendorRoleOwner || session?.isRBACAdmin);
5573
+ const teamMemberId = Number(session?.id);
5574
+ data = data.filter((row) => {
5575
+ if (vendorScopeRowAccess(row, scope, resource, flags) !== "ok") return false;
5576
+ if (resource === "orders" && scope.type === "vendor" && !isOwner) {
5577
+ return Number(row?.assignedUserId) === teamMemberId;
5578
+ }
5579
+ return true;
5580
+ });
5488
5581
  }
5489
5582
  const excludeCols = /* @__PURE__ */ new Set([
5490
5583
  "deletedAt",
@@ -5522,6 +5615,51 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
5522
5615
  type: "all"
5523
5616
  }));
5524
5617
  async function vendorScopeAccessJson(row, scope, resource) {
5618
+ if (!row) return json({
5619
+ message: "Not found"
5620
+ }, {
5621
+ status: 404
5622
+ });
5623
+ if (resource === "orders" && scope.type === "vendor") {
5624
+ const rowVendorId = Number(row?.vendorId);
5625
+ let orderBelongsToVendorScope = rowVendorId === scope.vendorId;
5626
+ if (!orderBelongsToVendorScope) {
5627
+ const aId = Number(row?.assignedUserId);
5628
+ if (Number.isFinite(aId) && aId > 0 && entityMap["vendor_users"]) {
5629
+ const vuRepo = dataSource.getRepository(entityMap["vendor_users"]);
5630
+ const isTeamMember = await vuRepo.count({
5631
+ where: {
5632
+ vendorId: scope.vendorId,
5633
+ userId: aId
5634
+ }
5635
+ });
5636
+ if (isTeamMember > 0) {
5637
+ orderBelongsToVendorScope = true;
5638
+ }
5639
+ }
5640
+ }
5641
+ if (!orderBelongsToVendorScope) {
5642
+ return json({
5643
+ error: "Forbidden"
5644
+ }, {
5645
+ status: 403
5646
+ });
5647
+ }
5648
+ const session = await getHydratedSessionUser?.() ?? null;
5649
+ const isOwner = Boolean(session?.isVendorOwner || session?.isVendorRoleOwner || session?.isRBACAdmin);
5650
+ if (!isOwner) {
5651
+ const sessionUserId = Number(session?.id);
5652
+ const orderAssignee = Number(row?.assignedUserId);
5653
+ if (!Number.isFinite(orderAssignee) || orderAssignee !== sessionUserId) {
5654
+ return json({
5655
+ error: "Forbidden: You can only access orders assigned directly to you"
5656
+ }, {
5657
+ status: 403
5658
+ });
5659
+ }
5660
+ }
5661
+ return null;
5662
+ }
5525
5663
  const flags = await getVendorCatalogCreateFlags(dataSource);
5526
5664
  const access = vendorScopeRowAccess(row, scope, resource, flags);
5527
5665
  if (access === "ok") return null;
@@ -5646,6 +5784,17 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
5646
5784
  }
5647
5785
  if (resource === "orders") {
5648
5786
  const scope2 = await resolveScopeById();
5787
+ const session = await getHydratedSessionUser?.() ?? null;
5788
+ console.log("[ORDERS-DEBUG][GET_BY_ID] Fetching order id:", id, "Scope:", scope2, "Session:", {
5789
+ id: session?.id,
5790
+ email: session?.email,
5791
+ role: session?.role,
5792
+ isRBACAdmin: session?.isRBACAdmin,
5793
+ isVendorOwner: session?.isVendorOwner,
5794
+ isVendorRoleOwner: session?.isVendorRoleOwner,
5795
+ activeVendorId: session?.activeVendorId,
5796
+ vendorIds: session?.vendorIds
5797
+ });
5649
5798
  const order = await repo.findOne({
5650
5799
  where: {
5651
5800
  id: Number(id)
@@ -5658,14 +5807,26 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
5658
5807
  "items.product",
5659
5808
  "items.product.collection",
5660
5809
  "payments",
5661
- "assignedUser"
5810
+ "assignedUser",
5811
+ "vendor"
5662
5812
  ]
5663
5813
  });
5814
+ console.log("[ORDERS-DEBUG][GET_BY_ID] Order found in DB:", order ? {
5815
+ id: order.id,
5816
+ orderNumber: order.orderNumber,
5817
+ vendorId: order.vendorId,
5818
+ assignedUserId: order.assignedUserId,
5819
+ status: order.status
5820
+ } : null);
5664
5821
  if (order) {
5665
5822
  await autoExpireOrderIfPaymentTimeExceeded(dataSource, entityMap, order);
5666
5823
  }
5667
5824
  const orderDenied = await vendorScopeAccessJson(order, scope2, resource);
5668
- if (orderDenied) return orderDenied;
5825
+ if (orderDenied) {
5826
+ console.log("[ORDERS-DEBUG][GET_BY_ID] Access DENIED for order id:", id);
5827
+ return orderDenied;
5828
+ }
5829
+ console.log("[ORDERS-DEBUG][GET_BY_ID] Access GRANTED for order id:", id);
5669
5830
  const relatedOrders = await repo.find({
5670
5831
  where: {
5671
5832
  parentOrderId: Number(id)
@@ -6049,21 +6210,67 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6049
6210
  lines: []
6050
6211
  } : await calculateOrderTotalsFromLines(dataSource, entityMap, orderLinesNorm, effectiveCurrency, putDiscountId, Number.isFinite(putOrderVendorId) ? putOrderVendorId : null);
6051
6212
  const scalarUpdate = pickColumnUpdates(repo, rawBody);
6052
- if (rawBody && typeof rawBody === "object" && "assignedUserId" in rawBody && rawBody.assignedUserId !== void 0) {
6053
- const aId = Number(rawBody.assignedUserId);
6054
- if (Number.isFinite(aId) && aId > 0) {
6055
- scalarUpdate.assignedUserId = aId;
6056
- scalarUpdate.assignedAt = /* @__PURE__ */ new Date();
6057
- } else {
6058
- scalarUpdate.assignedUserId = null;
6059
- scalarUpdate.assignedAt = null;
6213
+ if (rawBody && typeof rawBody === "object") {
6214
+ if (scopePutEarly.type === "all" && "vendorId" in rawBody && rawBody.vendorId !== void 0) {
6215
+ const vId = Number(rawBody.vendorId);
6216
+ if (Number.isFinite(vId) && vId > 0) {
6217
+ scalarUpdate.vendorId = vId;
6218
+ }
6219
+ }
6220
+ if ("assignedUserId" in rawBody && rawBody.assignedUserId !== void 0) {
6221
+ const aId = Number(rawBody.assignedUserId);
6222
+ if (Number.isFinite(aId) && aId > 0) {
6223
+ if (scopePutEarly.type === "vendor" && entityMap.vendor_users) {
6224
+ const vuRepo = dataSource.getRepository(entityMap.vendor_users);
6225
+ const vuLink = await vuRepo.findOne({
6226
+ where: {
6227
+ vendorId: scopePutEarly.vendorId,
6228
+ userId: aId
6229
+ }
6230
+ });
6231
+ if (!vuLink) {
6232
+ return json({
6233
+ error: "Cannot assign order to a user outside your vendor team."
6234
+ }, {
6235
+ status: 403
6236
+ });
6237
+ }
6238
+ scalarUpdate.vendorId = scopePutEarly.vendorId;
6239
+ } else if (scopePutEarly.type === "all" && entityMap.vendor_users) {
6240
+ if (entityMap.vendors) {
6241
+ const activeVu = await dataSource.query(`SELECT vu."vendorId"
6242
+ FROM vendor_users vu
6243
+ JOIN vendors v ON v.id = vu."vendorId"
6244
+ WHERE vu."userId" = $1 AND v.deleted = false
6245
+ ORDER BY vu.id DESC
6246
+ LIMIT 1`, [
6247
+ aId
6248
+ ]);
6249
+ if (activeVu.length > 0 && activeVu[0].vendorId) {
6250
+ scalarUpdate.vendorId = Number(activeVu[0].vendorId);
6251
+ }
6252
+ }
6253
+ }
6254
+ const prevAssigned = Number(existingOrderRow?.assignedUserId);
6255
+ const prevVendor = Number(existingOrderRow?.vendorId);
6256
+ const targetVendor = Number.isFinite(Number(scalarUpdate.vendorId)) ? Number(scalarUpdate.vendorId) : Number(existingOrderRow?.vendorId) || null;
6257
+ if (aId !== prevAssigned || targetVendor && targetVendor !== prevVendor) {
6258
+ await recordOrderAssigneeHistory(dataSource, entityMap, numericId, aId, targetVendor);
6259
+ }
6260
+ scalarUpdate.assignedUserId = aId;
6261
+ scalarUpdate.assignedAt = /* @__PURE__ */ new Date();
6262
+ } else {
6263
+ scalarUpdate.assignedUserId = null;
6264
+ scalarUpdate.assignedAt = null;
6265
+ }
6060
6266
  }
6061
6267
  }
6062
6268
  if (scalarUpdate.status === "processing") {
6063
6269
  const effectiveAssignee = scalarUpdate.assignedUserId !== void 0 ? scalarUpdate.assignedUserId : existingOrderRow?.assignedUserId ?? null;
6064
- if (!effectiveAssignee) {
6270
+ const effectiveVendor = scalarUpdate.vendorId !== void 0 ? Number(scalarUpdate.vendorId) : Number(existingOrderRow?.vendorId);
6271
+ if (!effectiveAssignee && (!Number.isFinite(effectiveVendor) || effectiveVendor <= 0)) {
6065
6272
  return json({
6066
- error: "Cannot start processing without assigning a teammate. Please assign a teammate first."
6273
+ error: "Cannot start processing without assigning a vendor or teammate. Please assign first."
6067
6274
  }, {
6068
6275
  status: 400
6069
6276
  });
@@ -6309,7 +6516,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6309
6516
  const paymentUpdated = Boolean(rawBody && typeof rawBody === "object" && rawBody.paymentStatus != null);
6310
6517
  const assigneeUpdated = Boolean(rawBody && typeof rawBody === "object" && "assignedUserId" in rawBody && rawBody.assignedUserId !== void 0 && Number(rawBody.assignedUserId) > 0 && Number(rawBody.assignedUserId) !== Number(existingOrderRow?.assignedUserId));
6311
6518
  if (assigneeUpdated) {
6312
- void import('./emit-order-notification-trigger-EJJZ6XTS.js').then(({ fireOrderNotificationTrigger }) => {
6519
+ void import('./emit-order-notification-trigger-YUQTPELC.js').then(({ fireOrderNotificationTrigger }) => {
6313
6520
  fireOrderNotificationTrigger("order_assigned", updatedOrder.id, {
6314
6521
  dataSource,
6315
6522
  entityMap
@@ -6326,7 +6533,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6326
6533
  const payments = Array.isArray(updatedOrder.payments) ? updatedOrder.payments : [];
6327
6534
  const bodyPayStatus = rawBody && typeof rawBody === "object" && rawBody.paymentStatus != null ? String(rawBody.paymentStatus).toLowerCase() : null;
6328
6535
  const curPayStatus = bodyPayStatus || String(payments[0]?.status || "unpaid").toLowerCase();
6329
- void import('./emit-order-notification-trigger-EJJZ6XTS.js').then(({ fireOrderNotificationTrigger }) => {
6536
+ void import('./emit-order-notification-trigger-YUQTPELC.js').then(({ fireOrderNotificationTrigger }) => {
6330
6537
  if (newStatus === "pending") {
6331
6538
  if (curPayStatus === "failed") {
6332
6539
  fireOrderNotificationTrigger("payment_failed", updatedOrder.id, {
@@ -6480,7 +6687,9 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6480
6687
  }
6481
6688
  const updatePayload = rawBody && typeof rawBody === "object" ? pickColumnUpdates(repo, rawBody) : {};
6482
6689
  if (resourceUsesVendorScope(resource)) {
6483
- delete updatePayload.vendorId;
6690
+ if (!(resource === "orders" && scopePut.type === "all")) {
6691
+ delete updatePayload.vendorId;
6692
+ }
6484
6693
  }
6485
6694
  if (resource === "contacts" && "type" in updatePayload) {
6486
6695
  const t = updatePayload.type;
@@ -6876,9 +7085,59 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6876
7085
  }
6877
7086
  }
6878
7087
  if (resource === "orders" && orderInvPrev && rawBody && typeof rawBody === "object") {
7088
+ console.log("[ORDERS-DEBUG][UPDATE] PUT /api/orders/" + numericId, "Scope:", scopePut, "rawBody:", rawBody, "existingOrder:", {
7089
+ id: existingOrderRow?.id,
7090
+ vendorId: existingOrderRow?.vendorId,
7091
+ assignedUserId: existingOrderRow?.assignedUserId,
7092
+ status: existingOrderRow?.status
7093
+ });
7094
+ if (scopePut.type === "all" && "vendorId" in rawBody && rawBody.vendorId !== void 0) {
7095
+ const vId = Number(rawBody.vendorId);
7096
+ if (Number.isFinite(vId) && vId > 0) {
7097
+ updatePayload.vendorId = vId;
7098
+ }
7099
+ }
6879
7100
  if ("assignedUserId" in rawBody && rawBody.assignedUserId !== void 0) {
6880
7101
  const aId = Number(rawBody.assignedUserId);
7102
+ console.log("[ORDERS-DEBUG][UPDATE] Updating assignedUserId to:", aId);
6881
7103
  if (Number.isFinite(aId) && aId > 0) {
7104
+ if (scopePut.type === "vendor" && entityMap.vendor_users) {
7105
+ const vuRepo = dataSource.getRepository(entityMap.vendor_users);
7106
+ const vuLink = await vuRepo.findOne({
7107
+ where: {
7108
+ vendorId: scopePut.vendorId,
7109
+ userId: aId
7110
+ }
7111
+ });
7112
+ if (!vuLink) {
7113
+ return json({
7114
+ error: "Cannot assign order to a user outside your vendor team."
7115
+ }, {
7116
+ status: 403
7117
+ });
7118
+ }
7119
+ updatePayload.vendorId = scopePut.vendorId;
7120
+ } else if (scopePut.type === "all" && entityMap.vendor_users) {
7121
+ if (entityMap.vendors) {
7122
+ const activeVu = await dataSource.query(`SELECT vu."vendorId"
7123
+ FROM vendor_users vu
7124
+ JOIN vendors v ON v.id = vu."vendorId"
7125
+ WHERE vu."userId" = $1 AND v.deleted = false
7126
+ ORDER BY vu.id DESC
7127
+ LIMIT 1`, [
7128
+ aId
7129
+ ]);
7130
+ if (activeVu.length > 0 && activeVu[0].vendorId) {
7131
+ updatePayload.vendorId = Number(activeVu[0].vendorId);
7132
+ }
7133
+ }
7134
+ }
7135
+ const prevAssigned = Number(existingOrderRow?.assignedUserId);
7136
+ const prevVendor = Number(existingOrderRow?.vendorId);
7137
+ const targetVendor = Number.isFinite(Number(updatePayload.vendorId)) ? Number(updatePayload.vendorId) : Number(existingOrderRow?.vendorId) || null;
7138
+ if (aId !== prevAssigned || targetVendor && targetVendor !== prevVendor) {
7139
+ await recordOrderAssigneeHistory(dataSource, entityMap, numericId, aId, targetVendor);
7140
+ }
6882
7141
  updatePayload.assignedUserId = aId;
6883
7142
  updatePayload.assignedAt = /* @__PURE__ */ new Date();
6884
7143
  } else {
@@ -6886,11 +7145,13 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6886
7145
  updatePayload.assignedAt = null;
6887
7146
  }
6888
7147
  }
7148
+ console.log("[ORDERS-DEBUG][UPDATE] Final updatePayload for order:", updatePayload);
6889
7149
  if (updatePayload.status === "processing") {
6890
7150
  const effectiveAssignee = updatePayload.assignedUserId !== void 0 ? updatePayload.assignedUserId : existingOrderRow?.assignedUserId ?? null;
6891
- if (!effectiveAssignee) {
7151
+ const effectiveVendor = updatePayload.vendorId !== void 0 ? Number(updatePayload.vendorId) : Number(existingOrderRow?.vendorId);
7152
+ if (!effectiveAssignee && (!Number.isFinite(effectiveVendor) || effectiveVendor <= 0)) {
6892
7153
  return json({
6893
- error: "Cannot start processing without assigning a teammate. Please assign a teammate first."
7154
+ error: "Cannot start processing without assigning a vendor or teammate. Please assign first."
6894
7155
  }, {
6895
7156
  status: 400
6896
7157
  });
@@ -6980,7 +7241,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6980
7241
  });
6981
7242
  }
6982
7243
  if (ordStatus === "pending" || ordStatus === "confirmed") {
6983
- void import('./emit-order-notification-trigger-EJJZ6XTS.js').then(({ fireOrderNotificationTrigger }) => {
7244
+ void import('./emit-order-notification-trigger-YUQTPELC.js').then(({ fireOrderNotificationTrigger }) => {
6984
7245
  fireOrderNotificationTrigger("order_placed", pOrder, {
6985
7246
  dataSource,
6986
7247
  entityMap
@@ -6994,7 +7255,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6994
7255
  }
6995
7256
  }
6996
7257
  } else if (newPayStatus === "failed") {
6997
- void import('./emit-order-notification-trigger-EJJZ6XTS.js').then(({ fireOrderNotificationTrigger }) => {
7258
+ void import('./emit-order-notification-trigger-YUQTPELC.js').then(({ fireOrderNotificationTrigger }) => {
6998
7259
  fireOrderNotificationTrigger("payment_failed", pOrder, {
6999
7260
  dataSource,
7000
7261
  entityMap
@@ -7002,7 +7263,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
7002
7263
  }).catch(() => {
7003
7264
  });
7004
7265
  } else if (newPayStatus === "refunded") {
7005
- void import('./emit-order-notification-trigger-EJJZ6XTS.js').then(({ fireOrderNotificationTrigger }) => {
7266
+ void import('./emit-order-notification-trigger-YUQTPELC.js').then(({ fireOrderNotificationTrigger }) => {
7006
7267
  fireOrderNotificationTrigger("payment_refund_initiated", pOrder, {
7007
7268
  dataSource,
7008
7269
  entityMap
@@ -7129,7 +7390,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
7129
7390
  const paymentUpdated = Boolean(rawBody && typeof rawBody === "object" && rawBody.paymentStatus != null);
7130
7391
  const assigneeUpdated = Boolean(rawBody && typeof rawBody === "object" && "assignedUserId" in rawBody && rawBody.assignedUserId !== void 0 && Number(rawBody.assignedUserId) > 0 && Number(rawBody.assignedUserId) !== Number(existingOrderRow?.assignedUserId));
7131
7392
  if (assigneeUpdated) {
7132
- void import('./emit-order-notification-trigger-EJJZ6XTS.js').then(({ fireOrderNotificationTrigger }) => {
7393
+ void import('./emit-order-notification-trigger-YUQTPELC.js').then(({ fireOrderNotificationTrigger }) => {
7133
7394
  fireOrderNotificationTrigger("order_assigned", ord.id, {
7134
7395
  dataSource,
7135
7396
  entityMap
@@ -7146,7 +7407,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
7146
7407
  const payments = Array.isArray(ord.payments) ? ord.payments : [];
7147
7408
  const bodyPayStatus = rawBody && typeof rawBody === "object" && rawBody.paymentStatus != null ? String(rawBody.paymentStatus).toLowerCase() : null;
7148
7409
  const curPayStatus = bodyPayStatus || String(payments[0]?.status || "unpaid").toLowerCase();
7149
- void import('./emit-order-notification-trigger-EJJZ6XTS.js').then(({ fireOrderNotificationTrigger }) => {
7410
+ void import('./emit-order-notification-trigger-YUQTPELC.js').then(({ fireOrderNotificationTrigger }) => {
7150
7411
  if (newStatus === "pending") {
7151
7412
  if (curPayStatus === "failed") {
7152
7413
  fireOrderNotificationTrigger("payment_failed", ord.id, {
@@ -15281,6 +15542,7 @@ function createVendorOnboardHandlers(config) {
15281
15542
  state: vp?.state ?? null,
15282
15543
  postalCode: vp?.postalCode ?? null,
15283
15544
  blocked: u?.blocked ?? false,
15545
+ inviteStatus: u?.inviteStatus ?? (u?.password ? "active" : "pending"),
15284
15546
  groupName: u?.group?.name ?? null
15285
15547
  };
15286
15548
  });
@@ -15754,14 +16016,24 @@ function createVendorOnboardHandlers(config) {
15754
16016
  });
15755
16017
  }
15756
16018
  }
15757
- const token = String(user.inviteToken ?? "").trim();
15758
- if (!token || user.inviteStatus !== "pending") {
16019
+ const hasPassword = !!(user.password && String(user.password).trim());
16020
+ const isPending = user.inviteStatus === "pending" || !hasPassword;
16021
+ if (!isPending) {
15759
16022
  return json({
15760
- error: "No pending invite for this user"
16023
+ error: "User has already accepted the invite"
15761
16024
  }, {
15762
16025
  status: 400
15763
16026
  });
15764
16027
  }
16028
+ let token = String(user.inviteToken ?? "").trim();
16029
+ if (!token) {
16030
+ token = newUserInviteToken();
16031
+ await dataSource.getRepository(entityMap.users).update(user.id, {
16032
+ inviteToken: token,
16033
+ inviteStatus: "pending",
16034
+ password: null
16035
+ });
16036
+ }
15765
16037
  const inviteLink = buildUserInviteLink(baseUrl, token);
15766
16038
  const emailSent = await trySendVendorOnboardEmails({
15767
16039
  vendorName,
@@ -25135,6 +25407,109 @@ _ts_decorate69([
25135
25407
  OrderNotificationTrigger = _ts_decorate69([
25136
25408
  Entity("order_notification_triggers")
25137
25409
  ], OrderNotificationTrigger);
25410
+ function _ts_decorate70(decorators, target, key, desc) {
25411
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
25412
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
25413
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
25414
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
25415
+ }
25416
+ __name(_ts_decorate70, "_ts_decorate");
25417
+ function _ts_metadata70(k, v) {
25418
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
25419
+ }
25420
+ __name(_ts_metadata70, "_ts_metadata");
25421
+ var OrderAssignee = class {
25422
+ static {
25423
+ __name(this, "OrderAssignee");
25424
+ }
25425
+ id;
25426
+ orderId;
25427
+ userId;
25428
+ vendorId;
25429
+ sortOrder;
25430
+ assignedAt;
25431
+ createdAt;
25432
+ order;
25433
+ user;
25434
+ vendor;
25435
+ };
25436
+ _ts_decorate70([
25437
+ PrimaryGeneratedColumn(),
25438
+ _ts_metadata70("design:type", Number)
25439
+ ], OrderAssignee.prototype, "id", void 0);
25440
+ _ts_decorate70([
25441
+ Column("int"),
25442
+ _ts_metadata70("design:type", Number)
25443
+ ], OrderAssignee.prototype, "orderId", void 0);
25444
+ _ts_decorate70([
25445
+ Column("int"),
25446
+ _ts_metadata70("design:type", Number)
25447
+ ], OrderAssignee.prototype, "userId", void 0);
25448
+ _ts_decorate70([
25449
+ Column("int", {
25450
+ nullable: true
25451
+ }),
25452
+ _ts_metadata70("design:type", Object)
25453
+ ], OrderAssignee.prototype, "vendorId", void 0);
25454
+ _ts_decorate70([
25455
+ Column("int", {
25456
+ default: 1
25457
+ }),
25458
+ _ts_metadata70("design:type", Number)
25459
+ ], OrderAssignee.prototype, "sortOrder", void 0);
25460
+ _ts_decorate70([
25461
+ Column({
25462
+ type: "timestamp with time zone",
25463
+ default: /* @__PURE__ */ __name(() => "CURRENT_TIMESTAMP", "default")
25464
+ }),
25465
+ _ts_metadata70("design:type", typeof Date === "undefined" ? Object : Date)
25466
+ ], OrderAssignee.prototype, "assignedAt", void 0);
25467
+ _ts_decorate70([
25468
+ CreateDateColumn({
25469
+ type: "timestamp with time zone"
25470
+ }),
25471
+ _ts_metadata70("design:type", typeof Date === "undefined" ? Object : Date)
25472
+ ], OrderAssignee.prototype, "createdAt", void 0);
25473
+ _ts_decorate70([
25474
+ ManyToOne(() => Order, {
25475
+ onDelete: "CASCADE"
25476
+ }),
25477
+ JoinColumn({
25478
+ name: "orderId"
25479
+ }),
25480
+ _ts_metadata70("design:type", typeof Order === "undefined" ? Object : Order)
25481
+ ], OrderAssignee.prototype, "order", void 0);
25482
+ _ts_decorate70([
25483
+ ManyToOne(() => User, {
25484
+ onDelete: "CASCADE"
25485
+ }),
25486
+ JoinColumn({
25487
+ name: "userId"
25488
+ }),
25489
+ _ts_metadata70("design:type", typeof User === "undefined" ? Object : User)
25490
+ ], OrderAssignee.prototype, "user", void 0);
25491
+ _ts_decorate70([
25492
+ ManyToOne(() => Vendor, {
25493
+ nullable: true,
25494
+ onDelete: "SET NULL"
25495
+ }),
25496
+ JoinColumn({
25497
+ name: "vendorId"
25498
+ }),
25499
+ _ts_metadata70("design:type", Object)
25500
+ ], OrderAssignee.prototype, "vendor", void 0);
25501
+ OrderAssignee = _ts_decorate70([
25502
+ Entity("order_assignees"),
25503
+ Index("idx_order_assignees_order", [
25504
+ "orderId"
25505
+ ]),
25506
+ Index("idx_order_assignees_user", [
25507
+ "userId"
25508
+ ]),
25509
+ Index("idx_order_assignees_vendor", [
25510
+ "vendorId"
25511
+ ])
25512
+ ], OrderAssignee);
25138
25513
 
25139
25514
  // src/entities/index.ts
25140
25515
  var CMS_ENTITY_MAP = {
@@ -25206,7 +25581,8 @@ var CMS_ENTITY_MAP = {
25206
25581
  attendees: Attendee,
25207
25582
  order_notification_bindings: OrderNotificationBinding,
25208
25583
  order_notification_triggers: OrderNotificationTrigger,
25209
- user_device_tokens: UserDeviceToken
25584
+ user_device_tokens: UserDeviceToken,
25585
+ order_assignees: OrderAssignee
25210
25586
  };
25211
25587
 
25212
25588
  // src/plugins/blog-generator/blog-generator-agent-defaults.ts
@@ -29062,7 +29438,7 @@ function createCmsApiHandler(config) {
29062
29438
  companyDetails
29063
29439
  };
29064
29440
  if (queue) {
29065
- const { queueEmail: queueEmail2 } = await import('./email-queue-HGXB2FIS.js');
29441
+ const { queueEmail: queueEmail2 } = await import('./email-queue-3QBQ63F7.js');
29066
29442
  await queueEmail2(cms, {
29067
29443
  to: opts.to,
29068
29444
  templateName: "passwordReset",
@@ -30072,6 +30448,110 @@ function createCmsApiHandler(config) {
30072
30448
  return socialMediaHandlers.publishBlogToFacebook(req, id);
30073
30449
  }
30074
30450
  }
30451
+ if (path2[0] === "settings" && path2.length === 2 && path2[1] === "invoice-preview" && m === "GET") {
30452
+ const a = await config.requireAuth(req);
30453
+ if (a) return a;
30454
+ const pe = await requireEntityPermissionEffective(req, "settings", "read");
30455
+ if (pe) return pe;
30456
+ const url = new URL(req.url);
30457
+ const templateParam = url.searchParams.get("template") || "classic";
30458
+ const qrParam = url.searchParams.get("qr");
30459
+ const configRepo = dataSource.getRepository(entityMap.configs);
30460
+ const rows = await configRepo.find({
30461
+ where: {
30462
+ settings: "store",
30463
+ deleted: false
30464
+ }
30465
+ });
30466
+ const storeMap = {};
30467
+ for (const r of rows) {
30468
+ storeMap[r.key] = r.value;
30469
+ }
30470
+ const { normalizeInvoiceTemplateId } = await import('./invoice-templates-GZ33OENC.js');
30471
+ const { generateLocalInvoicePdf } = await import('./generate-local-invoice-pdf-OCFG47SE.js');
30472
+ const { resolveInvoiceAssetUrl } = await import('./resolve-invoice-asset-url-QZ2FRDHI.js');
30473
+ const templateId = normalizeInvoiceTemplateId(templateParam);
30474
+ const includeQr = qrParam != null ? qrParam === "1" || qrParam === "true" : storeMap.invoice_include_qr === "true";
30475
+ const sampleInput = {
30476
+ templateId,
30477
+ orderNumber: "SAMPLE-10024",
30478
+ orderDate: (/* @__PURE__ */ new Date()).toISOString(),
30479
+ currency: storeMap.currency || "INR",
30480
+ company: {
30481
+ name: storeMap.companyName || storeMap.invoiceCompanyName || "ETOE Services",
30482
+ supportEmail: storeMap.companyEmail || storeMap.invoiceEmail || "support@example.com",
30483
+ supportPhone: storeMap.companyPhone || storeMap.invoicePhone || "+91 98765 43210",
30484
+ address: storeMap.companyAddress || storeMap.invoiceAddress || "65 Sanjay Nagar B, Kalwar Road, Jhotwara, Jaipur, Rajasthan, 302012, India",
30485
+ logoUrl: resolveInvoiceAssetUrl(storeMap.invoiceLogoUrl || storeMap.companyLogo || storeMap.logo)
30486
+ },
30487
+ customerName: "Sahil Sharma",
30488
+ customerEmail: "sahil@example.com",
30489
+ customerPhone: "+91 98875 51178",
30490
+ billingAddress: {
30491
+ line1: "65 Sanjay Nagar B, Kalwar Road",
30492
+ city: "Jaipur",
30493
+ state: "Rajasthan",
30494
+ postalCode: "302012",
30495
+ country: "India"
30496
+ },
30497
+ shippingAddress: {
30498
+ line1: "65 Sanjay Nagar B, Kalwar Road",
30499
+ city: "Jaipur",
30500
+ state: "Rajasthan",
30501
+ postalCode: "302012",
30502
+ country: "India"
30503
+ },
30504
+ serviceDate: (/* @__PURE__ */ new Date()).toISOString(),
30505
+ timeSlot: "6:00 PM",
30506
+ assignedTo: "Raaj Sharma",
30507
+ qrToken: "sample-track-token-12345",
30508
+ qrData: "https://etoe.in/track/sample-track-token-12345",
30509
+ includeQrCode: includeQr,
30510
+ lineItems: [
30511
+ {
30512
+ name: "Complete Home Deep Cleaning Service",
30513
+ sku: "ETOE-HDC-001",
30514
+ quantity: 1,
30515
+ unitPrice: 3499,
30516
+ tax: 0,
30517
+ total: 3499
30518
+ },
30519
+ {
30520
+ name: "Kitchen & Bathroom Sanitization Add-on",
30521
+ sku: "ETOE-SAN-002",
30522
+ quantity: 1,
30523
+ unitPrice: 999,
30524
+ tax: 0,
30525
+ total: 999
30526
+ }
30527
+ ],
30528
+ subtotal: 4498,
30529
+ discount: 499,
30530
+ tax: 0,
30531
+ total: 3999
30532
+ };
30533
+ try {
30534
+ const bytes = await generateLocalInvoicePdf(sampleInput);
30535
+ return new Response(Buffer.from(bytes), {
30536
+ status: 200,
30537
+ headers: {
30538
+ "Content-Type": "application/pdf",
30539
+ "Content-Disposition": `inline; filename="preview-invoice-${templateId}.pdf"`
30540
+ }
30541
+ });
30542
+ } catch (err) {
30543
+ const msg = err instanceof Error ? err.message : String(err);
30544
+ console.error("[invoice-preview] failed", {
30545
+ templateId,
30546
+ error: msg
30547
+ });
30548
+ return config.json({
30549
+ error: `Preview generation failed: ${msg}`
30550
+ }, {
30551
+ status: 500
30552
+ });
30553
+ }
30554
+ }
30075
30555
  if (path2[0] === "settings" && path2.length === 2 && settingsHandlers) {
30076
30556
  const group = path2[1];
30077
30557
  const isPublic = group === "multi_vendor" || group === "turnstile" || group === "auth_providers" || settingsConfig?.publicGetGroups?.includes(group);
@@ -30376,7 +30856,7 @@ function createCmsApiHandler(config) {
30376
30856
  const pe = await requireEntityPermissionEffective(req, "orders", "read");
30377
30857
  if (pe) return pe;
30378
30858
  const cms = await getCms();
30379
- const { streamOrderInvoicePdf: streamOrderInvoicePdf2 } = await import('./erp-order-invoice-H6HCJ7YS.js');
30859
+ const { streamOrderInvoicePdf: streamOrderInvoicePdf2 } = await import('./erp-order-invoice-XSYHAMBS.js');
30380
30860
  const oid = Number(path2[1]);
30381
30861
  if (!Number.isFinite(oid)) return config.json({
30382
30862
  error: "Invalid id"
@@ -30758,7 +31238,7 @@ function createCmsApiHandler(config) {
30758
31238
  status: 400
30759
31239
  });
30760
31240
  }
30761
- const { resendOrderNotification } = await import('./order-notification-dispatcher-ECPFI7CD.js');
31241
+ const { resendOrderNotification } = await import('./order-notification-dispatcher-KM2SY7TX.js');
30762
31242
  const result = await resendOrderNotification(triggerKey, orderId, {
30763
31243
  dataSource,
30764
31244
  entityMap,
@@ -30857,7 +31337,7 @@ function createCmsApiHandler(config) {
30857
31337
  status: "cancelled"
30858
31338
  });
30859
31339
  const fireOrderCancelledNotification = /* @__PURE__ */ __name((refundAmount) => {
30860
- void import('./emit-order-notification-trigger-EJJZ6XTS.js').then(({ fireOrderNotificationTrigger }) => {
31340
+ void import('./emit-order-notification-trigger-YUQTPELC.js').then(({ fireOrderNotificationTrigger }) => {
30861
31341
  fireOrderNotificationTrigger("order_cancelled", orderId, {
30862
31342
  dataSource,
30863
31343
  entityMap
@@ -31102,8 +31582,8 @@ function createCmsApiHandler(config) {
31102
31582
  }, {
31103
31583
  status: 400
31104
31584
  });
31105
- const { createOrderCompletionOtpHandlers } = await import('./order-completion-otp-handlers-LFRHXWK4.js');
31106
- const handlers = createOrderCompletionOtpHandlers(dataSource, entityMap, getCms);
31585
+ const { createOrderCompletionOtpHandlers } = await import('./order-completion-otp-handlers-NROWBGXN.js');
31586
+ const handlers = createOrderCompletionOtpHandlers(dataSource, entityMap, getCms, getHydratedSessionUser);
31107
31587
  return handlers.getChannels(req, orderId);
31108
31588
  }
31109
31589
  if (path2[0] === "orders" && path2.length === 4 && path2[2] === "completion-otp" && path2[3] === "send" && m === "POST" && getCms) {
@@ -31117,8 +31597,8 @@ function createCmsApiHandler(config) {
31117
31597
  }, {
31118
31598
  status: 400
31119
31599
  });
31120
- const { createOrderCompletionOtpHandlers } = await import('./order-completion-otp-handlers-LFRHXWK4.js');
31121
- const handlers = createOrderCompletionOtpHandlers(dataSource, entityMap, getCms);
31600
+ const { createOrderCompletionOtpHandlers } = await import('./order-completion-otp-handlers-NROWBGXN.js');
31601
+ const handlers = createOrderCompletionOtpHandlers(dataSource, entityMap, getCms, getHydratedSessionUser);
31122
31602
  return handlers.sendOtp(req, orderId);
31123
31603
  }
31124
31604
  if (path2[0] === "orders" && path2.length === 4 && path2[2] === "completion-otp" && path2[3] === "verify" && m === "POST" && getCms) {
@@ -31132,8 +31612,8 @@ function createCmsApiHandler(config) {
31132
31612
  }, {
31133
31613
  status: 400
31134
31614
  });
31135
- const { createOrderCompletionOtpHandlers } = await import('./order-completion-otp-handlers-LFRHXWK4.js');
31136
- const handlers = createOrderCompletionOtpHandlers(dataSource, entityMap, getCms);
31615
+ const { createOrderCompletionOtpHandlers } = await import('./order-completion-otp-handlers-NROWBGXN.js');
31616
+ const handlers = createOrderCompletionOtpHandlers(dataSource, entityMap, getCms, getHydratedSessionUser);
31137
31617
  return handlers.verifyOtp(req, orderId);
31138
31618
  }
31139
31619
  if (path2[0] === "orders" && path2.length === 3 && path2[2] === "eligible-assignees" && m === "GET") {
@@ -31147,7 +31627,7 @@ function createCmsApiHandler(config) {
31147
31627
  }, {
31148
31628
  status: 400
31149
31629
  });
31150
- const { createOrderAssigneesHandlers } = await import('./order-assignees-handlers-LKMAGLG6.js');
31630
+ const { createOrderAssigneesHandlers } = await import('./order-assignees-handlers-L3RVKUBS.js');
31151
31631
  const handlers = createOrderAssigneesHandlers(dataSource, entityMap, getHydratedSessionUser);
31152
31632
  return handlers.listEligibleAssignees(req, orderId);
31153
31633
  }
@@ -31764,7 +32244,7 @@ function createStorefrontApiHandler(config) {
31764
32244
  const otpPepper = config.otpPepper;
31765
32245
  const defaultPhoneCc = config.defaultPhoneCountryCode;
31766
32246
  function fireStorefrontCheckoutNotifications(orderId) {
31767
- void import('./emit-order-notification-trigger-EJJZ6XTS.js').then(({ fireOrderNotificationTrigger }) => {
32247
+ void import('./emit-order-notification-trigger-YUQTPELC.js').then(({ fireOrderNotificationTrigger }) => {
31768
32248
  fireOrderNotificationTrigger("order_pending", orderId, {
31769
32249
  dataSource,
31770
32250
  entityMap
@@ -34528,7 +35008,9 @@ function createStorefrontApiHandler(config) {
34528
35008
  },
34529
35009
  relations: [
34530
35010
  "items",
34531
- "items.product"
35011
+ "items.product",
35012
+ "assignedUser",
35013
+ "payments"
34532
35014
  ]
34533
35015
  });
34534
35016
  if (!order) return json({
@@ -34554,7 +35036,9 @@ function createStorefrontApiHandler(config) {
34554
35036
  },
34555
35037
  relations: [
34556
35038
  "items",
34557
- "items.product"
35039
+ "items.product",
35040
+ "assignedUser",
35041
+ "payments"
34558
35042
  ]
34559
35043
  });
34560
35044
  }
@@ -34620,6 +35104,17 @@ function createStorefrontApiHandler(config) {
34620
35104
  currency: o.currency,
34621
35105
  createdAt: o.createdAt,
34622
35106
  metadata: o.metadata ?? null,
35107
+ assignedUser: o.assignedUser ? {
35108
+ id: o.assignedUser.id,
35109
+ name: o.assignedUser.name,
35110
+ phone: o.assignedUser.phone
35111
+ } : null,
35112
+ payments: Array.isArray(o.payments) ? o.payments.map((pm) => ({
35113
+ id: pm.id,
35114
+ amount: pm.amount,
35115
+ method: pm.method,
35116
+ status: pm.status
35117
+ })) : [],
34623
35118
  items: lines
34624
35119
  },
34625
35120
  relatedOrders: relatedOrders.map((r) => ({
@@ -34694,7 +35189,7 @@ function createStorefrontApiHandler(config) {
34694
35189
  } catch {
34695
35190
  }
34696
35191
  try {
34697
- void import('./emit-order-notification-trigger-EJJZ6XTS.js').then(({ fireOrderNotificationTrigger }) => {
35192
+ void import('./emit-order-notification-trigger-YUQTPELC.js').then(({ fireOrderNotificationTrigger }) => {
34698
35193
  fireOrderNotificationTrigger("order_cancelled", orderId, {
34699
35194
  dataSource,
34700
35195
  entityMap
@@ -34735,4 +35230,4 @@ function createStorefrontApiHandler(config) {
34735
35230
  }
34736
35231
  __name(createStorefrontApiHandler, "createStorefrontApiHandler");
34737
35232
 
34738
- export { Address, Attendee, Attribute, BLOG_GENERATOR_AGENT_NAME, BLOG_GENERATOR_DEFAULT_SYSTEM_INSTRUCTION, BLOG_GENERATOR_DEFAULT_VALIDATION_RULES, BLOG_GENERATOR_LLM_AGENT_SLUG, BLOG_GENERATOR_MARKDOWN_ARTICLE_SEPARATOR, BLOG_METADATA_ENRICHER_AGENT_NAME, BLOG_METADATA_ENRICHER_DEFAULT_SYSTEM_INSTRUCTION, BLOG_METADATA_ENRICHER_DEFAULT_VALIDATION_RULES, BLOG_METADATA_ENRICHER_LLM_AGENT_SLUG, Blog, BlogGeneratorService, Brand, CMS_ENTITY_MAP, Cart, CartItem, Category, ChatConversation, ChatMessage, Collection, Combo, ComboItem, Comment, Config, Contact, Currency, CurrencyExchange, Customer, Customer_Contacts, Discount, DiscountRules, Event, EventProduct, Form, FormField, FormSubmission, JobSchedule, JobScheduleRun, KnowledgeBaseChunk, KnowledgeBaseDocument, LlmAgent, LlmAgentKnowledgeDocument, Media, MessageTemplate, Order, OrderAddresses, OrderDiscounts, OrderItem, OrderNotificationBinding, OrderNotificationTrigger, OtpChallenge, Page, PasswordResetToken, Payment, Permission, Product, ProductAttribute, ProductCategory, ProductConfig, ProductVariant, RefundPolicy, RefundRequest, RssArticle, RssFeed, Seo, Tag, Tax, User, UserDeviceToken, UserGroup, Vendor, VendorCustomer, VendorRole, VendorRolePermission, VendorUser, VendorUserProfile, Wishlist, WishlistItem, ZIP_MIME_TYPES, applyApprovalStatusSideEffects, applyEventApprovalStatusSideEffects, applyRotatingVendorInvite, applyVendorCustomersContactFilter, applyVendorEventCreateApproval, applyVendorProductCreateApproval, assertCaptchaOk, assertContactAllowedForVendorOrder, assertEventApprovalUpdate, assertProductApprovalUpdate, autoExpireOrderIfPaymentTimeExceeded, buildBlogMetadataUserPrompt, buildCronFromSchedule, buildRssUserPromptFromFeeds, buildUserInviteLink, buildVendorInviteLink, calculateOrderRefundPreview, calculateRefundFromPolicy, checkAndIncrementDiscountUsage, checkEventsEnabled, checkMultiVendorEnabled, completeUserInviteAccept, consumeAppliedDiscountUsages, contactIsVendorCustomer, countDiscountOrdersForContact, createAnalyticsHandlers, createBlogBySlugHandler, createChangePasswordHandler, createCmsApiHandler, createCmsApp, createCmsAppWithMessaging, createCrudByIdHandler, createCrudHandler, createDashboardStatsHandler, createEcommerceAnalyticsHandler, createEventOrderMessageTemplateHandlers, createForgotPasswordHandler, createFormBySlugHandler, createInviteAcceptHandler, createJobScheduleHandlers, createLlmAgentKnowledgeHandlers, createMediaZipExtractHandler, createMessageTemplateRowLoader, createSetPasswordHandler, createSettingsApiHandlers, createSocialMediaHandlers, createStorefrontApiHandler, createUploadHandler, createUserAuthApiRouter, createUserAvatarHandler, createUserProfileHandler, createUsersApiHandlers, createVendorDashboardHandler, createVendorOnboardHandlers, daysBeforeEventStart, decrementDiscountUsage, describeEventTierPolicy, ensureMessagingPluginsOnCms, ensureScheduleQueueWorker, ensureVendorCustomerForOrderContact, ensureVendorCustomersForOrder, findActiveRefundPolicyForVendor, findUserByInviteToken, findVendorByInviteToken, formatTierRange, getPublicSettingsGroup, getRequireEventApproval, getRequireProductApproval, getRssArticleSummaryFromItem, getVendorCatalogCreateFlags, hydrateVendorSessionUser, invalidateEventsCache, invalidateMultiVendorCache, invalidateRequireEventApprovalCache, invalidateRequireProductApprovalCache, invalidateVendorCatalogCreateFlagsCache, isCustomerTypeContact, isMaxPerUserUsageReached, isMaxTotalUsageReached, isZipMedia, llmAgentToChatAgentOptions, loadSettingsGroupFromDb, loadUserVendorContext, mergeGuardrailsIntoSystemPrompt, messagingPlugins, metaFetchUserManagedPages, metaPostPageFeed, metaPostPagePhoto, metaResolvePageAccessToken, newUserInviteToken, normalizeRefundTiers, overlayCmsPlugins, parseBlogGeneratorAgentContent, parseBlogGeneratorModelOutput, parseBlogMetadataEnrichmentJson, parseLlmAgentValidationRules, pgBossScheduleNameForId, queueErpCreateContactIfEnabled, queueJobScheduleNow, queuePlugin, recordDiscountUsage, registerJobRunnerWorker, registerMessagingQueueProcessors, relativePathFromMediaParentId, resolveBlogCategoryIdByName, resolveSettingsEncryptionKey, resolveVendorIdForContactCheck, sanitizeMediaFolderPath, sanitizeStorageSegment, sendVendorOnboardEmails, simpleDecrypt, simpleEncrypt, syncJobScheduleToPgBoss, validateRefundTiers, validateScheduleInput, validateUserMessageAgainstAgentRules, validateUserMessageAgainstStructuredRules, whatsappPlugin, wrapGetCmsWithMessaging };
35233
+ 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, OrderAssignee, OrderDiscounts, OrderItem, OrderNotificationBinding, OrderNotificationTrigger, OtpChallenge, Page, PasswordResetToken, Payment, Permission, Product, ProductAttribute, ProductCategory, ProductConfig, ProductVariant, RefundPolicy, RefundRequest, RssArticle, RssFeed, Seo, Tag, Tax, User, UserDeviceToken, UserGroup, Vendor, VendorCustomer, VendorRole, VendorRolePermission, VendorUser, VendorUserProfile, Wishlist, WishlistItem, ZIP_MIME_TYPES, applyApprovalStatusSideEffects, applyEventApprovalStatusSideEffects, applyRotatingVendorInvite, applyVendorCustomersContactFilter, applyVendorEventCreateApproval, applyVendorProductCreateApproval, assertCaptchaOk, assertContactAllowedForVendorOrder, assertEventApprovalUpdate, assertProductApprovalUpdate, autoExpireOrderIfPaymentTimeExceeded, buildBlogMetadataUserPrompt, buildCronFromSchedule, buildRssUserPromptFromFeeds, buildUserInviteLink, buildVendorInviteLink, calculateOrderRefundPreview, calculateRefundFromPolicy, checkAndIncrementDiscountUsage, checkEventsEnabled, checkMultiVendorEnabled, completeUserInviteAccept, consumeAppliedDiscountUsages, contactIsVendorCustomer, countDiscountOrdersForContact, createAnalyticsHandlers, createBlogBySlugHandler, createChangePasswordHandler, createCmsApiHandler, createCmsApp, createCmsAppWithMessaging, createCrudByIdHandler, createCrudHandler, createDashboardStatsHandler, createEcommerceAnalyticsHandler, createEventOrderMessageTemplateHandlers, createForgotPasswordHandler, createFormBySlugHandler, createInviteAcceptHandler, createJobScheduleHandlers, createLlmAgentKnowledgeHandlers, createMediaZipExtractHandler, createMessageTemplateRowLoader, createSetPasswordHandler, createSettingsApiHandlers, createSocialMediaHandlers, createStorefrontApiHandler, createUploadHandler, createUserAuthApiRouter, createUserAvatarHandler, createUserProfileHandler, createUsersApiHandlers, createVendorDashboardHandler, createVendorOnboardHandlers, daysBeforeEventStart, decrementDiscountUsage, describeEventTierPolicy, ensureMessagingPluginsOnCms, ensureScheduleQueueWorker, ensureVendorCustomerForOrderContact, ensureVendorCustomersForOrder, findActiveRefundPolicyForVendor, findUserByInviteToken, findVendorByInviteToken, formatTierRange, getPublicSettingsGroup, getRequireEventApproval, getRequireProductApproval, getRssArticleSummaryFromItem, getVendorCatalogCreateFlags, hydrateVendorSessionUser, invalidateEventsCache, invalidateMultiVendorCache, invalidateRequireEventApprovalCache, invalidateRequireProductApprovalCache, invalidateVendorCatalogCreateFlagsCache, isCustomerTypeContact, isMaxPerUserUsageReached, isMaxTotalUsageReached, isZipMedia, llmAgentToChatAgentOptions, loadSettingsGroupFromDb, loadUserVendorContext, mergeGuardrailsIntoSystemPrompt, messagingPlugins, metaFetchUserManagedPages, metaPostPageFeed, metaPostPagePhoto, metaResolvePageAccessToken, newUserInviteToken, normalizeRefundTiers, overlayCmsPlugins, parseBlogGeneratorAgentContent, parseBlogGeneratorModelOutput, parseBlogMetadataEnrichmentJson, parseLlmAgentValidationRules, pgBossScheduleNameForId, queueErpCreateContactIfEnabled, queueJobScheduleNow, queuePlugin, recordDiscountUsage, registerJobRunnerWorker, registerMessagingQueueProcessors, relativePathFromMediaParentId, resolveBlogCategoryIdByName, resolveSettingsEncryptionKey, resolveVendorIdForContactCheck, sanitizeMediaFolderPath, sanitizeStorageSegment, sendVendorOnboardEmails, simpleDecrypt, simpleEncrypt, syncJobScheduleToPgBoss, validateRefundTiers, validateScheduleInput, validateUserMessageAgainstAgentRules, validateUserMessageAgainstStructuredRules, whatsappPlugin, wrapGetCmsWithMessaging };