@axova/shared 1.0.0

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 (112) hide show
  1. package/CONFIGURATION_GUIDE.md +1 -0
  2. package/README.md +384 -0
  3. package/SCHEMA_ORGANIZATION.md +209 -0
  4. package/dist/configs/index.d.ts +85 -0
  5. package/dist/configs/index.js +555 -0
  6. package/dist/events/kafka.d.ts +40 -0
  7. package/dist/events/kafka.js +311 -0
  8. package/dist/index.d.ts +13 -0
  9. package/dist/index.js +41 -0
  10. package/dist/interfaces/customer-events.d.ts +85 -0
  11. package/dist/interfaces/customer-events.js +2 -0
  12. package/dist/interfaces/inventory-events.d.ts +453 -0
  13. package/dist/interfaces/inventory-events.js +3 -0
  14. package/dist/interfaces/inventory-types.d.ts +894 -0
  15. package/dist/interfaces/inventory-types.js +3 -0
  16. package/dist/interfaces/order-events.d.ts +320 -0
  17. package/dist/interfaces/order-events.js +3 -0
  18. package/dist/lib/auditLogger.d.ts +162 -0
  19. package/dist/lib/auditLogger.js +626 -0
  20. package/dist/lib/authOrganization.d.ts +24 -0
  21. package/dist/lib/authOrganization.js +110 -0
  22. package/dist/lib/db.d.ts +6 -0
  23. package/dist/lib/db.js +88 -0
  24. package/dist/middleware/serviceAuth.d.ts +60 -0
  25. package/dist/middleware/serviceAuth.js +272 -0
  26. package/dist/middleware/storeOwnership.d.ts +15 -0
  27. package/dist/middleware/storeOwnership.js +156 -0
  28. package/dist/middleware/storeValidationMiddleware.d.ts +44 -0
  29. package/dist/middleware/storeValidationMiddleware.js +180 -0
  30. package/dist/middleware/userAuth.d.ts +27 -0
  31. package/dist/middleware/userAuth.js +218 -0
  32. package/dist/schemas/admin/admin-schema.d.ts +741 -0
  33. package/dist/schemas/admin/admin-schema.js +111 -0
  34. package/dist/schemas/ai-moderation/ai-moderation-schema.d.ts +648 -0
  35. package/dist/schemas/ai-moderation/ai-moderation-schema.js +88 -0
  36. package/dist/schemas/common/common-schemas.d.ts +436 -0
  37. package/dist/schemas/common/common-schemas.js +94 -0
  38. package/dist/schemas/compliance/compliance-schema.d.ts +3388 -0
  39. package/dist/schemas/compliance/compliance-schema.js +472 -0
  40. package/dist/schemas/compliance/kyc-schema.d.ts +2642 -0
  41. package/dist/schemas/compliance/kyc-schema.js +361 -0
  42. package/dist/schemas/customer/customer-schema.d.ts +2727 -0
  43. package/dist/schemas/customer/customer-schema.js +399 -0
  44. package/dist/schemas/index.d.ts +27 -0
  45. package/dist/schemas/index.js +138 -0
  46. package/dist/schemas/inventory/inventory-tables.d.ts +9476 -0
  47. package/dist/schemas/inventory/inventory-tables.js +1470 -0
  48. package/dist/schemas/inventory/lot-tables.d.ts +3281 -0
  49. package/dist/schemas/inventory/lot-tables.js +608 -0
  50. package/dist/schemas/order/order-schema.d.ts +5825 -0
  51. package/dist/schemas/order/order-schema.js +954 -0
  52. package/dist/schemas/product/discount-relations.d.ts +15 -0
  53. package/dist/schemas/product/discount-relations.js +34 -0
  54. package/dist/schemas/product/discount-schema.d.ts +1975 -0
  55. package/dist/schemas/product/discount-schema.js +297 -0
  56. package/dist/schemas/product/product-relations.d.ts +41 -0
  57. package/dist/schemas/product/product-relations.js +133 -0
  58. package/dist/schemas/product/product-schema.d.ts +4544 -0
  59. package/dist/schemas/product/product-schema.js +671 -0
  60. package/dist/schemas/store/store-audit-schema.d.ts +4135 -0
  61. package/dist/schemas/store/store-audit-schema.js +556 -0
  62. package/dist/schemas/store/store-schema.d.ts +3100 -0
  63. package/dist/schemas/store/store-schema.js +381 -0
  64. package/dist/schemas/store/store-settings-schema.d.ts +665 -0
  65. package/dist/schemas/store/store-settings-schema.js +141 -0
  66. package/dist/schemas/types.d.ts +50 -0
  67. package/dist/schemas/types.js +3 -0
  68. package/dist/types/events.d.ts +2396 -0
  69. package/dist/types/events.js +505 -0
  70. package/dist/utils/errorHandler.d.ts +12 -0
  71. package/dist/utils/errorHandler.js +36 -0
  72. package/dist/utils/subdomain.d.ts +6 -0
  73. package/dist/utils/subdomain.js +20 -0
  74. package/nul +8 -0
  75. package/package.json +43 -0
  76. package/src/configs/index.ts +654 -0
  77. package/src/events/kafka.ts +429 -0
  78. package/src/index.ts +26 -0
  79. package/src/interfaces/customer-events.ts +106 -0
  80. package/src/interfaces/inventory-events.ts +545 -0
  81. package/src/interfaces/inventory-types.ts +1004 -0
  82. package/src/interfaces/order-events.ts +381 -0
  83. package/src/lib/auditLogger.ts +1117 -0
  84. package/src/lib/authOrganization.ts +153 -0
  85. package/src/lib/db.ts +64 -0
  86. package/src/middleware/serviceAuth.ts +328 -0
  87. package/src/middleware/storeOwnership.ts +199 -0
  88. package/src/middleware/storeValidationMiddleware.ts +247 -0
  89. package/src/middleware/userAuth.ts +248 -0
  90. package/src/schemas/admin/admin-schema.ts +208 -0
  91. package/src/schemas/ai-moderation/ai-moderation-schema.ts +180 -0
  92. package/src/schemas/common/common-schemas.ts +108 -0
  93. package/src/schemas/compliance/compliance-schema.ts +927 -0
  94. package/src/schemas/compliance/kyc-schema.ts +649 -0
  95. package/src/schemas/customer/customer-schema.ts +576 -0
  96. package/src/schemas/index.ts +189 -0
  97. package/src/schemas/inventory/inventory-tables.ts +1927 -0
  98. package/src/schemas/inventory/lot-tables.ts +799 -0
  99. package/src/schemas/order/order-schema.ts +1400 -0
  100. package/src/schemas/product/discount-relations.ts +44 -0
  101. package/src/schemas/product/discount-schema.ts +464 -0
  102. package/src/schemas/product/product-relations.ts +187 -0
  103. package/src/schemas/product/product-schema.ts +955 -0
  104. package/src/schemas/store/ethiopian_business_api.md.resolved +212 -0
  105. package/src/schemas/store/store-audit-schema.ts +1257 -0
  106. package/src/schemas/store/store-schema.ts +661 -0
  107. package/src/schemas/store/store-settings-schema.ts +231 -0
  108. package/src/schemas/types.ts +67 -0
  109. package/src/types/events.ts +646 -0
  110. package/src/utils/errorHandler.ts +44 -0
  111. package/src/utils/subdomain.ts +19 -0
  112. package/tsconfig.json +21 -0
