@infuro/cms-core 1.0.60 → 1.0.62

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 (50) hide show
  1. package/dist/admin.cjs +4179 -2665
  2. package/dist/admin.js +2990 -1476
  3. package/dist/api.cjs +41 -37
  4. package/dist/api.js +9 -5
  5. package/dist/{chunk-URN7GS23.js → chunk-6LV36PCL.js} +199 -1059
  6. package/dist/{chunk-O2642WVS.js → chunk-6XAVZE4I.js} +17 -3
  7. package/dist/{chunk-BXYZDMTZ.cjs → chunk-AXMP2U43.cjs} +3 -94
  8. package/dist/{chunk-T3HPSF7K.js → chunk-AYWDQFJZ.js} +3 -0
  9. package/dist/chunk-CTIEAHQL.cjs +96 -0
  10. package/dist/chunk-GWDI752Q.js +83 -0
  11. package/dist/chunk-GZGFNVTK.js +886 -0
  12. package/dist/chunk-H3IVLIPR.cjs +86 -0
  13. package/dist/{chunk-2KUCQVAQ.js → chunk-HMLVPIJR.js} +2 -91
  14. package/dist/{chunk-V25RDUOU.cjs → chunk-LRD4CGOG.cjs} +38 -4
  15. package/dist/{chunk-73WVHINE.cjs → chunk-LVQSG25Y.cjs} +18 -4
  16. package/dist/chunk-NMYGQWHV.js +93 -0
  17. package/dist/chunk-OVTOP42W.js +199 -0
  18. package/dist/{chunk-BSLNXKV2.cjs → chunk-QA5C477U.cjs} +927 -351
  19. package/dist/{chunk-JAEUYYGA.js → chunk-R6Q67HAS.js} +876 -291
  20. package/dist/{chunk-YSYX4GUD.cjs → chunk-TWTISTZB.cjs} +210 -1080
  21. package/dist/{chunk-77I3KS7V.cjs → chunk-UEE4PTTB.cjs} +3 -0
  22. package/dist/chunk-WFMVD567.cjs +209 -0
  23. package/dist/{chunk-L3525VXI.js → chunk-YW7EF7K7.js} +36 -2
  24. package/dist/chunk-ZPAPCGCR.cjs +899 -0
  25. package/dist/{email-queue-OI2HSCGE.js → email-queue-65PQAG4C.js} +3 -2
  26. package/dist/{email-queue-6NJY6HNM.cjs → email-queue-J7DXYNCE.cjs} +7 -6
  27. package/dist/email-service-F7HA4X63.js +3 -0
  28. package/dist/email-service-RDOTY3CO.cjs +28 -0
  29. package/dist/{emit-order-notification-trigger-TNEZOYEE.cjs → emit-order-notification-trigger-K7URAZHJ.cjs} +4 -4
  30. package/dist/{emit-order-notification-trigger-CZU3V2WE.js → emit-order-notification-trigger-MD7EBODC.js} +2 -2
  31. package/dist/{erp-order-invoice-EYYNR526.cjs → erp-order-invoice-C5GZCOBM.cjs} +6 -5
  32. package/dist/{erp-order-invoice-3GXDE443.js → erp-order-invoice-MYFCXOCY.js} +2 -1
  33. package/dist/index.cjs +638 -346
  34. package/dist/index.d.cts +53 -19
  35. package/dist/index.d.ts +53 -19
  36. package/dist/index.js +350 -58
  37. package/dist/migrations/1783000000000-AddOrderPendingProcessingCompletedTriggers.ts +56 -0
  38. package/dist/migrations/1783100000000-AddSmsToOrderNotificationBindingsChannelEnum.ts +17 -0
  39. package/dist/migrations/1783200000000-AddOrderAssigneeColumns.ts +30 -0
  40. package/dist/order-assignees-handlers-LKMAGLG6.js +150 -0
  41. package/dist/order-assignees-handlers-NPKD64P6.cjs +152 -0
  42. package/dist/order-completion-otp-handlers-3NTOGEA5.js +361 -0
  43. package/dist/order-completion-otp-handlers-4EOLYLAP.cjs +363 -0
  44. package/dist/order-notification-dispatcher-IYMOS4VY.js +10 -0
  45. package/dist/order-notification-dispatcher-X2XM5VUY.cjs +35 -0
  46. package/dist/sms-notification-templates-handlers-SJLO7JGZ.js +47 -0
  47. package/dist/sms-notification-templates-handlers-YSB3L2PK.cjs +49 -0
  48. package/package.json +1 -1
  49. package/dist/order-notification-dispatcher-KJVGLK5E.cjs +0 -24
  50. package/dist/order-notification-dispatcher-ZSFKEYMP.js +0 -7
