@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,311 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KAFKA_TOPICS = exports.AxovaKafka = void 0;
4
+ exports.createKafkaInstance = createKafkaInstance;
5
+ exports.getKafkaInstance = getKafkaInstance;
6
+ exports.getKafkaConfigFromEnv = getKafkaConfigFromEnv;
7
+ const cuid2_1 = require("@paralleldrive/cuid2");
8
+ const kafkajs_1 = require("kafkajs");
9
+ const events_1 = require("../types/events");
10
+ Object.defineProperty(exports, "KAFKA_TOPICS", { enumerable: true, get: function () { return events_1.KAFKA_TOPICS; } });
11
+ // Kafka client wrapper
12
+ class AxovaKafka {
13
+ constructor(config) {
14
+ this.producer = null;
15
+ this.consumers = new Map();
16
+ this.eventHandlers = new Map();
17
+ const kafkaConfig = {
18
+ clientId: config.clientId,
19
+ brokers: config.brokers,
20
+ };
21
+ if (config.ssl) {
22
+ kafkaConfig.ssl = config.ssl;
23
+ }
24
+ if (config.sasl) {
25
+ kafkaConfig.sasl = config.sasl;
26
+ }
27
+ this.kafka = new kafkajs_1.Kafka(kafkaConfig);
28
+ }
29
+ // Initialize producer with optimized settings for high throughput and reliability
30
+ async initializeProducer(config) {
31
+ if (this.producer)
32
+ return;
33
+ const optimizedConfig = {
34
+ // Idempotency ensures exactly-once semantics
35
+ idempotent: true,
36
+ // Allow up to 5 requests in flight for better throughput
37
+ // (safe with idempotent=true)
38
+ maxInFlightRequests: 5,
39
+ // Batching configuration for better throughput
40
+ allowAutoTopicCreation: false,
41
+ transactionTimeout: 60000,
42
+ // Retry configuration
43
+ retry: {
44
+ initialRetryTime: 100,
45
+ retries: 10,
46
+ maxRetryTime: 30000,
47
+ multiplier: 2,
48
+ factor: 0.2,
49
+ },
50
+ // Override with user config if provided
51
+ ...config,
52
+ };
53
+ this.producer = this.kafka.producer(optimizedConfig);
54
+ await this.producer.connect();
55
+ console.log("✅ Kafka producer connected with optimized settings");
56
+ console.log(" • Idempotent: enabled");
57
+ console.log(" • Max in-flight: 5");
58
+ }
59
+ // Initialize consumer with optimized settings for throughput and reliability
60
+ async initializeConsumer(groupId, topics, config) {
61
+ if (this.consumers.has(groupId))
62
+ return;
63
+ const optimizedConfig = {
64
+ groupId,
65
+ // Session timeout - how long broker waits before considering consumer dead
66
+ sessionTimeout: 30000,
67
+ // Rebalance timeout - max time for rebalancing
68
+ rebalanceTimeout: 60000,
69
+ // Heartbeat interval - how often to send heartbeats
70
+ heartbeatInterval: 3000,
71
+ // Retry configuration
72
+ retry: {
73
+ initialRetryTime: 100,
74
+ retries: 10,
75
+ maxRetryTime: 30000,
76
+ multiplier: 2,
77
+ factor: 0.2,
78
+ },
79
+ // Auto-commit configuration
80
+ // Note: For critical applications, consider manual commits
81
+ // autoCommit: false,
82
+ // autoCommitInterval: 5000,
83
+ // Performance tuning
84
+ maxBytesPerPartition: 1048576, // 1MB
85
+ maxWaitTimeInMs: 500, // Wait up to 500ms for batch
86
+ // Override with user config if provided
87
+ ...config,
88
+ };
89
+ const consumer = this.kafka.consumer(optimizedConfig);
90
+ await consumer.connect();
91
+ await consumer.subscribe({
92
+ topics: topics,
93
+ fromBeginning: false,
94
+ });
95
+ this.consumers.set(groupId, consumer);
96
+ console.log(`✅ Kafka consumer connected for group: ${groupId}`);
97
+ console.log(` • Topics: ${topics.join(", ")}`);
98
+ console.log(" • Session timeout: 30s");
99
+ console.log(" • Max bytes per partition: 1MB");
100
+ }
101
+ // Publish event with optimized batching and error handling
102
+ async publishEvent(topic, event) {
103
+ if (!this.producer) {
104
+ throw new Error("Producer not initialized. Call initializeProducer() first.");
105
+ }
106
+ // Ensure all header values are strings (KafkaJS requirement)
107
+ const headers = {};
108
+ if (event.type)
109
+ headers.eventType = String(event.type);
110
+ if (event.source)
111
+ headers.source = String(event.source);
112
+ if (event.version)
113
+ headers.version = String(event.version);
114
+ const message = {
115
+ key: event.id || (0, cuid2_1.createId)(), // Use event ID or generate a new one as string key
116
+ value: JSON.stringify(event),
117
+ timestamp: Date.now().toString(),
118
+ headers,
119
+ };
120
+ try {
121
+ const result = await this.producer.send({
122
+ topic,
123
+ messages: [message],
124
+ // Require acknowledgment from all in-sync replicas for durability
125
+ acks: -1, // Wait for all in-sync replicas
126
+ timeout: 30000,
127
+ compression: 1, // LZ4 compression
128
+ });
129
+ console.log(`✅ Event published successfully to ${topic}:`, event.type);
130
+ console.log(` • Partition: ${result[0].partition}, Offset: ${result[0].baseOffset}`);
131
+ }
132
+ catch (error) {
133
+ console.error(`❌ Failed to publish event to ${topic}:`, error);
134
+ if (error instanceof Error) {
135
+ if (error.message.includes("UNKNOWN_TOPIC_OR_PARTITION")) {
136
+ console.error(` • Topic '${topic}' does not exist. Create it manually or enable auto-creation.`);
137
+ }
138
+ else if (error.message.includes("NOT_LEADER_FOR_PARTITION")) {
139
+ console.error(" • Kafka cluster leadership issue. Check broker status.");
140
+ }
141
+ else if (error.message.includes("NOT_ENOUGH_REPLICAS")) {
142
+ console.error(" • Not enough in-sync replicas available. Check broker health.");
143
+ }
144
+ else if (error.message.includes("REQUEST_TIMED_OUT")) {
145
+ console.error(" • Request timed out. Check network and broker performance.");
146
+ }
147
+ }
148
+ throw error;
149
+ }
150
+ }
151
+ // Batch publish events for higher throughput
152
+ async publishEventsBatch(topic, events) {
153
+ if (!this.producer) {
154
+ throw new Error("Producer not initialized. Call initializeProducer() first.");
155
+ }
156
+ if (events.length === 0)
157
+ return;
158
+ const messages = events.map((event) => {
159
+ const headers = {};
160
+ if (event.type)
161
+ headers.eventType = String(event.type);
162
+ if (event.source)
163
+ headers.source = String(event.source);
164
+ if (event.version)
165
+ headers.version = String(event.version);
166
+ return {
167
+ key: event.id || (0, cuid2_1.createId)(),
168
+ value: JSON.stringify(event),
169
+ timestamp: Date.now().toString(),
170
+ headers,
171
+ };
172
+ });
173
+ try {
174
+ const result = await this.producer.send({
175
+ topic,
176
+ messages,
177
+ acks: -1,
178
+ timeout: 30000,
179
+ compression: 1,
180
+ });
181
+ console.log(`✅ Batch published ${events.length} events to ${topic}`);
182
+ console.log(` • Partitions used: ${result.length}`);
183
+ }
184
+ catch (error) {
185
+ console.error(`❌ Failed to batch publish events to ${topic}:`, error);
186
+ throw error;
187
+ }
188
+ }
189
+ // Subscribe to events
190
+ onEvent(eventType, handler) {
191
+ const handlers = this.eventHandlers.get(eventType) || [];
192
+ handlers.push(handler);
193
+ this.eventHandlers.set(eventType, handlers);
194
+ }
195
+ // Start consuming events with optimized batch processing
196
+ async startConsuming(groupId) {
197
+ const consumer = this.consumers.get(groupId);
198
+ if (!consumer) {
199
+ throw new Error(`Consumer for group ${groupId} not initialized`);
200
+ }
201
+ await consumer.run({
202
+ // Process messages in batches for better throughput
203
+ // Can be configured per service based on requirements
204
+ partitionsConsumedConcurrently: 3, // Process 3 partitions concurrently
205
+ eachMessage: async ({ topic, partition, message, }) => {
206
+ const startTime = Date.now();
207
+ try {
208
+ if (!message.value)
209
+ return;
210
+ const event = JSON.parse(message.value.toString());
211
+ const handlers = this.eventHandlers.get(event.type) || [];
212
+ if (handlers.length === 0) {
213
+ console.warn(`⚠️ No handlers registered for event type: ${event.type}`);
214
+ return;
215
+ }
216
+ // Execute all handlers for this event type
217
+ const handlerPromises = handlers.map(async (handler) => {
218
+ try {
219
+ await handler(event);
220
+ }
221
+ catch (handlerError) {
222
+ console.error(`❌ Handler error for event ${event.type}:`, handlerError);
223
+ // Log error but don't throw - allows other handlers to execute
224
+ // TODO: Consider implementing dead letter queue for failed handlers
225
+ }
226
+ });
227
+ // Wait for all handlers to complete
228
+ await Promise.allSettled(handlerPromises);
229
+ const processingTime = Date.now() - startTime;
230
+ console.log(`✅ Processed ${handlers.length} handler(s) for event: ${event.type} (${processingTime}ms)`);
231
+ }
232
+ catch (error) {
233
+ const processingTime = Date.now() - startTime;
234
+ console.error(`❌ Failed to process message from ${topic} [partition ${partition}] (${processingTime}ms):`, error);
235
+ // TODO: Implement dead letter queue for failed messages
236
+ // For now, the message will be retried based on consumer config
237
+ }
238
+ },
239
+ });
240
+ console.log(`✅ Started consuming events for group: ${groupId}`);
241
+ console.log(" • Processing 3 partitions concurrently");
242
+ console.log(" • Handlers execute in parallel per message");
243
+ }
244
+ // Disconnect all connections
245
+ async disconnect() {
246
+ if (this.producer) {
247
+ await this.producer.disconnect();
248
+ this.producer = null;
249
+ }
250
+ for (const [_groupId, consumer] of this.consumers.entries()) {
251
+ await consumer.disconnect();
252
+ }
253
+ this.consumers.clear();
254
+ console.log("All Kafka connections disconnected");
255
+ }
256
+ // Utility method to create event with base properties
257
+ createEvent(type, data, source) {
258
+ // Validate required fields
259
+ if (!type) {
260
+ throw new Error("Event type is required for Kafka event creation");
261
+ }
262
+ if (!source) {
263
+ throw new Error("Event source is required for Kafka event creation");
264
+ }
265
+ return {
266
+ id: (0, cuid2_1.createId)(),
267
+ timestamp: new Date().toISOString(),
268
+ source: String(source),
269
+ version: "1.0",
270
+ type: String(type),
271
+ data: data || {},
272
+ };
273
+ }
274
+ }
275
+ exports.AxovaKafka = AxovaKafka;
276
+ // Singleton factory for Kafka instance
277
+ let kafkaInstance = null;
278
+ function createKafkaInstance(config) {
279
+ if (!kafkaInstance) {
280
+ kafkaInstance = new AxovaKafka(config);
281
+ }
282
+ return kafkaInstance;
283
+ }
284
+ function getKafkaInstance() {
285
+ if (!kafkaInstance) {
286
+ throw new Error("Kafka instance not created. Call createKafkaInstance() first.");
287
+ }
288
+ return kafkaInstance;
289
+ }
290
+ // Utility function to get Kafka config from environment
291
+ function getKafkaConfigFromEnv() {
292
+ const brokers = process.env.KAFKA_BROKERS?.split(",") || ["localhost:9092"];
293
+ const clientId = process.env.KAFKA_CLIENT_ID || "axova-service";
294
+ const config = {
295
+ brokers,
296
+ clientId,
297
+ };
298
+ // Add SSL if configured
299
+ if (process.env.KAFKA_SSL === "true") {
300
+ config.ssl = true;
301
+ }
302
+ // Add SASL if configured
303
+ if (process.env.KAFKA_USERNAME && process.env.KAFKA_PASSWORD) {
304
+ config.sasl = {
305
+ mechanism: "plain",
306
+ username: process.env.KAFKA_USERNAME,
307
+ password: process.env.KAFKA_PASSWORD,
308
+ };
309
+ }
310
+ return config;
311
+ }
@@ -0,0 +1,13 @@
1
+ export * from "./configs";
2
+ export * from "./events/kafka";
3
+ export * from "./lib/auditLogger";
4
+ export * from "./lib/authOrganization";
5
+ export { db, pool } from "./lib/db";
6
+ export * from "./middleware/serviceAuth";
7
+ export * from "./middleware/storeOwnership";
8
+ export * from "./middleware/storeValidationMiddleware";
9
+ export * from "./middleware/userAuth";
10
+ export * from "./schemas";
11
+ export * from "./types/events";
12
+ export * from "./utils/errorHandler";
13
+ export * from "./utils/subdomain";
package/dist/index.js ADDED
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ // Database
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
16
+ };
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.pool = exports.db = void 0;
19
+ // Service Configuration Profiles
20
+ __exportStar(require("./configs"), exports);
21
+ // Kafka Events and Utilities
22
+ __exportStar(require("./events/kafka"), exports);
23
+ // Audit Logging
24
+ __exportStar(require("./lib/auditLogger"), exports);
25
+ // Auth Organization
26
+ __exportStar(require("./lib/authOrganization"), exports);
27
+ var db_1 = require("./lib/db");
28
+ Object.defineProperty(exports, "db", { enumerable: true, get: function () { return db_1.db; } });
29
+ Object.defineProperty(exports, "pool", { enumerable: true, get: function () { return db_1.pool; } });
30
+ // Service Authentication
31
+ __exportStar(require("./middleware/serviceAuth"), exports);
32
+ __exportStar(require("./middleware/storeOwnership"), exports);
33
+ __exportStar(require("./middleware/storeValidationMiddleware"), exports);
34
+ __exportStar(require("./middleware/userAuth"), exports);
35
+ // Schemas - Organized by Service
36
+ __exportStar(require("./schemas"), exports);
37
+ // Types and Interfaces
38
+ __exportStar(require("./types/events"), exports);
39
+ // Utilities
40
+ __exportStar(require("./utils/errorHandler"), exports);
41
+ __exportStar(require("./utils/subdomain"), exports);
@@ -0,0 +1,85 @@
1
+ export interface CustomerServiceConfig {
2
+ serviceName: string;
3
+ version: string;
4
+ events: CustomerServiceEvents;
5
+ }
6
+ export interface CustomerServiceEvents {
7
+ CUSTOMER_CREATED: "customer.created";
8
+ CUSTOMER_UPDATED: "customer.updated";
9
+ CUSTOMER_DELETED: "customer.deleted";
10
+ CUSTOMER_VISIT_CREATED: "customer.visit.created";
11
+ CUSTOMER_INTERACTION_CREATED: "customer.interaction.created";
12
+ CUSTOMER_NOTE_CREATED: "customer.note.created";
13
+ CUSTOMER_SUPPORT_TICKET_CREATED: "customer.support.ticket.created";
14
+ CUSTOMER_REVIEW_SUBMITTED: "customer.review.submitted";
15
+ }
16
+ export type CustomerEventType = "customer.created" | "customer.updated" | "customer.deleted" | "customer.visit.created" | "customer.interaction.created" | "customer.note.created" | "customer.support.ticket.created" | "customer.review.submitted";
17
+ export interface CustomerCreatedEvent {
18
+ customerId: string;
19
+ userId: string;
20
+ email: string;
21
+ firstName: string;
22
+ lastName: string;
23
+ customerType: string;
24
+ registrationSource: string;
25
+ storeLocationId?: string;
26
+ }
27
+ export interface CustomerUpdatedEvent {
28
+ customerId: string;
29
+ userId: string;
30
+ changes: Record<string, unknown>;
31
+ previousValues: Record<string, unknown>;
32
+ registrationSourceChanged: boolean;
33
+ }
34
+ export interface CustomerDeletedEvent {
35
+ customerId: string;
36
+ userId: string;
37
+ email: string;
38
+ customerType: string;
39
+ registrationSource: string;
40
+ totalSpent: string;
41
+ totalOrders: number;
42
+ totalVisits: number;
43
+ totalInteractions: number;
44
+ }
45
+ export interface CustomerVisitCreatedEvent {
46
+ visitId: string;
47
+ customerId: string;
48
+ visitType: string;
49
+ storeLocationId?: string;
50
+ outcome?: string;
51
+ duration?: number;
52
+ }
53
+ export interface CustomerInteractionCreatedEvent {
54
+ interactionId: string;
55
+ customerId: string;
56
+ interactionType: string;
57
+ targetType?: string;
58
+ targetId?: string;
59
+ outcome?: string;
60
+ staffId?: string;
61
+ }
62
+ export interface CustomerNoteCreatedEvent {
63
+ noteId: string;
64
+ customerId: string;
65
+ noteType: string;
66
+ priority: string;
67
+ isAlert: boolean;
68
+ createdBy: string;
69
+ }
70
+ export interface CustomerSupportTicketCreatedEvent {
71
+ ticketId: string;
72
+ ticketNumber: string;
73
+ customerId: string;
74
+ subject: string;
75
+ category: string;
76
+ priority: string;
77
+ }
78
+ export interface CustomerReviewSubmittedEvent {
79
+ reviewId: string;
80
+ customerId: string;
81
+ targetType: string;
82
+ targetId: string;
83
+ rating: number;
84
+ isVerifiedPurchase: boolean;
85
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });