@infuro/cms-core 1.0.45 → 1.0.47

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 (82) hide show
  1. package/README.md +19 -2
  2. package/dist/admin.cjs +4249 -2872
  3. package/dist/admin.d.cts +24 -4
  4. package/dist/admin.d.ts +24 -4
  5. package/dist/admin.js +3179 -1804
  6. package/dist/api.cjs +41 -39
  7. package/dist/api.d.cts +10 -4
  8. package/dist/api.d.ts +10 -4
  9. package/dist/api.js +9 -7
  10. package/dist/auth.cjs +55 -51
  11. package/dist/auth.d.cts +6 -3
  12. package/dist/auth.d.ts +6 -3
  13. package/dist/auth.js +3 -3
  14. package/dist/{chunk-KFFB6EMZ.js → chunk-2HU5R2JE.js} +2 -0
  15. package/dist/chunk-2IAXTKQN.cjs +19 -0
  16. package/dist/chunk-2KUCQVAQ.js +936 -0
  17. package/dist/chunk-3K5AIEIZ.js +256 -0
  18. package/dist/{chunk-SPQFNIYJ.cjs → chunk-4PMK3RNA.cjs} +2 -0
  19. package/dist/{chunk-X6UQFV4X.cjs → chunk-77NUXO6A.cjs} +14 -12
  20. package/dist/chunk-BXYZDMTZ.cjs +953 -0
  21. package/dist/chunk-DBPSJYLZ.js +47 -0
  22. package/dist/chunk-EIZKW2PF.js +13 -0
  23. package/dist/chunk-HY3AXLOI.cjs +265 -0
  24. package/dist/{chunk-X47PBV4I.js → chunk-JE22VP6S.js} +1 -0
  25. package/dist/{chunk-DN65KDIA.js → chunk-JIWUVQ6B.js} +14 -13
  26. package/dist/{chunk-HT5DI3XW.cjs → chunk-KOTXDSQB.cjs} +1 -0
  27. package/dist/chunk-L3525VXI.js +243 -0
  28. package/dist/{chunk-22FFHLTO.cjs → chunk-LMJ7RKPF.cjs} +421 -150
  29. package/dist/chunk-OY2YTBMP.cjs +50 -0
  30. package/dist/{chunk-TAHX46EI.cjs → chunk-Q3HQEM4R.cjs} +15 -7
  31. package/dist/chunk-V25RDUOU.cjs +248 -0
  32. package/dist/{chunk-ZMRQ72F6.cjs → chunk-VUQFARRT.cjs} +10 -10
  33. package/dist/{chunk-MVXLRANV.js → chunk-W42UZLQO.js} +1977 -891
  34. package/dist/{chunk-F5XFHYTG.cjs → chunk-XUCKZPML.cjs} +2088 -991
  35. package/dist/{chunk-I6NH72MO.js → chunk-YC4NUZCS.js} +10 -2
  36. package/dist/{chunk-NNQBWDCI.js → chunk-YXH2UUEZ.js} +418 -146
  37. package/dist/{chunk-BLR6H5GL.js → chunk-ZF2RQWXB.js} +4 -4
  38. package/dist/cli.cjs +9 -4
  39. package/dist/cli.js +9 -4
  40. package/dist/{email-queue-TPZWLTIV.cjs → email-queue-6NJY6HNM.cjs} +7 -5
  41. package/dist/email-queue-OI2HSCGE.js +4 -0
  42. package/dist/{emit-order-notification-trigger-IVLWKKJL.js → emit-order-notification-trigger-6XX7LSC4.js} +1 -1
  43. package/dist/{emit-order-notification-trigger-D2N3KFHL.cjs → emit-order-notification-trigger-NASG7ZEO.cjs} +3 -3
  44. package/dist/erp-order-invoice-3GXDE443.js +3 -0
  45. package/dist/erp-order-invoice-EYYNR526.cjs +24 -0
  46. package/dist/{event-order-defaults-EMWBIGL3.cjs → event-order-defaults-7Z3UZOEH.cjs} +9 -9
  47. package/dist/{event-order-defaults-SDRNAZHC.js → event-order-defaults-XQ3IDPD7.js} +1 -1
  48. package/dist/hooks.cjs +43 -0
  49. package/dist/hooks.d.cts +10 -1
  50. package/dist/hooks.d.ts +10 -1
  51. package/dist/hooks.js +39 -1
  52. package/dist/index.cjs +429 -298
  53. package/dist/index.d.cts +317 -30
  54. package/dist/index.d.ts +317 -30
  55. package/dist/index.js +17 -13
  56. package/dist/migrations/1781810000000-OrderItemsVariantId.ts +44 -0
  57. package/dist/migrations/1781900000000-UserInviteStatusToken.ts +46 -0
  58. package/dist/migrations/1782000000000-ComboSlug.ts +58 -0
  59. package/dist/migrations/1782100000000-DiscountDeviceType.ts +20 -0
  60. package/dist/migrations/1782200000000-VendorTeamProfiles.ts +233 -0
  61. package/dist/migrations/1782300000000-AddTypeToOrderNotificationBindings.ts +75 -0
  62. package/dist/order-inventory-2MYRKEPC.cjs +39 -0
  63. package/dist/order-inventory-76V4XIGW.js +2 -0
  64. package/dist/{order-notification-dispatcher-XWIJYDGA.js → order-notification-dispatcher-6WNG24NY.js} +4 -2
  65. package/dist/{order-notification-dispatcher-RU7BTGGX.cjs → order-notification-dispatcher-6XSU3AR7.cjs} +6 -4
  66. package/dist/{rbac-debug-db-2SGNLANF.js → rbac-debug-db-6EMIVMGF.js} +1 -1
  67. package/dist/{rbac-debug-db-4Z6A425H.cjs → rbac-debug-db-6PWTLBEL.cjs} +2 -2
  68. package/dist/retire-soft-deleted-unique-5VXBA5XX.cjs +15 -0
  69. package/dist/retire-soft-deleted-unique-NXQIH4BC.js +2 -0
  70. package/dist/theme.cjs +6 -1
  71. package/dist/theme.d.cts +4 -1
  72. package/dist/theme.d.ts +4 -1
  73. package/dist/theme.js +3 -1
  74. package/package.json +5 -4
  75. package/src/admin/admin.css +34 -24
  76. package/dist/chunk-5ELSW2UP.js +0 -150
  77. package/dist/chunk-PNOKNSG2.cjs +0 -222
  78. package/dist/chunk-WEMDMVHQ.js +0 -216
  79. package/dist/chunk-XW5ATPRW.cjs +0 -155
  80. package/dist/email-queue-CGZBVVAS.js +0 -2
  81. package/dist/erp-order-invoice-3YISSOWW.js +0 -3
  82. package/dist/erp-order-invoice-ZR5F2KTA.cjs +0 -12
@@ -1,12 +1,14 @@
1
- import { resolveChatEmailToolSettings, CHAT_EMAIL_LOG, detectChatLeadIntent, parseIntentRecipientEmails, mergeEmailLayoutCompanyDetails, sendChatLeadEmail, buildTranscriptForLeadEmail, buildChatbotSystemPromptWithEmailTool, parseEmailRecipientsFromConfig, isWhatsAppPluginEnabled, mergeWhatsAppConfigLayers, whatsAppConfigured, WhatsAppService, registerWhatsAppQueueProcessor, emailPlugin, initWhatsappTriggerDispatcher } from './chunk-NNQBWDCI.js';
1
+ import { validateInventoryForConfirmedOrderLines, orderStatusHoldsStock, reconcileOrderInventoryBetweenSnapshots, orderInventorySnapshotFromRow, validateInventoryForOrderBecomingConfirmed } from './chunk-3K5AIEIZ.js';
2
+ import { retireSoftDeletedUniqueValue, activeUniqueValueExists } from './chunk-DBPSJYLZ.js';
3
+ import { resolveChatEmailToolSettings, CHAT_EMAIL_LOG, detectChatLeadIntent, parseIntentRecipientEmails, sendChatLeadEmail, buildTranscriptForLeadEmail, buildChatbotSystemPromptWithEmailTool, parseEmailRecipientsFromConfig, isWhatsAppPluginEnabled, mergeWhatsAppConfigLayers, whatsAppConfigured, WhatsAppService, registerWhatsAppQueueProcessor, emailPlugin, initWhatsappTriggerDispatcher } from './chunk-YXH2UUEZ.js';
2
4
  import { inviteStatusForActivation } from './chunk-JXF23MPG.js';
3
- import { unwrapErpReadData, mapErpPayloadToFulfillment, extractChildOrderRefsFromSalePayload, mapErpPayloadToInvoiceNumber, streamOrderInvoicePdf } from './chunk-WEMDMVHQ.js';
4
- import { queueEmail, queueVendorOnboardEmails, registerEmailQueueProcessor } from './chunk-5ELSW2UP.js';
5
+ import { queueEmail, queueVendorOnboardEmails, registerEmailQueueProcessor } from './chunk-L3525VXI.js';
6
+ import { mergeEmailLayoutCompanyDetails, unwrapErpReadData, mapErpPayloadToFulfillment, extractChildOrderRefsFromSalePayload, mapErpPayloadToInvoiceNumber, streamOrderInvoicePdf } from './chunk-2KUCQVAQ.js';
5
7
  import { getSmsTemplateDefault, SMS_MESSAGE_TEMPLATE_DEFAULTS } from './chunk-MQBT33IV.js';
6
- import { EVENT_ORDER_MESSAGE_TEMPLATE_DEFAULTS, EVENT_ORDER_TEMPLATE_KEY, EVENT_ORDER_TEMPLATE_VARIABLES } from './chunk-KFFB6EMZ.js';
8
+ import { EVENT_ORDER_MESSAGE_TEMPLATE_DEFAULTS, EVENT_ORDER_TEMPLATE_KEY, EVENT_ORDER_TEMPLATE_VARIABLES } from './chunk-2HU5R2JE.js';
7
9
  import { JOB_RUNNER_QUEUE } from './chunk-GO7PPYNU.js';
8
- import { canManageRoles, sessionHasEntityAccess } from './chunk-BLR6H5GL.js';
9
- 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_OWNER_GROUP_NAME, resolveVendorScopeFromSessionUser, canManageVendorRoles, isPlatformAdministrator, canManageVendorTeam, resolveDisabledMultiVendorScope, logEntityAccessDecision, explainSessionEntityAccess } from './chunk-DN65KDIA.js';
10
+ import { canManageRoles, sessionHasEntityAccess } from './chunk-ZF2RQWXB.js';
11
+ 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';
10
12
  import { queueErp } from './chunk-SYBOCAWB.js';
11
13
  import { isErpIntegrationEnabled } from './chunk-JC6DLWTE.js';
12
14
  import { __name } from './chunk-SHUYVCID.js';
