@legible-sync/example-eda 1.2.0 → 1.3.1

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 (28) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/LICENSE +24 -0
  3. package/__tests__/integration/ecommerce-flow.test.ts +1 -0
  4. package/__tests__/integration/syncs.test.ts +438 -0
  5. package/dist/plugins/analytics/concepts/Analytics.d.ts.map +1 -1
  6. package/dist/plugins/analytics/concepts/Analytics.js +5 -0
  7. package/dist/plugins/analytics/concepts/Analytics.js.map +1 -1
  8. package/dist/plugins/inventory/concepts/Inventory.d.ts.map +1 -1
  9. package/dist/plugins/inventory/concepts/Inventory.js +15 -5
  10. package/dist/plugins/inventory/concepts/Inventory.js.map +1 -1
  11. package/dist/plugins/notifications/concepts/Notification.d.ts.map +1 -1
  12. package/dist/plugins/notifications/concepts/Notification.js +4 -0
  13. package/dist/plugins/notifications/concepts/Notification.js.map +1 -1
  14. package/dist/plugins/orders/concepts/Order.d.ts.map +1 -1
  15. package/dist/plugins/orders/concepts/Order.js +8 -3
  16. package/dist/plugins/orders/concepts/Order.js.map +1 -1
  17. package/dist/plugins/payments/concepts/Payment.d.ts.map +1 -1
  18. package/dist/plugins/payments/concepts/Payment.js +5 -0
  19. package/dist/plugins/payments/concepts/Payment.js.map +1 -1
  20. package/eda_output.txt +3963 -0
  21. package/jest.config.js +18 -0
  22. package/package.json +3 -3
  23. package/src/plugins/analytics/concepts/Analytics.ts +6 -0
  24. package/src/plugins/analytics/syncs/analytics-events.sync.ts +2 -1
  25. package/src/plugins/inventory/concepts/Inventory.ts +16 -5
  26. package/src/plugins/notifications/concepts/Notification.ts +5 -0
  27. package/src/plugins/orders/concepts/Order.ts +9 -3
  28. package/src/plugins/payments/concepts/Payment.ts +6 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,30 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ ## [1.3.0](https://github.com/mastepanoski/legiblesync/compare/v1.2.0...v1.3.0) (2025-11-21)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * add publishConfig for EDA package to enable public publishing ([c8910cd](https://github.com/mastepanoski/legiblesync/commit/c8910cd3f6011ceeb8fecce81faa942f1c8200a3))