@@ -0,0 +1,56 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class AddOrderPendingProcessingCompletedTriggers1783000000000 implements MigrationInterface {
4
+ name = "AddOrderPendingProcessingCompletedTriggers1783000000000";
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ const tableExists = await queryRunner.hasTable("notification_triggers");
8
+ if (!tableExists) return;
9
+
10
+ const triggers = [
11
+ {
12
+ id: "order.pending",
13
+ name: "Order Pending",
14
+ description: "Triggered when a customer places an order and it is pending confirmation or payment.",
15
+ category: "orders",
16
+ enabled: true,
17
+ },
18
+ {
19
+ id: "order.processing",
20
+ name: "Order Processing",
21
+ description: "Triggered when an order transitions to processing status after being assigned to a team member.",
22
+ category: "orders",
23
+ enabled: true,
24
+ },
25
+ {
26
+ id: "order.completed",
27
+ name: "Order Completed",
28
+ description: "Triggered when an order is completed after customer OTP validation.",
29
+ category: "orders",
30
+ enabled: true,
31
+ },
32
+ ];
33
+
34
+ for (const t of triggers) {
35
+ await queryRunner.query(
36
+ `INSERT INTO "notification_triggers" ("id", "name", "description", "category", "enabled")
37
+ VALUES ($1, $2, $3, $4, $5)
38
+ ON CONFLICT ("id") DO UPDATE
39
+ SET "name" = EXCLUDED."name",
40
+ "description" = EXCLUDED."description",
41
+ "category" = EXCLUDED."category",
42
+ "enabled" = EXCLUDED."enabled"`,
43
+ [t.id, t.name, t.description, t.category, t.enabled]
44
+ );
45
+ }
46
+ }
47
+
48
+ public async down(queryRunner: QueryRunner): Promise<void> {
49
+ const tableExists = await queryRunner.hasTable("notification_triggers");
50
+ if (!tableExists) return;
51
+
52
+ await queryRunner.query(
53
+ `DELETE FROM "notification_triggers" WHERE "id" IN ('order.pending', 'order.processing', 'order.completed')`
54
+ );
55
+ }
56
+ }
@@ -0,0 +1,17 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class AddSmsToOrderNotificationBindingsChannelEnum1783100000000 implements MigrationInterface {
4
+ name = "AddSmsToOrderNotificationBindingsChannelEnum1783100000000";
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ try {
8
+ await queryRunner.query(`ALTER TYPE "order_notification_bindings_channel_enum" ADD VALUE IF NOT EXISTS 'sms'`);
9
+ } catch {
10
+ /* ignore if enum doesn't exist or already added */
11
+ }
12
+ }
13
+
14
+ public async down(_queryRunner: QueryRunner): Promise<void> {
15
+ // Enum values cannot easily be removed in Postgres without recreating
16
+ }
17
+ }
@@ -0,0 +1,30 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+
3
+ /** Add assignedUserId and assignedAt columns to orders table. */
4
+ export class AddOrderAssigneeColumns1783200000000 implements MigrationInterface {
5
+ name = 'AddOrderAssigneeColumns1783200000000';
6
+
7
+ public async up(queryRunner: QueryRunner): Promise<void> {
8
+ await queryRunner.query(`
9
+ ALTER TABLE "orders"
10
+ ADD COLUMN IF NOT EXISTS "assignedUserId" integer NULL,
11
+ ADD COLUMN IF NOT EXISTS "assignedAt" TIMESTAMP NULL;
12
+ `);
13
+
14
+ await queryRunner.query(`
15
+ CREATE INDEX IF NOT EXISTS "IDX_orders_assigned_user"
16
+ ON "orders" ("assignedUserId");
17
+ `);
18
+ }
19
+
20
+ public async down(queryRunner: QueryRunner): Promise<void> {
21
+ await queryRunner.query(`
22
+ DROP INDEX IF EXISTS "IDX_orders_assigned_user";
23
+ `);
24
+ await queryRunner.query(`
25
+ ALTER TABLE "orders"
26
+ DROP COLUMN IF EXISTS "assignedAt",
27
+ DROP COLUMN IF EXISTS "assignedUserId";
28
+ `);
29
+ }
30
+ }
@@ -0,0 +1,150 @@
1
+ import { __name } from './chunk-SHUYVCID.js';
2
+
3
+ // src/api/order-assignees-handlers.ts
4
+ function json(data, init) {
5
+ return new Response(JSON.stringify(data), {
6
+ status: init?.status ?? 200,
7
+ headers: {
8
+ "Content-Type": "application/json",
9
+ ...init?.headers || {}
10
+ }
11
+ });
12
+ }
13
+ __name(json, "json");
14
+ function createOrderAssigneesHandlers(dataSource, entityMap, getHydratedSessionUser) {
15
+ return {
16
+ /** GET /api/orders/:id/eligible-assignees */
17
+ async listEligibleAssignees(req, orderId) {
18
+ if (!entityMap.orders || !entityMap.users) {
19
+ return json({
20
+ error: "Order or User entity not configured"
21
+ }, {
22
+ status: 500
23
+ });
24
+ }
25
+ const orderRepo = dataSource.getRepository(entityMap.orders);
26
+ const order = await orderRepo.findOne({
27
+ where: {
28
+ id: orderId,
29
+ deleted: false
30
+ },
31
+ select: [
32
+ "id",
33
+ "vendorId",
34
+ "assignedUserId"
35
+ ]
36
+ });
37
+ if (!order) {
38
+ return json({
39
+ error: "Order not found"
40
+ }, {
41
+ status: 404
42
+ });
43
+ }
44
+ const orderVendorId = order.vendorId;
45
+ const session = await getHydratedSessionUser?.() ?? null;
46
+ const userVendorIds = session?.vendorIds ?? [];
47
+ const isVendorSession = Boolean(session?.isVendorPortal || !session?.isRBACAdmin && userVendorIds.length > 0);
48
+ Boolean(session?.isRBACAdmin && !session?.isVendorPortal);
49
+ if (isVendorSession && orderVendorId && !userVendorIds.includes(orderVendorId)) {
50
+ return json({
51
+ error: "Forbidden: Access denied to vendor order"
52
+ }, {
53
+ status: 403
54
+ });
55
+ }
56
+ const assigneesMap = /* @__PURE__ */ new Map();
57
+ if (isVendorSession) {
58
+ const targetVendorId = orderVendorId ?? session?.activeVendorId ?? userVendorIds[0];
59
+ if (entityMap.vendor_users && targetVendorId) {
60
+ const vuRepo = dataSource.getRepository(entityMap.vendor_users);
61
+ const vendorUsers = await vuRepo.find({
62
+ where: {
63
+ vendorId: targetVendorId
64
+ },
65
+ relations: [
66
+ "user",
67
+ "vendorRole"
68
+ ]
69
+ });
70
+ for (const vu of vendorUsers) {
71
+ const u = vu.user;
72
+ const r = vu.vendorRole;
73
+ if (u && u.id && !u.deleted && !u.blocked && u.inviteStatus === "active") {
74
+ const roleName = r?.name || (r?.isOwnerRole ? "Owner" : "Vendor Staff");
75
+ assigneesMap.set(u.id, {
76
+ id: u.id,
77
+ name: u.name || u.email?.split("@")[0] || `User #${u.id}`,
78
+ email: u.email || "",
79
+ role: roleName
80
+ });
81
+ }
82
+ }
83
+ }
84
+ } else {
85
+ if (entityMap.vendor_users) {
86
+ const vuRepo = dataSource.getRepository(entityMap.vendor_users);
87
+ const vendorUsers = await vuRepo.find({
88
+ relations: [
89
+ "user",
90
+ "vendorRole"
91
+ ]
92
+ });
93
+ for (const vu of vendorUsers) {
94
+ const u = vu.user;
95
+ const r = vu.vendorRole;
96
+ if (u && u.id && !u.deleted && !u.blocked && u.inviteStatus === "active") {
97
+ const roleName = r?.name || (r?.isOwnerRole ? "Owner" : "Vendor Staff");
98
+ assigneesMap.set(u.id, {
99
+ id: u.id,
100
+ name: u.name || u.email?.split("@")[0] || `User #${u.id}`,
101
+ email: u.email || "",
102
+ role: roleName
103
+ });
104
+ }
105
+ }
106
+ }
107
+ const userRepo = dataSource.getRepository(entityMap.users);
108
+ const users = await userRepo.find({
109
+ where: {
110
+ deleted: false,
111
+ blocked: false,
112
+ inviteStatus: "active"
113
+ },
114
+ relations: [
115
+ "group"
116
+ ],
117
+ order: {
118
+ name: "ASC"
119
+ }
120
+ });
121
+ for (const u of users) {
122
+ const groupName = u.group?.name ? String(u.group.name).trim() : "";
123
+ const isCustomer = groupName.toLowerCase() === "customer";
124
+ if (isCustomer) continue;
125
+ if (!assigneesMap.has(u.id)) {
126
+ let roleLabel = "Staff";
127
+ if (groupName) {
128
+ roleLabel = groupName;
129
+ } else if (u.adminAccess) {
130
+ roleLabel = "Administrator";
131
+ }
132
+ assigneesMap.set(u.id, {
133
+ id: u.id,
134
+ name: u.name || u.email?.split("@")[0] || `User #${u.id}`,
135
+ email: u.email || "",
136
+ role: roleLabel
137
+ });
138
+ }
139
+ }
140
+ }
141
+ return json({
142
+ assignees: Array.from(assigneesMap.values()),
143
+ currentAssignedUserId: order.assignedUserId ?? null
144
+ });
145
+ }
146
+ };
147
+ }
148
+ __name(createOrderAssigneesHandlers, "createOrderAssigneesHandlers");
149
+
150
+ export { createOrderAssigneesHandlers };
@@ -0,0 +1,152 @@
1
+ 'use strict';
2
+
3
+ var chunkUSNT2KNT_cjs = require('./chunk-USNT2KNT.cjs');
4
+
5
+ // src/api/order-assignees-handlers.ts
6
+ function json(data, init) {
7
+ return new Response(JSON.stringify(data), {
8
+ status: init?.status ?? 200,
9
+ headers: {
10
+ "Content-Type": "application/json",
11
+ ...init?.headers || {}
12
+ }
13
+ });
14
+ }
15
+ chunkUSNT2KNT_cjs.__name(json, "json");
16
+ function createOrderAssigneesHandlers(dataSource, entityMap, getHydratedSessionUser) {
17
+ return {
18
+ /** GET /api/orders/:id/eligible-assignees */
19
+ async listEligibleAssignees(req, orderId) {
20
+ if (!entityMap.orders || !entityMap.users) {
21
+ return json({
22
+ error: "Order or User entity not configured"
23
+ }, {
24
+ status: 500
25
+ });
26
+ }
27
+ const orderRepo = dataSource.getRepository(entityMap.orders);
28
+ const order = await orderRepo.findOne({
29
+ where: {
30
+ id: orderId,
31
+ deleted: false
32
+ },
33
+ select: [
34
+ "id",
35
+ "vendorId",
36
+ "assignedUserId"
37
+ ]
38
+ });
39
+ if (!order) {
40
+ return json({
41
+ error: "Order not found"
42
+ }, {
43
+ status: 404
44
+ });
45
+ }
46
+ const orderVendorId = order.vendorId;
47
+ const session = await getHydratedSessionUser?.() ?? null;
48
+ const userVendorIds = session?.vendorIds ?? [];
49
+ const isVendorSession = Boolean(session?.isVendorPortal || !session?.isRBACAdmin && userVendorIds.length > 0);
50
+ Boolean(session?.isRBACAdmin && !session?.isVendorPortal);
51
+ if (isVendorSession && orderVendorId && !userVendorIds.includes(orderVendorId)) {
52
+ return json({
53
+ error: "Forbidden: Access denied to vendor order"
54
+ }, {
55
+ status: 403
56
+ });
57
+ }
58
+ const assigneesMap = /* @__PURE__ */ new Map();
59
+ if (isVendorSession) {
60
+ const targetVendorId = orderVendorId ?? session?.activeVendorId ?? userVendorIds[0];
61
+ if (entityMap.vendor_users && targetVendorId) {
62
+ const vuRepo = dataSource.getRepository(entityMap.vendor_users);
63
+ const vendorUsers = await vuRepo.find({
64
+ where: {
65
+ vendorId: targetVendorId
66
+ },
67
+ relations: [
68
+ "user",
69
+ "vendorRole"
70
+ ]
71
+ });
72
+ for (const vu of vendorUsers) {
73
+ const u = vu.user;
74
+ const r = vu.vendorRole;
75
+ if (u && u.id && !u.deleted && !u.blocked && u.inviteStatus === "active") {
76
+ const roleName = r?.name || (r?.isOwnerRole ? "Owner" : "Vendor Staff");
77
+ assigneesMap.set(u.id, {
78
+ id: u.id,
79
+ name: u.name || u.email?.split("@")[0] || `User #${u.id}`,
80
+ email: u.email || "",
81
+ role: roleName
82
+ });
83
+ }
84
+ }
85
+ }
86
+ } else {
87
+ if (entityMap.vendor_users) {
88
+ const vuRepo = dataSource.getRepository(entityMap.vendor_users);
89
+ const vendorUsers = await vuRepo.find({
90
+ relations: [
91
+ "user",
92
+ "vendorRole"
93
+ ]
94
+ });
95
+ for (const vu of vendorUsers) {
96
+ const u = vu.user;
97
+ const r = vu.vendorRole;
98
+ if (u && u.id && !u.deleted && !u.blocked && u.inviteStatus === "active") {
99
+ const roleName = r?.name || (r?.isOwnerRole ? "Owner" : "Vendor Staff");
100
+ assigneesMap.set(u.id, {
101
+ id: u.id,
102
+ name: u.name || u.email?.split("@")[0] || `User #${u.id}`,
103
+ email: u.email || "",
104
+ role: roleName
105
+ });
106
+ }
107
+ }
108
+ }
109
+ const userRepo = dataSource.getRepository(entityMap.users);
110
+ const users = await userRepo.find({
111
+ where: {
112
+ deleted: false,
113
+ blocked: false,
114
+ inviteStatus: "active"
115
+ },
116
+ relations: [
117
+ "group"
118
+ ],
119
+ order: {
120
+ name: "ASC"
121
+ }
122
+ });
123
+ for (const u of users) {
124
+ const groupName = u.group?.name ? String(u.group.name).trim() : "";
125
+ const isCustomer = groupName.toLowerCase() === "customer";
126
+ if (isCustomer) continue;
127
+ if (!assigneesMap.has(u.id)) {
128
+ let roleLabel = "Staff";
129
+ if (groupName) {
130
+ roleLabel = groupName;
131
+ } else if (u.adminAccess) {
132
+ roleLabel = "Administrator";
133
+ }
134
+ assigneesMap.set(u.id, {
135
+ id: u.id,
136
+ name: u.name || u.email?.split("@")[0] || `User #${u.id}`,
137
+ email: u.email || "",
138
+ role: roleLabel
139
+ });
140
+ }
141
+ }
142
+ }
143
+ return json({
144
+ assignees: Array.from(assigneesMap.values()),
145
+ currentAssignedUserId: order.assignedUserId ?? null
146
+ });
147
+ }
148
+ };
149
+ }
150
+ chunkUSNT2KNT_cjs.__name(createOrderAssigneesHandlers, "createOrderAssigneesHandlers");
151
+
152
+ exports.createOrderAssigneesHandlers = createOrderAssigneesHandlers;