@@ -31,7 +33,6 @@ async function queryVendorLinks(dataSource, userId) {
31
33
  return await dataSource.query(`
32
34
  SELECT
33
35
  vu."vendorId" AS "vendorId",
34
- vu."role" AS "role",
35
36
  vu."vendorRoleId" AS "vendorRoleId",
36
37
  vr."name" AS "vendorRoleName",
37
38
  vr."isOwnerRole" AS "isOwnerRole"
@@ -45,22 +46,25 @@ async function queryVendorLinks(dataSource, userId) {
45
46
  ]);
46
47
  } catch (err) {
47
48
  if (!isMissingVendorRoleSchemaError(err)) throw err;
48
- const legacy = await dataSource.query(`
49
- SELECT vu."vendorId" AS "vendorId", vu."role" AS "role"
50
- FROM "vendor_users" vu
51
- INNER JOIN "vendors" v ON v.id = vu."vendorId" AND v.deleted = false
52
- WHERE vu."userId" = $1
53
- ORDER BY vu.id ASC
54
- `, [
55
- userId
56
- ]);
57
- return legacy.map((r) => ({
58
- vendorId: Number(r.vendorId),
59
- role: r.role,
60
- vendorRoleId: null,
61
- vendorRoleName: null,
62
- isOwnerRole: r.role === "owner" ? true : null
63
- }));
49
+ try {
50
+ const legacy = await dataSource.query(`
51
+ SELECT vu."vendorId" AS "vendorId", vu."role" AS "role"
52
+ FROM "vendor_users" vu
53
+ INNER JOIN "vendors" v ON v.id = vu."vendorId" AND v.deleted = false
54
+ WHERE vu."userId" = $1
55
+ ORDER BY vu.id ASC
56
+ `, [
57
+ userId
58
+ ]);
59
+ return legacy.map((r) => ({
60
+ vendorId: Number(r.vendorId),
61
+ vendorRoleId: null,
62
+ vendorRoleName: null,
63
+ isOwnerRole: r.role === "owner" ? true : null
64
+ }));
65
+ } catch {
66
+ return [];
67
+ }
64
68
  }
65
69
  }
66
70
  __name(queryVendorLinks, "queryVendorLinks");
@@ -87,7 +91,6 @@ async function loadUserVendorContext(dataSource, userId, preferredVendorId) {
87
91
  if (linkIds.has(ownedId)) continue;
88
92
  rows.push({
89
93
  vendorId: ownedId,
90
- role: "owner",
91
94
  vendorRoleId: null,
92
95
  vendorRoleName: null,
93
96
  isOwnerRole: true
@@ -112,13 +115,14 @@ async function loadUserVendorContext(dataSource, userId, preferredVendorId) {
112
115
  if (!isMissingVendorRoleSchemaError(err)) throw err;
113
116
  }
114
117
  }
118
+ const isOwner = !!primary?.isOwnerRole;
115
119
  return {
116
120
  vendorIds,
117
121
  activeVendorId: primary != null ? Number(primary.vendorId) : vendorIds[0] ?? null,
118
- vendorRole: primary?.role ?? null,
122
+ vendorRole: isOwner ? "owner" : primary ? "staff" : null,
119
123
  vendorRoleId: primary?.vendorRoleId != null ? Number(primary.vendorRoleId) : null,
120
124
  vendorRoleName: primary?.vendorRoleName ?? null,
121
- isVendorRoleOwner: !!primary?.isOwnerRole || primary?.role === "owner",
125
+ isVendorRoleOwner: isOwner,
122
126
  vendorEntityPerms
123
127
  };
124
128
  }
@@ -646,6 +650,144 @@ function applyEventApprovalStatusSideEffects(updatePayload, opts) {
646
650
  }
647
651
  __name(applyEventApprovalStatusSideEffects, "applyEventApprovalStatusSideEffects");
648
652
 
653
+ // src/lib/discount-usage.ts
654
+ async function countDiscountOrdersForContact(dataSource, discountId, contactId) {
655
+ try {
656
+ const rows = await dataSource.query(`SELECT COUNT(DISTINCT od."orderId")::int AS count
657
+ FROM order_discounts od
658
+ WHERE od."discountId" = $1 AND od."userId" = $2`, [
659
+ discountId,
660
+ contactId
661
+ ]);
662
+ return Number(rows?.[0]?.count ?? 0);
663
+ } catch {
664
+ return 0;
665
+ }
666
+ }
667
+ __name(countDiscountOrdersForContact, "countDiscountOrdersForContact");
668
+ function isMaxTotalUsageReached(discount) {
669
+ if (discount.maxTotalUsage == null) return false;
670
+ return Number(discount.usedCount ?? 0) >= Number(discount.maxTotalUsage);
671
+ }
672
+ __name(isMaxTotalUsageReached, "isMaxTotalUsageReached");
673
+ async function isMaxPerUserUsageReached(dataSource, discount, contactId) {
674
+ if (discount.maxUsagePerUser == null || contactId == null) return false;
675
+ const count = await countDiscountOrdersForContact(dataSource, discount.id, contactId);
676
+ return count >= Number(discount.maxUsagePerUser);
677
+ }
678
+ __name(isMaxPerUserUsageReached, "isMaxPerUserUsageReached");
679
+ async function checkAndIncrementDiscountUsage(dataSource, entityMap, discountId, contactId) {
680
+ if (!entityMap.discounts) return null;
681
+ const discountRepo = dataSource.getRepository(entityMap.discounts);
682
+ const discount = await discountRepo.findOne({
683
+ where: {
684
+ id: discountId
685
+ }
686
+ });
687
+ if (!discount) return `Discount #${discountId} not found`;
688
+ const d = discount;
689
+ if (d.maxUsagePerUser != null) {
690
+ const usageCount = await countDiscountOrdersForContact(dataSource, discountId, contactId);
691
+ if (usageCount >= Number(d.maxUsagePerUser)) {
692
+ return "You have reached the maximum usage limit for this discount";
693
+ }
694
+ }
695
+ const updated = await dataSource.query(`UPDATE discounts
696
+ SET "usedCount" = "usedCount" + 1
697
+ WHERE id = $1
698
+ AND ("maxTotalUsage" IS NULL OR "usedCount" < "maxTotalUsage")
699
+ RETURNING id`, [
700
+ discountId
701
+ ]);
702
+ if (!Array.isArray(updated) || updated.length === 0) {
703
+ return "Discount usage limit has been reached";
704
+ }
705
+ return null;
706
+ }
707
+ __name(checkAndIncrementDiscountUsage, "checkAndIncrementDiscountUsage");
708
+ async function decrementDiscountUsage(dataSource, entityMap, discountId, orderId) {
709
+ if (!entityMap.discounts) return;
710
+ try {
711
+ await dataSource.query(`UPDATE discounts SET "usedCount" = GREATEST("usedCount" - 1, 0) WHERE id = $1`, [
712
+ discountId
713
+ ]);
714
+ if (entityMap.order_discounts) {
715
+ await dataSource.getRepository(entityMap.order_discounts).delete({
716
+ orderId,
717
+ discountId
718
+ });
719
+ }
720
+ } catch (err) {
721
+ console.error("[discountEngine] decrementDiscountUsage failed:", err);
722
+ }
723
+ }
724
+ __name(decrementDiscountUsage, "decrementDiscountUsage");
725
+ async function recordDiscountUsage(dataSource, entityMap, orderId, discountId, contactId, discountAmount) {
726
+ if (!entityMap.order_discounts) return;
727
+ try {
728
+ let discountCode = "";
729
+ if (entityMap.discounts) {
730
+ const discountRow = await dataSource.getRepository(entityMap.discounts).findOne({
731
+ where: {
732
+ id: discountId
733
+ }
734
+ });
735
+ discountCode = discountRow?.couponCode ?? "";
736
+ }
737
+ const odRepo = dataSource.getRepository(entityMap.order_discounts);
738
+ const orderItemRepo = dataSource.getRepository(entityMap.order_items);
739
+ const items = await orderItemRepo.find({
740
+ where: {
741
+ orderId
742
+ }
743
+ });
744
+ const discountedItems = items.filter((item) => Number(item.discount ?? 0) > 0);
745
+ if (discountedItems.length === 0) {
746
+ const firstItem = items[0];
747
+ if (!firstItem) return;
748
+ await odRepo.save(odRepo.create({
749
+ orderId,
750
+ orderItemId: firstItem.id,
751
+ discountId,
752
+ discountCode,
753
+ discountAmount,
754
+ userId: contactId
755
+ }));
756
+ return;
757
+ }
758
+ for (const item of discountedItems) {
759
+ const i = item;
760
+ await odRepo.save(odRepo.create({
761
+ orderId,
762
+ orderItemId: i.id,
763
+ discountId,
764
+ discountCode,
765
+ discountAmount: Number(i.discount ?? 0),
766
+ userId: contactId
767
+ }));
768
+ }
769
+ } catch (err) {
770
+ console.error("[discountEngine] recordDiscountUsage failed:", err);
771
+ }
772
+ }
773
+ __name(recordDiscountUsage, "recordDiscountUsage");
774
+ async function consumeAppliedDiscountUsages(dataSource, entityMap, orderId, contactId, applied) {
775
+ const unique = /* @__PURE__ */ new Map();
776
+ for (const row of applied) {
777
+ const id = Number(row.id);
778
+ if (!Number.isFinite(id) || id < 1) continue;
779
+ const amount = Math.max(0, Number(row.calculatedDiscount) || 0);
780
+ unique.set(id, (unique.get(id) ?? 0) + amount);
781
+ }
782
+ for (const [discountId, discountAmount] of unique) {
783
+ const usageErr = await checkAndIncrementDiscountUsage(dataSource, entityMap, discountId, contactId);
784
+ if (usageErr) return usageErr;
785
+ await recordDiscountUsage(dataSource, entityMap, orderId, discountId, contactId, discountAmount);
786
+ }
787
+ return null;
788
+ }
789
+ __name(consumeAppliedDiscountUsages, "consumeAppliedDiscountUsages");
790
+
649
791
  // src/lib/default-vendor-id.ts
650
792
  function getDefaultVendorId() {
651
793
  const raw = process.env.DEFAULT_VENDOR_ID;
@@ -1989,6 +2131,7 @@ async function ensureUniqueProductSlug(repo, baseSlug, vendorId, excludeId) {
1989
2131
  let slug = baseSlug;
1990
2132
  let suffix = 0;
1991
2133
  while (true) {
2134
+ await retireSoftDeletedUniqueValue(repo, "slug", slug);
1992
2135
  const where = excludeId != null ? {
1993
2136
  slug,
1994
2137
  vendorId,
@@ -2008,6 +2151,21 @@ async function ensureUniqueProductSlug(repo, baseSlug, vendorId, excludeId) {
2008
2151
  }
2009
2152
  }
2010
2153
  __name(ensureUniqueProductSlug, "ensureUniqueProductSlug");
2154
+ async function normalizeComboNameAndSlug(repo, body, vendorId, existing, excludeId) {
2155
+ const incomingName = typeof body.name === "string" ? body.name.trim() : "";
2156
+ const incomingSlugRaw = typeof body.slug === "string" ? body.slug.trim() : "";
2157
+ const existingName = typeof existing?.name === "string" ? existing.name.trim() : "";
2158
+ const existingSlug = typeof existing?.slug === "string" ? existing.slug.trim() : "";
2159
+ const name = incomingName || existingName;
2160
+ if (!name) return "Name is required";
2161
+ if (incomingName) body.name = name;
2162
+ const nameBasedSlug = slugifyProductLabel(name);
2163
+ const typedSlug = incomingSlugRaw ? slugifyProductLabel(incomingSlugRaw) : "";
2164
+ const slug = typedSlug || (excludeId != null ? existingSlug : "") || nameBasedSlug;
2165
+ body.slug = await ensureUniqueProductSlug(repo, slug, vendorId, excludeId);
2166
+ return null;
2167
+ }
2168
+ __name(normalizeComboNameAndSlug, "normalizeComboNameAndSlug");
2011
2169
  async function hydrateProductEventNames(dataSource, entityMap, products) {
2012
2170
  if (!products.length) return products;
2013
2171
  if (!entityMap.event_products || !entityMap.events) {
@@ -2254,6 +2412,20 @@ async function normalizeProductNameAndSlug(repo, body, vendorId, existing, exclu
2254
2412
  return null;
2255
2413
  }
2256
2414
  __name(normalizeProductNameAndSlug, "normalizeProductNameAndSlug");
2415
+ async function retireSoftDeletedUniquesFromBody(repo, body) {
2416
+ const cols = new Set(repo.metadata.columns.map((c) => c.propertyName));
2417
+ if (!cols.has("deleted")) return;
2418
+ for (const col of [
2419
+ "slug",
2420
+ "email"
2421
+ ]) {
2422
+ if (!cols.has(col)) continue;
2423
+ const raw = body[col];
2424
+ if (typeof raw !== "string" || !raw.trim()) continue;
2425
+ await retireSoftDeletedUniqueValue(repo, col, raw.trim());
2426
+ }
2427
+ }
2428
+ __name(retireSoftDeletedUniquesFromBody, "retireSoftDeletedUniquesFromBody");
2257
2429
  function buildSoftDeletePayload(meta, deletedBy) {
2258
2430
  const payload = {
2259
2431
  deleted: true
@@ -2490,6 +2662,7 @@ function discountEvaluateRule(rule, cartLines, cartTotal) {
2490
2662
  case "category":
2491
2663
  case "cart":
2492
2664
  case "paymentMethod":
2665
+ case "deviceType":
2493
2666
  case "order": {
2494
2667
  if (rule.subType === "nthOrder") {
2495
2668
  return true;
@@ -2673,87 +2846,22 @@ function applyDiscountToOrderLines(lines, evalResult, maxDiscountAmount) {
2673
2846
  return totalDiscountApplied;
2674
2847
  }
2675
2848
  __name(applyDiscountToOrderLines, "applyDiscountToOrderLines");
2676
- async function checkAndIncrementDiscountUsage(dataSource, entityMap, discountId, contactId) {
2677
- if (!entityMap["discounts"]) return null;
2678
- const discountRepo = dataSource.getRepository(entityMap["discounts"]);
2679
- const discount = await discountRepo.findOne({
2680
- where: {
2681
- id: discountId
2682
- }
2683
- });
2684
- if (!discount) return `Discount #${discountId} not found`;
2685
- await dataSource.query(`UPDATE discounts SET "usedCount" = "usedCount" + 1 WHERE id = $1`, [
2686
- discountId
2687
- ]);
2688
- return null;
2849
+ function asDiscountUsageEntityMap(entityMap) {
2850
+ return entityMap;
2689
2851
  }
2690
- __name(checkAndIncrementDiscountUsage, "checkAndIncrementDiscountUsage");
2691
- async function decrementDiscountUsage(dataSource, entityMap, discountId, orderId) {
2692
- if (!entityMap["discounts"]) return;
2693
- try {
2694
- await dataSource.query(`UPDATE discounts SET "usedCount" = GREATEST("usedCount" - 1, 0) WHERE id = $1`, [
2695
- discountId
2696
- ]);
2697
- if (entityMap["order_discounts"]) {
2698
- await dataSource.getRepository(entityMap["order_discounts"]).delete({
2699
- orderId,
2700
- discountId
2701
- });
2702
- }
2703
- } catch (err) {
2704
- console.error("[discountEngine] decrementDiscountUsage failed:", err);
2705
- }
2852
+ __name(asDiscountUsageEntityMap, "asDiscountUsageEntityMap");
2853
+ async function checkAndIncrementDiscountUsage2(dataSource, entityMap, discountId, contactId) {
2854
+ return checkAndIncrementDiscountUsage(dataSource, asDiscountUsageEntityMap(entityMap), discountId, contactId);
2706
2855
  }
2707
- __name(decrementDiscountUsage, "decrementDiscountUsage");
2708
- async function recordDiscountUsage(dataSource, entityMap, orderId, discountId, contactId, discountAmount) {
2709
- if (!entityMap["order_discounts"]) return;
2710
- try {
2711
- let discountCode = "";
2712
- if (entityMap["discounts"]) {
2713
- const discountRow = await dataSource.getRepository(entityMap["discounts"]).findOne({
2714
- where: {
2715
- id: discountId
2716
- }
2717
- });
2718
- discountCode = discountRow?.couponCode ?? "";
2719
- }
2720
- const odRepo = dataSource.getRepository(entityMap["order_discounts"]);
2721
- const orderItemRepo = dataSource.getRepository(entityMap.order_items);
2722
- const items = await orderItemRepo.find({
2723
- where: {
2724
- orderId
2725
- }
2726
- });
2727
- const discountedItems = items.filter((item) => Number(item.discount ?? 0) > 0);
2728
- if (discountedItems.length === 0) {
2729
- const firstItem = items[0];
2730
- if (!firstItem) return;
2731
- await odRepo.save(odRepo.create({
2732
- orderId,
2733
- orderItemId: firstItem.id,
2734
- discountId,
2735
- discountCode,
2736
- discountAmount,
2737
- userId: contactId
2738
- }));
2739
- return;
2740
- }
2741
- for (const item of discountedItems) {
2742
- const i = item;
2743
- await odRepo.save(odRepo.create({
2744
- orderId,
2745
- orderItemId: i.id,
2746
- discountId,
2747
- discountCode,
2748
- discountAmount: Number(i.discount ?? 0),
2749
- userId: contactId
2750
- }));
2751
- }
2752
- } catch (err) {
2753
- console.error("[discountEngine] recordDiscountUsage failed:", err);
2754
- }
2856
+ __name(checkAndIncrementDiscountUsage2, "checkAndIncrementDiscountUsage");
2857
+ async function decrementDiscountUsage2(dataSource, entityMap, discountId, orderId) {
2858
+ return decrementDiscountUsage(dataSource, asDiscountUsageEntityMap(entityMap), discountId, orderId);
2755
2859
  }
2756
- __name(recordDiscountUsage, "recordDiscountUsage");
2860
+ __name(decrementDiscountUsage2, "decrementDiscountUsage");
2861
+ async function recordDiscountUsage2(dataSource, entityMap, orderId, discountId, contactId, discountAmount) {
2862
+ return recordDiscountUsage(dataSource, asDiscountUsageEntityMap(entityMap), orderId, discountId, contactId, discountAmount);
2863
+ }
2864
+ __name(recordDiscountUsage2, "recordDiscountUsage");
2757
2865
  async function validateCoupon(dataSource, entityMap, couponCode, orderLines, currency = "INR", contactId, isAutomatic, discountId, vendorId) {
2758
2866
  if (!entityMap["discounts"]) return {
2759
2867
  valid: false,
@@ -2798,21 +2906,12 @@ async function validateCoupon(dataSource, entityMap, couponCode, orderLines, cur
2798
2906
  };
2799
2907
  }
2800
2908
  if (contactId != null && d.maxUsagePerUser != null) {
2801
- try {
2802
- const userUsage = await dataSource.query(`SELECT COUNT(DISTINCT od."orderId") as count FROM order_discounts od
2803
- WHERE od."discountId" = $1
2804
- AND od."userId" = $2`, [
2805
- d.id,
2806
- contactId
2807
- ]);
2808
- const usageCount = Number(userUsage?.[0]?.count ?? 0);
2809
- if (usageCount >= d.maxUsagePerUser) {
2810
- return {
2811
- valid: false,
2812
- error: "You have reached the maximum usage limit for this discount"
2813
- };
2814
- }
2815
- } catch {
2909
+ const usageCount = await countDiscountOrdersForContact(dataSource, d.id, contactId);
2910
+ if (usageCount >= d.maxUsagePerUser) {
2911
+ return {
2912
+ valid: false,
2913
+ error: "You have reached the maximum usage limit for this discount"
2914
+ };
2816
2915
  }
2817
2916
  }
2818
2917
  const flatRules = entityMap["discount_rules"] ? await dataSource.getRepository(entityMap["discount_rules"]).find({
@@ -2890,128 +2989,32 @@ function normalizeOrderLinesInput(raw) {
2890
2989
  if (!Number.isFinite(productId) || productId <= 0) continue;
2891
2990
  const qRaw = Number(r.quantity ?? 1);
2892
2991
  const q = Number.isFinite(qRaw) ? Math.min(99999, Math.max(1, Math.floor(qRaw))) : 1;
2893
- merged.set(productId, (merged.get(productId) ?? 0) + q);
2992
+ const vidRaw = r.variantId ?? r.variant_id;
2993
+ const vid = vidRaw != null && String(vidRaw).trim() !== "" ? Number(vidRaw) : NaN;
2994
+ const variantId = Number.isFinite(vid) && vid > 0 ? vid : null;
2995
+ const key = `${productId}:${variantId ?? 0}`;
2996
+ const prev = merged.get(key);
2997
+ if (prev) prev.quantity += q;
2998
+ else merged.set(key, {
2999
+ productId,
3000
+ quantity: q,
3001
+ variantId
3002
+ });
2894
3003
  }
2895
3004
  return [
2896
- ...merged.entries()
2897
- ].map(([productId, quantity]) => ({
2898
- productId,
2899
- quantity
2900
- }));
3005
+ ...merged.values()
3006
+ ];
2901
3007
  }
2902
3008
  __name(normalizeOrderLinesInput, "normalizeOrderLinesInput");
2903
3009
  var ORDER_STATUS_CONFIRMED = "confirmed";
2904
- function orderInventorySnapshotFromRow(order) {
2905
- return {
2906
- status: order.status ?? "pending",
2907
- lines: (order.items ?? []).map((i) => ({
2908
- productId: Number(i.productId),
2909
- quantity: Math.max(0, Math.floor(Number(i.quantity) || 0))
2910
- })).filter((l) => l.productId > 0 && l.quantity > 0)
2911
- };
2912
- }
2913
- __name(orderInventorySnapshotFromRow, "orderInventorySnapshotFromRow");
2914
- function mergeInventoryLinesByProduct(lines) {
2915
- const m = /* @__PURE__ */ new Map();
2916
- for (const { productId, quantity } of lines) {
2917
- if (!Number.isFinite(productId) || productId <= 0 || quantity <= 0) continue;
2918
- m.set(productId, (m.get(productId) ?? 0) + quantity);
2919
- }
2920
- return m;
2921
- }
2922
- __name(mergeInventoryLinesByProduct, "mergeInventoryLinesByProduct");
2923
- async function validateInventoryForConfirmedOrderLines(dataSource, entityMap, calcLines) {
2924
- const productRepo = dataSource.getRepository(entityMap.products);
2925
- const merged = mergeInventoryLinesByProduct(calcLines.filter((l) => l.found && l.productId != null).map((l) => ({
3010
+ async function validateInventoryForConfirmedOrderLines2(dataSource, entityMap, calcLines) {
3011
+ const lines = calcLines.filter((l) => l.found && l.productId != null).map((l) => ({
2926
3012
  productId: l.productId,
2927
3013
  quantity: l.quantity
2928
- })));
2929
- for (const [productId, qty] of merged) {
2930
- const row = await productRepo.findOne({
2931
- where: {
2932
- id: productId,
2933
- deleted: false
2934
- }
2935
- });
2936
- if (!row) return `Product #${productId} not found`;
2937
- if (row.type === "service") continue;
2938
- const cur = Number(row.quantity ?? 0);
2939
- if (cur < qty) {
2940
- const name = row.name ?? String(productId);
2941
- return `Insufficient stock for ${name}: available ${cur}, required ${qty}`;
2942
- }
2943
- }
2944
- return null;
2945
- }
2946
- __name(validateInventoryForConfirmedOrderLines, "validateInventoryForConfirmedOrderLines");
2947
- async function applyInventoryDeltaForMergedLines(dataSource, entityMap, merged, sign, validateDeduct) {
2948
- const productRepo = dataSource.getRepository(entityMap.products);
2949
- for (const [productId, qty] of merged) {
2950
- const row = await productRepo.findOne({
2951
- where: {
2952
- id: productId,
2953
- deleted: false
2954
- }
2955
- });
2956
- if (!row) return `Product #${productId} not found`;
2957
- if (row.type === "service") continue;
2958
- const cur = Number(row.quantity ?? 0);
2959
- if (sign === -1) {
2960
- if (validateDeduct && cur < qty) {
2961
- const name = row.name ?? String(productId);
2962
- return `Insufficient stock for ${name}: available ${cur}, required ${qty}`;
2963
- }
2964
- await productRepo.update(productId, {
2965
- quantity: Math.max(0, cur - qty)
2966
- });
2967
- } else {
2968
- await productRepo.update(productId, {
2969
- quantity: cur + qty
2970
- });
2971
- }
2972
- }
2973
- return null;
2974
- }
2975
- __name(applyInventoryDeltaForMergedLines, "applyInventoryDeltaForMergedLines");
2976
- async function validateInventoryForOrderBecomingConfirmed(dataSource, entityMap, prevSnap, nextLines) {
2977
- const mergedNext = mergeInventoryLinesByProduct(nextLines);
2978
- const productRepo = dataSource.getRepository(entityMap.products);
2979
- const prevByProduct = prevSnap?.status === ORDER_STATUS_CONFIRMED ? mergeInventoryLinesByProduct(prevSnap.lines) : /* @__PURE__ */ new Map();
2980
- for (const [productId, need] of mergedNext) {
2981
- const row = await productRepo.findOne({
2982
- where: {
2983
- id: productId,
2984
- deleted: false
2985
- }
2986
- });
2987
- if (!row) return `Product #${productId} not found`;
2988
- if (row.type === "service") continue;
2989
- let available = Number(row.quantity ?? 0);
2990
- available += prevByProduct.get(productId) ?? 0;
2991
- if (available < need) {
2992
- const name = row.name ?? String(productId);
2993
- return `Insufficient stock for ${name}: available ${available}, required ${need}`;
2994
- }
2995
- }
2996
- return null;
2997
- }
2998
- __name(validateInventoryForOrderBecomingConfirmed, "validateInventoryForOrderBecomingConfirmed");
2999
- async function reconcileOrderInventoryBetweenSnapshots(dataSource, entityMap, prev, next) {
3000
- const wasConfirmed = prev.status === ORDER_STATUS_CONFIRMED;
3001
- const isConfirmed = next.status === ORDER_STATUS_CONFIRMED;
3002
- if (wasConfirmed) {
3003
- const merged = mergeInventoryLinesByProduct(prev.lines);
3004
- const err = await applyInventoryDeltaForMergedLines(dataSource, entityMap, merged, 1, false);
3005
- if (err) return err;
3006
- }
3007
- if (isConfirmed) {
3008
- const merged = mergeInventoryLinesByProduct(next.lines);
3009
- const err = await applyInventoryDeltaForMergedLines(dataSource, entityMap, merged, -1, true);
3010
- if (err) return err;
3011
- }
3012
- return null;
3014
+ }));
3015
+ return validateInventoryForConfirmedOrderLines(dataSource, entityMap, lines);
3013
3016
  }
3014
- __name(reconcileOrderInventoryBetweenSnapshots, "reconcileOrderInventoryBetweenSnapshots");
3017
+ __name(validateInventoryForConfirmedOrderLines2, "validateInventoryForConfirmedOrderLines");
3015
3018
  async function resolveProductTaxRate(dataSource, entityMap, productId, productVendorId) {
3016
3019
  if (!entityMap.product_config || !entityMap.taxes) {
3017
3020
  return {
@@ -4997,6 +5000,22 @@ function createCrudHandler(dataSource, entityMap, options) {
4997
5000
  status: 400
4998
5001
  });
4999
5002
  }
5003
+ if (resource === "combos") {
5004
+ const vendorIdForSlug = scopeCreate.type === "vendor" ? scopeCreate.vendorId : Number(persistBody.vendorId);
5005
+ if (!Number.isFinite(vendorIdForSlug) || vendorIdForSlug <= 0) {
5006
+ return json({
5007
+ error: "vendorId is required"
5008
+ }, {
5009
+ status: 400
5010
+ });
5011
+ }
5012
+ const comboSlugErr = await normalizeComboNameAndSlug(repo, persistBody, vendorIdForSlug);
5013
+ if (comboSlugErr) return json({
5014
+ error: comboSlugErr
5015
+ }, {
5016
+ status: 400
5017
+ });
5018
+ }
5000
5019
  sanitizeBodyForEntity(repo, persistBody);
5001
5020
  let created;
5002
5021
  try {
@@ -5095,6 +5114,7 @@ function createCrudHandler(dataSource, entityMap, options) {
5095
5114
  persistBody.orderNumber = `ORD00${randomPart}`;
5096
5115
  persistBody.qrToken = crypto2.randomBytes(16).toString("hex");
5097
5116
  }
5117
+ await retireSoftDeletedUniquesFromBody(repo, persistBody);
5098
5118
  created = await repo.save(repo.create(persistBody));
5099
5119
  if (resource === "orders") {
5100
5120
  const orderItemRepo = dataSource.getRepository(entityMap.order_items);
@@ -5136,8 +5156,8 @@ function createCrudHandler(dataSource, entityMap, options) {
5136
5156
  }
5137
5157
  }
5138
5158
  const createdStatus = String(persistBody.status ?? "pending");
5139
- if (createdStatus === ORDER_STATUS_CONFIRMED) {
5140
- const stockErr = await validateInventoryForConfirmedOrderLines(dataSource, entityMap, lines);
5159
+ if (orderStatusHoldsStock(createdStatus)) {
5160
+ const stockErr = await validateInventoryForConfirmedOrderLines2(dataSource, entityMap, lines);
5141
5161
  if (stockErr) {
5142
5162
  await repo.delete(created.id);
5143
5163
  return json({
@@ -5159,6 +5179,7 @@ function createCrudHandler(dataSource, entityMap, options) {
5159
5179
  await orderItemRepo.save(orderItemRepo.create({
5160
5180
  orderId: created.id,
5161
5181
  productId: line.productId,
5182
+ variantId: null,
5162
5183
  quantity: line.quantity,
5163
5184
  unitPrice: line.unitPrice,
5164
5185
  subTotal: line.subtotal,
@@ -5252,7 +5273,7 @@ function createCrudHandler(dataSource, entityMap, options) {
5252
5273
  }
5253
5274
  if (orderDiscountId) {
5254
5275
  if (createdStatus === ORDER_STATUS_CONFIRMED) {
5255
- const usageErr = await checkAndIncrementDiscountUsage(dataSource, entityMap, orderDiscountId, persistBody.contactId);
5276
+ const usageErr = await checkAndIncrementDiscountUsage2(dataSource, entityMap, orderDiscountId, persistBody.contactId);
5256
5277
  if (usageErr) {
5257
5278
  await repo.delete(created.id);
5258
5279
  return json({
@@ -5262,10 +5283,10 @@ function createCrudHandler(dataSource, entityMap, options) {
5262
5283
  });
5263
5284
  }
5264
5285
  }
5265
- await recordDiscountUsage(dataSource, entityMap, created.id, orderDiscountId, persistBody.contactId, discount);
5286
+ await recordDiscountUsage2(dataSource, entityMap, created.id, orderDiscountId, persistBody.contactId, discount);
5266
5287
  }
5267
5288
  const orderIdForNotify = created.id;
5268
- void import('./emit-order-notification-trigger-IVLWKKJL.js').then(({ fireOrderNotificationTrigger }) => {
5289
+ void import('./emit-order-notification-trigger-6XX7LSC4.js').then(({ fireOrderNotificationTrigger }) => {
5269
5290
  fireOrderNotificationTrigger("order_placed", orderIdForNotify, {
5270
5291
  dataSource,
5271
5292
  entityMap
@@ -5916,6 +5937,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
5916
5937
  }
5917
5938
  }
5918
5939
  sanitizeBodyForEntity(repo, updatePayload2);
5940
+ await retireSoftDeletedUniquesFromBody(repo, updatePayload2);
5919
5941
  await repo.update(numericId, updatePayload2);
5920
5942
  if (Array.isArray(rawBody.tags)) {
5921
5943
  const tagNames = rawBody.tags.map((t) => String(t).trim()).filter(Boolean);
@@ -6004,7 +6026,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6004
6026
  } : await calculateOrderTotalsFromLines(dataSource, entityMap, orderLinesNorm, effectiveCurrency, putDiscountId, Number.isFinite(putOrderVendorId) ? putOrderVendorId : null);
6005
6027
  const scalarUpdate = pickColumnUpdates(repo, rawBody);
6006
6028
  const nextStatus = typeof scalarUpdate.status === "string" && scalarUpdate.status ? String(scalarUpdate.status) : orderInvPrev?.status ?? "pending";
6007
- if (nextStatus === ORDER_STATUS_CONFIRMED && lines.length > 0) {
6029
+ if (orderStatusHoldsStock(nextStatus) && lines.length > 0) {
6008
6030
  const verr = await validateInventoryForOrderBecomingConfirmed(dataSource, entityMap, orderInvPrev, lines.filter((l) => l.found && l.productId != null).map((l) => ({
6009
6031
  productId: l.productId,
6010
6032
  quantity: l.quantity
@@ -6133,17 +6155,17 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6133
6155
  }) : null;
6134
6156
  const existingDiscountId = existingOd ? existingOd.discountId : null;
6135
6157
  if (!putDiscountId && existingDiscountId && wasConfirmed) {
6136
- await decrementDiscountUsage(dataSource, entityMap, existingDiscountId, numericId);
6158
+ await decrementDiscountUsage2(dataSource, entityMap, existingDiscountId, numericId);
6137
6159
  if (entityMap["order_discounts"] && existingOd) {
6138
6160
  await dataSource.getRepository(entityMap["order_discounts"]).delete(existingOd.id);
6139
6161
  }
6140
6162
  }
6141
6163
  if (putDiscountId && existingDiscountId && putDiscountId !== existingDiscountId) {
6142
6164
  if (wasConfirmed) {
6143
- await decrementDiscountUsage(dataSource, entityMap, existingDiscountId, numericId);
6165
+ await decrementDiscountUsage2(dataSource, entityMap, existingDiscountId, numericId);
6144
6166
  }
6145
6167
  if (isNowConfirmed) {
6146
- const usageErr = await checkAndIncrementDiscountUsage(dataSource, entityMap, putDiscountId);
6168
+ const usageErr = await checkAndIncrementDiscountUsage2(dataSource, entityMap, putDiscountId, cid);
6147
6169
  if (usageErr) return json({
6148
6170
  error: usageErr
6149
6171
  }, {
@@ -6156,12 +6178,12 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6156
6178
  discountAmount: discount
6157
6179
  });
6158
6180
  } else {
6159
- await recordDiscountUsage(dataSource, entityMap, numericId, putDiscountId, cid, discount);
6181
+ await recordDiscountUsage2(dataSource, entityMap, numericId, putDiscountId, cid, discount);
6160
6182
  }
6161
6183
  }
6162
6184
  if (putDiscountId && existingDiscountId && putDiscountId === existingDiscountId) {
6163
6185
  if (!wasConfirmed && isNowConfirmed) {
6164
- const usageErr = await checkAndIncrementDiscountUsage(dataSource, entityMap, putDiscountId);
6186
+ const usageErr = await checkAndIncrementDiscountUsage2(dataSource, entityMap, putDiscountId, cid);
6165
6187
  if (usageErr) return json({
6166
6188
  error: usageErr
6167
6189
  }, {
@@ -6169,7 +6191,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6169
6191
  });
6170
6192
  }
6171
6193
  if (wasConfirmed && !isNowConfirmed) {
6172
- await decrementDiscountUsage(dataSource, entityMap, putDiscountId, numericId);
6194
+ await decrementDiscountUsage2(dataSource, entityMap, putDiscountId, numericId);
6173
6195
  }
6174
6196
  if (existingOd && entityMap["order_discounts"]) {
6175
6197
  await dataSource.getRepository(entityMap["order_discounts"]).update(existingOd.id, {
@@ -6179,14 +6201,14 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6179
6201
  }
6180
6202
  if (putDiscountId && !existingDiscountId) {
6181
6203
  if (isNowConfirmed) {
6182
- const usageErr = await checkAndIncrementDiscountUsage(dataSource, entityMap, putDiscountId);
6204
+ const usageErr = await checkAndIncrementDiscountUsage2(dataSource, entityMap, putDiscountId, cid);
6183
6205
  if (usageErr) return json({
6184
6206
  error: usageErr
6185
6207
  }, {
6186
6208
  status: 400
6187
6209
  });
6188
6210
  }
6189
- await recordDiscountUsage(dataSource, entityMap, numericId, putDiscountId, cid, discount);
6211
+ await recordDiscountUsage2(dataSource, entityMap, numericId, putDiscountId, cid, discount);
6190
6212
  }
6191
6213
  }
6192
6214
  }
@@ -6657,7 +6679,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6657
6679
  }
6658
6680
  if (resource === "orders" && orderInvPrev) {
6659
6681
  const nextSt = typeof updatePayload.status === "string" && updatePayload.status ? String(updatePayload.status) : orderInvPrev.status;
6660
- if (nextSt === ORDER_STATUS_CONFIRMED && orderInvPrev.lines.length > 0) {
6682
+ if (orderStatusHoldsStock(nextSt) && orderInvPrev.lines.length > 0) {
6661
6683
  const verr = await validateInventoryForOrderBecomingConfirmed(dataSource, entityMap, orderInvPrev, orderInvPrev.lines);
6662
6684
  if (verr) return json({
6663
6685
  error: verr
@@ -6666,6 +6688,33 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6666
6688
  });
6667
6689
  }
6668
6690
  }
6691
+ if (resource === "combos") {
6692
+ const currentCombo = await repo.findOne({
6693
+ where: {
6694
+ id: numericId,
6695
+ deleted: false
6696
+ }
6697
+ });
6698
+ if (!currentCombo) return json({
6699
+ message: "Not found"
6700
+ }, {
6701
+ status: 404
6702
+ });
6703
+ const vendorIdForSlug = scopePut.type === "vendor" ? scopePut.vendorId : Number(currentCombo.vendorId);
6704
+ if (!Number.isFinite(vendorIdForSlug) || vendorIdForSlug <= 0) {
6705
+ return json({
6706
+ error: "vendorId is required"
6707
+ }, {
6708
+ status: 400
6709
+ });
6710
+ }
6711
+ const comboSlugErr = await normalizeComboNameAndSlug(repo, updatePayload, vendorIdForSlug, currentCombo, numericId);
6712
+ if (comboSlugErr) return json({
6713
+ error: comboSlugErr
6714
+ }, {
6715
+ status: 400
6716
+ });
6717
+ }
6669
6718
  if (Object.keys(updatePayload).length > 0) {
6670
6719
  if (resource === "payments" && updatePayload.status === "paid" && updatePayload.paidAt == null) {
6671
6720
  const existingPayment = await repo.findOne({
@@ -6679,6 +6728,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6679
6728
  }
6680
6729
  }
6681
6730
  sanitizeBodyForEntity(repo, updatePayload);
6731
+ await retireSoftDeletedUniquesFromBody(repo, updatePayload);
6682
6732
  await repo.update(numericId, updatePayload);
6683
6733
  }
6684
6734
  if (resource === "orders" && rawBody && entityMap["order_addresses"]) {
@@ -6854,7 +6904,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6854
6904
  });
6855
6905
  if (od) {
6856
6906
  const odRow = od;
6857
- await decrementDiscountUsage(dataSource, entityMap, odRow.discountId, numericId);
6907
+ await decrementDiscountUsage2(dataSource, entityMap, odRow.discountId, numericId);
6858
6908
  }
6859
6909
  }
6860
6910
  }
@@ -6867,11 +6917,19 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
6867
6917
  }
6868
6918
  }
6869
6919
  await repo.update(numericId, buildSoftDeletePayload(repo.metadata, deletedBy));
6870
- if ((resource === "forms" || resource === "vendors") && existing && typeof existing.slug === "string") {
6871
- const slug = String(existing.slug).trim();
6872
- if (slug && !slug.includes("__deleted_")) {
6920
+ const softDeletedCols = repo.metadata.columns.map((c) => c.propertyName);
6921
+ const uniqueColsToRetire = [
6922
+ "slug",
6923
+ "email"
6924
+ ].filter((col) => softDeletedCols.includes(col));
6925
+ if (existing && uniqueColsToRetire.length > 0) {
6926
+ for (const col of uniqueColsToRetire) {
6927
+ const raw = existing[col];
6928
+ if (typeof raw !== "string") continue;
6929
+ const value = raw.trim();
6930
+ if (!value || value.includes("__deleted_")) continue;
6873
6931
  await repo.update(numericId, {
6874
- slug: `${slug}__deleted_${numericId}`
6932
+ [col]: `${value}__deleted_${numericId}`
6875
6933
  });
6876
6934
  }
6877
6935
  }
@@ -6919,6 +6977,49 @@ async function linkUnclaimedContactToUser(dataSource, contactsEntity, userId, em
6919
6977
  });
6920
6978
  }
6921
6979
  __name(linkUnclaimedContactToUser, "linkUnclaimedContactToUser");
6980
+ function buildUserInviteLink(baseUrl, token) {
6981
+ const base = baseUrl.replace(/\/+$/, "");
6982
+ return `${base}/admin/invite?token=${encodeURIComponent(token)}`;
6983
+ }
6984
+ __name(buildUserInviteLink, "buildUserInviteLink");
6985
+ function newUserInviteToken() {
6986
+ return randomBytes(32).toString("hex");
6987
+ }
6988
+ __name(newUserInviteToken, "newUserInviteToken");
6989
+ async function findUserByInviteToken(dataSource, userEntity, token) {
6990
+ const trimmed = token.trim();
6991
+ if (!trimmed) return null;
6992
+ const repo = dataSource.getRepository(userEntity);
6993
+ const row = await repo.findOne({
6994
+ where: {
6995
+ inviteToken: trimmed,
6996
+ deleted: false
6997
+ },
6998
+ select: [
6999
+ "id",
7000
+ "email",
7001
+ "blocked",
7002
+ "password",
7003
+ "inviteStatus",
7004
+ "inviteToken"
7005
+ ]
7006
+ });
7007
+ if (!row) return null;
7008
+ const u = row;
7009
+ return u;
7010
+ }
7011
+ __name(findUserByInviteToken, "findUserByInviteToken");
7012
+ async function completeUserInviteAccept(dataSource, userEntity, userId, passwordHash) {
7013
+ await dataSource.getRepository(userEntity).update(userId, {
7014
+ password: passwordHash,
7015
+ blocked: false,
7016
+ inviteStatus: "active",
7017
+ inviteToken: null
7018
+ });
7019
+ }
7020
+ __name(completeUserInviteAccept, "completeUserInviteAccept");
7021
+
7022
+ // src/lib/vendor-invite-token.ts
6922
7023
  var VENDOR_INVITE_METADATA_TOKEN = "inviteToken";
6923
7024
  var VENDOR_INVITE_METADATA_EXPIRES = "inviteExpiresAt";
6924
7025
  var VENDOR_INVITE_METADATA_SENT = "inviteSentAt";
@@ -6943,6 +7044,13 @@ function invalidatedInviteMessage() {
6943
7044
  return "This invitation is no longer valid. Ask an admin to resend the invite.";
6944
7045
  }
6945
7046
  __name(invalidatedInviteMessage, "invalidatedInviteMessage");
7047
+ function userAlreadyActive(user) {
7048
+ const hasPassword = !!(user.password && String(user.password).trim());
7049
+ if (user.inviteStatus === "active" && hasPassword) return true;
7050
+ if (user.inviteStatus === "pending") return false;
7051
+ return !user.blocked && hasPassword;
7052
+ }
7053
+ __name(userAlreadyActive, "userAlreadyActive");
6946
7054
  async function validateInviteTokenForActivation(dataSource, entityMap, token) {
6947
7055
  const trimmedToken = String(token ?? "").trim();
6948
7056
  if (!trimmedToken) {
@@ -6989,15 +7097,15 @@ async function validateInviteTokenForActivation(dataSource, entityMap, token) {
6989
7097
  "id",
6990
7098
  "email",
6991
7099
  "blocked",
6992
- "password"
7100
+ "password",
7101
+ "inviteStatus"
6993
7102
  ]
6994
7103
  });
6995
7104
  if (!user2) return {
6996
7105
  ok: false,
6997
7106
  error: "User not found"
6998
7107
  };
6999
- const hasPassword2 = !!user2.password;
7000
- if (!user2.blocked && hasPassword2) {
7108
+ if (userAlreadyActive(user2)) {
7001
7109
  return {
7002
7110
  ok: false,
7003
7111
  error: "User is already active"
@@ -7013,6 +7121,24 @@ async function validateInviteTokenForActivation(dataSource, entityMap, token) {
7013
7121
  };
7014
7122
  }
7015
7123
  }
7124
+ if (userRepo && entityMap.users) {
7125
+ const userMatch = await findUserByInviteToken(dataSource, entityMap.users, trimmedToken);
7126
+ if (userMatch) {
7127
+ if (userMatch.inviteStatus === "active" || userAlreadyActive(userMatch)) {
7128
+ return {
7129
+ ok: false,
7130
+ error: "This invitation has already been accepted"
7131
+ };
7132
+ }
7133
+ return {
7134
+ ok: true,
7135
+ target: {
7136
+ userId: userMatch.id,
7137
+ email: userMatch.email
7138
+ }
7139
+ };
7140
+ }
7141
+ }
7016
7142
  let email;
7017
7143
  try {
7018
7144
  email = Buffer.from(trimmedToken, "base64").toString("utf8").trim();
@@ -7042,22 +7168,30 @@ async function validateInviteTokenForActivation(dataSource, entityMap, token) {
7042
7168
  "id",
7043
7169
  "email",
7044
7170
  "blocked",
7045
- "password"
7171
+ "password",
7172
+ "inviteStatus",
7173
+ "inviteToken"
7046
7174
  ]
7047
7175
  });
7048
7176
  if (!user) return {
7049
7177
  ok: false,
7050
7178
  error: "User not found"
7051
7179
  };
7052
- const hasPassword = !!user.password;
7053
- if (!user.blocked && hasPassword) {
7180
+ const u = user;
7181
+ if (userAlreadyActive(u)) {
7054
7182
  return {
7055
7183
  ok: false,
7056
7184
  error: "User is already active"
7057
7185
  };
7058
7186
  }
7187
+ if (u.inviteToken && String(u.inviteToken).trim()) {
7188
+ return {
7189
+ ok: false,
7190
+ error: invalidatedInviteMessage()
7191
+ };
7192
+ }
7059
7193
  if (entityMap.vendors) {
7060
- const ownerVendor = await loadOwnerVendorForUser(dataSource, entityMap.vendors, user.id);
7194
+ const ownerVendor = await loadOwnerVendorForUser(dataSource, entityMap.vendors, u.id);
7061
7195
  if (ownerVendor && readVendorInviteToken(ownerVendor.metadata)) {
7062
7196
  return {
7063
7197
  ok: false,
@@ -7068,8 +7202,8 @@ async function validateInviteTokenForActivation(dataSource, entityMap, token) {
7068
7202
  return {
7069
7203
  ok: true,
7070
7204
  target: {
7071
- userId: user.id,
7072
- email: String(user.email)
7205
+ userId: u.id,
7206
+ email: String(u.email)
7073
7207
  }
7074
7208
  };
7075
7209
  }
@@ -7287,10 +7421,7 @@ function createInviteAcceptHandler(config) {
7287
7421
  }
7288
7422
  if (beforeActivate) await beforeActivate(email, userId);
7289
7423
  const hashedPassword = await hashPassword(password);
7290
- await dataSource.getRepository(entityMap.users).update(userId, {
7291
- password: hashedPassword,
7292
- blocked: false
7293
- });
7424
+ await completeUserInviteAccept(dataSource, entityMap.users, userId, hashedPassword);
7294
7425
  if (vendorId != null && entityMap.vendors) {
7295
7426
  await completeVendorInviteAccept(dataSource, entityMap.vendors, vendorId);
7296
7427
  }
@@ -7651,50 +7782,6 @@ async function findLlmAgentByScope(dataSource, entityMap, scope, options = {}) {
7651
7782
  }
7652
7783
  __name(findLlmAgentByScope, "findLlmAgentByScope");
7653
7784
 
7654
- // src/lib/retire-soft-deleted-unique.ts
7655
- async function retireSoftDeletedUniqueValue(repo, column, value) {
7656
- const trimmed = typeof value === "string" ? value.trim() : "";
7657
- if (!trimmed) return;
7658
- const cols = new Set(repo.metadata.columns.map((c) => c.propertyName));
7659
- if (!cols.has(column) || !cols.has("deleted")) return;
7660
- const rows = await repo.find({
7661
- where: {
7662
- [column]: trimmed,
7663
- deleted: true
7664
- }
7665
- });
7666
- for (const row of rows) {
7667
- const id = row.id;
7668
- if (!Number.isFinite(id)) continue;
7669
- const current = String(row[column] ?? "");
7670
- if (current.includes("__deleted_")) continue;
7671
- await repo.update(id, {
7672
- [column]: `${trimmed}__deleted_${id}`
7673
- });
7674
- }
7675
- }
7676
- __name(retireSoftDeletedUniqueValue, "retireSoftDeletedUniqueValue");
7677
- async function activeUniqueValueExists(repo, column, value, excludeId) {
7678
- const trimmed = typeof value === "string" ? value.trim() : "";
7679
- if (!trimmed) return false;
7680
- const cols = new Set(repo.metadata.columns.map((c) => c.propertyName));
7681
- if (!cols.has(column)) return false;
7682
- const qb = repo.createQueryBuilder("row").where(`row.${column} = :value`, {
7683
- value: trimmed
7684
- });
7685
- if (cols.has("deleted")) {
7686
- qb.andWhere("row.deleted = false");
7687
- }
7688
- if (excludeId != null && Number.isFinite(excludeId) && excludeId > 0) {
7689
- qb.andWhere("row.id != :excludeId", {
7690
- excludeId
7691
- });
7692
- }
7693
- const hit = await qb.getOne();
7694
- return !!hit;
7695
- }
7696
- __name(activeUniqueValueExists, "activeUniqueValueExists");
7697
-
7698
7785
  // src/lib/media-folder-path.ts
7699
7786
  function sanitizeMediaFolderPath(input) {
7700
7787
  if (input == null) return "";
@@ -8761,6 +8848,9 @@ function createUploadHandler(config) {
8761
8848
  "image/png",
8762
8849
  "image/gif",
8763
8850
  "image/webp",
8851
+ "video/mp4",
8852
+ "video/webm",
8853
+ "video/quicktime",
8764
8854
  "application/pdf",
8765
8855
  "text/plain",
8766
8856
  "application/zip",
@@ -8788,8 +8878,11 @@ function createUploadHandler(config) {
8788
8878
  });
8789
8879
  const defaultMax = 10 * 1024 * 1024;
8790
8880
  const maxZipBytes = 80 * 1024 * 1024;
8881
+ const maxVideoBytes = 100 * 1024 * 1024;
8791
8882
  const baseMax = maxSizeBytes ?? defaultMax;
8792
- const effectiveMax = file.type === "application/zip" || file.type === "application/x-zip-compressed" ? Math.max(baseMax, maxZipBytes) : baseMax;
8883
+ const isZip = file.type === "application/zip" || file.type === "application/x-zip-compressed";
8884
+ const isVideo = file.type === "video/mp4" || file.type === "video/webm" || file.type === "video/quicktime";
8885
+ const effectiveMax = isZip ? Math.max(baseMax, maxZipBytes) : isVideo ? Math.max(baseMax, maxVideoBytes) : baseMax;
8793
8886
  if (file.size > effectiveMax) return json({
8794
8887
  error: "File size exceeds limit"
8795
8888
  }, {
@@ -8862,12 +8955,20 @@ function createUploadHandler(config) {
8862
8955
  parentId
8863
8956
  });
8864
8957
  } catch (err) {
8958
+ const message = err instanceof Error ? err.message : String(err);
8865
8959
  console.error("[upload] File upload failed", {
8866
- error: err instanceof Error ? err.message : String(err),
8960
+ error: message,
8867
8961
  stack: err instanceof Error ? err.stack : void 0,
8868
8962
  name: err instanceof Error ? err.name : void 0,
8869
8963
  metadata: err && typeof err === "object" && "$metadata" in err ? err.$metadata : void 0
8870
8964
  });
8965
+ if (/Failed to parse body as FormData/i.test(message)) {
8966
+ return json({
8967
+ error: "File upload failed: request body could not be read as FormData. Exclude /api/upload from middleware matcher and raise proxyClientMaxBodySize."
8968
+ }, {
8969
+ status: 500
8970
+ });
8971
+ }
8871
8972
  return json({
8872
8973
  error: "File upload failed"
8873
8974
  }, {
@@ -9621,7 +9722,8 @@ function createUsersApiHandlers(config) {
9621
9722
  "name",
9622
9723
  "email",
9623
9724
  "id",
9624
- "blocked"
9725
+ "blocked",
9726
+ "inviteStatus"
9625
9727
  ]);
9626
9728
  const sortField = allowedSort.has(sortFieldRaw) ? sortFieldRaw : "createdAt";
9627
9729
  const sortOrder = url.searchParams.get("sortOrder") === "desc" ? "DESC" : "ASC";
@@ -9634,6 +9736,7 @@ function createUsersApiHandlers(config) {
9634
9736
  "u.name",
9635
9737
  "u.email",
9636
9738
  "u.blocked",
9739
+ "u.inviteStatus",
9637
9740
  "u.createdAt",
9638
9741
  "u.updatedAt",
9639
9742
  "u.groupId",
@@ -9729,6 +9832,7 @@ function createUsersApiHandlers(config) {
9729
9832
  const isCustomer = !!(customerG && gid === customerG.id);
9730
9833
  const adminAccess = isCustomer ? false : body.adminAccess === false ? false : true;
9731
9834
  const blocked = body.blocked === true || body.blocked === "true" || body.blocked === 1 || body.blocked === "1";
9835
+ const inviteToken = newUserInviteToken();
9732
9836
  const newUser = existing?.deleted ? await (async () => {
9733
9837
  await userRepo().update(existing.id, {
9734
9838
  deleted: false,
@@ -9738,6 +9842,8 @@ function createUsersApiHandlers(config) {
9738
9842
  email,
9739
9843
  password: null,
9740
9844
  blocked,
9845
+ inviteStatus: "pending",
9846
+ inviteToken,
9741
9847
  groupId: gid,
9742
9848
  adminAccess,
9743
9849
  updatedAt: /* @__PURE__ */ new Date()
@@ -9754,6 +9860,8 @@ function createUsersApiHandlers(config) {
9754
9860
  email,
9755
9861
  password: null,
9756
9862
  blocked,
9863
+ inviteStatus: "pending",
9864
+ inviteToken,
9757
9865
  groupId: gid,
9758
9866
  adminAccess
9759
9867
  }));
@@ -9771,13 +9879,12 @@ function createUsersApiHandlers(config) {
9771
9879
  phone
9772
9880
  });
9773
9881
  }
9774
- const emailToken = Buffer.from(newUser.email).toString("base64");
9775
- const inviteLink = `${baseUrl}/admin/invite?token=${emailToken}`;
9776
- await trySendInviteEmail(newUser.email, inviteLink, newUser.name ?? "");
9882
+ const inviteLink = buildUserInviteLink(baseUrl, inviteToken);
9777
9883
  return json({
9778
- message: blocked ? "User created successfully (blocked until password is set)" : "User created successfully",
9884
+ message: "User created successfully. Invite is pending until they set a password.",
9779
9885
  user: newUser,
9780
- inviteLink
9886
+ inviteLink,
9887
+ emailSent: false
9781
9888
  }, {
9782
9889
  status: 201
9783
9890
  });
@@ -9811,6 +9918,7 @@ function createUsersApiHandlers(config) {
9811
9918
  "email",
9812
9919
  "phone",
9813
9920
  "blocked",
9921
+ "inviteStatus",
9814
9922
  "createdAt",
9815
9923
  "updatedAt",
9816
9924
  "groupId"
@@ -9923,6 +10031,7 @@ function createUsersApiHandlers(config) {
9923
10031
  "email",
9924
10032
  "phone",
9925
10033
  "blocked",
10034
+ "inviteStatus",
9926
10035
  "createdAt",
9927
10036
  "updatedAt",
9928
10037
  "groupId"
@@ -9990,13 +10099,21 @@ function createUsersApiHandlers(config) {
9990
10099
  });
9991
10100
  }
9992
10101
  },
9993
- async regenerateInvite(_req, id) {
9994
- const authErr = await requireAuth(new Request(_req.url));
10102
+ async regenerateInvite(req, id) {
10103
+ const authErr = await requireAuth(new Request(req.url));
9995
10104
  if (authErr) return authErr;
9996
10105
  if (requireEntityPermission) {
9997
- const pe = await requireEntityPermission(_req, "users", "update");
10106
+ const pe = await requireEntityPermission(req, "users", "update");
9998
10107
  if (pe) return pe;
9999
10108
  }
10109
+ let sendEmail = true;
10110
+ let rotate = true;
10111
+ try {
10112
+ const body = await req.json().catch(() => ({}));
10113
+ if (body.sendEmail === false) sendEmail = false;
10114
+ if (body.rotate === false) rotate = false;
10115
+ } catch {
10116
+ }
10000
10117
  try {
10001
10118
  const user = await userRepo().findOne({
10002
10119
  where: {
@@ -10006,7 +10123,11 @@ function createUsersApiHandlers(config) {
10006
10123
  select: [
10007
10124
  "id",
10008
10125
  "email",
10009
- "name"
10126
+ "name",
10127
+ "password",
10128
+ "inviteStatus",
10129
+ "inviteToken",
10130
+ "blocked"
10010
10131
  ]
10011
10132
  });
10012
10133
  if (!user) return json({
@@ -10014,34 +10135,75 @@ function createUsersApiHandlers(config) {
10014
10135
  }, {
10015
10136
  status: 404
10016
10137
  });
10017
- let inviteLink = `${baseUrl}/admin/invite?token=${Buffer.from(user.email).toString("base64")}`;
10138
+ const u = user;
10139
+ const hasPassword = !!(u.password && String(u.password).trim());
10140
+ if (u.inviteStatus === "active" && hasPassword) {
10141
+ return json({
10142
+ error: "User has already accepted the invite"
10143
+ }, {
10144
+ status: 400
10145
+ });
10146
+ }
10147
+ let inviteLink = "";
10018
10148
  if (entityMap.vendors) {
10019
10149
  const vendorRepo = dataSource.getRepository(entityMap.vendors);
10020
10150
  const vendor = await vendorRepo.findOne({
10021
10151
  where: {
10022
- userId: user.id,
10152
+ userId: u.id,
10023
10153
  deleted: false
10024
10154
  }
10025
10155
  });
10026
10156
  const v = vendor;
10027
10157
  if (v && (v.inviteStatus === "pending" || v.inviteStatus === "expired")) {
10028
- const rotatedMetadata = applyRotatingVendorInvite(v.metadata);
10029
- await vendorRepo.update(v.id, {
10030
- metadata: rotatedMetadata,
10031
- inviteStatus: "pending"
10032
- });
10033
- const token = readVendorInviteToken(rotatedMetadata);
10158
+ const nextMetadata = rotate ? applyRotatingVendorInvite(v.metadata) : {
10159
+ ...v.metadata ?? {}
10160
+ };
10161
+ if (rotate || v.inviteStatus !== "pending") {
10162
+ await vendorRepo.update(v.id, {
10163
+ metadata: nextMetadata,
10164
+ inviteStatus: "pending"
10165
+ });
10166
+ }
10167
+ const token = readVendorInviteToken(nextMetadata);
10034
10168
  if (token) {
10035
10169
  inviteLink = buildVendorInviteLink(baseUrl, token);
10036
10170
  }
10171
+ const { markVendorInvitePendingForUser } = await import('./vendor-invite-status-PWJ3DE76.js');
10172
+ await markVendorInvitePendingForUser(dataSource, entityMap.vendors, u.id);
10173
+ }
10174
+ }
10175
+ if (!inviteLink) {
10176
+ let token = u.inviteToken?.trim() || "";
10177
+ if (rotate || !token) {
10178
+ token = newUserInviteToken();
10179
+ await userRepo().update(u.id, {
10180
+ inviteToken: token,
10181
+ inviteStatus: "pending",
10182
+ password: null
10183
+ });
10184
+ } else if (u.inviteStatus !== "pending") {
10185
+ await userRepo().update(u.id, {
10186
+ inviteStatus: "pending"
10187
+ });
10037
10188
  }
10038
- const { markVendorInvitePendingForUser } = await import('./vendor-invite-status-PWJ3DE76.js');
10039
- await markVendorInvitePendingForUser(dataSource, entityMap.vendors, user.id);
10189
+ inviteLink = buildUserInviteLink(baseUrl, token);
10190
+ } else if (rotate) {
10191
+ await userRepo().update(u.id, {
10192
+ inviteStatus: "pending",
10193
+ password: null
10194
+ });
10195
+ }
10196
+ let emailSent = false;
10197
+ if (sendEmail && inviteLink) {
10198
+ await trySendInviteEmail(u.email, inviteLink, u.name ?? "");
10199
+ emailSent = true;
10040
10200
  }
10041
- await trySendInviteEmail(user.email, inviteLink, user.name ?? "");
10201
+ const rotatedNote = rotate ? " Previous invite link is no longer valid." : "";
10042
10202
  return json({
10043
- message: "New invite link generated successfully",
10044
- inviteLink
10203
+ message: emailSent ? `Invite email sent.${rotatedNote}` : sendEmail ? `Invite link ready (email may not have been sent \u2014 check email plugin).${rotatedNote}` : rotate ? "New invite link created. Previous invite link is no longer valid." : "Invite link ready.",
10204
+ emailSent,
10205
+ inviteLink,
10206
+ inviteStatus: "pending"
10045
10207
  });
10046
10208
  } catch {
10047
10209
  return json({
@@ -12857,6 +13019,15 @@ async function seedVendorDefaultRoles(em, vendorId) {
12857
13019
  }
12858
13020
  __name(seedVendorDefaultRoles, "seedVendorDefaultRoles");
12859
13021
  async function backfillVendorUserRoleIds(em, vendorId, seeded) {
13022
+ const cols = await em.query(`
13023
+ SELECT 1
13024
+ FROM information_schema.columns
13025
+ WHERE table_schema = 'public'
13026
+ AND table_name = 'vendor_users'
13027
+ AND column_name = 'role'
13028
+ LIMIT 1
13029
+ `);
13030
+ if (!cols.length) return;
12860
13031
  if (seeded.ownerRoleId) {
12861
13032
  await em.query(`
12862
13033
  UPDATE "vendor_users"
@@ -12948,11 +13119,29 @@ function parseVendorProfileFromBody(raw, options) {
12948
13119
  country: trimOrNull(raw?.country) ?? "IN",
12949
13120
  postalCode: trimOrNull(raw?.postalCode),
12950
13121
  gstin: trimOrNull(raw?.gstin)?.toUpperCase() ?? null,
12951
- pan: trimOrNull(raw?.pan)?.toUpperCase() ?? null,
12952
13122
  registrationStatus: parseRegistrationStatus(raw?.registrationStatus, defaultStatus)
12953
13123
  };
12954
13124
  }
12955
13125
  __name(parseVendorProfileFromBody, "parseVendorProfileFromBody");
13126
+ function parseVendorPersonProfileFromBody(raw, fallbacks) {
13127
+ const name = trimOrNull(raw?.name) ?? trimOrNull(fallbacks?.name) ?? "";
13128
+ const email = (trimOrNull(raw?.email) ?? trimOrNull(fallbacks?.email) ?? "").toLowerCase();
13129
+ const aadhaarRaw = trimOrNull(raw?.aadhaarNo) ?? trimOrNull(raw?.aadhaar);
13130
+ const panRaw = trimOrNull(raw?.panNo) ?? trimOrNull(raw?.pan);
13131
+ return {
13132
+ name,
13133
+ email,
13134
+ phone: trimOrNull(raw?.phone) ?? trimOrNull(fallbacks?.phone),
13135
+ aadhaarNo: aadhaarRaw ? aadhaarRaw.replace(/\s+/g, "") : null,
13136
+ panNo: panRaw ? panRaw.toUpperCase() : null,
13137
+ addressLine1: trimOrNull(raw?.addressLine1),
13138
+ addressLine2: trimOrNull(raw?.addressLine2),
13139
+ city: trimOrNull(raw?.city),
13140
+ state: trimOrNull(raw?.state),
13141
+ postalCode: trimOrNull(raw?.postalCode)
13142
+ };
13143
+ }
13144
+ __name(parseVendorPersonProfileFromBody, "parseVendorPersonProfileFromBody");
12956
13145
  function validateIndiaTaxIds(gstin, pan) {
12957
13146
  if (gstin && !/^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z][1-9A-Z]Z[0-9A-Z]$/i.test(gstin)) {
12958
13147
  return "Invalid GSTIN format (15 characters, e.g. 22AAAAA0000A1Z5)";
@@ -12963,6 +13152,25 @@ function validateIndiaTaxIds(gstin, pan) {
12963
13152
  return null;
12964
13153
  }
12965
13154
  __name(validateIndiaTaxIds, "validateIndiaTaxIds");
13155
+ function validateAadhaar(aadhaar) {
13156
+ if (!aadhaar) return null;
13157
+ if (!/^[0-9]{12}$/.test(aadhaar)) {
13158
+ return "Invalid Aadhaar number (12 digits)";
13159
+ }
13160
+ return null;
13161
+ }
13162
+ __name(validateAadhaar, "validateAadhaar");
13163
+ function validatePersonKyc(person, options) {
13164
+ const required = options?.required === true;
13165
+ if (required && !person.aadhaarNo) return "Aadhaar number is required";
13166
+ if (required && !person.panNo) return "PAN is required";
13167
+ const aadhaarErr = validateAadhaar(person.aadhaarNo ?? null);
13168
+ if (aadhaarErr) return aadhaarErr;
13169
+ const panErr = validateIndiaTaxIds(null, person.panNo ?? null);
13170
+ if (panErr) return panErr;
13171
+ return null;
13172
+ }
13173
+ __name(validatePersonKyc, "validatePersonKyc");
12966
13174
  function buildVendorMetadata(existing, input) {
12967
13175
  const next = {
12968
13176
  ...existing ?? {}
@@ -12977,11 +13185,86 @@ function buildVendorMetadata(existing, input) {
12977
13185
  }
12978
13186
  __name(buildVendorMetadata, "buildVendorMetadata");
12979
13187
 
13188
+ // src/lib/vendor-pending-team-invite.ts
13189
+ var VENDOR_PENDING_TEAM_INVITES_KEY = "pendingTeamInvites";
13190
+ function asMetadata(raw) {
13191
+ if (raw && typeof raw === "object" && !Array.isArray(raw)) {
13192
+ return {
13193
+ ...raw
13194
+ };
13195
+ }
13196
+ return {};
13197
+ }
13198
+ __name(asMetadata, "asMetadata");
13199
+ function readPendingTeamInvites(metadata) {
13200
+ const list = metadata?.[VENDOR_PENDING_TEAM_INVITES_KEY];
13201
+ if (!Array.isArray(list)) return [];
13202
+ return list.filter((row) => {
13203
+ if (!row || typeof row !== "object") return false;
13204
+ const r = row;
13205
+ return typeof r.token === "string" && typeof r.userId === "number" && typeof r.email === "string" && typeof r.vendorRoleId === "number" && typeof r.vendorUserProfileId === "number" && typeof r.name === "string";
13206
+ });
13207
+ }
13208
+ __name(readPendingTeamInvites, "readPendingTeamInvites");
13209
+ function findPendingTeamInviteByToken(metadata, token) {
13210
+ const trimmed = token.trim();
13211
+ if (!trimmed) return null;
13212
+ return readPendingTeamInvites(metadata).find((i) => i.token === trimmed) ?? null;
13213
+ }
13214
+ __name(findPendingTeamInviteByToken, "findPendingTeamInviteByToken");
13215
+ function findPendingTeamInviteByUserId(metadata, userId) {
13216
+ if (!Number.isFinite(userId) || userId <= 0) return null;
13217
+ return readPendingTeamInvites(metadata).find((i) => i.userId === userId) ?? null;
13218
+ }
13219
+ __name(findPendingTeamInviteByUserId, "findPendingTeamInviteByUserId");
13220
+ function upsertPendingTeamInviteInMetadata(metadata, email, next) {
13221
+ const meta = asMetadata(metadata);
13222
+ const emailLc = email.trim().toLowerCase();
13223
+ const rest = readPendingTeamInvites(meta).filter((i) => i.email.toLowerCase() !== emailLc);
13224
+ const pending = next ? [
13225
+ ...rest,
13226
+ next
13227
+ ] : rest;
13228
+ if (pending.length === 0) {
13229
+ delete meta[VENDOR_PENDING_TEAM_INVITES_KEY];
13230
+ } else {
13231
+ meta[VENDOR_PENDING_TEAM_INVITES_KEY] = pending;
13232
+ }
13233
+ return meta;
13234
+ }
13235
+ __name(upsertPendingTeamInviteInMetadata, "upsertPendingTeamInviteInMetadata");
13236
+ function removePendingTeamInviteTokenFromMetadata(metadata, token) {
13237
+ const meta = asMetadata(metadata);
13238
+ const trimmed = token.trim();
13239
+ const pending = readPendingTeamInvites(meta).filter((i) => i.token !== trimmed);
13240
+ if (pending.length === 0) {
13241
+ delete meta[VENDOR_PENDING_TEAM_INVITES_KEY];
13242
+ } else {
13243
+ meta[VENDOR_PENDING_TEAM_INVITES_KEY] = pending;
13244
+ }
13245
+ return meta;
13246
+ }
13247
+ __name(removePendingTeamInviteTokenFromMetadata, "removePendingTeamInviteTokenFromMetadata");
13248
+
12980
13249
  // src/api/vendor-handlers.ts
12981
13250
  function slugify(input) {
12982
13251
  return input.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
12983
13252
  }
12984
13253
  __name(slugify, "slugify");
13254
+ function userHasActiveLogin(user) {
13255
+ if (user.deleted) return false;
13256
+ if (user.blocked) return false;
13257
+ const hasPassword = !!(user.password && String(user.password).trim());
13258
+ if (!hasPassword) return false;
13259
+ if (user.inviteStatus === "pending") return false;
13260
+ return true;
13261
+ }
13262
+ __name(userHasActiveLogin, "userHasActiveLogin");
13263
+ function buildTeamMembershipInviteLink(baseUrl, token, vendorId) {
13264
+ const base = baseUrl.replace(/\/+$/, "");
13265
+ return `${base}/admin/invite?token=${encodeURIComponent(token)}&mode=team&vendorId=${vendorId}`;
13266
+ }
13267
+ __name(buildTeamMembershipInviteLink, "buildTeamMembershipInviteLink");
12985
13268
  async function userHasActiveVendor(em, entityMap, userId) {
12986
13269
  const vendorRepo = em.getRepository(entityMap.vendors);
12987
13270
  const owned = await vendorRepo.findOne({
@@ -13034,7 +13317,7 @@ function vendorOnboardErrorResponse(json, err) {
13034
13317
  }
13035
13318
  if (msg === "VENDOR_OWNER_GROUP_MISSING") {
13036
13319
  return json({
13037
- error: "Vendor Owner group not found. Run migrations (VendorOwnerRbacSeed)."
13320
+ error: "Vendor group not found. Run migrations (VendorTeamProfiles / VendorOwnerRbacSeed)."
13038
13321
  }, {
13039
13322
  status: 500
13040
13323
  });
@@ -13094,7 +13377,7 @@ function vendorOnboardErrorResponse(json, err) {
13094
13377
  }
13095
13378
  __name(vendorOnboardErrorResponse, "vendorOnboardErrorResponse");
13096
13379
  function createVendorOnboardHandlers(config) {
13097
- const { dataSource, entityMap, json, getSessionUser, baseUrl, getCms, hashPassword, minPasswordLength = 6 } = config;
13380
+ const { dataSource, entityMap, json, getSessionUser, baseUrl, getCms } = config;
13098
13381
  async function gateAdmin() {
13099
13382
  const u = await getSessionUser();
13100
13383
  if (!u?.email) return json({
@@ -13244,7 +13527,7 @@ function createVendorOnboardHandlers(config) {
13244
13527
  async getProfile() {
13245
13528
  const gated = await gateVendorPortal();
13246
13529
  if (gated instanceof Response) return gated;
13247
- const { vendorId } = gated;
13530
+ const { user, vendorId } = gated;
13248
13531
  if (!entityMap.vendors) {
13249
13532
  return json({
13250
13533
  error: "Vendors not configured"
@@ -13264,7 +13547,39 @@ function createVendorOnboardHandlers(config) {
13264
13547
  }, {
13265
13548
  status: 404
13266
13549
  });
13267
- return json(row);
13550
+ let personProfile = null;
13551
+ const userId = user.id != null ? Number(user.id) : null;
13552
+ if (userId != null && Number.isFinite(userId) && entityMap.vendor_users && entityMap.vendor_user_profiles) {
13553
+ const link = await dataSource.getRepository(entityMap.vendor_users).findOne({
13554
+ where: {
13555
+ vendorId,
13556
+ userId
13557
+ },
13558
+ relations: [
13559
+ "vendorUserProfile"
13560
+ ]
13561
+ });
13562
+ const vp = link?.vendorUserProfile;
13563
+ if (vp) {
13564
+ personProfile = {
13565
+ id: vp.id,
13566
+ name: vp.name ?? null,
13567
+ email: vp.email ?? null,
13568
+ phone: vp.phone ?? null,
13569
+ aadhaarNo: vp.aadhaarNo ?? null,
13570
+ panNo: vp.panNo ?? null,
13571
+ addressLine1: vp.addressLine1 ?? null,
13572
+ addressLine2: vp.addressLine2 ?? null,
13573
+ city: vp.city ?? null,
13574
+ state: vp.state ?? null,
13575
+ postalCode: vp.postalCode ?? null
13576
+ };
13577
+ }
13578
+ }
13579
+ return json({
13580
+ ...row,
13581
+ personProfile
13582
+ });
13268
13583
  } catch (e) {
13269
13584
  console.error("[vendor.profile]", e);
13270
13585
  return json({
@@ -13285,6 +13600,13 @@ function createVendorOnboardHandlers(config) {
13285
13600
  status: 500
13286
13601
  });
13287
13602
  }
13603
+ if (!entityMap.vendor_user_profiles) {
13604
+ return json({
13605
+ error: "vendor_user_profiles not configured. Run migrations."
13606
+ }, {
13607
+ status: 500
13608
+ });
13609
+ }
13288
13610
  try {
13289
13611
  const body = await req.json();
13290
13612
  const vendorName = trimOrNull(body.vendor?.name);
@@ -13316,12 +13638,35 @@ function createVendorOnboardHandlers(config) {
13316
13638
  const profile = parseVendorProfileFromBody(body.vendor, {
13317
13639
  defaultRegistrationStatus: "approved"
13318
13640
  });
13319
- const taxError = validateIndiaTaxIds(profile.gstin, profile.pan);
13320
- if (taxError) return json({
13321
- error: taxError
13641
+ const gstError = validateIndiaTaxIds(profile.gstin, null);
13642
+ if (gstError) return json({
13643
+ error: gstError
13644
+ }, {
13645
+ status: 400
13646
+ });
13647
+ const person = parseVendorPersonProfileFromBody({
13648
+ ...body.ownerProfile ?? {},
13649
+ ...body.user ?? {}
13650
+ }, {
13651
+ name: userName,
13652
+ email: userEmail,
13653
+ phone: ownerPhone
13654
+ });
13655
+ const personErr = validatePersonKyc(person, {
13656
+ required: true
13657
+ });
13658
+ if (personErr) return json({
13659
+ error: personErr
13322
13660
  }, {
13323
13661
  status: 400
13324
13662
  });
13663
+ if (!person.addressLine1?.trim()) {
13664
+ return json({
13665
+ error: "Owner address line 1 is required"
13666
+ }, {
13667
+ status: 400
13668
+ });
13669
+ }
13325
13670
  const activation = "invite";
13326
13671
  const ownerPasswordHash = null;
13327
13672
  const slug = trimOrNull(body.vendor?.slug) || slugify(vendorName);
@@ -13335,6 +13680,7 @@ function createVendorOnboardHandlers(config) {
13335
13680
  const userRepo = em.getRepository(entityMap.users);
13336
13681
  const vuRepo = em.getRepository(entityMap.vendor_users);
13337
13682
  const groupRepo = em.getRepository(entityMap.user_groups);
13683
+ const profileRepo = em.getRepository(entityMap.vendor_user_profiles);
13338
13684
  const dupVendor = await vendorRepo.findOne({
13339
13685
  where: {
13340
13686
  slug,
@@ -13345,24 +13691,32 @@ function createVendorOnboardHandlers(config) {
13345
13691
  await retireSoftDeletedUniqueValue(vendorRepo, "slug", slug);
13346
13692
  let ownerGroup = await groupRepo.findOne({
13347
13693
  where: {
13348
- name: VENDOR_OWNER_GROUP_NAME,
13694
+ name: VENDOR_GROUP_NAME,
13349
13695
  deleted: false
13350
13696
  }
13351
13697
  });
13698
+ if (!ownerGroup) {
13699
+ ownerGroup = await groupRepo.findOne({
13700
+ where: {
13701
+ name: "Vendor Owner",
13702
+ deleted: false
13703
+ }
13704
+ });
13705
+ }
13352
13706
  if (!ownerGroup) {
13353
13707
  try {
13354
13708
  await groupRepo.save(groupRepo.create({
13355
- name: VENDOR_OWNER_GROUP_NAME,
13709
+ name: VENDOR_GROUP_NAME,
13356
13710
  deleted: false
13357
13711
  }));
13358
13712
  ownerGroup = await groupRepo.findOne({
13359
13713
  where: {
13360
- name: VENDOR_OWNER_GROUP_NAME,
13714
+ name: VENDOR_GROUP_NAME,
13361
13715
  deleted: false
13362
13716
  }
13363
13717
  });
13364
13718
  } catch (seedErr) {
13365
- console.error("[vendor-onboard] failed to seed Vendor Owner group", seedErr);
13719
+ console.error("[vendor-onboard] failed to seed Vendor group", seedErr);
13366
13720
  }
13367
13721
  }
13368
13722
  if (!ownerGroup) throw new Error("VENDOR_OWNER_GROUP_MISSING");
@@ -13430,7 +13784,6 @@ function createVendorOnboardHandlers(config) {
13430
13784
  country: profile.country,
13431
13785
  postalCode: profile.postalCode,
13432
13786
  gstin: profile.gstin,
13433
- pan: profile.pan,
13434
13787
  registrationStatus: profile.registrationStatus,
13435
13788
  metadata,
13436
13789
  active: body.vendor?.active !== false,
@@ -13438,6 +13791,18 @@ function createVendorOnboardHandlers(config) {
13438
13791
  userId: newUser.id,
13439
13792
  inviteStatus: inviteStatusForActivation(activation)
13440
13793
  }));
13794
+ const personRow = await profileRepo.save(profileRepo.create({
13795
+ name: person.name || userName,
13796
+ email: person.email || userEmail,
13797
+ phone: person.phone,
13798
+ aadhaarNo: person.aadhaarNo,
13799
+ panNo: person.panNo,
13800
+ addressLine1: person.addressLine1,
13801
+ addressLine2: person.addressLine2,
13802
+ city: person.city,
13803
+ state: person.state,
13804
+ postalCode: person.postalCode
13805
+ }));
13441
13806
  const seeded = await ensureVendorRolesForVendor(em, vendor.id);
13442
13807
  if (!seeded.ownerRoleId) {
13443
13808
  throw new Error("VENDOR_ROLES_SEED_FAILED");
@@ -13452,12 +13817,13 @@ function createVendorOnboardHandlers(config) {
13452
13817
  await vuRepo.save(vuRepo.create({
13453
13818
  vendorId: vendor.id,
13454
13819
  userId: newUser.id,
13455
- role: "owner",
13456
- vendorRoleId: seeded.ownerRoleId
13820
+ vendorRoleId: seeded.ownerRoleId,
13821
+ vendorUserProfileId: personRow.id
13457
13822
  }));
13458
- } else if (!existingLink.vendorRoleId) {
13823
+ } else {
13459
13824
  await vuRepo.update(existingLink.id, {
13460
- vendorRoleId: seeded.ownerRoleId
13825
+ vendorRoleId: seeded.ownerRoleId,
13826
+ vendorUserProfileId: personRow.id
13461
13827
  });
13462
13828
  }
13463
13829
  if (entityMap.customer) {
@@ -13686,9 +14052,14 @@ function createVendorOnboardHandlers(config) {
13686
14052
  order: {
13687
14053
  id: "ASC"
13688
14054
  },
13689
- relations: entityMap.vendor_roles ? [
13690
- "vendorRole"
13691
- ] : []
14055
+ relations: [
14056
+ ...entityMap.vendor_roles ? [
14057
+ "vendorRole"
14058
+ ] : [],
14059
+ ...entityMap.vendor_user_profiles ? [
14060
+ "vendorUserProfile"
14061
+ ] : []
14062
+ ]
13692
14063
  });
13693
14064
  if (links.length === 0) return json({
13694
14065
  vendorId,
@@ -13721,28 +14092,38 @@ function createVendorOnboardHandlers(config) {
13721
14092
  select: [
13722
14093
  "id",
13723
14094
  "name",
13724
- "isOwnerRole"
14095
+ "isOwnerRole",
14096
+ "isSystem"
13725
14097
  ]
13726
14098
  });
13727
14099
  roles = roleRows.map((r) => ({
13728
14100
  id: r.id,
13729
14101
  name: r.name,
13730
- isOwnerRole: r.isOwnerRole
14102
+ isOwnerRole: r.isOwnerRole,
14103
+ isSystem: r.isSystem === true
13731
14104
  }));
13732
14105
  }
13733
14106
  const members = links.map((l) => {
13734
14107
  const u = userById.get(l.userId);
13735
14108
  const vr = l.vendorRole;
14109
+ const vp = l.vendorUserProfile;
13736
14110
  return {
13737
14111
  vendorUserId: l.id,
13738
14112
  userId: l.userId,
13739
- role: l.role,
13740
14113
  vendorRoleId: l.vendorRoleId ?? null,
13741
14114
  vendorRoleName: vr?.name ?? null,
13742
- isOwnerRole: vr?.isOwnerRole ?? l.role === "owner",
14115
+ isOwnerRole: vr?.isOwnerRole === true,
14116
+ vendorUserProfileId: l.vendorUserProfileId ?? null,
13743
14117
  name: u?.name ?? null,
13744
14118
  email: u?.email ?? null,
13745
- phone: u?.phone ?? null,
14119
+ phone: vp?.phone ?? u?.phone ?? null,
14120
+ aadhaarNo: vp?.aadhaarNo ?? null,
14121
+ panNo: vp?.panNo ?? null,
14122
+ addressLine1: vp?.addressLine1 ?? null,
14123
+ addressLine2: vp?.addressLine2 ?? null,
14124
+ city: vp?.city ?? null,
14125
+ state: vp?.state ?? null,
14126
+ postalCode: vp?.postalCode ?? null,
13746
14127
  blocked: u?.blocked ?? false,
13747
14128
  groupName: u?.group?.name ?? null
13748
14129
  };
@@ -13753,7 +14134,7 @@ function createVendorOnboardHandlers(config) {
13753
14134
  roles
13754
14135
  });
13755
14136
  },
13756
- /** POST /api/admin/vendor/team — add staff to vendor */
14137
+ /** POST /api/admin/vendor/team — invite staff (set-password for new; accept-only for existing vendor people) */
13757
14138
  async addTeamMember(req) {
13758
14139
  const gated = await gateVendorTeam();
13759
14140
  if (gated instanceof Response) return gated;
@@ -13765,8 +14146,16 @@ function createVendorOnboardHandlers(config) {
13765
14146
  status: 500
13766
14147
  });
13767
14148
  }
14149
+ if (!entityMap.vendor_user_profiles) {
14150
+ return json({
14151
+ error: "vendor_user_profiles not configured. Run migrations."
14152
+ }, {
14153
+ status: 500
14154
+ });
14155
+ }
13768
14156
  try {
13769
14157
  const body = await req.json();
14158
+ const sendEmail = body.sendEmail === true;
13770
14159
  const userName = body.name?.trim();
13771
14160
  const userEmail = body.email?.trim().toLowerCase();
13772
14161
  if (!userName || !userEmail) {
@@ -13776,125 +14165,248 @@ function createVendorOnboardHandlers(config) {
13776
14165
  status: 400
13777
14166
  });
13778
14167
  }
13779
- const activation = body.activation === "password" ? "password" : "invite";
13780
- const sendOwnerEmail = body.sendOwnerEmail !== false && body.sendInviteEmail !== false;
13781
- let ownerPasswordHash = null;
13782
- if (activation === "password") {
13783
- const plain = body.user?.password?.trim();
13784
- if (!plain) return json({
13785
- error: "Password is required"
14168
+ if (body.activation === "password" || body.user?.password) {
14169
+ return json({
14170
+ error: "Setting a password for team members is not supported. Invite by email or copy the invite link."
13786
14171
  }, {
13787
14172
  status: 400
13788
14173
  });
13789
- if (plain.length < minPasswordLength) {
13790
- return json({
13791
- error: `Password must be at least ${minPasswordLength} characters`
13792
- }, {
13793
- status: 400
13794
- });
13795
- }
13796
- if (!hashPassword) return json({
13797
- error: "Password hashing not configured"
13798
- }, {
13799
- status: 501
13800
- });
13801
- ownerPasswordHash = await hashPassword(plain);
13802
14174
  }
13803
- const staffGroupId = actor.groupId;
13804
- const result = await dataSource.transaction(async (em) => {
13805
- const userRepo = em.getRepository(entityMap.users);
13806
- const vuRepo = em.getRepository(entityMap.vendor_users);
13807
- const groupRepo = em.getRepository(entityMap.user_groups);
13808
- await ensureVendorRolesForVendor(em, vendorId);
13809
- let staffRoleId = body.vendorRoleId;
13810
- if (staffRoleId != null && entityMap.vendor_roles) {
13811
- const roleRow = await em.getRepository(entityMap.vendor_roles).findOne({
13812
- where: {
13813
- id: staffRoleId,
13814
- vendorId,
13815
- deleted: false
13816
- }
13817
- });
13818
- if (!roleRow) throw new Error("INVALID_VENDOR_ROLE");
13819
- if (roleRow.isOwnerRole) throw new Error("CANNOT_ASSIGN_OWNER_ROLE");
13820
- } else {
13821
- staffRoleId = await getDefaultStaffRoleIdForVendor(em, vendorId) ?? void 0;
13822
- }
13823
- let groupId = staffGroupId ?? null;
13824
- if (!groupId) {
13825
- const g = await groupRepo.findOne({
13826
- where: {
13827
- name: VENDOR_OWNER_GROUP_NAME,
13828
- deleted: false
13829
- }
13830
- });
13831
- groupId = g?.id ?? null;
14175
+ const person = parseVendorPersonProfileFromBody(body, {
14176
+ name: userName,
14177
+ email: userEmail,
14178
+ phone: body.phone
14179
+ });
14180
+ const vendorRow = await dataSource.getRepository(entityMap.vendors).findOne({
14181
+ where: {
14182
+ id: vendorId,
14183
+ deleted: false
14184
+ }
14185
+ });
14186
+ const vendorName = String(vendorRow?.name ?? "Vendor store");
14187
+ const vendorSlug = String(vendorRow?.slug ?? "");
14188
+ const profileRepo = dataSource.getRepository(entityMap.vendor_user_profiles);
14189
+ const existingProfile = await profileRepo.createQueryBuilder("p").where("LOWER(p.email) = :email", {
14190
+ email: userEmail
14191
+ }).orderBy("p.id", "ASC").getOne();
14192
+ const existingUser = await dataSource.getRepository(entityMap.users).findOne({
14193
+ where: {
14194
+ email: userEmail
14195
+ },
14196
+ select: [
14197
+ "id",
14198
+ "email",
14199
+ "name",
14200
+ "password",
14201
+ "inviteStatus",
14202
+ "blocked",
14203
+ "deleted"
14204
+ ]
14205
+ });
14206
+ const isExistingVendorPerson = !!existingProfile && !!existingUser && !existingUser.deleted && userHasActiveLogin(existingUser);
14207
+ if (isExistingVendorPerson) {
14208
+ const membershipToken = newUserInviteToken();
14209
+ const invitee = await dataSource.transaction(async (em) => {
14210
+ const vuRepo = em.getRepository(entityMap.vendor_users);
14211
+ const vendorRepo = em.getRepository(entityMap.vendors);
14212
+ await ensureVendorRolesForVendor(em, vendorId);
14213
+ let staffRoleId = body.vendorRoleId;
14214
+ if (staffRoleId != null && entityMap.vendor_roles) {
14215
+ const roleRow = await em.getRepository(entityMap.vendor_roles).findOne({
14216
+ where: {
14217
+ id: staffRoleId,
14218
+ vendorId,
14219
+ deleted: false
14220
+ }
14221
+ });
14222
+ if (!roleRow) throw new Error("INVALID_VENDOR_ROLE");
14223
+ if (roleRow.isOwnerRole) throw new Error("CANNOT_ASSIGN_OWNER_ROLE");
14224
+ } else {
14225
+ staffRoleId = await getDefaultStaffRoleIdForVendor(em, vendorId) ?? void 0;
14226
+ }
14227
+ if (staffRoleId == null) throw new Error("INVALID_VENDOR_ROLE");
14228
+ const link = await vuRepo.findOne({
14229
+ where: {
14230
+ vendorId,
14231
+ userId: existingUser.id
14232
+ }
14233
+ });
14234
+ if (link) throw new Error("USER_ALREADY_ON_TEAM");
14235
+ const priorLink = await vuRepo.findOne({
14236
+ where: {
14237
+ userId: existingUser.id
14238
+ },
14239
+ order: {
14240
+ id: "ASC"
14241
+ }
14242
+ });
14243
+ const vendorUserProfileId = priorLink?.vendorUserProfileId ?? existingProfile.id;
14244
+ const vendorFresh = await vendorRepo.findOne({
14245
+ where: {
14246
+ id: vendorId,
14247
+ deleted: false
14248
+ }
14249
+ });
14250
+ if (!vendorFresh) throw new Error("VENDOR_NOT_FOUND");
14251
+ const pending = {
14252
+ token: membershipToken,
14253
+ userId: existingUser.id,
14254
+ email: userEmail,
14255
+ vendorRoleId: staffRoleId,
14256
+ vendorUserProfileId,
14257
+ name: userName || String(existingUser.name ?? ""),
14258
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
14259
+ };
14260
+ const nextMeta = upsertPendingTeamInviteInMetadata(vendorFresh.metadata, userEmail, pending);
14261
+ await vendorRepo.update(vendorId, {
14262
+ metadata: nextMeta,
14263
+ updatedAt: /* @__PURE__ */ new Date()
14264
+ });
14265
+ return existingUser;
14266
+ });
14267
+ const inviteLink2 = buildTeamMembershipInviteLink(baseUrl, membershipToken, vendorId);
14268
+ let emailSent2 = false;
14269
+ if (sendEmail) {
14270
+ emailSent2 = await trySendVendorOnboardEmails({
14271
+ vendorName,
14272
+ vendorSlug,
14273
+ ownerName: userName,
14274
+ ownerEmail: userEmail,
14275
+ activation: "membership",
14276
+ inviteLink: inviteLink2,
14277
+ kind: "team_invite",
14278
+ sendToOwner: true
14279
+ });
14280
+ }
14281
+ return json({
14282
+ message: sendEmail ? emailSent2 ? "Existing vendor invited. They can accept without setting a new password." : "Existing vendor invited (email may not have been sent). Share the accept link." : "Existing vendor invited. Send the invite email or copy the invite link.",
14283
+ activation: "membership",
14284
+ emailSent: emailSent2,
14285
+ inviteLink: inviteLink2,
14286
+ user: {
14287
+ id: invitee.id,
14288
+ name: invitee.name,
14289
+ email: invitee.email
14290
+ }
14291
+ }, {
14292
+ status: 201
14293
+ });
14294
+ }
14295
+ const personErr = validatePersonKyc(person, {
14296
+ required: true
14297
+ });
14298
+ if (personErr) return json({
14299
+ error: personErr
14300
+ }, {
14301
+ status: 400
14302
+ });
14303
+ const activation = "invite";
14304
+ const staffGroupId = actor.groupId;
14305
+ const inviteToken = newUserInviteToken();
14306
+ const result = await dataSource.transaction(async (em) => {
14307
+ const userRepo = em.getRepository(entityMap.users);
14308
+ const vuRepo = em.getRepository(entityMap.vendor_users);
14309
+ const groupRepo = em.getRepository(entityMap.user_groups);
14310
+ const profileRepoTx = em.getRepository(entityMap.vendor_user_profiles);
14311
+ await ensureVendorRolesForVendor(em, vendorId);
14312
+ let staffRoleId = body.vendorRoleId;
14313
+ if (staffRoleId != null && entityMap.vendor_roles) {
14314
+ const roleRow = await em.getRepository(entityMap.vendor_roles).findOne({
14315
+ where: {
14316
+ id: staffRoleId,
14317
+ vendorId,
14318
+ deleted: false
14319
+ }
14320
+ });
14321
+ if (!roleRow) throw new Error("INVALID_VENDOR_ROLE");
14322
+ if (roleRow.isOwnerRole) throw new Error("CANNOT_ASSIGN_OWNER_ROLE");
14323
+ } else {
14324
+ staffRoleId = await getDefaultStaffRoleIdForVendor(em, vendorId) ?? void 0;
14325
+ }
14326
+ if (staffRoleId == null) throw new Error("INVALID_VENDOR_ROLE");
14327
+ let groupId = staffGroupId ?? null;
14328
+ if (!groupId) {
14329
+ const g = await groupRepo.findOne({
14330
+ where: {
14331
+ name: VENDOR_GROUP_NAME,
14332
+ deleted: false
14333
+ }
14334
+ }) ?? await groupRepo.findOne({
14335
+ where: {
14336
+ name: "Vendor Owner",
14337
+ deleted: false
14338
+ }
14339
+ });
14340
+ groupId = g?.id ?? null;
13832
14341
  }
13833
14342
  if (!groupId) throw new Error("VENDOR_OWNER_GROUP_MISSING");
13834
- const existingUser = await userRepo.findOne({
14343
+ const existing = await userRepo.findOne({
13835
14344
  where: {
13836
14345
  email: userEmail
13837
14346
  }
13838
14347
  });
13839
- if (existingUser && !existingUser.deleted) {
14348
+ if (existing && !existing.deleted) {
13840
14349
  const link = await vuRepo.findOne({
13841
14350
  where: {
13842
14351
  vendorId,
13843
- userId: existingUser.id
14352
+ userId: existing.id
13844
14353
  }
13845
14354
  });
13846
14355
  if (link) throw new Error("USER_ALREADY_ON_TEAM");
13847
14356
  }
13848
- let newUser = existingUser;
13849
- if (existingUser?.deleted) {
13850
- await userRepo.update(existingUser.id, {
14357
+ let newUser = existing;
14358
+ const inviteUserFields = {
14359
+ name: userName,
14360
+ email: userEmail,
14361
+ phone: person.phone,
14362
+ password: null,
14363
+ blocked: true,
14364
+ inviteStatus: "pending",
14365
+ inviteToken,
14366
+ groupId,
14367
+ adminAccess: true
14368
+ };
14369
+ if (existing?.deleted) {
14370
+ await userRepo.update(existing.id, {
13851
14371
  deleted: false,
13852
14372
  deletedAt: null,
13853
14373
  deletedBy: null,
13854
- name: userName,
13855
- email: userEmail,
13856
- password: ownerPasswordHash,
13857
- blocked: activation === "invite",
13858
- groupId,
13859
- adminAccess: true,
14374
+ ...inviteUserFields,
13860
14375
  updatedAt: /* @__PURE__ */ new Date()
13861
14376
  });
13862
14377
  newUser = await userRepo.findOne({
13863
14378
  where: {
13864
- id: existingUser.id
14379
+ id: existing.id
13865
14380
  }
13866
14381
  });
13867
14382
  if (!newUser) throw new Error("user missing after restore");
13868
- } else if (existingUser && !existingUser.deleted) {
13869
- await userRepo.update(existingUser.id, {
13870
- name: userName,
13871
- groupId,
13872
- adminAccess: true,
13873
- ...ownerPasswordHash ? {
13874
- password: ownerPasswordHash,
13875
- blocked: false
13876
- } : activation === "invite" ? {
13877
- password: null,
13878
- blocked: true
13879
- } : {}
14383
+ } else if (existing && !existing.deleted) {
14384
+ await userRepo.update(existing.id, {
14385
+ ...inviteUserFields,
14386
+ updatedAt: /* @__PURE__ */ new Date()
13880
14387
  });
13881
14388
  newUser = await userRepo.findOne({
13882
14389
  where: {
13883
- id: existingUser.id
14390
+ id: existing.id
13884
14391
  }
13885
14392
  });
13886
14393
  if (!newUser) throw new Error("user missing after update");
13887
- } else if (!existingUser) {
13888
- newUser = await userRepo.save(userRepo.create({
13889
- name: userName,
13890
- email: userEmail,
13891
- password: ownerPasswordHash,
13892
- blocked: activation === "invite",
13893
- groupId,
13894
- adminAccess: true
13895
- }));
14394
+ } else if (!existing) {
14395
+ newUser = await userRepo.save(userRepo.create(inviteUserFields));
13896
14396
  }
13897
14397
  if (!newUser) throw new Error("user missing");
14398
+ const personRow = await profileRepoTx.save(profileRepoTx.create({
14399
+ name: person.name || userName,
14400
+ email: person.email || userEmail,
14401
+ phone: person.phone,
14402
+ aadhaarNo: person.aadhaarNo,
14403
+ panNo: person.panNo,
14404
+ addressLine1: person.addressLine1,
14405
+ addressLine2: person.addressLine2,
14406
+ city: person.city,
14407
+ state: person.state,
14408
+ postalCode: person.postalCode
14409
+ }));
13898
14410
  const existingLink = await vuRepo.findOne({
13899
14411
  where: {
13900
14412
  vendorId,
@@ -13905,40 +14417,32 @@ function createVendorOnboardHandlers(config) {
13905
14417
  await vuRepo.save(vuRepo.create({
13906
14418
  vendorId,
13907
14419
  userId: newUser.id,
13908
- role: "staff",
13909
- vendorRoleId: staffRoleId ?? null
14420
+ vendorRoleId: staffRoleId,
14421
+ vendorUserProfileId: personRow.id
13910
14422
  }));
13911
- } else if (staffRoleId) {
14423
+ } else {
13912
14424
  await vuRepo.update(existingLink.id, {
13913
14425
  vendorRoleId: staffRoleId,
13914
- role: "staff"
14426
+ vendorUserProfileId: personRow.id
13915
14427
  });
13916
14428
  }
13917
14429
  if (entityMap.customer) {
13918
- await ensureCustomerForUser(em, entityMap.customer, {
13919
- id: newUser.id,
13920
- name: userName,
13921
- email: userEmail,
13922
- phone: newUser.phone ?? null
13923
- });
14430
+ try {
14431
+ await ensureCustomerForUser(em, entityMap.customer, {
14432
+ id: newUser.id,
14433
+ name: userName,
14434
+ email: userEmail,
14435
+ phone: person.phone
14436
+ });
14437
+ } catch (customerErr) {
14438
+ console.error("[vendor-team] ensureCustomerForUser skipped", customerErr);
14439
+ }
13924
14440
  }
13925
14441
  return newUser;
13926
14442
  });
13927
- const vendorRow = await dataSource.getRepository(entityMap.vendors).findOne({
13928
- where: {
13929
- id: vendorId,
13930
- deleted: false
13931
- }
13932
- });
13933
- const vendorName = String(vendorRow?.name ?? "Vendor store");
13934
- const vendorSlug = String(vendorRow?.slug ?? "");
13935
- let inviteLink;
14443
+ const inviteLink = buildUserInviteLink(baseUrl, inviteToken);
13936
14444
  let emailSent = false;
13937
- if (activation === "invite") {
13938
- const emailToken = Buffer.from(result.email).toString("base64");
13939
- inviteLink = `${baseUrl}/admin/invite?token=${emailToken}`;
13940
- }
13941
- if (sendOwnerEmail || getCms) {
14445
+ if (sendEmail) {
13942
14446
  emailSent = await trySendVendorOnboardEmails({
13943
14447
  vendorName,
13944
14448
  vendorSlug,
@@ -13947,18 +14451,19 @@ function createVendorOnboardHandlers(config) {
13947
14451
  activation,
13948
14452
  inviteLink,
13949
14453
  kind: "team_invite",
13950
- sendToOwner: sendOwnerEmail
14454
+ sendToOwner: true
13951
14455
  });
13952
14456
  }
13953
14457
  return json({
13954
- message: emailSent ? "Team member added. Invitation email sent." : sendOwnerEmail ? "Team member added (email may not have been sent \u2014 check email plugin)." : "Team member added",
14458
+ message: sendEmail ? emailSent ? "Team member invited. Invitation email sent." : "Team member invited (email may not have been sent \u2014 check email plugin). Share the invite link so they can set their password." : "Team member invited. Send the invite email or copy the invite link.",
14459
+ activation,
13955
14460
  emailSent,
14461
+ inviteLink,
13956
14462
  user: {
13957
14463
  id: result.id,
13958
14464
  name: result.name,
13959
14465
  email: result.email
13960
- },
13961
- inviteLink
14466
+ }
13962
14467
  }, {
13963
14468
  status: 201
13964
14469
  });
@@ -13971,9 +14476,16 @@ function createVendorOnboardHandlers(config) {
13971
14476
  status: 400
13972
14477
  });
13973
14478
  }
14479
+ if (msg === "VENDOR_NOT_FOUND") {
14480
+ return json({
14481
+ error: "Vendor not found"
14482
+ }, {
14483
+ status: 404
14484
+ });
14485
+ }
13974
14486
  if (msg === "VENDOR_OWNER_GROUP_MISSING") {
13975
14487
  return json({
13976
- error: "Vendor role group not found. Run migrations."
14488
+ error: "Vendor group not found. Run migrations."
13977
14489
  }, {
13978
14490
  status: 500
13979
14491
  });
@@ -13985,18 +14497,334 @@ function createVendorOnboardHandlers(config) {
13985
14497
  status: 400
13986
14498
  });
13987
14499
  }
13988
- if (msg === "CANNOT_ASSIGN_OWNER_ROLE") {
14500
+ if (msg === "CANNOT_ASSIGN_OWNER_ROLE") {
14501
+ return json({
14502
+ error: "Cannot assign the owner role to a team member"
14503
+ }, {
14504
+ status: 400
14505
+ });
14506
+ }
14507
+ return vendorOnboardErrorResponse(json, e);
14508
+ }
14509
+ },
14510
+ /** POST /api/admin/vendor/team/send-invite — send invite email for a pending team member */
14511
+ async sendTeamInviteEmail(req) {
14512
+ const gated = await gateVendorTeam();
14513
+ if (gated instanceof Response) return gated;
14514
+ const { vendorId } = gated;
14515
+ if (!entityMap.vendors || !entityMap.users) {
14516
+ return json({
14517
+ error: "Vendor entities not configured"
14518
+ }, {
14519
+ status: 500
14520
+ });
14521
+ }
14522
+ try {
14523
+ const body = await req.json().catch(() => ({}));
14524
+ const userId = Number(body.userId);
14525
+ if (!Number.isFinite(userId) || userId <= 0) {
14526
+ return json({
14527
+ error: "userId is required"
14528
+ }, {
14529
+ status: 400
14530
+ });
14531
+ }
14532
+ const vendorRow = await dataSource.getRepository(entityMap.vendors).findOne({
14533
+ where: {
14534
+ id: vendorId,
14535
+ deleted: false
14536
+ }
14537
+ });
14538
+ if (!vendorRow) return json({
14539
+ error: "Vendor not found"
14540
+ }, {
14541
+ status: 404
14542
+ });
14543
+ const vendorName = String(vendorRow.name ?? "Vendor store");
14544
+ const vendorSlug = String(vendorRow.slug ?? "");
14545
+ const meta = vendorRow.metadata;
14546
+ const pending = findPendingTeamInviteByUserId(meta, userId);
14547
+ if (pending) {
14548
+ const inviteLink2 = buildTeamMembershipInviteLink(baseUrl, pending.token, vendorId);
14549
+ const emailSent2 = await trySendVendorOnboardEmails({
14550
+ vendorName,
14551
+ vendorSlug,
14552
+ ownerName: pending.name,
14553
+ ownerEmail: pending.email,
14554
+ activation: "membership",
14555
+ inviteLink: inviteLink2,
14556
+ kind: "team_invite",
14557
+ sendToOwner: true
14558
+ });
14559
+ return json({
14560
+ message: emailSent2 ? "Invite email sent" : "Invite email may not have been sent",
14561
+ emailSent: emailSent2,
14562
+ inviteLink: inviteLink2,
14563
+ activation: "membership"
14564
+ });
14565
+ }
14566
+ const user = await dataSource.getRepository(entityMap.users).findOne({
14567
+ where: {
14568
+ id: userId,
14569
+ deleted: false
14570
+ },
14571
+ select: [
14572
+ "id",
14573
+ "name",
14574
+ "email",
14575
+ "inviteToken",
14576
+ "inviteStatus",
14577
+ "password",
14578
+ "blocked"
14579
+ ]
14580
+ });
14581
+ if (!user) return json({
14582
+ error: "User not found"
14583
+ }, {
14584
+ status: 404
14585
+ });
14586
+ if (entityMap.vendor_users) {
14587
+ const link = await dataSource.getRepository(entityMap.vendor_users).findOne({
14588
+ where: {
14589
+ vendorId,
14590
+ userId
14591
+ }
14592
+ });
14593
+ if (!link) {
14594
+ return json({
14595
+ error: "User is not on this vendor team"
14596
+ }, {
14597
+ status: 400
14598
+ });
14599
+ }
14600
+ }
14601
+ const token = String(user.inviteToken ?? "").trim();
14602
+ if (!token || user.inviteStatus !== "pending") {
14603
+ return json({
14604
+ error: "No pending invite for this user"
14605
+ }, {
14606
+ status: 400
14607
+ });
14608
+ }
14609
+ const inviteLink = buildUserInviteLink(baseUrl, token);
14610
+ const emailSent = await trySendVendorOnboardEmails({
14611
+ vendorName,
14612
+ vendorSlug,
14613
+ ownerName: String(user.name ?? ""),
14614
+ ownerEmail: String(user.email ?? ""),
14615
+ activation: "invite",
14616
+ inviteLink,
14617
+ kind: "team_invite",
14618
+ sendToOwner: true
14619
+ });
14620
+ return json({
14621
+ message: emailSent ? "Invite email sent" : "Invite email may not have been sent",
14622
+ emailSent,
14623
+ inviteLink,
14624
+ activation: "invite"
14625
+ });
14626
+ } catch (e) {
14627
+ console.error("[vendor.team send-invite]", e);
14628
+ return json({
14629
+ error: "Server Error"
14630
+ }, {
14631
+ status: 500
14632
+ });
14633
+ }
14634
+ },
14635
+ /** GET /api/admin/vendor/team-invite?token=&vendorId= — preflight for membership accept (no password) */
14636
+ async validateTeamInvite(req) {
14637
+ if (!entityMap.vendors) {
14638
+ return json({
14639
+ valid: false,
14640
+ error: "Vendors not configured"
14641
+ }, {
14642
+ status: 500
14643
+ });
14644
+ }
14645
+ try {
14646
+ const url = new URL(req.url);
14647
+ const token = url.searchParams.get("token")?.trim() ?? "";
14648
+ const vendorId = Number(url.searchParams.get("vendorId"));
14649
+ if (!token) return json({
14650
+ valid: false,
14651
+ error: "Invalid invite link. Token is missing."
14652
+ }, {
14653
+ status: 400
14654
+ });
14655
+ if (!Number.isFinite(vendorId) || vendorId <= 0) {
14656
+ return json({
14657
+ valid: false,
14658
+ error: "Invalid invite link. Store is missing."
14659
+ }, {
14660
+ status: 400
14661
+ });
14662
+ }
14663
+ const vendor = await dataSource.getRepository(entityMap.vendors).findOne({
14664
+ where: {
14665
+ id: vendorId,
14666
+ deleted: false
14667
+ }
14668
+ });
14669
+ if (!vendor) {
14670
+ return json({
14671
+ valid: false,
14672
+ error: "This invitation is no longer valid."
14673
+ }, {
14674
+ status: 400
14675
+ });
14676
+ }
14677
+ const invite = findPendingTeamInviteByToken(vendor.metadata, token);
14678
+ if (!invite) {
14679
+ return json({
14680
+ valid: false,
14681
+ error: "This invitation is no longer valid."
14682
+ }, {
14683
+ status: 400
14684
+ });
14685
+ }
14686
+ return json({
14687
+ valid: true,
14688
+ mode: "team",
14689
+ vendorId,
14690
+ vendorName: vendor.name ?? "Vendor store",
14691
+ email: invite.email
14692
+ });
14693
+ } catch (e) {
14694
+ console.error("[vendor.team-invite GET]", e);
14695
+ return json({
14696
+ valid: false,
14697
+ error: "Server Error"
14698
+ }, {
14699
+ status: 500
14700
+ });
14701
+ }
14702
+ },
14703
+ /** POST /api/admin/vendor/team-invite — accept membership (token; no password) */
14704
+ async acceptTeamInvite(req) {
14705
+ if (!entityMap.vendors || !entityMap.vendor_users || !entityMap.vendor_user_profiles || !entityMap.users) {
14706
+ return json({
14707
+ error: "Vendor entities not configured"
14708
+ }, {
14709
+ status: 500
14710
+ });
14711
+ }
14712
+ try {
14713
+ const body = await req.json().catch(() => ({}));
14714
+ const token = typeof body.token === "string" ? body.token.trim() : "";
14715
+ const vendorId = Number(body.vendorId);
14716
+ if (!token) return json({
14717
+ error: "token is required"
14718
+ }, {
14719
+ status: 400
14720
+ });
14721
+ if (!Number.isFinite(vendorId) || vendorId <= 0) {
14722
+ return json({
14723
+ error: "vendorId is required"
14724
+ }, {
14725
+ status: 400
14726
+ });
14727
+ }
14728
+ const result = await dataSource.transaction(async (em) => {
14729
+ const vendorRepo = em.getRepository(entityMap.vendors);
14730
+ const vendor = await vendorRepo.findOne({
14731
+ where: {
14732
+ id: vendorId,
14733
+ deleted: false
14734
+ }
14735
+ });
14736
+ if (!vendor) throw new Error("INVITE_INVALID");
14737
+ const meta = vendor.metadata;
14738
+ const inv = findPendingTeamInviteByToken(meta, token);
14739
+ if (!inv) throw new Error("INVITE_INVALID");
14740
+ const user = await em.getRepository(entityMap.users).findOne({
14741
+ where: {
14742
+ id: inv.userId,
14743
+ deleted: false
14744
+ }
14745
+ });
14746
+ if (!user || !userHasActiveLogin(user)) {
14747
+ throw new Error("INVITE_USER_INACTIVE");
14748
+ }
14749
+ const vuRepo = em.getRepository(entityMap.vendor_users);
14750
+ const existingLink = await vuRepo.findOne({
14751
+ where: {
14752
+ vendorId,
14753
+ userId: inv.userId
14754
+ }
14755
+ });
14756
+ if (existingLink) {
14757
+ await vendorRepo.update(vendorId, {
14758
+ metadata: removePendingTeamInviteTokenFromMetadata(meta, token),
14759
+ updatedAt: /* @__PURE__ */ new Date()
14760
+ });
14761
+ return {
14762
+ alreadyMember: true,
14763
+ vendorId
14764
+ };
14765
+ }
14766
+ if (entityMap.vendor_roles) {
14767
+ const roleRow = await em.getRepository(entityMap.vendor_roles).findOne({
14768
+ where: {
14769
+ id: inv.vendorRoleId,
14770
+ vendorId,
14771
+ deleted: false
14772
+ }
14773
+ });
14774
+ if (!roleRow || roleRow.isOwnerRole) {
14775
+ throw new Error("INVALID_VENDOR_ROLE");
14776
+ }
14777
+ }
14778
+ const profile = await em.getRepository(entityMap.vendor_user_profiles).findOne({
14779
+ where: {
14780
+ id: inv.vendorUserProfileId
14781
+ }
14782
+ });
14783
+ if (!profile) throw new Error("INVITE_INVALID");
14784
+ await vuRepo.save(vuRepo.create({
14785
+ vendorId,
14786
+ userId: inv.userId,
14787
+ vendorRoleId: inv.vendorRoleId,
14788
+ vendorUserProfileId: inv.vendorUserProfileId
14789
+ }));
14790
+ await vendorRepo.update(vendorId, {
14791
+ metadata: removePendingTeamInviteTokenFromMetadata(meta, token),
14792
+ updatedAt: /* @__PURE__ */ new Date()
14793
+ });
14794
+ return {
14795
+ alreadyMember: false,
14796
+ vendorId
14797
+ };
14798
+ });
14799
+ return json({
14800
+ success: true,
14801
+ message: result.alreadyMember ? "You are already on this store team. Sign in to continue." : "You joined the store team. Sign in with your existing password.",
14802
+ vendorId: result.vendorId
14803
+ });
14804
+ } catch (e) {
14805
+ const msg = e instanceof Error ? e.message : String(e);
14806
+ if (msg === "INVITE_INVALID") {
14807
+ return json({
14808
+ error: "This invitation is no longer valid."
14809
+ }, {
14810
+ status: 400
14811
+ });
14812
+ }
14813
+ if (msg === "INVITE_USER_INACTIVE") {
14814
+ return json({
14815
+ error: "Your account is not active. Complete account setup first, or contact support."
14816
+ }, {
14817
+ status: 400
14818
+ });
14819
+ }
14820
+ if (msg === "INVALID_VENDOR_ROLE") {
13989
14821
  return json({
13990
- error: "Cannot assign the owner role to a team member"
14822
+ error: "Invalid store role on this invitation"
13991
14823
  }, {
13992
14824
  status: 400
13993
14825
  });
13994
14826
  }
13995
- return json({
13996
- error: "Server error"
13997
- }, {
13998
- status: 500
13999
- });
14827
+ return vendorOnboardErrorResponse(json, e);
14000
14828
  }
14001
14829
  },
14002
14830
  /** PATCH /api/admin/vendor/team/:userId — change member store role */
@@ -14051,14 +14879,18 @@ function createVendorOnboardHandlers(config) {
14051
14879
  where: {
14052
14880
  vendorId,
14053
14881
  userId
14054
- }
14882
+ },
14883
+ relations: entityMap.vendor_roles ? [
14884
+ "vendorRole"
14885
+ ] : []
14055
14886
  });
14056
14887
  if (!link) return json({
14057
14888
  error: "Not found"
14058
14889
  }, {
14059
14890
  status: 404
14060
14891
  });
14061
- if (link.role === "owner") {
14892
+ const linkIsOwner = link.vendorRole?.isOwnerRole === true;
14893
+ if (linkIsOwner) {
14062
14894
  return json({
14063
14895
  error: "Cannot change the store owner role here"
14064
14896
  }, {
@@ -14066,8 +14898,7 @@ function createVendorOnboardHandlers(config) {
14066
14898
  });
14067
14899
  }
14068
14900
  await vuRepo.update(link.id, {
14069
- vendorRoleId,
14070
- role: "staff"
14901
+ vendorRoleId
14071
14902
  });
14072
14903
  return json({
14073
14904
  ok: true,
@@ -14113,7 +14944,7 @@ function createVendorOnboardHandlers(config) {
14113
14944
  }, {
14114
14945
  status: 404
14115
14946
  });
14116
- const isOwner = link.role === "owner" || !!link.vendorRole?.isOwnerRole;
14947
+ const isOwner = !!link.vendorRole?.isOwnerRole;
14117
14948
  if (isOwner && Number(actor.id) !== userId) {
14118
14949
  return json({
14119
14950
  error: "Cannot remove the store owner"
@@ -14258,13 +15089,28 @@ function createVendorRolesHandlers(config) {
14258
15089
  isSystem: false,
14259
15090
  isOwnerRole: false
14260
15091
  }));
15092
+ const permRepo = dataSource.getRepository(entityMap.vendor_role_permissions);
15093
+ await permRepo.save(vendorRoleEntities.map((entity) => permRepo.create({
15094
+ vendorRoleId: role.id,
15095
+ entity,
15096
+ canCreate: false,
15097
+ canRead: false,
15098
+ canUpdate: false,
15099
+ canDelete: false
15100
+ })));
14261
15101
  return json({
14262
15102
  id: role.id,
14263
15103
  name: role.name,
14264
15104
  description: role.description,
14265
15105
  isSystem: role.isSystem,
14266
15106
  isOwnerRole: role.isOwnerRole,
14267
- permissions: []
15107
+ permissions: vendorRoleEntities.map((entity) => ({
15108
+ entity,
15109
+ canCreate: false,
15110
+ canRead: false,
15111
+ canUpdate: false,
15112
+ canDelete: false
15113
+ }))
14268
15114
  }, {
14269
15115
  status: 201
14270
15116
  });
@@ -14462,16 +15308,15 @@ function createVendorRolesHandlers(config) {
14462
15308
  await em.getRepository(entityMap.vendor_role_permissions).delete({
14463
15309
  vendorRoleId: id
14464
15310
  });
14465
- for (const r of rows) {
14466
- await em.getRepository(entityMap.vendor_role_permissions).save(em.getRepository(entityMap.vendor_role_permissions).create({
14467
- vendorRoleId: id,
14468
- entity: r.entity,
14469
- canCreate: !!r.canCreate,
14470
- canRead: !!r.canRead,
14471
- canUpdate: !!r.canUpdate,
14472
- canDelete: !!r.canDelete
14473
- }));
14474
- }
15311
+ const permRepo = em.getRepository(entityMap.vendor_role_permissions);
15312
+ await permRepo.save(rows.map((r) => permRepo.create({
15313
+ vendorRoleId: id,
15314
+ entity: r.entity,
15315
+ canCreate: !!r.canCreate,
15316
+ canRead: !!r.canRead,
15317
+ canUpdate: !!r.canUpdate,
15318
+ canDelete: !!r.canDelete
15319
+ })));
14475
15320
  });
14476
15321
  const updated = await roleRepo.findOne({
14477
15322
  where: {
@@ -14491,7 +15336,8 @@ function createVendorRolesHandlers(config) {
14491
15336
  canDelete: p.canDelete
14492
15337
  }))
14493
15338
  });
14494
- } catch {
15339
+ } catch (e) {
15340
+ console.error("[vendor-roles.putPermissions]", e);
14495
15341
  return json({
14496
15342
  error: "Server error"
14497
15343
  }, {
@@ -14746,6 +15592,13 @@ var User = class {
14746
15592
  phoneVerifiedAt;
14747
15593
  emailVerifiedAt;
14748
15594
  password;
15595
+ /**
15596
+ * `pending` = invite outstanding (cannot sign in until password is set).
15597
+ * `active` = invite accepted / account usable (subject to `blocked`).
15598
+ */
15599
+ inviteStatus;
15600
+ /** Rotating invite token; null when active or no invite outstanding. */
15601
+ inviteToken;
14749
15602
  blocked;
14750
15603
  adminAccess;
14751
15604
  groupId;
@@ -14798,6 +15651,24 @@ _ts_decorate4([
14798
15651
  }),
14799
15652
  _ts_metadata4("design:type", Object)
14800
15653
  ], User.prototype, "password", void 0);
15654
+ _ts_decorate4([
15655
+ Column({
15656
+ type: "enum",
15657
+ enum: [
15658
+ "pending",
15659
+ "active"
15660
+ ],
15661
+ enumName: "users_invitestatus_enum",
15662
+ default: "active"
15663
+ }),
15664
+ _ts_metadata4("design:type", typeof UserInviteStatus === "undefined" ? Object : UserInviteStatus)
15665
+ ], User.prototype, "inviteStatus", void 0);
15666
+ _ts_decorate4([
15667
+ Column("varchar", {
15668
+ nullable: true
15669
+ }),
15670
+ _ts_metadata4("design:type", Object)
15671
+ ], User.prototype, "inviteToken", void 0);
14801
15672
  _ts_decorate4([
14802
15673
  Column("boolean", {
14803
15674
  default: false
@@ -16103,7 +16974,6 @@ var Vendor = class {
16103
16974
  country;
16104
16975
  postalCode;
16105
16976
  gstin;
16106
- pan;
16107
16977
  logo;
16108
16978
  description;
16109
16979
  metadata;
@@ -16207,12 +17077,6 @@ _ts_decorate16([
16207
17077
  }),
16208
17078
  _ts_metadata16("design:type", Object)
16209
17079
  ], Vendor.prototype, "gstin", void 0);
16210
- _ts_decorate16([
16211
- Column("varchar", {
16212
- nullable: true
16213
- }),
16214
- _ts_metadata16("design:type", Object)
16215
- ], Vendor.prototype, "pan", void 0);
16216
17080
  _ts_decorate16([
16217
17081
  Column("varchar", {
16218
17082
  nullable: true
@@ -19531,6 +20395,8 @@ var OrderItem = class {
19531
20395
  id;
19532
20396
  orderId;
19533
20397
  productId;
20398
+ /** Selected product variant at order time (optional). */
20399
+ variantId;
19534
20400
  discountIds;
19535
20401
  vendorId;
19536
20402
  vendor;
@@ -19566,6 +20432,12 @@ _ts_decorate39([
19566
20432
  Column("int"),
19567
20433
  _ts_metadata39("design:type", Number)
19568
20434
  ], OrderItem.prototype, "productId", void 0);
20435
+ _ts_decorate39([
20436
+ Column("int", {
20437
+ nullable: true
20438
+ }),
20439
+ _ts_metadata39("design:type", Object)
20440
+ ], OrderItem.prototype, "variantId", void 0);
19569
20441
  _ts_decorate39([
19570
20442
  Column({
19571
20443
  type: "int",
@@ -20375,6 +21247,7 @@ var Type = /* @__PURE__ */ (function(Type2) {
20375
21247
  Type2["CATEGORY"] = "category";
20376
21248
  Type2["CART"] = "cart";
20377
21249
  Type2["PAYMENT_METHOD"] = "paymentMethod";
21250
+ Type2["DEVICE_TYPE"] = "deviceType";
20378
21251
  Type2["ORDER"] = "order";
20379
21252
  Type2["QUANTITY"] = "quantity";
20380
21253
  Type2["TIME"] = "time";
@@ -21519,8 +22392,6 @@ VendorRole = _ts_decorate57([
21519
22392
  "vendorId"
21520
22393
  ])
21521
22394
  ], VendorRole);
21522
-
21523
- // src/entities/vendor-user.entity.ts
21524
22395
  function _ts_decorate58(decorators, target, key, desc) {
21525
22396
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
21526
22397
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -21532,89 +22403,201 @@ function _ts_metadata58(k, v) {
21532
22403
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
21533
22404
  }
21534
22405
  __name(_ts_metadata58, "_ts_metadata");
21535
- var VendorUser = class {
22406
+ var VendorUserProfile = class {
21536
22407
  static {
21537
- __name(this, "VendorUser");
22408
+ __name(this, "VendorUserProfile");
21538
22409
  }
21539
22410
  id;
21540
- vendorId;
21541
- userId;
21542
- /** @deprecated use vendorRoleId — kept for migration compatibility */
21543
- role;
21544
- vendorRoleId;
22411
+ name;
22412
+ email;
22413
+ phone;
22414
+ aadhaarNo;
22415
+ panNo;
22416
+ addressLine1;
22417
+ addressLine2;
22418
+ city;
22419
+ state;
22420
+ postalCode;
21545
22421
  createdAt;
21546
22422
  updatedAt;
21547
- vendor;
21548
- user;
21549
- vendorRole;
21550
22423
  };
21551
22424
  _ts_decorate58([
21552
22425
  PrimaryGeneratedColumn(),
21553
22426
  _ts_metadata58("design:type", Number)
21554
- ], VendorUser.prototype, "id", void 0);
22427
+ ], VendorUserProfile.prototype, "id", void 0);
21555
22428
  _ts_decorate58([
21556
- Column("int"),
21557
- _ts_metadata58("design:type", Number)
21558
- ], VendorUser.prototype, "vendorId", void 0);
22429
+ Column("varchar"),
22430
+ _ts_metadata58("design:type", String)
22431
+ ], VendorUserProfile.prototype, "name", void 0);
21559
22432
  _ts_decorate58([
21560
- Column("int"),
21561
- _ts_metadata58("design:type", Number)
21562
- ], VendorUser.prototype, "userId", void 0);
22433
+ Column("varchar"),
22434
+ _ts_metadata58("design:type", String)
22435
+ ], VendorUserProfile.prototype, "email", void 0);
21563
22436
  _ts_decorate58([
21564
22437
  Column("varchar", {
21565
- default: "staff"
22438
+ nullable: true
21566
22439
  }),
21567
- _ts_metadata58("design:type", typeof VendorUserRole === "undefined" ? Object : VendorUserRole)
21568
- ], VendorUser.prototype, "role", void 0);
22440
+ _ts_metadata58("design:type", Object)
22441
+ ], VendorUserProfile.prototype, "phone", void 0);
21569
22442
  _ts_decorate58([
21570
- Column("int", {
22443
+ Column("varchar", {
21571
22444
  nullable: true
21572
22445
  }),
21573
22446
  _ts_metadata58("design:type", Object)
21574
- ], VendorUser.prototype, "vendorRoleId", void 0);
22447
+ ], VendorUserProfile.prototype, "aadhaarNo", void 0);
22448
+ _ts_decorate58([
22449
+ Column("varchar", {
22450
+ nullable: true
22451
+ }),
22452
+ _ts_metadata58("design:type", Object)
22453
+ ], VendorUserProfile.prototype, "panNo", void 0);
22454
+ _ts_decorate58([
22455
+ Column("varchar", {
22456
+ nullable: true
22457
+ }),
22458
+ _ts_metadata58("design:type", Object)
22459
+ ], VendorUserProfile.prototype, "addressLine1", void 0);
22460
+ _ts_decorate58([
22461
+ Column("varchar", {
22462
+ nullable: true
22463
+ }),
22464
+ _ts_metadata58("design:type", Object)
22465
+ ], VendorUserProfile.prototype, "addressLine2", void 0);
22466
+ _ts_decorate58([
22467
+ Column("varchar", {
22468
+ nullable: true
22469
+ }),
22470
+ _ts_metadata58("design:type", Object)
22471
+ ], VendorUserProfile.prototype, "city", void 0);
22472
+ _ts_decorate58([
22473
+ Column("varchar", {
22474
+ nullable: true
22475
+ }),
22476
+ _ts_metadata58("design:type", Object)
22477
+ ], VendorUserProfile.prototype, "state", void 0);
22478
+ _ts_decorate58([
22479
+ Column("varchar", {
22480
+ nullable: true
22481
+ }),
22482
+ _ts_metadata58("design:type", Object)
22483
+ ], VendorUserProfile.prototype, "postalCode", void 0);
21575
22484
  _ts_decorate58([
21576
22485
  Column({
21577
22486
  type: "timestamp",
21578
22487
  default: /* @__PURE__ */ __name(() => "CURRENT_TIMESTAMP", "default")
21579
22488
  }),
21580
22489
  _ts_metadata58("design:type", typeof Date === "undefined" ? Object : Date)
21581
- ], VendorUser.prototype, "createdAt", void 0);
22490
+ ], VendorUserProfile.prototype, "createdAt", void 0);
21582
22491
  _ts_decorate58([
21583
22492
  Column({
21584
22493
  type: "timestamp",
21585
22494
  default: /* @__PURE__ */ __name(() => "CURRENT_TIMESTAMP", "default")
21586
22495
  }),
21587
22496
  _ts_metadata58("design:type", typeof Date === "undefined" ? Object : Date)
22497
+ ], VendorUserProfile.prototype, "updatedAt", void 0);
22498
+ VendorUserProfile = _ts_decorate58([
22499
+ Entity("vendor_user_profiles")
22500
+ ], VendorUserProfile);
22501
+
22502
+ // src/entities/vendor-user.entity.ts
22503
+ function _ts_decorate59(decorators, target, key, desc) {
22504
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
22505
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
22506
+ 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;
22507
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
22508
+ }
22509
+ __name(_ts_decorate59, "_ts_decorate");
22510
+ function _ts_metadata59(k, v) {
22511
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22512
+ }
22513
+ __name(_ts_metadata59, "_ts_metadata");
22514
+ var VendorUser = class {
22515
+ static {
22516
+ __name(this, "VendorUser");
22517
+ }
22518
+ id;
22519
+ vendorId;
22520
+ userId;
22521
+ vendorRoleId;
22522
+ vendorUserProfileId;
22523
+ createdAt;
22524
+ updatedAt;
22525
+ vendor;
22526
+ user;
22527
+ vendorRole;
22528
+ vendorUserProfile;
22529
+ };
22530
+ _ts_decorate59([
22531
+ PrimaryGeneratedColumn(),
22532
+ _ts_metadata59("design:type", Number)
22533
+ ], VendorUser.prototype, "id", void 0);
22534
+ _ts_decorate59([
22535
+ Column("int"),
22536
+ _ts_metadata59("design:type", Number)
22537
+ ], VendorUser.prototype, "vendorId", void 0);
22538
+ _ts_decorate59([
22539
+ Column("int"),
22540
+ _ts_metadata59("design:type", Number)
22541
+ ], VendorUser.prototype, "userId", void 0);
22542
+ _ts_decorate59([
22543
+ Column("int"),
22544
+ _ts_metadata59("design:type", Number)
22545
+ ], VendorUser.prototype, "vendorRoleId", void 0);
22546
+ _ts_decorate59([
22547
+ Column("int"),
22548
+ _ts_metadata59("design:type", Number)
22549
+ ], VendorUser.prototype, "vendorUserProfileId", void 0);
22550
+ _ts_decorate59([
22551
+ Column({
22552
+ type: "timestamp",
22553
+ default: /* @__PURE__ */ __name(() => "CURRENT_TIMESTAMP", "default")
22554
+ }),
22555
+ _ts_metadata59("design:type", typeof Date === "undefined" ? Object : Date)
22556
+ ], VendorUser.prototype, "createdAt", void 0);
22557
+ _ts_decorate59([
22558
+ Column({
22559
+ type: "timestamp",
22560
+ default: /* @__PURE__ */ __name(() => "CURRENT_TIMESTAMP", "default")
22561
+ }),
22562
+ _ts_metadata59("design:type", typeof Date === "undefined" ? Object : Date)
21588
22563
  ], VendorUser.prototype, "updatedAt", void 0);
21589
- _ts_decorate58([
22564
+ _ts_decorate59([
21590
22565
  ManyToOne(() => Vendor, (v) => v.vendorUsers, {
21591
22566
  onDelete: "CASCADE"
21592
22567
  }),
21593
22568
  JoinColumn({
21594
22569
  name: "vendorId"
21595
22570
  }),
21596
- _ts_metadata58("design:type", typeof Vendor === "undefined" ? Object : Vendor)
22571
+ _ts_metadata59("design:type", typeof Vendor === "undefined" ? Object : Vendor)
21597
22572
  ], VendorUser.prototype, "vendor", void 0);
21598
- _ts_decorate58([
22573
+ _ts_decorate59([
21599
22574
  ManyToOne(() => User, {
21600
22575
  onDelete: "CASCADE"
21601
22576
  }),
21602
22577
  JoinColumn({
21603
22578
  name: "userId"
21604
22579
  }),
21605
- _ts_metadata58("design:type", typeof User === "undefined" ? Object : User)
22580
+ _ts_metadata59("design:type", typeof User === "undefined" ? Object : User)
21606
22581
  ], VendorUser.prototype, "user", void 0);
21607
- _ts_decorate58([
22582
+ _ts_decorate59([
21608
22583
  ManyToOne(() => VendorRole, {
21609
- onDelete: "SET NULL",
21610
- nullable: true
22584
+ onDelete: "RESTRICT"
21611
22585
  }),
21612
22586
  JoinColumn({
21613
22587
  name: "vendorRoleId"
21614
22588
  }),
21615
- _ts_metadata58("design:type", Object)
22589
+ _ts_metadata59("design:type", typeof VendorRole === "undefined" ? Object : VendorRole)
21616
22590
  ], VendorUser.prototype, "vendorRole", void 0);
21617
- VendorUser = _ts_decorate58([
22591
+ _ts_decorate59([
22592
+ ManyToOne(() => VendorUserProfile, {
22593
+ onDelete: "RESTRICT"
22594
+ }),
22595
+ JoinColumn({
22596
+ name: "vendorUserProfileId"
22597
+ }),
22598
+ _ts_metadata59("design:type", typeof VendorUserProfile === "undefined" ? Object : VendorUserProfile)
22599
+ ], VendorUser.prototype, "vendorUserProfile", void 0);
22600
+ VendorUser = _ts_decorate59([
21618
22601
  Entity("vendor_users"),
21619
22602
  Unique("UQ_vendor_users_vendor_user", [
21620
22603
  "vendorId",
@@ -21628,19 +22611,22 @@ VendorUser = _ts_decorate58([
21628
22611
  ]),
21629
22612
  Index("IDX_vendor_users_vendor_role", [
21630
22613
  "vendorRoleId"
22614
+ ]),
22615
+ Index("IDX_vendor_users_profile", [
22616
+ "vendorUserProfileId"
21631
22617
  ])
21632
22618
  ], VendorUser);
21633
- function _ts_decorate59(decorators, target, key, desc) {
22619
+ function _ts_decorate60(decorators, target, key, desc) {
21634
22620
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
21635
22621
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21636
22622
  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;
21637
22623
  return c > 3 && r && Object.defineProperty(target, key, r), r;
21638
22624
  }
21639
- __name(_ts_decorate59, "_ts_decorate");
21640
- function _ts_metadata59(k, v) {
22625
+ __name(_ts_decorate60, "_ts_decorate");
22626
+ function _ts_metadata60(k, v) {
21641
22627
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
21642
22628
  }
21643
- __name(_ts_metadata59, "_ts_metadata");
22629
+ __name(_ts_metadata60, "_ts_metadata");
21644
22630
  var VendorCustomer = class {
21645
22631
  static {
21646
22632
  __name(this, "VendorCustomer");
@@ -21659,78 +22645,78 @@ var VendorCustomer = class {
21659
22645
  contact;
21660
22646
  customer;
21661
22647
  };
21662
- _ts_decorate59([
22648
+ _ts_decorate60([
21663
22649
  PrimaryGeneratedColumn(),
21664
- _ts_metadata59("design:type", Number)
22650
+ _ts_metadata60("design:type", Number)
21665
22651
  ], VendorCustomer.prototype, "id", void 0);
21666
- _ts_decorate59([
22652
+ _ts_decorate60([
21667
22653
  Column("int"),
21668
- _ts_metadata59("design:type", Number)
22654
+ _ts_metadata60("design:type", Number)
21669
22655
  ], VendorCustomer.prototype, "vendorId", void 0);
21670
- _ts_decorate59([
22656
+ _ts_decorate60([
21671
22657
  Column("int", {
21672
22658
  nullable: true
21673
22659
  }),
21674
- _ts_metadata59("design:type", Object)
22660
+ _ts_metadata60("design:type", Object)
21675
22661
  ], VendorCustomer.prototype, "contactId", void 0);
21676
- _ts_decorate59([
22662
+ _ts_decorate60([
21677
22663
  Column("int"),
21678
- _ts_metadata59("design:type", Number)
22664
+ _ts_metadata60("design:type", Number)
21679
22665
  ], VendorCustomer.prototype, "customerId", void 0);
21680
- _ts_decorate59([
22666
+ _ts_decorate60([
21681
22667
  Column("text", {
21682
22668
  nullable: true
21683
22669
  }),
21684
- _ts_metadata59("design:type", Object)
22670
+ _ts_metadata60("design:type", Object)
21685
22671
  ], VendorCustomer.prototype, "notes", void 0);
21686
- _ts_decorate59([
22672
+ _ts_decorate60([
21687
22673
  Column("simple-array", {
21688
22674
  nullable: true
21689
22675
  }),
21690
- _ts_metadata59("design:type", Object)
22676
+ _ts_metadata60("design:type", Object)
21691
22677
  ], VendorCustomer.prototype, "tags", void 0);
21692
- _ts_decorate59([
22678
+ _ts_decorate60([
21693
22679
  Column({
21694
22680
  type: "timestamp",
21695
22681
  default: /* @__PURE__ */ __name(() => "CURRENT_TIMESTAMP", "default")
21696
22682
  }),
21697
- _ts_metadata59("design:type", typeof Date === "undefined" ? Object : Date)
22683
+ _ts_metadata60("design:type", typeof Date === "undefined" ? Object : Date)
21698
22684
  ], VendorCustomer.prototype, "createdAt", void 0);
21699
- _ts_decorate59([
22685
+ _ts_decorate60([
21700
22686
  Column({
21701
22687
  type: "timestamp",
21702
22688
  default: /* @__PURE__ */ __name(() => "CURRENT_TIMESTAMP", "default")
21703
22689
  }),
21704
- _ts_metadata59("design:type", typeof Date === "undefined" ? Object : Date)
22690
+ _ts_metadata60("design:type", typeof Date === "undefined" ? Object : Date)
21705
22691
  ], VendorCustomer.prototype, "updatedAt", void 0);
21706
- _ts_decorate59([
22692
+ _ts_decorate60([
21707
22693
  ManyToOne(() => Vendor, {
21708
22694
  onDelete: "CASCADE"
21709
22695
  }),
21710
22696
  JoinColumn({
21711
22697
  name: "vendorId"
21712
22698
  }),
21713
- _ts_metadata59("design:type", typeof Vendor === "undefined" ? Object : Vendor)
22699
+ _ts_metadata60("design:type", typeof Vendor === "undefined" ? Object : Vendor)
21714
22700
  ], VendorCustomer.prototype, "vendor", void 0);
21715
- _ts_decorate59([
22701
+ _ts_decorate60([
21716
22702
  ManyToOne(() => Contact, {
21717
22703
  onDelete: "CASCADE"
21718
22704
  }),
21719
22705
  JoinColumn({
21720
22706
  name: "contactId"
21721
22707
  }),
21722
- _ts_metadata59("design:type", Object)
22708
+ _ts_metadata60("design:type", Object)
21723
22709
  ], VendorCustomer.prototype, "contact", void 0);
21724
- _ts_decorate59([
22710
+ _ts_decorate60([
21725
22711
  ManyToOne(() => Customer, {
21726
22712
  onDelete: "CASCADE"
21727
22713
  }),
21728
22714
  JoinColumn({
21729
22715
  name: "customerId"
21730
22716
  }),
21731
- _ts_metadata59("design:type", typeof Customer === "undefined" ? Object : Customer)
22717
+ _ts_metadata60("design:type", typeof Customer === "undefined" ? Object : Customer)
21732
22718
  ], VendorCustomer.prototype, "customer", void 0);
21733
- VendorCustomer = _ts_decorate59([
22719
+ VendorCustomer = _ts_decorate60([
21734
22720
  Entity("vendor_customers"),
21735
22721
  Index("IDX_vendor_customers_vendor", [
21736
22722
  "vendorId"
@@ -21739,17 +22725,17 @@ VendorCustomer = _ts_decorate59([
21739
22725
  "contactId"
21740
22726
  ])
21741
22727
  ], VendorCustomer);
21742
- function _ts_decorate60(decorators, target, key, desc) {
22728
+ function _ts_decorate61(decorators, target, key, desc) {
21743
22729
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
21744
22730
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21745
22731
  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;
21746
22732
  return c > 3 && r && Object.defineProperty(target, key, r), r;
21747
22733
  }
21748
- __name(_ts_decorate60, "_ts_decorate");
21749
- function _ts_metadata60(k, v) {
22734
+ __name(_ts_decorate61, "_ts_decorate");
22735
+ function _ts_metadata61(k, v) {
21750
22736
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
21751
22737
  }
21752
- __name(_ts_metadata60, "_ts_metadata");
22738
+ __name(_ts_metadata61, "_ts_metadata");
21753
22739
  var Event = class {
21754
22740
  static {
21755
22741
  __name(this, "Event");
@@ -21822,341 +22808,341 @@ var Event = class {
21822
22808
  refundPolicy;
21823
22809
  eventProducts;
21824
22810
  };
21825
- _ts_decorate60([
22811
+ _ts_decorate61([
21826
22812
  PrimaryGeneratedColumn(),
21827
- _ts_metadata60("design:type", Number)
22813
+ _ts_metadata61("design:type", Number)
21828
22814
  ], Event.prototype, "id", void 0);
21829
- _ts_decorate60([
22815
+ _ts_decorate61([
21830
22816
  Column("int", {
21831
22817
  nullable: true
21832
22818
  }),
21833
- _ts_metadata60("design:type", Object)
22819
+ _ts_metadata61("design:type", Object)
21834
22820
  ], Event.prototype, "vendorId", void 0);
21835
- _ts_decorate60([
22821
+ _ts_decorate61([
21836
22822
  Column("varchar"),
21837
- _ts_metadata60("design:type", String)
22823
+ _ts_metadata61("design:type", String)
21838
22824
  ], Event.prototype, "name", void 0);
21839
- _ts_decorate60([
22825
+ _ts_decorate61([
21840
22826
  Column("varchar"),
21841
- _ts_metadata60("design:type", String)
22827
+ _ts_metadata61("design:type", String)
21842
22828
  ], Event.prototype, "slug", void 0);
21843
- _ts_decorate60([
22829
+ _ts_decorate61([
21844
22830
  Column("text", {
21845
22831
  nullable: true
21846
22832
  }),
21847
- _ts_metadata60("design:type", Object)
22833
+ _ts_metadata61("design:type", Object)
21848
22834
  ], Event.prototype, "description", void 0);
21849
- _ts_decorate60([
22835
+ _ts_decorate61([
21850
22836
  Column("int", {
21851
22837
  nullable: true
21852
22838
  }),
21853
- _ts_metadata60("design:type", Object)
22839
+ _ts_metadata61("design:type", Object)
21854
22840
  ], Event.prototype, "expectedSpeakers", void 0);
21855
- _ts_decorate60([
22841
+ _ts_decorate61([
21856
22842
  Column("int", {
21857
22843
  nullable: true
21858
22844
  }),
21859
- _ts_metadata60("design:type", Object)
22845
+ _ts_metadata61("design:type", Object)
21860
22846
  ], Event.prototype, "expectedParticipants", void 0);
21861
- _ts_decorate60([
22847
+ _ts_decorate61([
21862
22848
  Column("boolean", {
21863
22849
  default: true
21864
22850
  }),
21865
- _ts_metadata60("design:type", Boolean)
22851
+ _ts_metadata61("design:type", Boolean)
21866
22852
  ], Event.prototype, "isActive", void 0);
21867
- _ts_decorate60([
22853
+ _ts_decorate61([
21868
22854
  Column("varchar", {
21869
22855
  nullable: true
21870
22856
  }),
21871
- _ts_metadata60("design:type", Object)
22857
+ _ts_metadata61("design:type", Object)
21872
22858
  ], Event.prototype, "approvalStatus", void 0);
21873
- _ts_decorate60([
22859
+ _ts_decorate61([
21874
22860
  Column("text", {
21875
22861
  nullable: true
21876
22862
  }),
21877
- _ts_metadata60("design:type", Object)
22863
+ _ts_metadata61("design:type", Object)
21878
22864
  ], Event.prototype, "rejectionReason", void 0);
21879
- _ts_decorate60([
22865
+ _ts_decorate61([
21880
22866
  Column({
21881
22867
  type: "timestamptz",
21882
22868
  nullable: true
21883
22869
  }),
21884
- _ts_metadata60("design:type", Object)
22870
+ _ts_metadata61("design:type", Object)
21885
22871
  ], Event.prototype, "rejectedAt", void 0);
21886
- _ts_decorate60([
22872
+ _ts_decorate61([
21887
22873
  Column("int", {
21888
22874
  nullable: true
21889
22875
  }),
21890
- _ts_metadata60("design:type", Object)
22876
+ _ts_metadata61("design:type", Object)
21891
22877
  ], Event.prototype, "rejectedBy", void 0);
21892
- _ts_decorate60([
22878
+ _ts_decorate61([
21893
22879
  Column("boolean", {
21894
22880
  default: false
21895
22881
  }),
21896
- _ts_metadata60("design:type", Boolean)
22882
+ _ts_metadata61("design:type", Boolean)
21897
22883
  ], Event.prototype, "comingSoon", void 0);
21898
- _ts_decorate60([
22884
+ _ts_decorate61([
21899
22885
  Column("varchar", {
21900
22886
  nullable: true
21901
22887
  }),
21902
- _ts_metadata60("design:type", Object)
22888
+ _ts_metadata61("design:type", Object)
21903
22889
  ], Event.prototype, "bannerImageUrl", void 0);
21904
- _ts_decorate60([
22890
+ _ts_decorate61([
21905
22891
  Column("varchar", {
21906
22892
  nullable: true
21907
22893
  }),
21908
- _ts_metadata60("design:type", Object)
22894
+ _ts_metadata61("design:type", Object)
21909
22895
  ], Event.prototype, "logoUrl", void 0);
21910
- _ts_decorate60([
22896
+ _ts_decorate61([
21911
22897
  Column("varchar", {
21912
22898
  nullable: true
21913
22899
  }),
21914
- _ts_metadata60("design:type", Object)
22900
+ _ts_metadata61("design:type", Object)
21915
22901
  ], Event.prototype, "venue", void 0);
21916
- _ts_decorate60([
22902
+ _ts_decorate61([
21917
22903
  Column("text", {
21918
22904
  nullable: true
21919
22905
  }),
21920
- _ts_metadata60("design:type", Object)
22906
+ _ts_metadata61("design:type", Object)
21921
22907
  ], Event.prototype, "additionalVenueDetails", void 0);
21922
- _ts_decorate60([
22908
+ _ts_decorate61([
21923
22909
  Column("varchar", {
21924
22910
  default: "public"
21925
22911
  }),
21926
- _ts_metadata60("design:type", typeof EventVisibility === "undefined" ? Object : EventVisibility)
22912
+ _ts_metadata61("design:type", typeof EventVisibility === "undefined" ? Object : EventVisibility)
21927
22913
  ], Event.prototype, "visibility", void 0);
21928
- _ts_decorate60([
22914
+ _ts_decorate61([
21929
22915
  Column({
21930
22916
  type: "timestamp",
21931
22917
  nullable: true
21932
22918
  }),
21933
- _ts_metadata60("design:type", Object)
22919
+ _ts_metadata61("design:type", Object)
21934
22920
  ], Event.prototype, "startDate", void 0);
21935
- _ts_decorate60([
22921
+ _ts_decorate61([
21936
22922
  Column({
21937
22923
  type: "timestamp",
21938
22924
  nullable: true
21939
22925
  }),
21940
- _ts_metadata60("design:type", Object)
22926
+ _ts_metadata61("design:type", Object)
21941
22927
  ], Event.prototype, "endDate", void 0);
21942
- _ts_decorate60([
22928
+ _ts_decorate61([
21943
22929
  Column({
21944
22930
  type: "timestamp",
21945
22931
  nullable: true
21946
22932
  }),
21947
- _ts_metadata60("design:type", Object)
22933
+ _ts_metadata61("design:type", Object)
21948
22934
  ], Event.prototype, "registrationOpensAt", void 0);
21949
- _ts_decorate60([
22935
+ _ts_decorate61([
21950
22936
  Column({
21951
22937
  type: "timestamp",
21952
22938
  nullable: true
21953
22939
  }),
21954
- _ts_metadata60("design:type", Object)
22940
+ _ts_metadata61("design:type", Object)
21955
22941
  ], Event.prototype, "registrationClosesAt", void 0);
21956
- _ts_decorate60([
22942
+ _ts_decorate61([
21957
22943
  Column("varchar", {
21958
22944
  nullable: true
21959
22945
  }),
21960
- _ts_metadata60("design:type", Object)
22946
+ _ts_metadata61("design:type", Object)
21961
22947
  ], Event.prototype, "pricingType", void 0);
21962
- _ts_decorate60([
22948
+ _ts_decorate61([
21963
22949
  Column("jsonb", {
21964
22950
  nullable: true
21965
22951
  }),
21966
- _ts_metadata60("design:type", Object)
22952
+ _ts_metadata61("design:type", Object)
21967
22953
  ], Event.prototype, "entityTypes", void 0);
21968
- _ts_decorate60([
22954
+ _ts_decorate61([
21969
22955
  Column("varchar", {
21970
22956
  nullable: true
21971
22957
  }),
21972
- _ts_metadata60("design:type", Object)
22958
+ _ts_metadata61("design:type", Object)
21973
22959
  ], Event.prototype, "entityMode", void 0);
21974
- _ts_decorate60([
22960
+ _ts_decorate61([
21975
22961
  Column("varchar", {
21976
22962
  nullable: true
21977
22963
  }),
21978
- _ts_metadata60("design:type", Object)
22964
+ _ts_metadata61("design:type", Object)
21979
22965
  ], Event.prototype, "city", void 0);
21980
- _ts_decorate60([
22966
+ _ts_decorate61([
21981
22967
  Column("varchar", {
21982
22968
  nullable: true
21983
22969
  }),
21984
- _ts_metadata60("design:type", Object)
22970
+ _ts_metadata61("design:type", Object)
21985
22971
  ], Event.prototype, "country", void 0);
21986
- _ts_decorate60([
22972
+ _ts_decorate61([
21987
22973
  Column("varchar", {
21988
22974
  nullable: true
21989
22975
  }),
21990
- _ts_metadata60("design:type", Object)
22976
+ _ts_metadata61("design:type", Object)
21991
22977
  ], Event.prototype, "cityCountry", void 0);
21992
- _ts_decorate60([
22978
+ _ts_decorate61([
21993
22979
  Column("varchar", {
21994
22980
  nullable: true
21995
22981
  }),
21996
- _ts_metadata60("design:type", Object)
22982
+ _ts_metadata61("design:type", Object)
21997
22983
  ], Event.prototype, "defaultCurrency", void 0);
21998
- _ts_decorate60([
22984
+ _ts_decorate61([
21999
22985
  Column("jsonb", {
22000
22986
  nullable: true
22001
22987
  }),
22002
- _ts_metadata60("design:type", Object)
22988
+ _ts_metadata61("design:type", Object)
22003
22989
  ], Event.prototype, "supportedCurrencies", void 0);
22004
- _ts_decorate60([
22990
+ _ts_decorate61([
22005
22991
  Column("varchar", {
22006
22992
  nullable: true
22007
22993
  }),
22008
- _ts_metadata60("design:type", Object)
22994
+ _ts_metadata61("design:type", Object)
22009
22995
  ], Event.prototype, "timezone", void 0);
22010
- _ts_decorate60([
22996
+ _ts_decorate61([
22011
22997
  Column("jsonb", {
22012
22998
  nullable: true
22013
22999
  }),
22014
- _ts_metadata60("design:type", Object)
23000
+ _ts_metadata61("design:type", Object)
22015
23001
  ], Event.prototype, "socialMediaLinks", void 0);
22016
- _ts_decorate60([
23002
+ _ts_decorate61([
22017
23003
  Column("varchar", {
22018
23004
  nullable: true
22019
23005
  }),
22020
- _ts_metadata60("design:type", Object)
23006
+ _ts_metadata61("design:type", Object)
22021
23007
  ], Event.prototype, "officialWebsiteUrl", void 0);
22022
- _ts_decorate60([
23008
+ _ts_decorate61([
22023
23009
  Column("varchar", {
22024
23010
  nullable: true
22025
23011
  }),
22026
- _ts_metadata60("design:type", Object)
23012
+ _ts_metadata61("design:type", Object)
22027
23013
  ], Event.prototype, "supportContact", void 0);
22028
- _ts_decorate60([
23014
+ _ts_decorate61([
22029
23015
  Column("boolean", {
22030
23016
  default: false
22031
23017
  }),
22032
- _ts_metadata60("design:type", Boolean)
23018
+ _ts_metadata61("design:type", Boolean)
22033
23019
  ], Event.prototype, "allowGroupOrders", void 0);
22034
- _ts_decorate60([
23020
+ _ts_decorate61([
22035
23021
  Column("boolean", {
22036
23022
  default: false
22037
23023
  }),
22038
- _ts_metadata60("design:type", Boolean)
23024
+ _ts_metadata61("design:type", Boolean)
22039
23025
  ], Event.prototype, "sendIndividualTicketPDFToAttendees", void 0);
22040
- _ts_decorate60([
23026
+ _ts_decorate61([
22041
23027
  Column("int", {
22042
23028
  nullable: true
22043
23029
  }),
22044
- _ts_metadata60("design:type", Object)
23030
+ _ts_metadata61("design:type", Object)
22045
23031
  ], Event.prototype, "contactFormId", void 0);
22046
- _ts_decorate60([
23032
+ _ts_decorate61([
22047
23033
  Column("int", {
22048
23034
  nullable: true
22049
23035
  }),
22050
- _ts_metadata60("design:type", Object)
23036
+ _ts_metadata61("design:type", Object)
22051
23037
  ], Event.prototype, "taxId", void 0);
22052
- _ts_decorate60([
23038
+ _ts_decorate61([
22053
23039
  Column("int", {
22054
23040
  nullable: true
22055
23041
  }),
22056
- _ts_metadata60("design:type", Object)
23042
+ _ts_metadata61("design:type", Object)
22057
23043
  ], Event.prototype, "refundPolicyId", void 0);
22058
- _ts_decorate60([
23044
+ _ts_decorate61([
22059
23045
  Column("decimal", {
22060
23046
  precision: 5,
22061
23047
  scale: 2,
22062
23048
  nullable: true
22063
23049
  }),
22064
- _ts_metadata60("design:type", Object)
23050
+ _ts_metadata61("design:type", Object)
22065
23051
  ], Event.prototype, "taxRate", void 0);
22066
- _ts_decorate60([
23052
+ _ts_decorate61([
22067
23053
  Column("int", {
22068
23054
  nullable: true
22069
23055
  }),
22070
- _ts_metadata60("design:type", Object)
23056
+ _ts_metadata61("design:type", Object)
22071
23057
  ], Event.prototype, "maxGroupPurchaseQuantity", void 0);
22072
- _ts_decorate60([
23058
+ _ts_decorate61([
22073
23059
  Column("jsonb", {
22074
23060
  nullable: true
22075
23061
  }),
22076
- _ts_metadata60("design:type", Object)
23062
+ _ts_metadata61("design:type", Object)
22077
23063
  ], Event.prototype, "sponsors", void 0);
22078
- _ts_decorate60([
23064
+ _ts_decorate61([
22079
23065
  Column("jsonb", {
22080
23066
  nullable: true
22081
23067
  }),
22082
- _ts_metadata60("design:type", Object)
23068
+ _ts_metadata61("design:type", Object)
22083
23069
  ], Event.prototype, "agenda", void 0);
22084
- _ts_decorate60([
23070
+ _ts_decorate61([
22085
23071
  Column("jsonb", {
22086
23072
  nullable: true
22087
23073
  }),
22088
- _ts_metadata60("design:type", Object)
23074
+ _ts_metadata61("design:type", Object)
22089
23075
  ], Event.prototype, "workshops", void 0);
22090
- _ts_decorate60([
23076
+ _ts_decorate61([
22091
23077
  Column("jsonb", {
22092
23078
  nullable: true
22093
23079
  }),
22094
- _ts_metadata60("design:type", Object)
23080
+ _ts_metadata61("design:type", Object)
22095
23081
  ], Event.prototype, "exhibitors", void 0);
22096
- _ts_decorate60([
23082
+ _ts_decorate61([
22097
23083
  Column("jsonb", {
22098
23084
  nullable: true
22099
23085
  }),
22100
- _ts_metadata60("design:type", Object)
23086
+ _ts_metadata61("design:type", Object)
22101
23087
  ], Event.prototype, "partners", void 0);
22102
- _ts_decorate60([
23088
+ _ts_decorate61([
22103
23089
  Column("jsonb", {
22104
23090
  nullable: true
22105
23091
  }),
22106
- _ts_metadata60("design:type", Object)
23092
+ _ts_metadata61("design:type", Object)
22107
23093
  ], Event.prototype, "speakers", void 0);
22108
- _ts_decorate60([
23094
+ _ts_decorate61([
22109
23095
  Column("int", {
22110
23096
  default: 0
22111
23097
  }),
22112
- _ts_metadata60("design:type", Number)
23098
+ _ts_metadata61("design:type", Number)
22113
23099
  ], Event.prototype, "sortOrder", void 0);
22114
- _ts_decorate60([
23100
+ _ts_decorate61([
22115
23101
  Column({
22116
23102
  type: "timestamp",
22117
23103
  default: /* @__PURE__ */ __name(() => "CURRENT_TIMESTAMP", "default")
22118
23104
  }),
22119
- _ts_metadata60("design:type", typeof Date === "undefined" ? Object : Date)
23105
+ _ts_metadata61("design:type", typeof Date === "undefined" ? Object : Date)
22120
23106
  ], Event.prototype, "createdAt", void 0);
22121
- _ts_decorate60([
23107
+ _ts_decorate61([
22122
23108
  Column({
22123
23109
  type: "timestamp",
22124
23110
  default: /* @__PURE__ */ __name(() => "CURRENT_TIMESTAMP", "default")
22125
23111
  }),
22126
- _ts_metadata60("design:type", typeof Date === "undefined" ? Object : Date)
23112
+ _ts_metadata61("design:type", typeof Date === "undefined" ? Object : Date)
22127
23113
  ], Event.prototype, "updatedAt", void 0);
22128
- _ts_decorate60([
23114
+ _ts_decorate61([
22129
23115
  Column({
22130
23116
  type: "timestamp",
22131
23117
  nullable: true
22132
23118
  }),
22133
- _ts_metadata60("design:type", Object)
23119
+ _ts_metadata61("design:type", Object)
22134
23120
  ], Event.prototype, "deletedAt", void 0);
22135
- _ts_decorate60([
23121
+ _ts_decorate61([
22136
23122
  Column("boolean", {
22137
23123
  default: false
22138
23124
  }),
22139
- _ts_metadata60("design:type", Boolean)
23125
+ _ts_metadata61("design:type", Boolean)
22140
23126
  ], Event.prototype, "deleted", void 0);
22141
- _ts_decorate60([
23127
+ _ts_decorate61([
22142
23128
  Column("int", {
22143
23129
  nullable: true
22144
23130
  }),
22145
- _ts_metadata60("design:type", Object)
23131
+ _ts_metadata61("design:type", Object)
22146
23132
  ], Event.prototype, "createdBy", void 0);
22147
- _ts_decorate60([
23133
+ _ts_decorate61([
22148
23134
  Column("int", {
22149
23135
  nullable: true
22150
23136
  }),
22151
- _ts_metadata60("design:type", Object)
23137
+ _ts_metadata61("design:type", Object)
22152
23138
  ], Event.prototype, "updatedBy", void 0);
22153
- _ts_decorate60([
23139
+ _ts_decorate61([
22154
23140
  Column("int", {
22155
23141
  nullable: true
22156
23142
  }),
22157
- _ts_metadata60("design:type", Object)
23143
+ _ts_metadata61("design:type", Object)
22158
23144
  ], Event.prototype, "deletedBy", void 0);
22159
- _ts_decorate60([
23145
+ _ts_decorate61([
22160
23146
  ManyToOne(() => Vendor, {
22161
23147
  onDelete: "RESTRICT",
22162
23148
  nullable: true
@@ -22164,9 +23150,9 @@ _ts_decorate60([
22164
23150
  JoinColumn({
22165
23151
  name: "vendorId"
22166
23152
  }),
22167
- _ts_metadata60("design:type", Object)
23153
+ _ts_metadata61("design:type", Object)
22168
23154
  ], Event.prototype, "vendor", void 0);
22169
- _ts_decorate60([
23155
+ _ts_decorate61([
22170
23156
  ManyToOne(() => Form, {
22171
23157
  onDelete: "SET NULL",
22172
23158
  nullable: true
@@ -22174,9 +23160,9 @@ _ts_decorate60([
22174
23160
  JoinColumn({
22175
23161
  name: "contactFormId"
22176
23162
  }),
22177
- _ts_metadata60("design:type", Object)
23163
+ _ts_metadata61("design:type", Object)
22178
23164
  ], Event.prototype, "contactForm", void 0);
22179
- _ts_decorate60([
23165
+ _ts_decorate61([
22180
23166
  ManyToOne(() => Tax, {
22181
23167
  onDelete: "SET NULL",
22182
23168
  nullable: true
@@ -22184,9 +23170,9 @@ _ts_decorate60([
22184
23170
  JoinColumn({
22185
23171
  name: "taxId"
22186
23172
  }),
22187
- _ts_metadata60("design:type", Object)
23173
+ _ts_metadata61("design:type", Object)
22188
23174
  ], Event.prototype, "tax", void 0);
22189
- _ts_decorate60([
23175
+ _ts_decorate61([
22190
23176
  ManyToOne(() => RefundPolicy, {
22191
23177
  onDelete: "SET NULL",
22192
23178
  nullable: true
@@ -22194,30 +23180,30 @@ _ts_decorate60([
22194
23180
  JoinColumn({
22195
23181
  name: "refundPolicyId"
22196
23182
  }),
22197
- _ts_metadata60("design:type", Object)
23183
+ _ts_metadata61("design:type", Object)
22198
23184
  ], Event.prototype, "refundPolicy", void 0);
22199
- _ts_decorate60([
23185
+ _ts_decorate61([
22200
23186
  OneToMany("EventProduct", "event"),
22201
- _ts_metadata60("design:type", Array)
23187
+ _ts_metadata61("design:type", Array)
22202
23188
  ], Event.prototype, "eventProducts", void 0);
22203
- Event = _ts_decorate60([
23189
+ Event = _ts_decorate61([
22204
23190
  Entity("events"),
22205
23191
  Unique("UQ_events_vendor_slug", [
22206
23192
  "vendorId",
22207
23193
  "slug"
22208
23194
  ])
22209
23195
  ], Event);
22210
- function _ts_decorate61(decorators, target, key, desc) {
23196
+ function _ts_decorate62(decorators, target, key, desc) {
22211
23197
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
22212
23198
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
22213
23199
  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;
22214
23200
  return c > 3 && r && Object.defineProperty(target, key, r), r;
22215
23201
  }
22216
- __name(_ts_decorate61, "_ts_decorate");
22217
- function _ts_metadata61(k, v) {
23202
+ __name(_ts_decorate62, "_ts_decorate");
23203
+ function _ts_metadata62(k, v) {
22218
23204
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22219
23205
  }
22220
- __name(_ts_metadata61, "_ts_metadata");
23206
+ __name(_ts_metadata62, "_ts_metadata");
22221
23207
  var EventProduct = class {
22222
23208
  static {
22223
23209
  __name(this, "EventProduct");
@@ -22232,63 +23218,63 @@ var EventProduct = class {
22232
23218
  event;
22233
23219
  product;
22234
23220
  };
22235
- _ts_decorate61([
23221
+ _ts_decorate62([
22236
23222
  PrimaryGeneratedColumn(),
22237
- _ts_metadata61("design:type", Number)
23223
+ _ts_metadata62("design:type", Number)
22238
23224
  ], EventProduct.prototype, "id", void 0);
22239
- _ts_decorate61([
23225
+ _ts_decorate62([
22240
23226
  Column("int"),
22241
- _ts_metadata61("design:type", Number)
23227
+ _ts_metadata62("design:type", Number)
22242
23228
  ], EventProduct.prototype, "eventId", void 0);
22243
- _ts_decorate61([
23229
+ _ts_decorate62([
22244
23230
  Column("int"),
22245
- _ts_metadata61("design:type", Number)
23231
+ _ts_metadata62("design:type", Number)
22246
23232
  ], EventProduct.prototype, "productId", void 0);
22247
- _ts_decorate61([
23233
+ _ts_decorate62([
22248
23234
  Column("int", {
22249
23235
  default: 0
22250
23236
  }),
22251
- _ts_metadata61("design:type", Number)
23237
+ _ts_metadata62("design:type", Number)
22252
23238
  ], EventProduct.prototype, "displayOrder", void 0);
22253
- _ts_decorate61([
23239
+ _ts_decorate62([
22254
23240
  Column("boolean", {
22255
23241
  default: true
22256
23242
  }),
22257
- _ts_metadata61("design:type", Boolean)
23243
+ _ts_metadata62("design:type", Boolean)
22258
23244
  ], EventProduct.prototype, "isActive", void 0);
22259
- _ts_decorate61([
23245
+ _ts_decorate62([
22260
23246
  Column({
22261
23247
  type: "timestamp",
22262
23248
  default: /* @__PURE__ */ __name(() => "CURRENT_TIMESTAMP", "default")
22263
23249
  }),
22264
- _ts_metadata61("design:type", typeof Date === "undefined" ? Object : Date)
23250
+ _ts_metadata62("design:type", typeof Date === "undefined" ? Object : Date)
22265
23251
  ], EventProduct.prototype, "createdAt", void 0);
22266
- _ts_decorate61([
23252
+ _ts_decorate62([
22267
23253
  Column({
22268
23254
  type: "timestamp",
22269
23255
  default: /* @__PURE__ */ __name(() => "CURRENT_TIMESTAMP", "default")
22270
23256
  }),
22271
- _ts_metadata61("design:type", typeof Date === "undefined" ? Object : Date)
23257
+ _ts_metadata62("design:type", typeof Date === "undefined" ? Object : Date)
22272
23258
  ], EventProduct.prototype, "updatedAt", void 0);
22273
- _ts_decorate61([
23259
+ _ts_decorate62([
22274
23260
  ManyToOne(() => Event, (event) => event.eventProducts, {
22275
23261
  onDelete: "CASCADE"
22276
23262
  }),
22277
23263
  JoinColumn({
22278
23264
  name: "eventId"
22279
23265
  }),
22280
- _ts_metadata61("design:type", typeof Event === "undefined" ? Object : Event)
23266
+ _ts_metadata62("design:type", typeof Event === "undefined" ? Object : Event)
22281
23267
  ], EventProduct.prototype, "event", void 0);
22282
- _ts_decorate61([
23268
+ _ts_decorate62([
22283
23269
  ManyToOne(() => Product, {
22284
23270
  onDelete: "CASCADE"
22285
23271
  }),
22286
23272
  JoinColumn({
22287
23273
  name: "productId"
22288
23274
  }),
22289
- _ts_metadata61("design:type", typeof Product === "undefined" ? Object : Product)
23275
+ _ts_metadata62("design:type", typeof Product === "undefined" ? Object : Product)
22290
23276
  ], EventProduct.prototype, "product", void 0);
22291
- EventProduct = _ts_decorate61([
23277
+ EventProduct = _ts_decorate62([
22292
23278
  Entity("event_products"),
22293
23279
  Unique("UQ_event_products_event_product", [
22294
23280
  "eventId",
@@ -22298,17 +23284,17 @@ EventProduct = _ts_decorate61([
22298
23284
  "eventId"
22299
23285
  ])
22300
23286
  ], EventProduct);
22301
- function _ts_decorate62(decorators, target, key, desc) {
23287
+ function _ts_decorate63(decorators, target, key, desc) {
22302
23288
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
22303
23289
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
22304
23290
  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;
22305
23291
  return c > 3 && r && Object.defineProperty(target, key, r), r;
22306
23292
  }
22307
- __name(_ts_decorate62, "_ts_decorate");
22308
- function _ts_metadata62(k, v) {
23293
+ __name(_ts_decorate63, "_ts_decorate");
23294
+ function _ts_metadata63(k, v) {
22309
23295
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22310
23296
  }
22311
- __name(_ts_metadata62, "_ts_metadata");
23297
+ __name(_ts_metadata63, "_ts_metadata");
22312
23298
  var ComboItemType = /* @__PURE__ */ (function(ComboItemType2) {
22313
23299
  ComboItemType2["FIXED"] = "fixed";
22314
23300
  ComboItemType2["ADDONS"] = "addons";
@@ -22325,64 +23311,64 @@ var ComboItem = class {
22325
23311
  product;
22326
23312
  type;
22327
23313
  };
22328
- _ts_decorate62([
23314
+ _ts_decorate63([
22329
23315
  PrimaryGeneratedColumn(),
22330
- _ts_metadata62("design:type", Number)
23316
+ _ts_metadata63("design:type", Number)
22331
23317
  ], ComboItem.prototype, "id", void 0);
22332
- _ts_decorate62([
23318
+ _ts_decorate63([
22333
23319
  Column({
22334
23320
  type: "integer"
22335
23321
  }),
22336
- _ts_metadata62("design:type", Number)
23322
+ _ts_metadata63("design:type", Number)
22337
23323
  ], ComboItem.prototype, "comboId", void 0);
22338
- _ts_decorate62([
23324
+ _ts_decorate63([
22339
23325
  ManyToOne(() => Combo, (combo) => combo.items, {
22340
23326
  onDelete: "CASCADE"
22341
23327
  }),
22342
23328
  JoinColumn({
22343
23329
  name: "comboId"
22344
23330
  }),
22345
- _ts_metadata62("design:type", typeof Combo === "undefined" ? Object : Combo)
23331
+ _ts_metadata63("design:type", typeof Combo === "undefined" ? Object : Combo)
22346
23332
  ], ComboItem.prototype, "combo", void 0);
22347
- _ts_decorate62([
23333
+ _ts_decorate63([
22348
23334
  Column({
22349
23335
  type: "integer"
22350
23336
  }),
22351
- _ts_metadata62("design:type", Number)
23337
+ _ts_metadata63("design:type", Number)
22352
23338
  ], ComboItem.prototype, "productId", void 0);
22353
- _ts_decorate62([
23339
+ _ts_decorate63([
22354
23340
  ManyToOne(() => Product, {
22355
23341
  onDelete: "CASCADE"
22356
23342
  }),
22357
23343
  JoinColumn({
22358
23344
  name: "productId"
22359
23345
  }),
22360
- _ts_metadata62("design:type", typeof Product === "undefined" ? Object : Product)
23346
+ _ts_metadata63("design:type", typeof Product === "undefined" ? Object : Product)
22361
23347
  ], ComboItem.prototype, "product", void 0);
22362
- _ts_decorate62([
23348
+ _ts_decorate63([
22363
23349
  Column({
22364
23350
  type: "enum",
22365
23351
  enum: ComboItemType,
22366
23352
  default: "fixed"
22367
23353
  }),
22368
- _ts_metadata62("design:type", String)
23354
+ _ts_metadata63("design:type", String)
22369
23355
  ], ComboItem.prototype, "type", void 0);
22370
- ComboItem = _ts_decorate62([
23356
+ ComboItem = _ts_decorate63([
22371
23357
  Entity("combo_items")
22372
23358
  ], ComboItem);
22373
23359
 
22374
23360
  // src/entities/combo.entity.ts
22375
- function _ts_decorate63(decorators, target, key, desc) {
23361
+ function _ts_decorate64(decorators, target, key, desc) {
22376
23362
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
22377
23363
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
22378
23364
  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;
22379
23365
  return c > 3 && r && Object.defineProperty(target, key, r), r;
22380
23366
  }
22381
- __name(_ts_decorate63, "_ts_decorate");
22382
- function _ts_metadata63(k, v) {
23367
+ __name(_ts_decorate64, "_ts_decorate");
23368
+ function _ts_metadata64(k, v) {
22383
23369
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22384
23370
  }
22385
- __name(_ts_metadata63, "_ts_metadata");
23371
+ __name(_ts_metadata64, "_ts_metadata");
22386
23372
  var ComboStatus = /* @__PURE__ */ (function(ComboStatus2) {
22387
23373
  ComboStatus2["ACTIVE"] = "active";
22388
23374
  ComboStatus2["INACTIVE"] = "inactive";
@@ -22397,6 +23383,7 @@ var Combo = class {
22397
23383
  vendorId;
22398
23384
  vendor;
22399
23385
  name;
23386
+ slug;
22400
23387
  desc;
22401
23388
  eventId;
22402
23389
  event;
@@ -22417,44 +23404,50 @@ var Combo = class {
22417
23404
  updatedBy;
22418
23405
  deletedBy;
22419
23406
  };
22420
- _ts_decorate63([
23407
+ _ts_decorate64([
22421
23408
  PrimaryGeneratedColumn(),
22422
- _ts_metadata63("design:type", Number)
23409
+ _ts_metadata64("design:type", Number)
22423
23410
  ], Combo.prototype, "id", void 0);
22424
- _ts_decorate63([
23411
+ _ts_decorate64([
22425
23412
  Column("int"),
22426
- _ts_metadata63("design:type", Number)
23413
+ _ts_metadata64("design:type", Number)
22427
23414
  ], Combo.prototype, "vendorId", void 0);
22428
- _ts_decorate63([
23415
+ _ts_decorate64([
22429
23416
  ManyToOne(() => Vendor, {
22430
23417
  onDelete: "RESTRICT"
22431
23418
  }),
22432
23419
  JoinColumn({
22433
23420
  name: "vendorId"
22434
23421
  }),
22435
- _ts_metadata63("design:type", typeof Vendor === "undefined" ? Object : Vendor)
23422
+ _ts_metadata64("design:type", typeof Vendor === "undefined" ? Object : Vendor)
22436
23423
  ], Combo.prototype, "vendor", void 0);
22437
- _ts_decorate63([
23424
+ _ts_decorate64([
22438
23425
  Column({
22439
23426
  type: "varchar"
22440
23427
  }),
22441
- _ts_metadata63("design:type", String)
23428
+ _ts_metadata64("design:type", String)
22442
23429
  ], Combo.prototype, "name", void 0);
22443
- _ts_decorate63([
23430
+ _ts_decorate64([
23431
+ Column({
23432
+ type: "varchar"
23433
+ }),
23434
+ _ts_metadata64("design:type", String)
23435
+ ], Combo.prototype, "slug", void 0);
23436
+ _ts_decorate64([
22444
23437
  Column({
22445
23438
  type: "text",
22446
23439
  nullable: true
22447
23440
  }),
22448
- _ts_metadata63("design:type", String)
23441
+ _ts_metadata64("design:type", String)
22449
23442
  ], Combo.prototype, "desc", void 0);
22450
- _ts_decorate63([
23443
+ _ts_decorate64([
22451
23444
  Column({
22452
23445
  type: "integer",
22453
23446
  nullable: true
22454
23447
  }),
22455
- _ts_metadata63("design:type", Object)
23448
+ _ts_metadata64("design:type", Object)
22456
23449
  ], Combo.prototype, "eventId", void 0);
22457
- _ts_decorate63([
23450
+ _ts_decorate64([
22458
23451
  ManyToOne(() => Event, {
22459
23452
  onDelete: "CASCADE",
22460
23453
  nullable: true
@@ -22462,134 +23455,138 @@ _ts_decorate63([
22462
23455
  JoinColumn({
22463
23456
  name: "eventId"
22464
23457
  }),
22465
- _ts_metadata63("design:type", Object)
23458
+ _ts_metadata64("design:type", Object)
22466
23459
  ], Combo.prototype, "event", void 0);
22467
- _ts_decorate63([
23460
+ _ts_decorate64([
22468
23461
  Column({
22469
23462
  type: "decimal",
22470
23463
  precision: 12,
22471
23464
  scale: 2,
22472
23465
  default: 0
22473
23466
  }),
22474
- _ts_metadata63("design:type", Number)
23467
+ _ts_metadata64("design:type", Number)
22475
23468
  ], Combo.prototype, "price", void 0);
22476
- _ts_decorate63([
23469
+ _ts_decorate64([
22477
23470
  Column({
22478
23471
  type: "jsonb",
22479
23472
  nullable: true
22480
23473
  }),
22481
- _ts_metadata63("design:type", Object)
23474
+ _ts_metadata64("design:type", Object)
22482
23475
  ], Combo.prototype, "currencyPrices", void 0);
22483
- _ts_decorate63([
23476
+ _ts_decorate64([
22484
23477
  Column({
22485
23478
  type: "integer",
22486
23479
  default: 1
22487
23480
  }),
22488
- _ts_metadata63("design:type", Number)
23481
+ _ts_metadata64("design:type", Number)
22489
23482
  ], Combo.prototype, "minSelectableItems", void 0);
22490
- _ts_decorate63([
23483
+ _ts_decorate64([
22491
23484
  Column({
22492
23485
  type: "integer",
22493
23486
  default: 1
22494
23487
  }),
22495
- _ts_metadata63("design:type", Number)
23488
+ _ts_metadata64("design:type", Number)
22496
23489
  ], Combo.prototype, "maxSelectableItems", void 0);
22497
- _ts_decorate63([
23490
+ _ts_decorate64([
22498
23491
  Column({
22499
23492
  type: "enum",
22500
23493
  enum: ComboStatus,
22501
23494
  default: "active"
22502
23495
  }),
22503
- _ts_metadata63("design:type", String)
23496
+ _ts_metadata64("design:type", String)
22504
23497
  ], Combo.prototype, "status", void 0);
22505
- _ts_decorate63([
23498
+ _ts_decorate64([
22506
23499
  Column({
22507
23500
  type: "timestamp",
22508
23501
  nullable: true
22509
23502
  }),
22510
- _ts_metadata63("design:type", typeof Date === "undefined" ? Object : Date)
23503
+ _ts_metadata64("design:type", typeof Date === "undefined" ? Object : Date)
22511
23504
  ], Combo.prototype, "startsAt", void 0);
22512
- _ts_decorate63([
23505
+ _ts_decorate64([
22513
23506
  Column({
22514
23507
  type: "timestamp",
22515
23508
  nullable: true
22516
23509
  }),
22517
- _ts_metadata63("design:type", typeof Date === "undefined" ? Object : Date)
23510
+ _ts_metadata64("design:type", typeof Date === "undefined" ? Object : Date)
22518
23511
  ], Combo.prototype, "endsAt", void 0);
22519
- _ts_decorate63([
23512
+ _ts_decorate64([
22520
23513
  Column({
22521
23514
  type: "jsonb",
22522
23515
  nullable: true
22523
23516
  }),
22524
- _ts_metadata63("design:type", typeof Record === "undefined" ? Object : Record)
23517
+ _ts_metadata64("design:type", typeof Record === "undefined" ? Object : Record)
22525
23518
  ], Combo.prototype, "metadata", void 0);
22526
- _ts_decorate63([
23519
+ _ts_decorate64([
22527
23520
  OneToMany(() => ComboItem, (item) => item.combo),
22528
- _ts_metadata63("design:type", Array)
23521
+ _ts_metadata64("design:type", Array)
22529
23522
  ], Combo.prototype, "items", void 0);
22530
- _ts_decorate63([
23523
+ _ts_decorate64([
22531
23524
  Column({
22532
23525
  type: "timestamp",
22533
23526
  default: /* @__PURE__ */ __name(() => "now()", "default")
22534
23527
  }),
22535
- _ts_metadata63("design:type", typeof Date === "undefined" ? Object : Date)
23528
+ _ts_metadata64("design:type", typeof Date === "undefined" ? Object : Date)
22536
23529
  ], Combo.prototype, "createdAt", void 0);
22537
- _ts_decorate63([
23530
+ _ts_decorate64([
22538
23531
  Column({
22539
23532
  type: "timestamp",
22540
23533
  default: /* @__PURE__ */ __name(() => "now()", "default")
22541
23534
  }),
22542
- _ts_metadata63("design:type", typeof Date === "undefined" ? Object : Date)
23535
+ _ts_metadata64("design:type", typeof Date === "undefined" ? Object : Date)
22543
23536
  ], Combo.prototype, "updatedAt", void 0);
22544
- _ts_decorate63([
23537
+ _ts_decorate64([
22545
23538
  Column({
22546
23539
  type: "timestamp",
22547
23540
  nullable: true
22548
23541
  }),
22549
- _ts_metadata63("design:type", typeof Date === "undefined" ? Object : Date)
23542
+ _ts_metadata64("design:type", typeof Date === "undefined" ? Object : Date)
22550
23543
  ], Combo.prototype, "deletedAt", void 0);
22551
- _ts_decorate63([
23544
+ _ts_decorate64([
22552
23545
  Column({
22553
23546
  type: "boolean",
22554
23547
  default: false
22555
23548
  }),
22556
- _ts_metadata63("design:type", Boolean)
23549
+ _ts_metadata64("design:type", Boolean)
22557
23550
  ], Combo.prototype, "deleted", void 0);
22558
- _ts_decorate63([
23551
+ _ts_decorate64([
22559
23552
  Column({
22560
23553
  type: "integer",
22561
23554
  nullable: true
22562
23555
  }),
22563
- _ts_metadata63("design:type", Number)
23556
+ _ts_metadata64("design:type", Number)
22564
23557
  ], Combo.prototype, "createdBy", void 0);
22565
- _ts_decorate63([
23558
+ _ts_decorate64([
22566
23559
  Column({
22567
23560
  type: "integer",
22568
23561
  nullable: true
22569
23562
  }),
22570
- _ts_metadata63("design:type", Number)
23563
+ _ts_metadata64("design:type", Number)
22571
23564
  ], Combo.prototype, "updatedBy", void 0);
22572
- _ts_decorate63([
23565
+ _ts_decorate64([
22573
23566
  Column({
22574
23567
  type: "integer",
22575
23568
  nullable: true
22576
23569
  }),
22577
- _ts_metadata63("design:type", Number)
23570
+ _ts_metadata64("design:type", Number)
22578
23571
  ], Combo.prototype, "deletedBy", void 0);
22579
- Combo = _ts_decorate63([
22580
- Entity("combos")
23572
+ Combo = _ts_decorate64([
23573
+ Entity("combos"),
23574
+ Unique("UQ_combos_vendor_slug", [
23575
+ "vendorId",
23576
+ "slug"
23577
+ ])
22581
23578
  ], Combo);
22582
- function _ts_decorate64(decorators, target, key, desc) {
23579
+ function _ts_decorate65(decorators, target, key, desc) {
22583
23580
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
22584
23581
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
22585
23582
  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;
22586
23583
  return c > 3 && r && Object.defineProperty(target, key, r), r;
22587
23584
  }
22588
- __name(_ts_decorate64, "_ts_decorate");
22589
- function _ts_metadata64(k, v) {
23585
+ __name(_ts_decorate65, "_ts_decorate");
23586
+ function _ts_metadata65(k, v) {
22590
23587
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22591
23588
  }
22592
- __name(_ts_metadata64, "_ts_metadata");
23589
+ __name(_ts_metadata65, "_ts_metadata");
22593
23590
  var RefundMethod = /* @__PURE__ */ (function(RefundMethod2) {
22594
23591
  RefundMethod2["CARD"] = "card";
22595
23592
  RefundMethod2["UPI"] = "upi";
@@ -22620,109 +23617,109 @@ var RefundRequest = class {
22620
23617
  expectedRefundAmount;
22621
23618
  approvedRefundAmount;
22622
23619
  };
22623
- _ts_decorate64([
23620
+ _ts_decorate65([
22624
23621
  PrimaryGeneratedColumn(),
22625
- _ts_metadata64("design:type", Number)
23622
+ _ts_metadata65("design:type", Number)
22626
23623
  ], RefundRequest.prototype, "id", void 0);
22627
- _ts_decorate64([
23624
+ _ts_decorate65([
22628
23625
  Column({
22629
23626
  type: "integer"
22630
23627
  }),
22631
- _ts_metadata64("design:type", Number)
23628
+ _ts_metadata65("design:type", Number)
22632
23629
  ], RefundRequest.prototype, "refundPolicyId", void 0);
22633
- _ts_decorate64([
23630
+ _ts_decorate65([
22634
23631
  ManyToOne(() => RefundPolicy, {
22635
23632
  onDelete: "CASCADE"
22636
23633
  }),
22637
23634
  JoinColumn({
22638
23635
  name: "refundPolicyId"
22639
23636
  }),
22640
- _ts_metadata64("design:type", typeof RefundPolicy === "undefined" ? Object : RefundPolicy)
23637
+ _ts_metadata65("design:type", typeof RefundPolicy === "undefined" ? Object : RefundPolicy)
22641
23638
  ], RefundRequest.prototype, "refundPolicy", void 0);
22642
- _ts_decorate64([
23639
+ _ts_decorate65([
22643
23640
  Column({
22644
23641
  type: "integer"
22645
23642
  }),
22646
- _ts_metadata64("design:type", Number)
23643
+ _ts_metadata65("design:type", Number)
22647
23644
  ], RefundRequest.prototype, "orderId", void 0);
22648
- _ts_decorate64([
23645
+ _ts_decorate65([
22649
23646
  ManyToOne(() => Order, {
22650
23647
  onDelete: "CASCADE"
22651
23648
  }),
22652
23649
  JoinColumn({
22653
23650
  name: "orderId"
22654
23651
  }),
22655
- _ts_metadata64("design:type", typeof Order === "undefined" ? Object : Order)
23652
+ _ts_metadata65("design:type", typeof Order === "undefined" ? Object : Order)
22656
23653
  ], RefundRequest.prototype, "order", void 0);
22657
- _ts_decorate64([
23654
+ _ts_decorate65([
22658
23655
  Column({
22659
23656
  type: "integer"
22660
23657
  }),
22661
- _ts_metadata64("design:type", Number)
23658
+ _ts_metadata65("design:type", Number)
22662
23659
  ], RefundRequest.prototype, "customerId", void 0);
22663
- _ts_decorate64([
23660
+ _ts_decorate65([
22664
23661
  ManyToOne(() => Customer, {
22665
23662
  onDelete: "CASCADE"
22666
23663
  }),
22667
23664
  JoinColumn({
22668
23665
  name: "customerId"
22669
23666
  }),
22670
- _ts_metadata64("design:type", typeof Customer === "undefined" ? Object : Customer)
23667
+ _ts_metadata65("design:type", typeof Customer === "undefined" ? Object : Customer)
22671
23668
  ], RefundRequest.prototype, "customer", void 0);
22672
- _ts_decorate64([
23669
+ _ts_decorate65([
22673
23670
  Column({
22674
23671
  type: "text",
22675
23672
  nullable: true
22676
23673
  }),
22677
- _ts_metadata64("design:type", String)
23674
+ _ts_metadata65("design:type", String)
22678
23675
  ], RefundRequest.prototype, "reason", void 0);
22679
- _ts_decorate64([
23676
+ _ts_decorate65([
22680
23677
  Column({
22681
23678
  type: "enum",
22682
23679
  enum: RefundMethod
22683
23680
  }),
22684
- _ts_metadata64("design:type", String)
23681
+ _ts_metadata65("design:type", String)
22685
23682
  ], RefundRequest.prototype, "refundMethod", void 0);
22686
- _ts_decorate64([
23683
+ _ts_decorate65([
22687
23684
  Column({
22688
23685
  type: "enum",
22689
23686
  enum: RefundRequestStatus,
22690
23687
  default: "requested"
22691
23688
  }),
22692
- _ts_metadata64("design:type", String)
23689
+ _ts_metadata65("design:type", String)
22693
23690
  ], RefundRequest.prototype, "status", void 0);
22694
- _ts_decorate64([
23691
+ _ts_decorate65([
22695
23692
  Column({
22696
23693
  type: "decimal",
22697
23694
  precision: 10,
22698
23695
  scale: 2,
22699
23696
  default: 0
22700
23697
  }),
22701
- _ts_metadata64("design:type", Number)
23698
+ _ts_metadata65("design:type", Number)
22702
23699
  ], RefundRequest.prototype, "expectedRefundAmount", void 0);
22703
- _ts_decorate64([
23700
+ _ts_decorate65([
22704
23701
  Column({
22705
23702
  type: "decimal",
22706
23703
  precision: 10,
22707
23704
  scale: 2,
22708
23705
  nullable: true
22709
23706
  }),
22710
- _ts_metadata64("design:type", Number)
23707
+ _ts_metadata65("design:type", Number)
22711
23708
  ], RefundRequest.prototype, "approvedRefundAmount", void 0);
22712
- RefundRequest = _ts_decorate64([
23709
+ RefundRequest = _ts_decorate65([
22713
23710
  Entity("refund_requests")
22714
23711
  ], RefundRequest);
22715
- function _ts_decorate65(decorators, target, key, desc) {
23712
+ function _ts_decorate66(decorators, target, key, desc) {
22716
23713
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
22717
23714
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
22718
23715
  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;
22719
23716
  return c > 3 && r && Object.defineProperty(target, key, r), r;
22720
23717
  }
22721
- __name(_ts_decorate65, "_ts_decorate");
22722
- function _ts_metadata65(k, v) {
23718
+ __name(_ts_decorate66, "_ts_decorate");
23719
+ function _ts_metadata66(k, v) {
22723
23720
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22724
23721
  }
22725
- __name(_ts_metadata65, "_ts_metadata");
23722
+ __name(_ts_metadata66, "_ts_metadata");
22726
23723
  var Attendee = class {
22727
23724
  static {
22728
23725
  __name(this, "Attendee");
@@ -22733,34 +23730,34 @@ var Attendee = class {
22733
23730
  contactId;
22734
23731
  contact;
22735
23732
  };
22736
- _ts_decorate65([
23733
+ _ts_decorate66([
22737
23734
  PrimaryGeneratedColumn(),
22738
- _ts_metadata65("design:type", Number)
23735
+ _ts_metadata66("design:type", Number)
22739
23736
  ], Attendee.prototype, "id", void 0);
22740
- _ts_decorate65([
23737
+ _ts_decorate66([
22741
23738
  Column("varchar"),
22742
- _ts_metadata65("design:type", String)
23739
+ _ts_metadata66("design:type", String)
22743
23740
  ], Attendee.prototype, "displayName", void 0);
22744
- _ts_decorate65([
23741
+ _ts_decorate66([
22745
23742
  Column("varchar"),
22746
- _ts_metadata65("design:type", String)
23743
+ _ts_metadata66("design:type", String)
22747
23744
  ], Attendee.prototype, "email", void 0);
22748
- _ts_decorate65([
23745
+ _ts_decorate66([
22749
23746
  Column("int", {
22750
23747
  nullable: true
22751
23748
  }),
22752
- _ts_metadata65("design:type", Object)
23749
+ _ts_metadata66("design:type", Object)
22753
23750
  ], Attendee.prototype, "contactId", void 0);
22754
- _ts_decorate65([
23751
+ _ts_decorate66([
22755
23752
  ManyToOne(() => Contact, {
22756
23753
  onDelete: "SET NULL"
22757
23754
  }),
22758
23755
  JoinColumn({
22759
23756
  name: "contactId"
22760
23757
  }),
22761
- _ts_metadata65("design:type", Object)
23758
+ _ts_metadata66("design:type", Object)
22762
23759
  ], Attendee.prototype, "contact", void 0);
22763
- Attendee = _ts_decorate65([
23760
+ Attendee = _ts_decorate66([
22764
23761
  Entity("attendees"),
22765
23762
  Index("IDX_attendees_contactId", [
22766
23763
  "contactId"
@@ -22769,22 +23766,28 @@ Attendee = _ts_decorate65([
22769
23766
  "email"
22770
23767
  ])
22771
23768
  ], Attendee);
22772
- function _ts_decorate66(decorators, target, key, desc) {
23769
+ function _ts_decorate67(decorators, target, key, desc) {
22773
23770
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
22774
23771
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
22775
23772
  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;
22776
23773
  return c > 3 && r && Object.defineProperty(target, key, r), r;
22777
23774
  }
22778
- __name(_ts_decorate66, "_ts_decorate");
22779
- function _ts_metadata66(k, v) {
23775
+ __name(_ts_decorate67, "_ts_decorate");
23776
+ function _ts_metadata67(k, v) {
22780
23777
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22781
23778
  }
22782
- __name(_ts_metadata66, "_ts_metadata");
23779
+ __name(_ts_metadata67, "_ts_metadata");
22783
23780
  var NotificationChannel = /* @__PURE__ */ (function(NotificationChannel2) {
22784
23781
  NotificationChannel2["WHATSAPP"] = "whatsapp";
22785
23782
  NotificationChannel2["EMAIL"] = "email";
22786
23783
  return NotificationChannel2;
22787
23784
  })({});
23785
+ var NotificationAudienceType = /* @__PURE__ */ (function(NotificationAudienceType2) {
23786
+ NotificationAudienceType2["CUSTOMERS"] = "customers";
23787
+ NotificationAudienceType2["VENDORS"] = "vendors";
23788
+ NotificationAudienceType2["ADMIN"] = "admin";
23789
+ return NotificationAudienceType2;
23790
+ })({});
22788
23791
  var OrderNotificationBinding = class {
22789
23792
  static {
22790
23793
  __name(this, "OrderNotificationBinding");
@@ -22792,71 +23795,81 @@ var OrderNotificationBinding = class {
22792
23795
  id;
22793
23796
  triggerKey;
22794
23797
  channel;
23798
+ type;
22795
23799
  messageTemplateId;
22796
23800
  enabled;
22797
23801
  createdAt;
22798
23802
  updatedAt;
22799
23803
  };
22800
- _ts_decorate66([
23804
+ _ts_decorate67([
22801
23805
  PrimaryGeneratedColumn(),
22802
- _ts_metadata66("design:type", Number)
23806
+ _ts_metadata67("design:type", Number)
22803
23807
  ], OrderNotificationBinding.prototype, "id", void 0);
22804
- _ts_decorate66([
23808
+ _ts_decorate67([
22805
23809
  Column({
22806
23810
  type: "varchar"
22807
23811
  }),
22808
- _ts_metadata66("design:type", String)
23812
+ _ts_metadata67("design:type", String)
22809
23813
  ], OrderNotificationBinding.prototype, "triggerKey", void 0);
22810
- _ts_decorate66([
23814
+ _ts_decorate67([
22811
23815
  Column({
22812
23816
  type: "enum",
22813
23817
  enum: NotificationChannel,
22814
23818
  default: "whatsapp"
22815
23819
  }),
22816
- _ts_metadata66("design:type", String)
23820
+ _ts_metadata67("design:type", String)
22817
23821
  ], OrderNotificationBinding.prototype, "channel", void 0);
22818
- _ts_decorate66([
23822
+ _ts_decorate67([
23823
+ Column({
23824
+ type: "enum",
23825
+ enum: NotificationAudienceType,
23826
+ default: "customers"
23827
+ }),
23828
+ _ts_metadata67("design:type", String)
23829
+ ], OrderNotificationBinding.prototype, "type", void 0);
23830
+ _ts_decorate67([
22819
23831
  Column({
22820
23832
  type: "int",
22821
23833
  nullable: true
22822
23834
  }),
22823
- _ts_metadata66("design:type", Object)
23835
+ _ts_metadata67("design:type", Object)
22824
23836
  ], OrderNotificationBinding.prototype, "messageTemplateId", void 0);
22825
- _ts_decorate66([
23837
+ _ts_decorate67([
22826
23838
  Column({
22827
23839
  type: "boolean",
22828
23840
  default: true
22829
23841
  }),
22830
- _ts_metadata66("design:type", Boolean)
23842
+ _ts_metadata67("design:type", Boolean)
22831
23843
  ], OrderNotificationBinding.prototype, "enabled", void 0);
22832
- _ts_decorate66([
23844
+ _ts_decorate67([
22833
23845
  CreateDateColumn(),
22834
- _ts_metadata66("design:type", typeof Date === "undefined" ? Object : Date)
23846
+ _ts_metadata67("design:type", typeof Date === "undefined" ? Object : Date)
22835
23847
  ], OrderNotificationBinding.prototype, "createdAt", void 0);
22836
- _ts_decorate66([
23848
+ _ts_decorate67([
22837
23849
  UpdateDateColumn(),
22838
- _ts_metadata66("design:type", typeof Date === "undefined" ? Object : Date)
23850
+ _ts_metadata67("design:type", typeof Date === "undefined" ? Object : Date)
22839
23851
  ], OrderNotificationBinding.prototype, "updatedAt", void 0);
22840
- OrderNotificationBinding = _ts_decorate66([
23852
+ OrderNotificationBinding = _ts_decorate67([
22841
23853
  Entity("order_notification_bindings"),
22842
23854
  Index([
22843
23855
  "triggerKey",
22844
- "channel"
23856
+ "channel",
23857
+ "type"
22845
23858
  ], {
22846
23859
  unique: true
22847
23860
  })
22848
23861
  ], OrderNotificationBinding);
22849
- function _ts_decorate67(decorators, target, key, desc) {
23862
+ function _ts_decorate68(decorators, target, key, desc) {
22850
23863
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
22851
23864
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
22852
23865
  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;
22853
23866
  return c > 3 && r && Object.defineProperty(target, key, r), r;
22854
23867
  }
22855
- __name(_ts_decorate67, "_ts_decorate");
22856
- function _ts_metadata67(k, v) {
23868
+ __name(_ts_decorate68, "_ts_decorate");
23869
+ function _ts_metadata68(k, v) {
22857
23870
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22858
23871
  }
22859
- __name(_ts_metadata67, "_ts_metadata");
23872
+ __name(_ts_metadata68, "_ts_metadata");
22860
23873
  var OrderNotificationTrigger = class {
22861
23874
  static {
22862
23875
  __name(this, "OrderNotificationTrigger");
@@ -22871,60 +23884,60 @@ var OrderNotificationTrigger = class {
22871
23884
  createdAt;
22872
23885
  updatedAt;
22873
23886
  };
22874
- _ts_decorate67([
23887
+ _ts_decorate68([
22875
23888
  PrimaryGeneratedColumn(),
22876
- _ts_metadata67("design:type", Number)
23889
+ _ts_metadata68("design:type", Number)
22877
23890
  ], OrderNotificationTrigger.prototype, "id", void 0);
22878
- _ts_decorate67([
23891
+ _ts_decorate68([
22879
23892
  Column({
22880
23893
  type: "varchar",
22881
23894
  unique: true
22882
23895
  }),
22883
- _ts_metadata67("design:type", String)
23896
+ _ts_metadata68("design:type", String)
22884
23897
  ], OrderNotificationTrigger.prototype, "triggerKey", void 0);
22885
- _ts_decorate67([
23898
+ _ts_decorate68([
22886
23899
  Column({
22887
23900
  type: "varchar"
22888
23901
  }),
22889
- _ts_metadata67("design:type", String)
23902
+ _ts_metadata68("design:type", String)
22890
23903
  ], OrderNotificationTrigger.prototype, "label", void 0);
22891
- _ts_decorate67([
23904
+ _ts_decorate68([
22892
23905
  Column({
22893
23906
  type: "text",
22894
23907
  nullable: true
22895
23908
  }),
22896
- _ts_metadata67("design:type", Object)
23909
+ _ts_metadata68("design:type", Object)
22897
23910
  ], OrderNotificationTrigger.prototype, "description", void 0);
22898
- _ts_decorate67([
23911
+ _ts_decorate68([
22899
23912
  Column({
22900
23913
  type: "varchar",
22901
23914
  default: "order"
22902
23915
  }),
22903
- _ts_metadata67("design:type", String)
23916
+ _ts_metadata68("design:type", String)
22904
23917
  ], OrderNotificationTrigger.prototype, "category", void 0);
22905
- _ts_decorate67([
23918
+ _ts_decorate68([
22906
23919
  Column({
22907
23920
  type: "boolean",
22908
23921
  default: true
22909
23922
  }),
22910
- _ts_metadata67("design:type", Boolean)
23923
+ _ts_metadata68("design:type", Boolean)
22911
23924
  ], OrderNotificationTrigger.prototype, "enabled", void 0);
22912
- _ts_decorate67([
23925
+ _ts_decorate68([
22913
23926
  Column({
22914
23927
  type: "int",
22915
23928
  default: 0
22916
23929
  }),
22917
- _ts_metadata67("design:type", Number)
23930
+ _ts_metadata68("design:type", Number)
22918
23931
  ], OrderNotificationTrigger.prototype, "sortOrder", void 0);
22919
- _ts_decorate67([
23932
+ _ts_decorate68([
22920
23933
  CreateDateColumn(),
22921
- _ts_metadata67("design:type", typeof Date === "undefined" ? Object : Date)
23934
+ _ts_metadata68("design:type", typeof Date === "undefined" ? Object : Date)
22922
23935
  ], OrderNotificationTrigger.prototype, "createdAt", void 0);
22923
- _ts_decorate67([
23936
+ _ts_decorate68([
22924
23937
  UpdateDateColumn(),
22925
- _ts_metadata67("design:type", typeof Date === "undefined" ? Object : Date)
23938
+ _ts_metadata68("design:type", typeof Date === "undefined" ? Object : Date)
22926
23939
  ], OrderNotificationTrigger.prototype, "updatedAt", void 0);
22927
- OrderNotificationTrigger = _ts_decorate67([
23940
+ OrderNotificationTrigger = _ts_decorate68([
22928
23941
  Entity("order_notification_triggers")
22929
23942
  ], OrderNotificationTrigger);
22930
23943
 
@@ -22983,6 +23996,7 @@ var CMS_ENTITY_MAP = {
22983
23996
  job_schedule_runs: JobScheduleRun,
22984
23997
  vendors: Vendor,
22985
23998
  vendor_users: VendorUser,
23999
+ vendor_user_profiles: VendorUserProfile,
22986
24000
  vendor_roles: VendorRole,
22987
24001
  vendor_role_permissions: VendorRolePermission,
22988
24002
  vendor_customers: VendorCustomer,
@@ -26503,8 +27517,11 @@ function createMessageTemplateRowLoader(dataSource, entityMap) {
26503
27517
  };
26504
27518
  }
26505
27519
  __name(createMessageTemplateRowLoader, "createMessageTemplateRowLoader");
26506
- function registerMessagingQueueProcessors(cms) {
26507
- registerEmailQueueProcessor(cms);
27520
+ function registerMessagingQueueProcessors(cms, entityMap) {
27521
+ registerEmailQueueProcessor(cms, {
27522
+ getDataSource: /* @__PURE__ */ __name(async () => cms.dataSource, "getDataSource"),
27523
+ entityMap
27524
+ });
26508
27525
  registerWhatsAppQueueProcessor(cms);
26509
27526
  }
26510
27527
  __name(registerMessagingQueueProcessors, "registerMessagingQueueProcessors");
@@ -26556,7 +27573,7 @@ async function ensureMessagingPluginsOnCms(base, options) {
26556
27573
  }
26557
27574
  }
26558
27575
  const merged = Object.keys(overlay).length > 0 ? overlayCmsPlugins(cms, overlay) : cms;
26559
- registerMessagingQueueProcessors(merged);
27576
+ registerMessagingQueueProcessors(merged, entityMap);
26560
27577
  return merged;
26561
27578
  }
26562
27579
  __name(ensureMessagingPluginsOnCms, "ensureMessagingPluginsOnCms");
@@ -26605,7 +27622,7 @@ async function createCmsAppWithMessaging(options) {
26605
27622
  logger,
26606
27623
  plugins: mergedPlugins
26607
27624
  });
26608
- registerMessagingQueueProcessors(cms);
27625
+ registerMessagingQueueProcessors(cms, entityMap);
26609
27626
  return cms;
26610
27627
  }
26611
27628
  __name(createCmsAppWithMessaging, "createCmsAppWithMessaging");
@@ -26802,7 +27819,7 @@ function createCmsApiHandler(config) {
26802
27819
  companyDetails
26803
27820
  };
26804
27821
  if (queue) {
26805
- const { queueEmail: queueEmail2 } = await import('./email-queue-CGZBVVAS.js');
27822
+ const { queueEmail: queueEmail2 } = await import('./email-queue-OI2HSCGE.js');
26806
27823
  await queueEmail2(cms, {
26807
27824
  to: opts.to,
26808
27825
  templateName: "passwordReset",
@@ -26877,9 +27894,7 @@ function createCmsApiHandler(config) {
26877
27894
  getSessionUser: getHydratedSessionUser,
26878
27895
  baseUrl: vendorOnboardBaseUrl,
26879
27896
  getCms,
26880
- hashPassword: userAuth?.hashPassword,
26881
- minPasswordLength: 6
26882
- });
27897
+ hashPassword: userAuth?.hashPassword});
26883
27898
  const vendorRolesHandlers = getHydratedSessionUser && createVendorRolesHandlers({
26884
27899
  dataSource,
26885
27900
  entityMap,
@@ -26919,10 +27934,30 @@ function createCmsApiHandler(config) {
26919
27934
  const zipExtractPost = uploadMerged ? createMediaZipExtractHandler(uploadMerged) : null;
26920
27935
  const blogBySlugGet = blogBySlug ? createBlogBySlugHandler(blogBySlug) : null;
26921
27936
  const formBySlugGet = formBySlug ? createFormBySlugHandler(formBySlug) : null;
26922
- const formSaveHandlers = formSaveConfig ? createFormSaveHandlers(mergePerm(formSaveConfig) ?? formSaveConfig) : null;
26923
- const formSubmissionPost = formSubmissionConfig ? createFormSubmissionHandler(formSubmissionConfig) : null;
26924
- const formSubmissionGetById = formSubmissionGetByIdConfig ? createFormSubmissionGetByIdHandler(mergePerm(formSubmissionGetByIdConfig) ?? formSubmissionGetByIdConfig) : null;
26925
- const formSubmissionList = formSubmissionGetByIdConfig ? createFormSubmissionListHandler(mergePerm(formSubmissionGetByIdConfig) ?? formSubmissionGetByIdConfig) : null;
27937
+ const formSaveResolved = formSaveConfig ?? {
27938
+ dataSource,
27939
+ entityMap,
27940
+ json: config.json,
27941
+ requireAuth: config.requireAuth
27942
+ };
27943
+ const formSaveHandlers = createFormSaveHandlers(mergePerm(formSaveResolved) ?? formSaveResolved);
27944
+ const formSubmissionResolved = formSubmissionConfig ?? {
27945
+ dataSource,
27946
+ entityMap,
27947
+ json: config.json,
27948
+ getCms,
27949
+ getCompanyDetails: config.getCompanyDetails,
27950
+ getRecipientForChannel: config.getRecipientForChannel
27951
+ };
27952
+ const formSubmissionPost = createFormSubmissionHandler(formSubmissionResolved);
27953
+ const formSubmissionGetByIdResolved = formSubmissionGetByIdConfig ?? {
27954
+ dataSource,
27955
+ entityMap,
27956
+ json: config.json,
27957
+ requireAuth: config.requireAuth
27958
+ };
27959
+ const formSubmissionGetById = createFormSubmissionGetByIdHandler(mergePerm(formSubmissionGetByIdResolved) ?? formSubmissionGetByIdResolved);
27960
+ const formSubmissionList = createFormSubmissionListHandler(mergePerm(formSubmissionGetByIdResolved) ?? formSubmissionGetByIdResolved);
26926
27961
  const usersApiMerged = usersApi && getCms ? {
26927
27962
  ...usersApi,
26928
27963
  getCms: usersApi.getCms ?? getCms,
@@ -27117,7 +28152,19 @@ function createCmsApiHandler(config) {
27117
28152
  status: 404
27118
28153
  });
27119
28154
  }
28155
+ if (path2[0] === "admin" && path2[1] === "vendor" && path2[2] === "team-invite" && vendorHandlers) {
28156
+ if (path2.length === 3 && m === "GET") return vendorHandlers.validateTeamInvite(req);
28157
+ if (path2.length === 3 && m === "POST") return vendorHandlers.acceptTeamInvite(req);
28158
+ return config.json({
28159
+ error: "Not found"
28160
+ }, {
28161
+ status: 404
28162
+ });
28163
+ }
27120
28164
  if (path2[0] === "admin" && path2[1] === "vendor" && path2[2] === "team" && vendorHandlers) {
28165
+ if (path2.length === 4 && path2[3] === "send-invite" && m === "POST") {
28166
+ return vendorHandlers.sendTeamInviteEmail(req);
28167
+ }
27121
28168
  if (path2.length === 3 && m === "GET") return vendorHandlers.listTeam();
27122
28169
  if (path2.length === 3 && m === "POST") return vendorHandlers.addTeamMember(req);
27123
28170
  if (path2.length === 4 && m === "PATCH") return vendorHandlers.updateTeamMemberRole(req, path2[3]);
@@ -28056,14 +29103,27 @@ function createCmsApiHandler(config) {
28056
29103
  const pe = await requireEntityPermissionEffective(req, "orders", "read");
28057
29104
  if (pe) return pe;
28058
29105
  const cms = await getCms();
28059
- const { streamOrderInvoicePdf: streamOrderInvoicePdf2 } = await import('./erp-order-invoice-3YISSOWW.js');
29106
+ const { streamOrderInvoicePdf: streamOrderInvoicePdf2 } = await import('./erp-order-invoice-3GXDE443.js');
28060
29107
  const oid = Number(path2[1]);
28061
29108
  if (!Number.isFinite(oid)) return config.json({
28062
29109
  error: "Invalid id"
28063
29110
  }, {
28064
29111
  status: 400
28065
29112
  });
28066
- return streamOrderInvoicePdf2(cms, dataSource, entityMap, oid, {});
29113
+ try {
29114
+ return await streamOrderInvoicePdf2(cms, dataSource, entityMap, oid, {});
29115
+ } catch (err) {
29116
+ const msg = err instanceof Error ? err.message : String(err);
29117
+ console.error("[invoice] route failed", {
29118
+ orderId: oid,
29119
+ error: msg
29120
+ });
29121
+ return config.json({
29122
+ error: `Invoice failed: ${msg}`
29123
+ }, {
29124
+ status: 500
29125
+ });
29126
+ }
28067
29127
  }
28068
29128
  if (path2[0] === "orders" && path2.length === 3 && path2[2] === "repost-erp" && getCms) {
28069
29129
  const a = await config.requireAuth(req);
@@ -28410,7 +29470,7 @@ function createCmsApiHandler(config) {
28410
29470
  status: 400
28411
29471
  });
28412
29472
  }
28413
- const { resendOrderNotification } = await import('./order-notification-dispatcher-XWIJYDGA.js');
29473
+ const { resendOrderNotification } = await import('./order-notification-dispatcher-6WNG24NY.js');
28414
29474
  const result = await resendOrderNotification(triggerKey, orderId, {
28415
29475
  dataSource,
28416
29476
  entityMap,
@@ -28482,11 +29542,35 @@ function createCmsApiHandler(config) {
28482
29542
  paymentId = Number(payment.id);
28483
29543
  }
28484
29544
  }
29545
+ const orderWithItems = await orderRepo.findOne({
29546
+ where: {
29547
+ id: orderId,
29548
+ deleted: false
29549
+ },
29550
+ relations: [
29551
+ "items"
29552
+ ]
29553
+ });
29554
+ if (orderWithItems) {
29555
+ const { reconcileOrderInventoryBetweenSnapshots: reconcileOrderInventoryBetweenSnapshots2, orderInventorySnapshotFromRow: orderInventorySnapshotFromRow2 } = await import('./order-inventory-76V4XIGW.js');
29556
+ const prevSnap = orderInventorySnapshotFromRow2(orderWithItems);
29557
+ const invErr = await reconcileOrderInventoryBetweenSnapshots2(dataSource, entityMap, prevSnap, {
29558
+ status: "cancelled",
29559
+ lines: prevSnap.lines
29560
+ });
29561
+ if (invErr) {
29562
+ return config.json({
29563
+ error: invErr
29564
+ }, {
29565
+ status: 400
29566
+ });
29567
+ }
29568
+ }
28485
29569
  await orderRepo.update(orderId, {
28486
29570
  status: "cancelled"
28487
29571
  });
28488
29572
  const fireOrderCancelledNotification = /* @__PURE__ */ __name((refundAmount) => {
28489
- void import('./emit-order-notification-trigger-IVLWKKJL.js').then(({ fireOrderNotificationTrigger }) => {
29573
+ void import('./emit-order-notification-trigger-6XX7LSC4.js').then(({ fireOrderNotificationTrigger }) => {
28490
29574
  fireOrderNotificationTrigger("order_cancelled", orderId, {
28491
29575
  dataSource,
28492
29576
  entityMap
@@ -29519,7 +30603,7 @@ function createStorefrontApiHandler(config) {
29519
30603
  const otpPepper = config.otpPepper;
29520
30604
  const defaultPhoneCc = config.defaultPhoneCountryCode;
29521
30605
  function fireOrderPlacedNotification(orderId) {
29522
- void import('./emit-order-notification-trigger-IVLWKKJL.js').then(({ fireOrderNotificationTrigger }) => {
30606
+ void import('./emit-order-notification-trigger-6XX7LSC4.js').then(({ fireOrderNotificationTrigger }) => {
29523
30607
  fireOrderNotificationTrigger("order_placed", orderId, {
29524
30608
  dataSource,
29525
30609
  entityMap
@@ -31293,9 +32377,12 @@ function createStorefrontApiHandler(config) {
31293
32377
  }, {
31294
32378
  status: 400
31295
32379
  });
32380
+ const { retireSoftDeletedUniqueValue: retireSoftDeletedUniqueValue2 } = await import('./retire-soft-deleted-unique-NXQIH4BC.js');
32381
+ await retireSoftDeletedUniqueValue2(userRepo(), "email", email);
31296
32382
  const existing = await userRepo().findOne({
31297
32383
  where: {
31298
- email
32384
+ email,
32385
+ deleted: false
31299
32386
  }
31300
32387
  });
31301
32388
  if (existing) return json({
@@ -31924,7 +33011,6 @@ function createStorefrontApiHandler(config) {
31924
33011
  }));
31925
33012
  }
31926
33013
  await linkOrderContactToVendors(contactId, vendorRes.vendorIds);
31927
- fireOrderPlacedNotification(oid);
31928
33014
  return json({
31929
33015
  orderId: oid,
31930
33016
  orderNumber: ord.orderNumber,
@@ -32001,7 +33087,6 @@ function createStorefrontApiHandler(config) {
32001
33087
  cartId: cart.id
32002
33088
  });
32003
33089
  await cartRepo().delete(cart.id);
32004
- fireOrderPlacedNotification(oid);
32005
33090
  return json({
32006
33091
  orderId: oid,
32007
33092
  orderNumber: ord.orderNumber,
@@ -32176,6 +33261,7 @@ function createStorefrontApiHandler(config) {
32176
33261
  unitPrice: line.unitPrice,
32177
33262
  tax: line.tax,
32178
33263
  total: line.total,
33264
+ metadata: line.metadata ?? null,
32179
33265
  product: p ? {
32180
33266
  name: p.name,
32181
33267
  slug: p.slug,
@@ -32243,4 +33329,4 @@ function createStorefrontApiHandler(config) {
32243
33329
  }
32244
33330
  __name(createStorefrontApiHandler, "createStorefrontApiHandler");
32245
33331
 
32246
- 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, 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, UserGroup, Vendor, VendorCustomer, VendorRole, VendorRolePermission, VendorUser, Wishlist, WishlistItem, ZIP_MIME_TYPES, applyApprovalStatusSideEffects, applyEventApprovalStatusSideEffects, applyRotatingVendorInvite, applyVendorCustomersContactFilter, applyVendorEventCreateApproval, applyVendorProductCreateApproval, assertCaptchaOk, assertContactAllowedForVendorOrder, assertEventApprovalUpdate, assertProductApprovalUpdate, buildBlogMetadataUserPrompt, buildCronFromSchedule, buildRssUserPromptFromFeeds, buildVendorInviteLink, calculateOrderRefundPreview, calculateRefundFromPolicy, checkEventsEnabled, checkMultiVendorEnabled, contactIsVendorCustomer, 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, customerPhoneForEmail, customerPhoneForUser, daysBeforeEventStart, describeEventTierPolicy, ensureCustomerForUser, ensureCustomerRecord, ensureMessagingPluginsOnCms, ensureScheduleQueueWorker, ensureVendorCustomerForOrderContact, ensureVendorCustomersForOrder, findActiveRefundPolicyForVendor, findVendorByInviteToken, formatTierRange, generateNumericOtp, getPublicSettingsGroup, getRequireEventApproval, getRequireProductApproval, getRssArticleSummaryFromItem, getVendorCatalogCreateFlags, hashOtpCode, hydrateVendorSessionUser, invalidateEventsCache, invalidateMultiVendorCache, invalidateRequireEventApprovalCache, invalidateRequireProductApprovalCache, invalidateVendorCatalogCreateFlagsCache, isCustomerTypeContact, isSyntheticCustomerPhone, isZipMedia, linkUnclaimedContactToUser, llmAgentToChatAgentOptions, loadSettingsGroupFromDb, loadUserVendorContext, mergeGuardrailsIntoSystemPrompt, messagingPlugins, metaFetchUserManagedPages, metaPostPageFeed, metaPostPagePhoto, metaResolvePageAccessToken, normalizeCustomerPhone, normalizePhoneE164, normalizeRefundTiers, overlayCmsPlugins, parseBlogGeneratorAgentContent, parseBlogGeneratorModelOutput, parseBlogMetadataEnrichmentJson, parseLlmAgentValidationRules, pgBossScheduleNameForId, queueErpCreateContactIfEnabled, queueJobScheduleNow, queuePlugin, queueSms, registerJobRunnerWorker, registerMessagingQueueProcessors, registerSmsQueueProcessor, relativePathFromMediaParentId, resolveBlogCategoryIdByName, resolveSettingsEncryptionKey, resolveVendorIdForContactCheck, sanitizeMediaFolderPath, sanitizeStorageSegment, sendVendorOnboardEmails, simpleDecrypt, simpleEncrypt, syncJobScheduleToPgBoss, validateRefundTiers, validateScheduleInput, validateUserMessageAgainstAgentRules, validateUserMessageAgainstStructuredRules, verifyAndConsumeOtpChallenge, verifyOtpCodeHash, whatsappPlugin, wrapGetCmsWithMessaging };
33332
+ 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, 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, 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, customerPhoneForEmail, customerPhoneForUser, daysBeforeEventStart, decrementDiscountUsage, describeEventTierPolicy, ensureCustomerForUser, ensureCustomerRecord, ensureMessagingPluginsOnCms, ensureScheduleQueueWorker, ensureVendorCustomerForOrderContact, ensureVendorCustomersForOrder, findActiveRefundPolicyForVendor, findUserByInviteToken, findVendorByInviteToken, formatTierRange, generateNumericOtp, getPublicSettingsGroup, getRequireEventApproval, getRequireProductApproval, getRssArticleSummaryFromItem, getVendorCatalogCreateFlags, hashOtpCode, hydrateVendorSessionUser, invalidateEventsCache, invalidateMultiVendorCache, invalidateRequireEventApprovalCache, invalidateRequireProductApprovalCache, invalidateVendorCatalogCreateFlagsCache, isCustomerTypeContact, isMaxPerUserUsageReached, isMaxTotalUsageReached, isSyntheticCustomerPhone, isZipMedia, linkUnclaimedContactToUser, llmAgentToChatAgentOptions, loadSettingsGroupFromDb, loadUserVendorContext, mergeGuardrailsIntoSystemPrompt, messagingPlugins, metaFetchUserManagedPages, metaPostPageFeed, metaPostPagePhoto, metaResolvePageAccessToken, newUserInviteToken, normalizeCustomerPhone, 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 };