12
+ * add publishConfig for example packages to enable public publishing ([dd6666c](https://github.com/mastepanoski/legiblesync/commit/dd6666c2d64ab7b588b29dcee58841d7c8ee2a3f))
13
+ * resolve Next.js SSE field name translation and test isolation ([d0bc29f](https://github.com/mastepanoski/legiblesync/commit/d0bc29fa6c00ac5239f3faaa25c4cc52a68c5446))
14
+
15
+
16
+ ### Features
17
+
18
+ * implement SQLite queue system and parser ([f8e2f20](https://github.com/mastepanoski/legiblesync/commit/f8e2f20926bd4b49ccd9b73d1cb629cd47a3dd1e))
19
+
20
+
21
+
22
+
23
+
24
+ ## [1.2.2](https://github.com/mastepanoski/legiblesync/compare/v1.2.0...v1.2.2) (2025-11-11)
25
+
26
+
27
+ ### Bug Fixes
28
+
29
+ * add publishConfig for EDA package to enable public publishing ([c8910cd](https://github.com/mastepanoski/legiblesync/commit/c8910cd3f6011ceeb8fecce81faa942f1c8200a3))
30
+ * resolve Next.js SSE field name translation and test isolation ([d0bc29f](https://github.com/mastepanoski/legiblesync/commit/d0bc29fa6c00ac5239f3faaa25c4cc52a68c5446))
package/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Mauro Stepanoski
4
+
5
+ Implementation of the "What You See Is What It Does" architectural pattern
6
+ based on the research paper by Eagon Meng and Daniel Jackson.
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ of this software and associated documentation files (the "Software"), to deal
10
+ in the Software without restriction, including without limitation the rights
11
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ copies of the Software, and to permit persons to whom the Software is
13
+ furnished to do so, subject to the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be included in all
16
+ copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ SOFTWARE.
@@ -49,6 +49,7 @@ describe('E-commerce Flow Integration', () => {
49
49
  // Reset concept states for test isolation
50
50
  await engine.invoke('User', 'reset', {}, 'reset');
51
51
  await engine.invoke('Product', 'reset', {}, 'reset');
52
+ await engine.invoke('Analytics', 'reset', {}, 'reset');
52
53
  });
53
54
 
54
55
  describe('Complete User Registration Flow', () => {
@@ -0,0 +1,438 @@
1
+ import { LegibleEngine } from '@legible-sync/core';
2
+ import { PluginManager } from '../../src/core/PluginManager';
3
+ import { EventBus } from '../../src/core/EventBus';
4
+ import { usersPlugin } from '../../src/plugins/users';
5
+ import { productsPlugin } from '../../src/plugins/products';
6
+ import { ordersPlugin } from '../../src/plugins/orders';
7
+ import { inventoryPlugin } from '../../src/plugins/inventory';
8
+ import { notificationsPlugin } from '../../src/plugins/notifications';
9
+ import { analyticsPlugin } from '../../src/plugins/analytics';
10
+ import { paymentsPlugin } from '../../src/plugins/payments';
11
+
12
+ // Mock concepts to track when their execute methods are called
13
+ const createMockConcept = (originalConcept: any, conceptName: string) => {
14
+ const executeSpy = jest.fn(originalConcept.execute.bind(originalConcept));
15
+ return {
16
+ ...originalConcept,
17
+ execute: executeSpy,
18
+ __spy: executeSpy,
19
+ __name: conceptName
20
+ };
21
+ };
22
+
23
+ describe('EDA Sync Rules Integration Tests', () => {
24
+ let engine: LegibleEngine;
25
+ let pluginManager: PluginManager;
26
+ let eventBus: EventBus;
27
+ let mockConcepts: { [key: string]: any };
28
+
29
+ beforeEach(async () => {
30
+ engine = new LegibleEngine();
31
+ pluginManager = new PluginManager(engine);
32
+ eventBus = new EventBus();
33
+
34
+ // Create mock EventBus concept
35
+ const mockEventBus = createMockConcept({
36
+ state: {},
37
+ async execute(action: string, input: any) {
38
+ if (action === 'publish') {
39
+ const { event, data } = input;
40
+ await eventBus.publish({
41
+ type: event,
42
+ payload: data,
43
+ source: 'system',
44
+ flowId: input.flowId || 'system'
45
+ });
46
+ return { published: true };
47
+ }
48
+ throw new Error(`Unknown EventBus action: ${action}`);
49
+ }
50
+ }, 'EventBus');
51
+
52
+ // Register EventBus as a concept
53
+ engine.registerConcept('EventBus', mockEventBus);
54
+
55
+ // Create mock concepts for all plugins
56
+ mockConcepts = {
57
+ EventBus: mockEventBus
58
+ };
59
+
60
+ // Load all plugins
61
+ await pluginManager.loadPlugin(usersPlugin);
62
+ await pluginManager.loadPlugin(productsPlugin);
63
+ await pluginManager.loadPlugin(inventoryPlugin);
64
+ await pluginManager.loadPlugin(ordersPlugin);
65
+ await pluginManager.loadPlugin(paymentsPlugin);
66
+ await pluginManager.loadPlugin(notificationsPlugin);
67
+ await pluginManager.loadPlugin(analyticsPlugin);
68
+
69
+ // Reset concept states for test isolation
70
+ await engine.invoke('User', 'reset', {}, 'reset');
71
+ await engine.invoke('Product', 'reset', {}, 'reset');
72
+ await engine.invoke('Order', 'reset', {}, 'reset');
73
+ await engine.invoke('Inventory', 'reset', {}, 'reset');
74
+ await engine.invoke('Notification', 'reset', {}, 'reset');
75
+ await engine.invoke('Analytics', 'reset', {}, 'reset');
76
+ await engine.invoke('Payment', 'reset', {}, 'reset');
77
+ });
78
+
79
+ afterEach(() => {
80
+ // Clear all mocks
81
+ Object.values(mockConcepts).forEach(concept => {
82
+ if (concept.__spy) {
83
+ concept.__spy.mockClear();
84
+ }
85
+ });
86
+ });
87
+
88
+ describe('User Event Syncs', () => {
89
+ it('should call EventBus.publish when User.register succeeds', async () => {
90
+ const flow = 'user-register-flow';
91
+
92
+ // Register a user
93
+ await engine.invoke('User', 'register', {
94
+ username: 'johndoe',
95
+ email: 'john@example.com',
96
+ password: 'password123'
97
+ }, flow);
98
+
99
+ // Check that EventBus.publish was called with user.registered event
100
+ expect(mockConcepts.EventBus.__spy).toHaveBeenCalledWith('publish', {
101
+ event: 'user.registered',
102
+ data: {
103
+ userId: expect.any(String),
104
+ username: 'johndoe',
105
+ email: 'john@example.com'
106
+ }
107
+ });
108
+ });
109
+ });
110
+
111
+ describe('Product Event Syncs', () => {
112
+ it('should call EventBus.publish when Product.create succeeds', async () => {
113
+ const flow = 'product-create-flow';
114
+
115
+ // Create a product
116
+ await engine.invoke('Product', 'create', {
117
+ name: 'Test Product',
118
+ sku: 'TEST-001',
119
+ price: 29.99,
120
+ description: 'A test product',
121
+ category: 'test'
122
+ }, flow);
123
+
124
+ // Check that EventBus.publish was called with product.created event
125
+ expect(mockConcepts.EventBus.__spy).toHaveBeenCalledWith('publish', {
126
+ event: 'product.created',
127
+ data: {
128
+ productId: expect.any(String),
129
+ name: 'Test Product',
130
+ sku: 'TEST-001',
131
+ price: 29.99,
132
+ category: 'test'
133
+ }
134
+ });
135
+ });
136
+ });
137
+
138
+ describe('Order Workflow Syncs', () => {
139
+ let userId: string;
140
+ let productId: string;
141
+
142
+ beforeEach(async () => {
143
+ // Create user
144
+ const userResult = await engine.invoke('User', 'register', {
145
+ username: 'testuser',
146
+ email: 'test@example.com',
147
+ password: 'password123'
148
+ }, 'setup-user');
149
+ userId = userResult.userId;
150
+
151
+ // Create product
152
+ const productResult = await engine.invoke('Product', 'create', {
153
+ name: 'Test Product',
154
+ sku: 'TEST-001',
155
+ price: 29.99,
156
+ category: 'test'
157
+ }, 'setup-product');
158
+ productId = productResult.productId;
159
+
160
+ // Set inventory
161
+ await engine.invoke('Inventory', 'setStock', {
162
+ productId,
163
+ quantity: 10
164
+ }, 'setup-inventory');
165
+ });
166
+
167
+ it('should call Inventory.checkAvailability when Order.create succeeds', async () => {
168
+ const flow = 'order-create-flow';
169
+
170
+ // Create order
171
+ await engine.invoke('Order', 'create', {
172
+ userId,
173
+ items: [
174
+ {
175
+ productId,
176
+ quantity: 2,
177
+ price: 29.99
178
+ }
179
+ ]
180
+ }, flow);
181
+
182
+ // Wait for async operations
183
+ await new Promise(resolve => setTimeout(resolve, 50));
184
+
185
+ // Get the actions that were executed
186
+ const actions = engine.getActionsByFlow(flow);
187
+
188
+ // Check that Inventory.checkAvailability was called
189
+ const inventoryCheckAction = actions.find(a =>
190
+ a.concept === 'Inventory' && a.action === 'checkAvailability'
191
+ );
192
+ expect(inventoryCheckAction).toBeDefined();
193
+ expect(inventoryCheckAction!.input).toEqual({
194
+ orderId: expect.any(String),
195
+ items: [
196
+ {
197
+ productId,
198
+ quantity: 2,
199
+ price: 29.99
200
+ }
201
+ ]
202
+ });
203
+ });
204
+
205
+ it('should call Order.confirm when Inventory.checkAvailability returns available=true', async () => {
206
+ const flow = 'order-confirm-flow';
207
+
208
+ // Create order first
209
+ await engine.invoke('Order', 'create', {
210
+ userId,
211
+ items: [{ productId, quantity: 1, price: 29.99 }]
212
+ }, flow);
213
+
214
+ // Wait for processing
215
+ await new Promise(resolve => setTimeout(resolve, 50));
216
+
217
+ // Get the actions that were executed
218
+ const actions = engine.getActionsByFlow(flow);
219
+
220
+ // Check that Order.confirm was called
221
+ const orderConfirmAction = actions.find(a =>
222
+ a.concept === 'Order' && a.action === 'confirm'
223
+ );
224
+ expect(orderConfirmAction).toBeDefined();
225
+ expect(orderConfirmAction!.input).toEqual({
226
+ orderId: expect.any(String),
227
+ total: 29.99
228
+ });
229
+ });
230
+
231
+ it('should call User.get when Order.confirm succeeds', async () => {
232
+ const flow = 'order-user-flow';
233
+
234
+ // Create and confirm order
235
+ const orderResult = await engine.invoke('Order', 'create', {
236
+ userId,
237
+ items: [{ productId, quantity: 1, price: 29.99 }]
238
+ }, flow);
239
+
240
+ // Wait for processing
241
+ await new Promise(resolve => setTimeout(resolve, 100));
242
+
243
+ // Get the actions that were executed
244
+ const actions = engine.getActionsByFlow(flow);
245
+
246
+ // Check that User.get was called
247
+ const userGetAction = actions.find(a =>
248
+ a.concept === 'User' && a.action === 'get'
249
+ );
250
+ expect(userGetAction).toBeDefined();
251
+ expect(userGetAction!.input).toEqual({
252
+ userId
253
+ });
254
+ });
255
+
256
+ it('should call Inventory.deduct when Order.confirm succeeds', async () => {
257
+ const flow = 'order-inventory-flow';
258
+
259
+ // Create and confirm order
260
+ await engine.invoke('Order', 'create', {
261
+ userId,
262
+ items: [{ productId, quantity: 1, price: 29.99 }]
263
+ }, flow);
264
+
265
+ // Wait for processing
266
+ await new Promise(resolve => setTimeout(resolve, 100));
267
+
268
+ // Get the actions that were executed
269
+ const actions = engine.getActionsByFlow(flow);
270
+
271
+ // Check that Inventory.deduct was called
272
+ const inventoryDeductAction = actions.find(a =>
273
+ a.concept === 'Inventory' && a.action === 'deduct'
274
+ );
275
+ expect(inventoryDeductAction).toBeDefined();
276
+ expect(inventoryDeductAction!.input).toEqual({
277
+ orderId: expect.any(String),
278
+ items: [{ productId, quantity: 1, price: 29.99 }]
279
+ });
280
+ });
281
+
282
+ it('should call Notification.send when Order.confirm and User.get succeed', async () => {
283
+ const flow = 'order-notification-flow';
284
+
285
+ // Create and confirm order
286
+ await engine.invoke('Order', 'create', {
287
+ userId,
288
+ items: [{ productId, quantity: 1, price: 29.99 }]
289
+ }, flow);
290
+
291
+ // Wait for processing
292
+ await new Promise(resolve => setTimeout(resolve, 100));
293
+
294
+ // Get the actions that were executed
295
+ const actions = engine.getActionsByFlow(flow);
296
+
297
+ // Check that Notification.send was called
298
+ const notificationAction = actions.find(a =>
299
+ a.concept === 'Notification' && a.action === 'send'
300
+ );
301
+ expect(notificationAction).toBeDefined();
302
+ expect(notificationAction!.input).toEqual({
303
+ type: 'email',
304
+ to: 'test@example.com',
305
+ template: 'order-confirmation',
306
+ data: {
307
+ orderId: expect.any(String),
308
+ total: 29.99,
309
+ items: [{ productId, quantity: 1, price: 29.99 }]
310
+ }
311
+ });
312
+ });
313
+ });
314
+
315
+ describe('Analytics Event Syncs', () => {
316
+ it('should call Analytics.track when User.register succeeds', async () => {
317
+ const flow = 'analytics-user-flow';
318
+
319
+ // Register a user
320
+ await engine.invoke('User', 'register', {
321
+ username: 'johndoe',
322
+ email: 'john@example.com',
323
+ password: 'password123'
324
+ }, flow);
325
+
326
+ // Wait for processing
327
+ await new Promise(resolve => setTimeout(resolve, 50));
328
+
329
+ // Get the actions that were executed
330
+ const actions = engine.getActionsByFlow(flow);
331
+
332
+ // Check that Analytics.track was called for user registration
333
+ const analyticsAction = actions.find(a =>
334
+ a.concept === 'Analytics' && a.action === 'track'
335
+ );
336
+ expect(analyticsAction).toBeDefined();
337
+ expect(analyticsAction!.input).toEqual({
338
+ event: 'user_registered',
339
+ data: {
340
+ userId: expect.any(String),
341
+ username: 'johndoe',
342
+ email: 'john@example.com'
343
+ }
344
+ });
345
+ });
346
+
347
+ it('should call Analytics.track when Product.create succeeds', async () => {
348
+ const flow = 'analytics-product-flow';
349
+
350
+ // Create a product
351
+ await engine.invoke('Product', 'create', {
352
+ name: 'Test Product',
353
+ sku: 'TEST-001',
354
+ price: 29.99,
355
+ category: 'test'
356
+ }, flow);
357
+
358
+ // Wait for processing
359
+ await new Promise(resolve => setTimeout(resolve, 50));
360
+
361
+ // Get the actions that were executed
362
+ const actions = engine.getActionsByFlow(flow);
363
+
364
+ // Check that Analytics.track was called for product creation
365
+ const analyticsAction = actions.find(a =>
366
+ a.concept === 'Analytics' && a.action === 'track'
367
+ );
368
+ expect(analyticsAction).toBeDefined();
369
+ expect(analyticsAction!.input).toEqual({
370
+ event: 'product_created',
371
+ data: {
372
+ productId: expect.any(String),
373
+ name: 'Test Product',
374
+ sku: 'TEST-001',
375
+ price: 29.99,
376
+ category: 'test'
377
+ }
378
+ });
379
+ });
380
+
381
+ it('should call Analytics.track when Order.create succeeds', async () => {
382
+ const flow = 'analytics-order-flow';
383
+
384
+ // Create user and product first
385
+ const userResult = await engine.invoke('User', 'register', {
386
+ username: 'testuser',
387
+ email: 'test@example.com',
388
+ password: 'password123'
389
+ }, flow);
390
+
391
+ const productResult = await engine.invoke('Product', 'create', {
392
+ name: 'Test Product',
393
+ sku: 'TEST-001',
394
+ price: 29.99,
395
+ category: 'test'
396
+ }, flow);
397
+
398
+ // Set inventory
399
+ await engine.invoke('Inventory', 'setStock', {
400
+ productId: productResult.productId,
401
+ quantity: 10
402
+ }, flow);
403
+
404
+ // Create order
405
+ await engine.invoke('Order', 'create', {
406
+ userId: userResult.userId,
407
+ items: [{
408
+ productId: productResult.productId,
409
+ quantity: 1,
410
+ price: 29.99
411
+ }]
412
+ }, flow);
413
+
414
+ // Wait for processing
415
+ await new Promise(resolve => setTimeout(resolve, 100));
416
+
417
+ // Get the actions that were executed
418
+ const actions = engine.getActionsByFlow(flow);
419
+
420
+ // Check that Analytics.track was called for order creation
421
+ const analyticsActions = actions.filter(a =>
422
+ a.concept === 'Analytics' && a.action === 'track'
423
+ );
424
+ const orderCreatedAction = analyticsActions.find(a =>
425
+ a.input.event === 'order_created'
426
+ );
427
+ expect(orderCreatedAction).toBeDefined();
428
+ expect(orderCreatedAction!.input).toEqual({
429
+ event: 'order_created',
430
+ data: {
431
+ orderId: expect.any(String),
432
+ userId: userResult.userId,
433
+ itemCount: 1
434
+ }
435
+ });
436
+ });
437
+ });
438
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"Analytics.d.ts","sourceRoot":"","sources":["../../../../src/plugins/analytics/concepts/Analytics.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,eAAO,MAAM,SAAS,EAAE,OAiDvB,CAAC"}
1
+ {"version":3,"file":"Analytics.d.ts","sourceRoot":"","sources":["../../../../src/plugins/analytics/concepts/Analytics.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,eAAO,MAAM,SAAS,EAAE,OAuDvB,CAAC"}
@@ -35,6 +35,11 @@ exports.Analytics = {
35
35
  const events = state.events.get(event) || [];
36
36
  return { events: events.slice(-limit) };
37
37
  }
38
+ case 'reset': {
39
+ state.events.clear();
40
+ state.metrics.clear();
41
+ return { success: true };
42
+ }
38
43
  default:
39
44
  throw new Error(`Unknown action: ${action}`);
40
45
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Analytics.js","sourceRoot":"","sources":["../../../../src/plugins/analytics/concepts/Analytics.ts"],"names":[],"mappings":";;;AAGa,QAAA,SAAS,GAAY;IAChC,KAAK,EAAE;QACL,MAAM,EAAE,IAAI,GAAG,EAAiB;QAChC,OAAO,EAAE,IAAI,GAAG,EAAkB;KACnC;IAED,KAAK,CAAC,OAAO,CAAC,MAAc,EAAE,KAAU;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAEzB,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,OAAO,CAAC,CAAC,CAAC;gBACb,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;gBAE9B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC7B,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBAC9B,CAAC;gBAED,MAAM,SAAS,GAAG;oBAChB,GAAG,IAAI;oBACP,SAAS,EAAE,IAAI,IAAI,EAAE;oBACrB,EAAE,EAAE,SAAS,IAAI,CAAC,GAAG,EAAE,EAAE;iBAC1B,CAAC;gBAEF,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAEzC,iBAAiB;gBACjB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC5C,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;gBAEpC,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;gBAE1C,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC;YACnC,CAAC;YAED,KAAK,YAAY,CAAC,CAAC,CAAC;gBAClB,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBAClD,OAAO,EAAE,OAAO,EAAE,CAAC;YACrB,CAAC;YAED,KAAK,WAAW,CAAC,CAAC,CAAC;gBACjB,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,EAAE,EAAE,GAAG,KAAK,CAAC;gBACpC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;gBAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1C,CAAC;YAED;gBACE,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,EAAE,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"Analytics.js","sourceRoot":"","sources":["../../../../src/plugins/analytics/concepts/Analytics.ts"],"names":[],"mappings":";;;AAGa,QAAA,SAAS,GAAY;IAChC,KAAK,EAAE;QACL,MAAM,EAAE,IAAI,GAAG,EAAiB;QAChC,OAAO,EAAE,IAAI,GAAG,EAAkB;KACnC;IAED,KAAK,CAAC,OAAO,CAAC,MAAc,EAAE,KAAU;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAEzB,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,OAAO,CAAC,CAAC,CAAC;gBACb,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;gBAE9B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC7B,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBAC9B,CAAC;gBAED,MAAM,SAAS,GAAG;oBAChB,GAAG,IAAI;oBACP,SAAS,EAAE,IAAI,IAAI,EAAE;oBACrB,EAAE,EAAE,SAAS,IAAI,CAAC,GAAG,EAAE,EAAE;iBAC1B,CAAC;gBAEF,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAEzC,iBAAiB;gBACjB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC5C,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;gBAEpC,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;gBAE1C,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC;YACnC,CAAC;YAED,KAAK,YAAY,CAAC,CAAC,CAAC;gBAClB,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBAClD,OAAO,EAAE,OAAO,EAAE,CAAC;YACrB,CAAC;YAED,KAAK,WAAW,CAAC,CAAC,CAAC;gBACjB,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,EAAE,EAAE,GAAG,KAAK,CAAC;gBACpC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;gBAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1C,CAAC;YAED,KAAK,OAAO,CAAC,CAAC,CAAC;gBACb,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;gBACrB,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBACtB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YAC3B,CAAC;YAED;gBACE,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,EAAE,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Inventory.d.ts","sourceRoot":"","sources":["../../../../src/plugins/inventory/concepts/Inventory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,eAAO,MAAM,SAAS,EAAE,OAqEvB,CAAC"}
1
+ {"version":3,"file":"Inventory.d.ts","sourceRoot":"","sources":["../../../../src/plugins/inventory/concepts/Inventory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,eAAO,MAAM,SAAS,EAAE,OAgFvB,CAAC"}
@@ -22,16 +22,21 @@ exports.Inventory = {
22
22
  let total = 0;
23
23
  const unavailable = [];
24
24
  for (const item of items) {
25
+ console.log(`[Inventory.checkAvailability] Processing item: productId=${item.productId}, quantity=${item.quantity}, price=${item.price}`);
26
+ const parsedQuantity = parseFloat(item.quantity) || 0;
27
+ console.log(`[Inventory.checkAvailability] Parsed quantity: ${parsedQuantity}`);
28
+ const parsedPrice = parseFloat(item.price) || 0;
29
+ console.log(`[Inventory.checkAvailability] Parsed price: ${parsedPrice}`);
25
30
  const stock = state.stock.get(item.productId) || 0;
26
- if (stock < item.quantity) {
31
+ if (stock < parsedQuantity) {
27
32
  unavailable.push({
28
33
  productId: item.productId,
29
- requested: item.quantity,
34
+ requested: parsedQuantity,
30
35
  available: stock
31
36
  });
32
37
  }
33
38
  // Calculate total from input items (prices should be provided)
34
- total += item.quantity * (item.price || 0);
39
+ total += parsedQuantity * parsedPrice;
35
40
  }
36
41
  const available = unavailable.length === 0;
37
42
  return { available, total, unavailable };
@@ -39,11 +44,12 @@ exports.Inventory = {
39
44
  case 'deduct': {
40
45
  const { orderId, items } = input;
41
46
  for (const item of items) {
47
+ const parsedQuantity = parseFloat(item.quantity) || 0;
42
48
  const currentStock = state.stock.get(item.productId) || 0;
43
- if (currentStock < item.quantity) {
49
+ if (currentStock < parsedQuantity) {
44
50
  throw new Error(`Insufficient stock for product ${item.productId}`);
45
51
  }
46
- state.stock.set(item.productId, currentStock - item.quantity);
52
+ state.stock.set(item.productId, currentStock - parsedQuantity);
47
53
  }
48
54
  return { success: true };
49
55
  }
@@ -52,6 +58,10 @@ exports.Inventory = {
52
58
  const quantity = state.stock.get(productId) || 0;
53
59
  return { productId, quantity };
54
60
  }
61
+ case 'reset': {
62
+ state.stock.clear();
63
+ return { reset: true };
64
+ }
55
65
  default:
56
66
  throw new Error(`Unknown action: ${action}`);
57
67
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Inventory.js","sourceRoot":"","sources":["../../../../src/plugins/inventory/concepts/Inventory.ts"],"names":[],"mappings":";;;AAGa,QAAA,SAAS,GAAY;IAChC,KAAK,EAAE;QACL,KAAK,EAAE,IAAI,GAAG,EAAkB;QAChC,YAAY,EAAE,IAAI,GAAG,EAAiB;KACvC;IAED,KAAK,CAAC,OAAO,CAAC,MAAc,EAAE,KAAU;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAEzB,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,UAAU,CAAC,CAAC,CAAC;gBAChB,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;gBAEtC,IAAI,CAAC,SAAS,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;oBAC/B,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;gBACxE,CAAC;gBAED,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;gBACrC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;YACjC,CAAC;YAED,KAAK,mBAAmB,CAAC,CAAC,CAAC;gBACzB,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;gBAEjC,IAAI,KAAK,GAAG,CAAC,CAAC;gBACd,MAAM,WAAW,GAAU,EAAE,CAAC;gBAE9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;oBACnD,IAAI,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;wBAC1B,WAAW,CAAC,IAAI,CAAC;4BACf,SAAS,EAAE,IAAI,CAAC,SAAS;4BACzB,SAAS,EAAE,IAAI,CAAC,QAAQ;4BACxB,SAAS,EAAE,KAAK;yBACjB,CAAC,CAAC;oBACL,CAAC;oBACD,+DAA+D;oBAC/D,KAAK,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;gBAC7C,CAAC;gBAED,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,KAAK,CAAC,CAAC;gBAC3C,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;YAC3C,CAAC;YAED,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;gBAEjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;oBAC1D,IAAI,YAAY,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;wBACjC,MAAM,IAAI,KAAK,CAAC,kCAAkC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;oBACtE,CAAC;oBAED,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAChE,CAAC;gBAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YAC3B,CAAC;YAED,KAAK,UAAU,CAAC,CAAC,CAAC;gBAChB,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;gBAC5B,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBACjD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;YACjC,CAAC;YAED;gBACE,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,EAAE,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"Inventory.js","sourceRoot":"","sources":["../../../../src/plugins/inventory/concepts/Inventory.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Notification.d.ts","sourceRoot":"","sources":["../../../../src/plugins/notifications/concepts/Notification.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,eAAO,MAAM,YAAY,EAAE,OA6C1B,CAAC"}
1
+ {"version":3,"file":"Notification.d.ts","sourceRoot":"","sources":["../../../../src/plugins/notifications/concepts/Notification.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,eAAO,MAAM,YAAY,EAAE,OAkD1B,CAAC"}
@@ -34,6 +34,10 @@ exports.Notification = {
34
34
  const history = state.sent.get(recipient) || [];
35
35
  return { notifications: history };
36
36
  }
37
+ case 'reset': {
38
+ state.sent.clear();
39
+ return { reset: true };
40
+ }
37
41
  default:
38
42
  throw new Error(`Unknown action: ${action}`);
39
43
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Notification.js","sourceRoot":"","sources":["../../../../src/plugins/notifications/concepts/Notification.ts"],"names":[],"mappings":";;;AAGa,QAAA,YAAY,GAAY;IACnC,KAAK,EAAE;QACL,IAAI,EAAE,IAAI,GAAG,EAAiB;KAC/B;IAED,KAAK,CAAC,OAAO,CAAC,MAAc,EAAE,KAAU;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAEzB,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;gBAE3C,gCAAgC;gBAChC,MAAM,cAAc,GAAG,SAAS,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;gBAC7C,MAAM,YAAY,GAAG;oBACnB,EAAE,EAAE,cAAc;oBAClB,IAAI;oBACJ,EAAE;oBACF,QAAQ;oBACR,IAAI;oBACJ,MAAM,EAAE,IAAI,IAAI,EAAE;oBAClB,MAAM,EAAE,MAAM;iBACf,CAAC;gBAEF,2BAA2B;gBAC3B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oBACxB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;gBACzB,CAAC;gBACD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAEvC,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,YAAY,EAAE,KAAK,QAAQ,EAAE,CAAC,CAAC;gBAEnE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC;YAC1C,CAAC;YAED,KAAK,YAAY,CAAC,CAAC,CAAC;gBAClB,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;gBAC5B,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;gBAChD,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC;YACpC,CAAC;YAED;gBACE,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,EAAE,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"Notification.js","sourceRoot":"","sources":["../../../../src/plugins/notifications/concepts/Notification.ts"],"names":[],"mappings":";;;AAGa,QAAA,YAAY,GAAY;IACnC,KAAK,EAAE;QACL,IAAI,EAAE,IAAI,GAAG,EAAiB;KAC/B;IAED,KAAK,CAAC,OAAO,CAAC,MAAc,EAAE,KAAU;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAEzB,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;gBAE3C,gCAAgC;gBAChC,MAAM,cAAc,GAAG,SAAS,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;gBAC7C,MAAM,YAAY,GAAG;oBACnB,EAAE,EAAE,cAAc;oBAClB,IAAI;oBACJ,EAAE;oBACF,QAAQ;oBACR,IAAI;oBACJ,MAAM,EAAE,IAAI,IAAI,EAAE;oBAClB,MAAM,EAAE,MAAM;iBACf,CAAC;gBAEF,2BAA2B;gBAC3B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oBACxB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;gBACzB,CAAC;gBACD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAEvC,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,YAAY,EAAE,KAAK,QAAQ,EAAE,CAAC,CAAC;gBAEnE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC;YAC1C,CAAC;YAED,KAAK,YAAY,CAAC,CAAC,CAAC;gBAClB,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;gBAC5B,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;gBAChD,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC;YACpC,CAAC;YAED,KAAK,OAAO,CAAC,CAAC,CAAC;gBACb,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACnB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;YACzB,CAAC;YAED;gBACE,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,EAAE,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Order.d.ts","sourceRoot":"","sources":["../../../../src/plugins/orders/concepts/Order.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAG7C,eAAO,MAAM,KAAK,EAAE,OAiHnB,CAAC"}
1
+ {"version":3,"file":"Order.d.ts","sourceRoot":"","sources":["../../../../src/plugins/orders/concepts/Order.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAG7C,eAAO,MAAM,KAAK,EAAE,OAuHnB,CAAC"}
@@ -32,8 +32,8 @@ exports.Order = {
32
32
  createdAt: new Date(),
33
33
  items: items.map((item) => ({
34
34
  productId: item.productId,
35
- quantity: item.quantity,
36
- price: item.price || 0
35
+ quantity: parseFloat(item.quantity) || 0,
36
+ price: parseFloat(item.price) || 0
37
37
  }))
38
38
  };
39
39
  state.orders.set(orderId, order);
@@ -50,7 +50,7 @@ exports.Order = {
50
50
  throw new Error('Order is not in pending status');
51
51
  }
52
52
  order.status = 'confirmed';
53
- order.total = total;
53
+ order.total = parseFloat(total);
54
54
  order.confirmedAt = new Date();
55
55
  state.orders.set(orderId, order);
56
56
  return { order };
@@ -90,6 +90,11 @@ exports.Order = {
90
90
  const items = state.orderItems.get(orderId) || [];
91
91
  return { order: { ...order, items } };
92
92
  }
93
+ case 'reset': {
94
+ state.orders.clear();
95
+ state.orderItems.clear();
96
+ return { reset: true };
97
+ }
93
98
  default:
94
99
  throw new Error(`Unknown action: ${action}`);
95
100
  }