@@ -0,0 +1,505 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KAFKA_TOPICS = exports.OrderRefundProcessedEventSchema = exports.OrderReturnRequestedEventSchema = exports.SubscriptionCancelledEventSchema = exports.SubscriptionRenewedEventSchema = exports.SubscriptionOrderCreatedEventSchema = exports.OrderDiscountAppliedEventSchema = exports.OrderItemRemovedEventSchema = exports.OrderItemAddedEventSchema = exports.OrderNoteAddedEventSchema = exports.OrderRefundedEventSchema = exports.OrderCancelledEventSchema = exports.OrderDeliveredEventSchema = exports.OrderShippedEventSchema = exports.OrderPaymentProcessedEventSchema = exports.OrderStatusChangedEventSchema = exports.OrderUpdatedEventSchema = exports.OrderCreatedEventSchema = exports.CustomerReviewSubmittedEventSchema = exports.CustomerSupportTicketCreatedEventSchema = exports.CustomerNoteCreatedEventSchema = exports.CustomerInteractionCreatedEventSchema = exports.CustomerVisitCreatedEventSchema = exports.CustomerDeletedEventSchema = exports.CustomerUpdatedEventSchema = exports.CustomerCreatedEventSchema = exports.AppealReviewedEventSchema = exports.AppealSubmittedEventSchema = exports.AuditLoggedEventSchema = exports.NotificationSendEventSchema = exports.StoreUnbannedEventSchema = exports.StoreSuspendedEventSchema = exports.ComplianceViolationDetectedEventSchema = exports.StoreUpdatedEventSchema = exports.StoreCreatedEventSchema = exports.BaseEventSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ // Base event schema
6
+ exports.BaseEventSchema = zod_1.z.object({
7
+ id: zod_1.z.string(),
8
+ timestamp: zod_1.z.string(),
9
+ source: zod_1.z.string(),
10
+ version: zod_1.z.string().default("1.0"),
11
+ });
12
+ // Store Events
13
+ exports.StoreCreatedEventSchema = exports.BaseEventSchema.extend({
14
+ type: zod_1.z.literal("store.created"),
15
+ data: zod_1.z.object({
16
+ storeId: zod_1.z.string(),
17
+ userId: zod_1.z.string(),
18
+ storeName: zod_1.z.string(),
19
+ subdomain: zod_1.z.string(),
20
+ timezone: zod_1.z.string(),
21
+ currency: zod_1.z.string(),
22
+ isActive: zod_1.z.boolean(),
23
+ organizationId: zod_1.z.string().optional(),
24
+ }),
25
+ });
26
+ exports.StoreUpdatedEventSchema = exports.BaseEventSchema.extend({
27
+ type: zod_1.z.literal("store.updated"),
28
+ data: zod_1.z.object({
29
+ storeId: zod_1.z.string(),
30
+ userId: zod_1.z.string(),
31
+ changes: zod_1.z.record(zod_1.z.unknown()),
32
+ previousValues: zod_1.z.record(zod_1.z.unknown()).optional(),
33
+ }),
34
+ });
35
+ // Compliance Events
36
+ exports.ComplianceViolationDetectedEventSchema = exports.BaseEventSchema.extend({
37
+ type: zod_1.z.literal("compliance.violation.detected"),
38
+ data: zod_1.z.object({
39
+ storeId: zod_1.z.string(),
40
+ violationType: zod_1.z.enum([
41
+ "CONTENT_VIOLATION",
42
+ "POLICY_VIOLATION",
43
+ "BEHAVIOR_VIOLATION",
44
+ ]),
45
+ severity: zod_1.z.enum(["LOW", "MEDIUM", "HIGH", "CRITICAL"]),
46
+ description: zod_1.z.string(),
47
+ evidence: zod_1.z.record(zod_1.z.unknown()).optional(),
48
+ autoAction: zod_1.z.enum(["NONE", "WARNING", "SUSPEND", "BAN"]).optional(),
49
+ }),
50
+ });
51
+ exports.StoreSuspendedEventSchema = exports.BaseEventSchema.extend({
52
+ type: zod_1.z.literal("store.suspended"),
53
+ data: zod_1.z.object({
54
+ storeId: zod_1.z.string(),
55
+ reason: zod_1.z.string(),
56
+ duration: zod_1.z.number().optional(), // Duration in hours, null for indefinite
57
+ suspendedBy: zod_1.z.string(),
58
+ additionalNotes: zod_1.z.string().optional(),
59
+ }),
60
+ });
61
+ exports.StoreUnbannedEventSchema = exports.BaseEventSchema.extend({
62
+ type: zod_1.z.literal("store.unbanned"),
63
+ data: zod_1.z.object({
64
+ storeId: zod_1.z.string(),
65
+ reason: zod_1.z.string(),
66
+ unbannedBy: zod_1.z.string(),
67
+ previousBanReason: zod_1.z.string().optional(),
68
+ additionalNotes: zod_1.z.string().optional(),
69
+ }),
70
+ });
71
+ // Notification Events
72
+ exports.NotificationSendEventSchema = exports.BaseEventSchema.extend({
73
+ type: zod_1.z.literal("notification.send"),
74
+ data: zod_1.z.object({
75
+ recipientId: zod_1.z.string(),
76
+ recipientType: zod_1.z.enum(["USER", "STORE", "ADMIN"]),
77
+ channel: zod_1.z.enum(["EMAIL", "SMS", "IN_APP", "PUSH"]),
78
+ template: zod_1.z.string(),
79
+ templateData: zod_1.z.record(zod_1.z.unknown()),
80
+ priority: zod_1.z.enum(["LOW", "NORMAL", "HIGH", "URGENT"]).default("NORMAL"),
81
+ scheduledFor: zod_1.z.string().optional(), // ISO date string
82
+ }),
83
+ });
84
+ // Audit Events
85
+ exports.AuditLoggedEventSchema = exports.BaseEventSchema.extend({
86
+ type: zod_1.z.literal("audit.logged"),
87
+ data: zod_1.z.object({
88
+ action: zod_1.z.string(),
89
+ resource: zod_1.z.string(),
90
+ resourceId: zod_1.z.string(),
91
+ performedBy: zod_1.z.string(),
92
+ performedByType: zod_1.z.enum(["USER", "SYSTEM", "ADMIN", "SERVICE"]),
93
+ changes: zod_1.z.record(zod_1.z.unknown()).optional(),
94
+ metadata: zod_1.z.record(zod_1.z.unknown()).optional(),
95
+ ip: zod_1.z.string().optional(),
96
+ userAgent: zod_1.z.string().optional(),
97
+ }),
98
+ });
99
+ // Appeal Events
100
+ exports.AppealSubmittedEventSchema = exports.BaseEventSchema.extend({
101
+ type: zod_1.z.literal("appeal.submitted"),
102
+ data: zod_1.z.object({
103
+ appealId: zod_1.z.string(),
104
+ storeId: zod_1.z.string(),
105
+ userId: zod_1.z.string(),
106
+ appealType: zod_1.z.enum([
107
+ "BAN_APPEAL",
108
+ "SUSPENSION_APPEAL",
109
+ "WARNING_APPEAL",
110
+ "POLICY_DISPUTE",
111
+ ]),
112
+ reason: zod_1.z.string(),
113
+ evidence: zod_1.z.array(zod_1.z.string()).optional(), // Array of URLs or file references
114
+ originalViolationId: zod_1.z.string().optional(),
115
+ }),
116
+ });
117
+ exports.AppealReviewedEventSchema = exports.BaseEventSchema.extend({
118
+ type: zod_1.z.literal("appeal.reviewed"),
119
+ data: zod_1.z.object({
120
+ appealId: zod_1.z.string(),
121
+ storeId: zod_1.z.string(),
122
+ reviewedBy: zod_1.z.string(),
123
+ decision: zod_1.z.enum(["APPROVED", "REJECTED", "PARTIALLY_APPROVED"]),
124
+ reasoning: zod_1.z.string(),
125
+ actionTaken: zod_1.z.string().optional(),
126
+ reviewNotes: zod_1.z.string().optional(),
127
+ }),
128
+ });
129
+ // Union type of all events
130
+ // Customer Events
131
+ exports.CustomerCreatedEventSchema = exports.BaseEventSchema.extend({
132
+ type: zod_1.z.literal("customer.created"),
133
+ data: zod_1.z.object({
134
+ customerId: zod_1.z.string(),
135
+ userId: zod_1.z.string(),
136
+ email: zod_1.z.string(),
137
+ firstName: zod_1.z.string(),
138
+ lastName: zod_1.z.string(),
139
+ customerType: zod_1.z.string(),
140
+ registrationSource: zod_1.z.string(),
141
+ storeLocationId: zod_1.z.string().optional(),
142
+ }),
143
+ });
144
+ exports.CustomerUpdatedEventSchema = exports.BaseEventSchema.extend({
145
+ type: zod_1.z.literal("customer.updated"),
146
+ data: zod_1.z.object({
147
+ customerId: zod_1.z.string(),
148
+ userId: zod_1.z.string(),
149
+ changes: zod_1.z.record(zod_1.z.unknown()),
150
+ previousValues: zod_1.z.record(zod_1.z.unknown()),
151
+ registrationSourceChanged: zod_1.z.boolean(),
152
+ }),
153
+ });
154
+ exports.CustomerDeletedEventSchema = exports.BaseEventSchema.extend({
155
+ type: zod_1.z.literal("customer.deleted"),
156
+ data: zod_1.z.object({
157
+ customerId: zod_1.z.string(),
158
+ userId: zod_1.z.string(),
159
+ email: zod_1.z.string(),
160
+ customerType: zod_1.z.string(),
161
+ registrationSource: zod_1.z.string(),
162
+ totalSpent: zod_1.z.string(),
163
+ totalOrders: zod_1.z.number(),
164
+ totalVisits: zod_1.z.number(),
165
+ totalInteractions: zod_1.z.number(),
166
+ }),
167
+ });
168
+ exports.CustomerVisitCreatedEventSchema = exports.BaseEventSchema.extend({
169
+ type: zod_1.z.literal("customer.visit.created"),
170
+ data: zod_1.z.object({
171
+ visitId: zod_1.z.string(),
172
+ customerId: zod_1.z.string(),
173
+ visitType: zod_1.z.string(),
174
+ storeLocationId: zod_1.z.string().optional(),
175
+ outcome: zod_1.z.string().optional(),
176
+ duration: zod_1.z.number().optional(),
177
+ }),
178
+ });
179
+ exports.CustomerInteractionCreatedEventSchema = exports.BaseEventSchema.extend({
180
+ type: zod_1.z.literal("customer.interaction.created"),
181
+ data: zod_1.z.object({
182
+ interactionId: zod_1.z.string(),
183
+ customerId: zod_1.z.string(),
184
+ interactionType: zod_1.z.string(),
185
+ targetType: zod_1.z.string().optional(),
186
+ targetId: zod_1.z.string().optional(),
187
+ outcome: zod_1.z.string().optional(),
188
+ staffId: zod_1.z.string().optional(),
189
+ }),
190
+ });
191
+ exports.CustomerNoteCreatedEventSchema = exports.BaseEventSchema.extend({
192
+ type: zod_1.z.literal("customer.note.created"),
193
+ data: zod_1.z.object({
194
+ noteId: zod_1.z.string(),
195
+ customerId: zod_1.z.string(),
196
+ noteType: zod_1.z.string(),
197
+ priority: zod_1.z.string(),
198
+ isAlert: zod_1.z.boolean(),
199
+ createdBy: zod_1.z.string(),
200
+ }),
201
+ });
202
+ exports.CustomerSupportTicketCreatedEventSchema = exports.BaseEventSchema.extend({
203
+ type: zod_1.z.literal("customer.support.ticket.created"),
204
+ data: zod_1.z.object({
205
+ ticketId: zod_1.z.string(),
206
+ ticketNumber: zod_1.z.string(),
207
+ customerId: zod_1.z.string(),
208
+ subject: zod_1.z.string(),
209
+ category: zod_1.z.string(),
210
+ priority: zod_1.z.string(),
211
+ }),
212
+ });
213
+ exports.CustomerReviewSubmittedEventSchema = exports.BaseEventSchema.extend({
214
+ type: zod_1.z.literal("customer.review.submitted"),
215
+ data: zod_1.z.object({
216
+ reviewId: zod_1.z.string(),
217
+ customerId: zod_1.z.string(),
218
+ targetType: zod_1.z.string(),
219
+ targetId: zod_1.z.string(),
220
+ rating: zod_1.z.number(),
221
+ isVerifiedPurchase: zod_1.z.boolean(),
222
+ }),
223
+ });
224
+ // Order Events
225
+ exports.OrderCreatedEventSchema = exports.BaseEventSchema.extend({
226
+ type: zod_1.z.literal("order.created"),
227
+ data: zod_1.z.object({
228
+ orderId: zod_1.z.string(),
229
+ orderNumber: zod_1.z.string(),
230
+ storeId: zod_1.z.string(),
231
+ customerId: zod_1.z.string().optional(),
232
+ userId: zod_1.z.string().optional(),
233
+ orderType: zod_1.z.string(),
234
+ orderSource: zod_1.z.string(),
235
+ status: zod_1.z.string(),
236
+ totalAmount: zod_1.z.string(),
237
+ currency: zod_1.z.string(),
238
+ itemCount: zod_1.z.number(),
239
+ isGuestOrder: zod_1.z.boolean(),
240
+ paymentMethod: zod_1.z.string().optional(),
241
+ shippingRequired: zod_1.z.boolean(),
242
+ priority: zod_1.z.string(),
243
+ }),
244
+ });
245
+ exports.OrderUpdatedEventSchema = exports.BaseEventSchema.extend({
246
+ type: zod_1.z.literal("order.updated"),
247
+ data: zod_1.z.object({
248
+ orderId: zod_1.z.string(),
249
+ orderNumber: zod_1.z.string(),
250
+ storeId: zod_1.z.string(),
251
+ customerId: zod_1.z.string().optional(),
252
+ changes: zod_1.z.record(zod_1.z.unknown()),
253
+ previousValues: zod_1.z.record(zod_1.z.unknown()),
254
+ statusChanged: zod_1.z.boolean(),
255
+ paymentStatusChanged: zod_1.z.boolean(),
256
+ fulfillmentStatusChanged: zod_1.z.boolean(),
257
+ amountChanged: zod_1.z.boolean(),
258
+ }),
259
+ });
260
+ exports.OrderStatusChangedEventSchema = exports.BaseEventSchema.extend({
261
+ type: zod_1.z.literal("order.status.changed"),
262
+ data: zod_1.z.object({
263
+ orderId: zod_1.z.string(),
264
+ orderNumber: zod_1.z.string(),
265
+ storeId: zod_1.z.string(),
266
+ customerId: zod_1.z.string().optional(),
267
+ fromStatus: zod_1.z.string(),
268
+ toStatus: zod_1.z.string(),
269
+ reason: zod_1.z.string().optional(),
270
+ actorId: zod_1.z.string(),
271
+ actorType: zod_1.z.string(),
272
+ timestamp: zod_1.z.string(),
273
+ }),
274
+ });
275
+ exports.OrderPaymentProcessedEventSchema = exports.BaseEventSchema.extend({
276
+ type: zod_1.z.literal("order.payment.processed"),
277
+ data: zod_1.z.object({
278
+ orderId: zod_1.z.string(),
279
+ paymentId: zod_1.z.string(),
280
+ transactionId: zod_1.z.string().optional(),
281
+ paymentMethod: zod_1.z.string(),
282
+ paymentProvider: zod_1.z.string().optional(),
283
+ amount: zod_1.z.string(),
284
+ currency: zod_1.z.string(),
285
+ status: zod_1.z.string(),
286
+ isSuccessful: zod_1.z.boolean(),
287
+ failureReason: zod_1.z.string().optional(),
288
+ }),
289
+ });
290
+ exports.OrderShippedEventSchema = exports.BaseEventSchema.extend({
291
+ type: zod_1.z.literal("order.shipped"),
292
+ data: zod_1.z.object({
293
+ orderId: zod_1.z.string(),
294
+ fulfillmentId: zod_1.z.string(),
295
+ trackingNumber: zod_1.z.string().optional(),
296
+ trackingUrl: zod_1.z.string().optional(),
297
+ shippingCarrier: zod_1.z.string().optional(),
298
+ shippingService: zod_1.z.string().optional(),
299
+ estimatedDeliveryDate: zod_1.z.string().optional(),
300
+ packedBy: zod_1.z.string().optional(),
301
+ shippedBy: zod_1.z.string().optional(),
302
+ }),
303
+ });
304
+ exports.OrderDeliveredEventSchema = exports.BaseEventSchema.extend({
305
+ type: zod_1.z.literal("order.delivered"),
306
+ data: zod_1.z.object({
307
+ orderId: zod_1.z.string(),
308
+ fulfillmentId: zod_1.z.string(),
309
+ deliveredAt: zod_1.z.string(),
310
+ deliveredBy: zod_1.z.string().optional(),
311
+ signedBy: zod_1.z.string().optional(),
312
+ deliveryLocation: zod_1.z.string().optional(),
313
+ proofOfDelivery: zod_1.z.record(zod_1.z.unknown()).optional(),
314
+ }),
315
+ });
316
+ exports.OrderCancelledEventSchema = exports.BaseEventSchema.extend({
317
+ type: zod_1.z.literal("order.cancelled"),
318
+ data: zod_1.z.object({
319
+ orderId: zod_1.z.string(),
320
+ orderNumber: zod_1.z.string(),
321
+ storeId: zod_1.z.string(),
322
+ customerId: zod_1.z.string().optional(),
323
+ cancellationReason: zod_1.z.string(),
324
+ cancelledBy: zod_1.z.string(),
325
+ cancelledByType: zod_1.z.string(),
326
+ refundRequired: zod_1.z.boolean(),
327
+ refundAmount: zod_1.z.string().optional(),
328
+ inventoryReleased: zod_1.z.boolean(),
329
+ }),
330
+ });
331
+ exports.OrderRefundedEventSchema = exports.BaseEventSchema.extend({
332
+ type: zod_1.z.literal("order.refunded"),
333
+ data: zod_1.z.object({
334
+ orderId: zod_1.z.string(),
335
+ paymentId: zod_1.z.string(),
336
+ refundId: zod_1.z.string(),
337
+ refundAmount: zod_1.z.string(),
338
+ refundReason: zod_1.z.string(),
339
+ refundMethod: zod_1.z.string(),
340
+ isPartialRefund: zod_1.z.boolean(),
341
+ processedBy: zod_1.z.string(),
342
+ customerNotified: zod_1.z.boolean(),
343
+ }),
344
+ });
345
+ exports.OrderNoteAddedEventSchema = exports.BaseEventSchema.extend({
346
+ type: zod_1.z.literal("order.note.added"),
347
+ data: zod_1.z.object({
348
+ orderId: zod_1.z.string(),
349
+ noteId: zod_1.z.string(),
350
+ noteType: zod_1.z.string(),
351
+ content: zod_1.z.string(),
352
+ isCustomerVisible: zod_1.z.boolean(),
353
+ priority: zod_1.z.string(),
354
+ createdBy: zod_1.z.string(),
355
+ createdByName: zod_1.z.string(),
356
+ requiresFollowUp: zod_1.z.boolean(),
357
+ }),
358
+ });
359
+ exports.OrderItemAddedEventSchema = exports.BaseEventSchema.extend({
360
+ type: zod_1.z.literal("order.item.added"),
361
+ data: zod_1.z.object({
362
+ orderId: zod_1.z.string(),
363
+ itemId: zod_1.z.string(),
364
+ productId: zod_1.z.string(),
365
+ variantId: zod_1.z.string().optional(),
366
+ sku: zod_1.z.string(),
367
+ productTitle: zod_1.z.string(),
368
+ quantity: zod_1.z.number(),
369
+ unitPrice: zod_1.z.string(),
370
+ totalPrice: zod_1.z.string(),
371
+ addedBy: zod_1.z.string(),
372
+ }),
373
+ });
374
+ exports.OrderItemRemovedEventSchema = exports.BaseEventSchema.extend({
375
+ type: zod_1.z.literal("order.item.removed"),
376
+ data: zod_1.z.object({
377
+ orderId: zod_1.z.string(),
378
+ itemId: zod_1.z.string(),
379
+ productId: zod_1.z.string(),
380
+ sku: zod_1.z.string(),
381
+ productTitle: zod_1.z.string(),
382
+ quantity: zod_1.z.number(),
383
+ removedBy: zod_1.z.string(),
384
+ removalReason: zod_1.z.string().optional(),
385
+ }),
386
+ });
387
+ exports.OrderDiscountAppliedEventSchema = exports.BaseEventSchema.extend({
388
+ type: zod_1.z.literal("order.discount.applied"),
389
+ data: zod_1.z.object({
390
+ orderId: zod_1.z.string(),
391
+ discountId: zod_1.z.string(),
392
+ discountCode: zod_1.z.string().optional(),
393
+ discountType: zod_1.z.string(),
394
+ discountAmount: zod_1.z.string(),
395
+ discountPercentage: zod_1.z.number().optional(),
396
+ appliedBy: zod_1.z.string().optional(),
397
+ campaignId: zod_1.z.string().optional(),
398
+ }),
399
+ });
400
+ // Subscription Events
401
+ exports.SubscriptionOrderCreatedEventSchema = exports.BaseEventSchema.extend({
402
+ type: zod_1.z.literal("subscription.order.created"),
403
+ data: zod_1.z.object({
404
+ subscriptionId: zod_1.z.string(),
405
+ orderId: zod_1.z.string(),
406
+ orderNumber: zod_1.z.string(),
407
+ storeId: zod_1.z.string(),
408
+ customerId: zod_1.z.string().optional(),
409
+ frequency: zod_1.z.string(),
410
+ planId: zod_1.z.string(),
411
+ totalAmount: zod_1.z.string(),
412
+ correlationId: zod_1.z.string().optional(),
413
+ }),
414
+ });
415
+ exports.SubscriptionRenewedEventSchema = exports.BaseEventSchema.extend({
416
+ type: zod_1.z.literal("subscription.renewed"),
417
+ data: zod_1.z.object({
418
+ subscriptionId: zod_1.z.string(),
419
+ orderId: zod_1.z.string(),
420
+ orderNumber: zod_1.z.string(),
421
+ storeId: zod_1.z.string(),
422
+ customerId: zod_1.z.string().optional(),
423
+ cycle: zod_1.z.number(),
424
+ totalAmount: zod_1.z.string(),
425
+ correlationId: zod_1.z.string().optional(),
426
+ }),
427
+ });
428
+ exports.SubscriptionCancelledEventSchema = exports.BaseEventSchema.extend({
429
+ type: zod_1.z.literal("subscription.cancelled"),
430
+ data: zod_1.z.object({
431
+ subscriptionId: zod_1.z.string(),
432
+ orderId: zod_1.z.string(),
433
+ orderNumber: zod_1.z.string(),
434
+ storeId: zod_1.z.string(),
435
+ customerId: zod_1.z.string().optional(),
436
+ reason: zod_1.z.string().optional(),
437
+ action: zod_1.z.string(),
438
+ parameters: zod_1.z.record(zod_1.z.unknown()).optional(),
439
+ correlationId: zod_1.z.string().optional(),
440
+ }),
441
+ });
442
+ exports.OrderReturnRequestedEventSchema = exports.BaseEventSchema.extend({
443
+ type: zod_1.z.literal("order.return.requested"),
444
+ data: zod_1.z.object({
445
+ orderId: zod_1.z.string(),
446
+ orderNumber: zod_1.z.string(),
447
+ storeId: zod_1.z.string(),
448
+ customerId: zod_1.z.string(),
449
+ returnId: zod_1.z.string(),
450
+ returnType: zod_1.z.string(),
451
+ reason: zod_1.z.string(),
452
+ itemCount: zod_1.z.number(),
453
+ totalAmount: zod_1.z.string().optional(),
454
+ correlationId: zod_1.z.string().optional(),
455
+ }),
456
+ });
457
+ exports.OrderRefundProcessedEventSchema = exports.BaseEventSchema.extend({
458
+ type: zod_1.z.literal("order.refund.processed"),
459
+ data: zod_1.z.object({
460
+ orderId: zod_1.z.string(),
461
+ orderNumber: zod_1.z.string(),
462
+ storeId: zod_1.z.string(),
463
+ customerId: zod_1.z.string().optional(),
464
+ refundId: zod_1.z.string(),
465
+ refundAmount: zod_1.z.string(),
466
+ refundMethod: zod_1.z.string(),
467
+ reason: zod_1.z.string(),
468
+ processedBy: zod_1.z.string(),
469
+ correlationId: zod_1.z.string().optional(),
470
+ }),
471
+ });
472
+ // Kafka topic mappings
473
+ exports.KAFKA_TOPICS = {
474
+ STORE_CREATED: "store.created",
475
+ STORE_UPDATED: "store.updated",
476
+ COMPLIANCE_VIOLATION_DETECTED: "compliance.violation.detected",
477
+ STORE_SUSPENDED: "store.suspended",
478
+ STORE_UNBANNED: "store.unbanned",
479
+ NOTIFICATION_SEND: "notification.send",
480
+ AUDIT_LOGGED: "audit.logged",
481
+ APPEAL_SUBMITTED: "appeal.submitted",
482
+ APPEAL_REVIEWED: "appeal.reviewed",
483
+ // Order service topics
484
+ ORDER_CREATED: "order.created",
485
+ ORDER_UPDATED: "order.updated",
486
+ ORDER_STATUS_CHANGED: "order.status.changed",
487
+ ORDER_PAYMENT_PROCESSED: "order.payment.processed",
488
+ ORDER_SHIPPED: "order.shipped",
489
+ ORDER_DELIVERED: "order.delivered",
490
+ ORDER_CANCELLED: "order.cancelled",
491
+ ORDER_REFUNDED: "order.refunded",
492
+ ORDER_NOTE_ADDED: "order.note.added",
493
+ ORDER_ITEM_ADDED: "order.item.added",
494
+ ORDER_ITEM_REMOVED: "order.item.removed",
495
+ ORDER_DISCOUNT_APPLIED: "order.discount.applied",
496
+ // Customer service topics
497
+ CUSTOMER_CREATED: "customer.created",
498
+ CUSTOMER_UPDATED: "customer.updated",
499
+ CUSTOMER_DELETED: "customer.deleted",
500
+ CUSTOMER_VISIT_CREATED: "customer.visit.created",
501
+ CUSTOMER_INTERACTION_CREATED: "customer.interaction.created",
502
+ CUSTOMER_NOTE_CREATED: "customer.note.created",
503
+ CUSTOMER_SUPPORT_TICKET_CREATED: "customer.support.ticket.created",
504
+ CUSTOMER_REVIEW_SUBMITTED: "customer.review.submitted",
505
+ };
@@ -0,0 +1,12 @@
1
+ import type { FastifyReply } from "fastify";
2
+ export declare class APIError extends Error {
3
+ statusCode: number;
4
+ details?: unknown;
5
+ constructor(message: string, statusCode?: number, details?: unknown);
6
+ }
7
+ /**
8
+ * Handles API errors in a unified way.
9
+ * @param {FastifyReply} reply The Fastify reply object.
10
+ * @param {APIError} error The API error object.
11
+ */
12
+ export declare const handleAPIError: (reply: FastifyReply, error: APIError | Error) => void;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleAPIError = exports.APIError = void 0;
4
+ class APIError extends Error {
5
+ constructor(message, statusCode = 400, details) {
6
+ super(message);
7
+ this.statusCode = statusCode;
8
+ this.details = details;
9
+ }
10
+ }
11
+ exports.APIError = APIError;
12
+ /**
13
+ * Handles API errors in a unified way.
14
+ * @param {FastifyReply} reply The Fastify reply object.
15
+ * @param {APIError} error The API error object.
16
+ */
17
+ const handleAPIError = (reply, error) => {
18
+ // Default status code
19
+ let statusCode = 500;
20
+ let details;
21
+ // If it's an APIError, use its status code and details
22
+ if (error instanceof APIError) {
23
+ statusCode = error.statusCode || 500;
24
+ details = error.details;
25
+ }
26
+ // Ensure there's always a message
27
+ const message = error.message || "An unexpected error occurred";
28
+ reply.status(statusCode).send({
29
+ success: false,
30
+ message,
31
+ ...(details ? { details } : {}),
32
+ });
33
+ // Log the error for debugging
34
+ console.error(`[API Error] ${statusCode}: ${message}`, details || "");
35
+ };
36
+ exports.handleAPIError = handleAPIError;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Checks if a subdomain is available.
3
+ * @param subdomain The subdomain to check.
4
+ * @returns {Promise<boolean>} True if available, false if taken.
5
+ */
6
+ export declare const isSubdomainAvailable: (subdomain: string) => Promise<boolean>;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isSubdomainAvailable = void 0;
4
+ const drizzle_orm_1 = require("drizzle-orm");
5
+ const db_1 = require("../lib/db");
6
+ const store_schema_1 = require("../schemas/store/store-schema");
7
+ /**
8
+ * Checks if a subdomain is available.
9
+ * @param subdomain The subdomain to check.
10
+ * @returns {Promise<boolean>} True if available, false if taken.
11
+ */
12
+ const isSubdomainAvailable = async (subdomain) => {
13
+ const existingStore = await db_1.db
14
+ .select()
15
+ .from(store_schema_1.stores)
16
+ .where((0, drizzle_orm_1.eq)(store_schema_1.stores.subdomain, subdomain))
17
+ .limit(1);
18
+ return existingStore.length === 0;
19
+ };
20
+ exports.isSubdomainAvailable = isSubdomainAvailable;
package/nul ADDED
@@ -0,0 +1,8 @@
1
+ At line:1 char:40
2
+ + Get-NetTCPConnection -LocalPort 3005 2> | Select-Object LocalAddress, ...
3
+ + ~
4
+ Missing file specification after redirection operator.
5
+ + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordEx
6
+ ception
7
+ + FullyQualifiedErrorId : MissingFileSpecification
8
+
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@axova/shared",
3
+ "version": "1.0.0",
4
+ "description": "Shared utilities, models, and libraries for Axova platform",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "dev": "tsc --watch",
10
+ "clean": "rm -rf dist",
11
+ "prepare": "npm run build"
12
+ },
13
+ "keywords": [
14
+ "axova",
15
+ "shared",
16
+ "utilities",
17
+ "models"
18
+ ],
19
+ "author": "Axova Team",
20
+ "license": "MIT",
21
+ "dependencies": {
22
+ "@paralleldrive/cuid2": "^2.2.2",
23
+ "@types/jsonwebtoken": "^9.0.9",
24
+ "@types/uuid": "^11.0.0",
25
+ "better-middleware": "^0.0.1",
26
+ "dotenv": "^16.6.1",
27
+ "jsonwebtoken": "^9.0.2",
28
+ "kafkajs": "^2.2.4",
29
+ "pg": "^8.16.3",
30
+ "uuid": "^13.0.0",
31
+ "zod": "^3.25.76"
32
+ },
33
+
34
+ "devDependencies": {
35
+ "@types/node": "^20.10.5",
36
+ "@types/pg": "^8.10.9",
37
+ "typescript": "^5.3.3"
38
+ },
39
+ "peerDependencies": {
40
+ "fastify": "^5.2.1",
41
+ "drizzle-orm": "^0.39.3"
42
+ }
43
+ }