@contractspec/example.marketplace 3.7.6 → 3.8.2
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.
- package/README.md +64 -131
- package/dist/browser/entities/index.js +470 -470
- package/dist/browser/index.js +1257 -1019
- package/dist/browser/marketplace.feature.js +175 -0
- package/dist/browser/order/index.js +155 -155
- package/dist/browser/order/order.event.js +1 -1
- package/dist/browser/payout/index.js +71 -71
- package/dist/browser/payout/payout.event.js +1 -1
- package/dist/browser/product/index.js +104 -104
- package/dist/browser/product/product.event.js +1 -1
- package/dist/browser/review/index.js +75 -75
- package/dist/browser/review/review.event.js +1 -1
- package/dist/browser/store/index.js +68 -68
- package/dist/browser/store/store.event.js +1 -1
- package/dist/browser/ui/MarketplaceDashboard.js +328 -110
- package/dist/browser/ui/MarketplaceDashboard.visualizations.js +216 -0
- package/dist/browser/ui/hooks/index.js +1 -1
- package/dist/browser/ui/hooks/useMarketplaceData.js +1 -1
- package/dist/browser/ui/index.js +590 -359
- package/dist/browser/ui/renderers/index.js +190 -4
- package/dist/browser/ui/renderers/marketplace.markdown.js +190 -4
- package/dist/browser/visualizations/catalog.js +126 -0
- package/dist/browser/visualizations/index.js +183 -0
- package/dist/browser/visualizations/selectors.js +177 -0
- package/dist/entities/index.d.ts +110 -110
- package/dist/entities/index.js +470 -470
- package/dist/index.d.ts +4 -3
- package/dist/index.js +1257 -1019
- package/dist/marketplace.feature.js +175 -0
- package/dist/node/entities/index.js +470 -470
- package/dist/node/index.js +1257 -1019
- package/dist/node/marketplace.feature.js +175 -0
- package/dist/node/order/index.js +155 -155
- package/dist/node/order/order.event.js +1 -1
- package/dist/node/payout/index.js +71 -71
- package/dist/node/payout/payout.event.js +1 -1
- package/dist/node/product/index.js +104 -104
- package/dist/node/product/product.event.js +1 -1
- package/dist/node/review/index.js +75 -75
- package/dist/node/review/review.event.js +1 -1
- package/dist/node/store/index.js +68 -68
- package/dist/node/store/store.event.js +1 -1
- package/dist/node/ui/MarketplaceDashboard.js +328 -110
- package/dist/node/ui/MarketplaceDashboard.visualizations.js +216 -0
- package/dist/node/ui/hooks/index.js +1 -1
- package/dist/node/ui/hooks/useMarketplaceData.js +1 -1
- package/dist/node/ui/index.js +590 -359
- package/dist/node/ui/renderers/index.js +190 -4
- package/dist/node/ui/renderers/marketplace.markdown.js +190 -4
- package/dist/node/visualizations/catalog.js +126 -0
- package/dist/node/visualizations/index.js +183 -0
- package/dist/node/visualizations/selectors.js +177 -0
- package/dist/order/index.d.ts +2 -2
- package/dist/order/index.js +155 -155
- package/dist/order/order.event.js +1 -1
- package/dist/payout/index.d.ts +2 -2
- package/dist/payout/index.js +71 -71
- package/dist/payout/payout.event.js +1 -1
- package/dist/product/index.d.ts +2 -2
- package/dist/product/index.js +104 -104
- package/dist/product/product.event.js +1 -1
- package/dist/review/index.d.ts +2 -2
- package/dist/review/index.js +75 -75
- package/dist/review/review.event.js +1 -1
- package/dist/store/index.d.ts +2 -2
- package/dist/store/index.js +68 -68
- package/dist/store/store.event.js +1 -1
- package/dist/ui/MarketplaceDashboard.js +328 -110
- package/dist/ui/MarketplaceDashboard.visualizations.d.ts +5 -0
- package/dist/ui/MarketplaceDashboard.visualizations.js +217 -0
- package/dist/ui/hooks/index.d.ts +1 -1
- package/dist/ui/hooks/index.js +1 -1
- package/dist/ui/hooks/useMarketplaceData.js +1 -1
- package/dist/ui/index.d.ts +2 -2
- package/dist/ui/index.js +590 -359
- package/dist/ui/renderers/index.d.ts +1 -1
- package/dist/ui/renderers/index.js +190 -4
- package/dist/ui/renderers/marketplace.markdown.js +190 -4
- package/dist/visualizations/catalog.d.ts +10 -0
- package/dist/visualizations/catalog.js +127 -0
- package/dist/visualizations/index.d.ts +2 -0
- package/dist/visualizations/index.js +184 -0
- package/dist/visualizations/selectors.d.ts +11 -0
- package/dist/visualizations/selectors.js +178 -0
- package/dist/visualizations/selectors.test.d.ts +1 -0
- package/package.json +66 -10
package/dist/node/index.js
CHANGED
|
@@ -299,345 +299,490 @@ function createMarketplaceHandlers(db) {
|
|
|
299
299
|
};
|
|
300
300
|
}
|
|
301
301
|
|
|
302
|
-
// src/
|
|
302
|
+
// src/order/order.enum.ts
|
|
303
303
|
import { defineEnum } from "@contractspec/lib.schema";
|
|
304
|
-
var
|
|
304
|
+
var OrderStatusEnum = defineEnum("OrderStatus", [
|
|
305
305
|
"PENDING",
|
|
306
|
-
"
|
|
307
|
-
"
|
|
308
|
-
"
|
|
306
|
+
"PAID",
|
|
307
|
+
"PROCESSING",
|
|
308
|
+
"SHIPPED",
|
|
309
|
+
"DELIVERED",
|
|
310
|
+
"COMPLETED",
|
|
311
|
+
"CANCELLED",
|
|
312
|
+
"REFUNDED",
|
|
313
|
+
"PARTIALLY_REFUNDED",
|
|
314
|
+
"DISPUTED"
|
|
309
315
|
]);
|
|
310
316
|
|
|
311
|
-
// src/
|
|
317
|
+
// src/order/order.event.ts
|
|
318
|
+
import { defineEvent } from "@contractspec/lib.contracts-spec";
|
|
312
319
|
import { defineSchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
|
|
313
|
-
var
|
|
314
|
-
name: "
|
|
315
|
-
description: "A seller store",
|
|
320
|
+
var OrderCreatedPayload = defineSchemaModel({
|
|
321
|
+
name: "OrderCreatedEventPayload",
|
|
316
322
|
fields: {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
totalProducts: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
|
|
326
|
-
averageRating: { type: ScalarTypeEnum.Float_unsecure(), isOptional: false },
|
|
327
|
-
createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false }
|
|
323
|
+
orderId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
324
|
+
orderNumber: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
325
|
+
buyerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
326
|
+
storeId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
327
|
+
total: { type: ScalarTypeEnum.Float_unsecure(), isOptional: false },
|
|
328
|
+
currency: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
329
|
+
itemCount: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
|
|
330
|
+
timestamp: { type: ScalarTypeEnum.DateTime(), isOptional: false }
|
|
328
331
|
}
|
|
329
332
|
});
|
|
330
|
-
var
|
|
331
|
-
name: "
|
|
333
|
+
var OrderPaidPayload = defineSchemaModel({
|
|
334
|
+
name: "OrderPaidEventPayload",
|
|
332
335
|
fields: {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
336
|
+
orderId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
337
|
+
orderNumber: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
338
|
+
total: { type: ScalarTypeEnum.Float_unsecure(), isOptional: false },
|
|
339
|
+
paymentMethod: {
|
|
340
|
+
type: ScalarTypeEnum.String_unsecure(),
|
|
341
|
+
isOptional: false
|
|
342
|
+
},
|
|
343
|
+
timestamp: { type: ScalarTypeEnum.DateTime(), isOptional: false }
|
|
339
344
|
}
|
|
340
345
|
});
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
goal: "Allow users to become sellers on the marketplace.",
|
|
354
|
-
context: "Seller onboarding."
|
|
355
|
-
},
|
|
356
|
-
io: { input: CreateStoreInputModel, output: StoreModel },
|
|
357
|
-
policy: { auth: "user" },
|
|
358
|
-
sideEffects: {
|
|
359
|
-
emits: [
|
|
360
|
-
{
|
|
361
|
-
key: "marketplace.store.created",
|
|
362
|
-
version: "1.0.0",
|
|
363
|
-
when: "Store is created",
|
|
364
|
-
payload: StoreModel
|
|
365
|
-
}
|
|
366
|
-
],
|
|
367
|
-
audit: ["marketplace.store.created"]
|
|
368
|
-
},
|
|
369
|
-
acceptance: {
|
|
370
|
-
scenarios: [
|
|
371
|
-
{
|
|
372
|
-
key: "create-store-happy-path",
|
|
373
|
-
given: ["User is authenticated"],
|
|
374
|
-
when: ["User creates a new store"],
|
|
375
|
-
then: ["Store is created", "StoreCreated event is emitted"]
|
|
376
|
-
}
|
|
377
|
-
],
|
|
378
|
-
examples: [
|
|
379
|
-
{
|
|
380
|
-
key: "create-fashion-store",
|
|
381
|
-
input: { name: "Fashion Boutique", category: "clothing" },
|
|
382
|
-
output: { id: "store-123", status: "active" }
|
|
383
|
-
}
|
|
384
|
-
]
|
|
346
|
+
var OrderStatusUpdatedPayload = defineSchemaModel({
|
|
347
|
+
name: "OrderStatusUpdatedEventPayload",
|
|
348
|
+
fields: {
|
|
349
|
+
orderId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
350
|
+
orderNumber: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
351
|
+
previousStatus: {
|
|
352
|
+
type: ScalarTypeEnum.String_unsecure(),
|
|
353
|
+
isOptional: false
|
|
354
|
+
},
|
|
355
|
+
newStatus: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
356
|
+
updatedBy: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
357
|
+
timestamp: { type: ScalarTypeEnum.DateTime(), isOptional: false }
|
|
385
358
|
}
|
|
386
359
|
});
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
import { ScalarTypeEnum as ScalarTypeEnum2, defineSchemaModel as defineSchemaModel2 } from "@contractspec/lib.schema";
|
|
390
|
-
import { defineEvent } from "@contractspec/lib.contracts-spec";
|
|
391
|
-
var StoreCreatedPayload = defineSchemaModel2({
|
|
392
|
-
name: "StoreCreatedEventPayload",
|
|
360
|
+
var OrderShippedPayload = defineSchemaModel({
|
|
361
|
+
name: "OrderShippedEventPayload",
|
|
393
362
|
fields: {
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
363
|
+
orderId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
364
|
+
orderNumber: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
365
|
+
trackingNumber: {
|
|
366
|
+
type: ScalarTypeEnum.String_unsecure(),
|
|
367
|
+
isOptional: true
|
|
368
|
+
},
|
|
369
|
+
trackingUrl: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
|
|
370
|
+
carrier: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
|
|
371
|
+
timestamp: { type: ScalarTypeEnum.DateTime(), isOptional: false }
|
|
399
372
|
}
|
|
400
373
|
});
|
|
401
|
-
var
|
|
402
|
-
name: "
|
|
374
|
+
var OrderCompletedPayload = defineSchemaModel({
|
|
375
|
+
name: "OrderCompletedEventPayload",
|
|
403
376
|
fields: {
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
},
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
timestamp: { type: ScalarTypeEnum2.DateTime(), isOptional: false }
|
|
377
|
+
orderId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
378
|
+
orderNumber: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
379
|
+
buyerId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
380
|
+
storeId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
381
|
+
total: { type: ScalarTypeEnum.Float_unsecure(), isOptional: false },
|
|
382
|
+
sellerPayout: { type: ScalarTypeEnum.Float_unsecure(), isOptional: false },
|
|
383
|
+
timestamp: { type: ScalarTypeEnum.DateTime(), isOptional: false }
|
|
412
384
|
}
|
|
413
385
|
});
|
|
414
|
-
var
|
|
386
|
+
var OrderCreatedEvent = defineEvent({
|
|
415
387
|
meta: {
|
|
416
|
-
key: "marketplace.
|
|
388
|
+
key: "marketplace.order.created",
|
|
417
389
|
version: "1.0.0",
|
|
418
|
-
description: "A new
|
|
390
|
+
description: "A new order has been created.",
|
|
419
391
|
stability: "experimental",
|
|
420
392
|
owners: ["@marketplace-team"],
|
|
421
|
-
tags: ["marketplace", "
|
|
393
|
+
tags: ["marketplace", "order"]
|
|
422
394
|
},
|
|
423
|
-
payload:
|
|
395
|
+
payload: OrderCreatedPayload
|
|
424
396
|
});
|
|
425
|
-
var
|
|
397
|
+
var OrderPaidEvent = defineEvent({
|
|
426
398
|
meta: {
|
|
427
|
-
key: "marketplace.
|
|
399
|
+
key: "marketplace.order.paid",
|
|
428
400
|
version: "1.0.0",
|
|
429
|
-
description: "
|
|
401
|
+
description: "An order has been paid.",
|
|
430
402
|
stability: "experimental",
|
|
431
403
|
owners: ["@marketplace-team"],
|
|
432
|
-
tags: ["marketplace", "
|
|
404
|
+
tags: ["marketplace", "order"]
|
|
433
405
|
},
|
|
434
|
-
payload:
|
|
406
|
+
payload: OrderPaidPayload
|
|
407
|
+
});
|
|
408
|
+
var OrderStatusUpdatedEvent = defineEvent({
|
|
409
|
+
meta: {
|
|
410
|
+
key: "marketplace.order.statusUpdated",
|
|
411
|
+
version: "1.0.0",
|
|
412
|
+
description: "An order status has been updated.",
|
|
413
|
+
stability: "experimental",
|
|
414
|
+
owners: ["@marketplace-team"],
|
|
415
|
+
tags: ["marketplace", "order"]
|
|
416
|
+
},
|
|
417
|
+
payload: OrderStatusUpdatedPayload
|
|
418
|
+
});
|
|
419
|
+
var OrderShippedEvent = defineEvent({
|
|
420
|
+
meta: {
|
|
421
|
+
key: "marketplace.order.shipped",
|
|
422
|
+
version: "1.0.0",
|
|
423
|
+
description: "An order has been shipped.",
|
|
424
|
+
stability: "experimental",
|
|
425
|
+
owners: ["@marketplace-team"],
|
|
426
|
+
tags: ["marketplace", "order"]
|
|
427
|
+
},
|
|
428
|
+
payload: OrderShippedPayload
|
|
429
|
+
});
|
|
430
|
+
var OrderCompletedEvent = defineEvent({
|
|
431
|
+
meta: {
|
|
432
|
+
key: "marketplace.order.completed",
|
|
433
|
+
version: "1.0.0",
|
|
434
|
+
description: "An order has been completed.",
|
|
435
|
+
stability: "experimental",
|
|
436
|
+
owners: ["@marketplace-team"],
|
|
437
|
+
tags: ["marketplace", "order"]
|
|
438
|
+
},
|
|
439
|
+
payload: OrderCompletedPayload
|
|
435
440
|
});
|
|
436
|
-
// src/product/product.enum.ts
|
|
437
|
-
import { defineEnum as defineEnum2 } from "@contractspec/lib.schema";
|
|
438
|
-
var ProductStatusEnum = defineEnum2("ProductStatus", [
|
|
439
|
-
"DRAFT",
|
|
440
|
-
"PENDING_REVIEW",
|
|
441
|
-
"ACTIVE",
|
|
442
|
-
"OUT_OF_STOCK",
|
|
443
|
-
"DISCONTINUED",
|
|
444
|
-
"REJECTED"
|
|
445
|
-
]);
|
|
446
441
|
|
|
447
|
-
// src/
|
|
448
|
-
import { defineSchemaModel as
|
|
449
|
-
var
|
|
450
|
-
name: "
|
|
451
|
-
description: "A product listing",
|
|
442
|
+
// src/order/order.schema.ts
|
|
443
|
+
import { defineSchemaModel as defineSchemaModel2, ScalarTypeEnum as ScalarTypeEnum2 } from "@contractspec/lib.schema";
|
|
444
|
+
var OrderItemModel = defineSchemaModel2({
|
|
445
|
+
name: "OrderItemModel",
|
|
452
446
|
fields: {
|
|
453
|
-
id: { type:
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
price: { type: ScalarTypeEnum3.Float_unsecure(), isOptional: false },
|
|
460
|
-
currency: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false },
|
|
461
|
-
quantity: { type: ScalarTypeEnum3.Int_unsecure(), isOptional: false },
|
|
462
|
-
categoryId: { type: ScalarTypeEnum3.String_unsecure(), isOptional: true },
|
|
463
|
-
primaryImageId: {
|
|
464
|
-
type: ScalarTypeEnum3.String_unsecure(),
|
|
465
|
-
isOptional: true
|
|
466
|
-
},
|
|
467
|
-
averageRating: { type: ScalarTypeEnum3.Float_unsecure(), isOptional: false },
|
|
468
|
-
totalSold: { type: ScalarTypeEnum3.Int_unsecure(), isOptional: false },
|
|
469
|
-
createdAt: { type: ScalarTypeEnum3.DateTime(), isOptional: false }
|
|
447
|
+
id: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
|
|
448
|
+
productId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
|
|
449
|
+
productName: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
|
|
450
|
+
unitPrice: { type: ScalarTypeEnum2.Float_unsecure(), isOptional: false },
|
|
451
|
+
quantity: { type: ScalarTypeEnum2.Int_unsecure(), isOptional: false },
|
|
452
|
+
subtotal: { type: ScalarTypeEnum2.Float_unsecure(), isOptional: false }
|
|
470
453
|
}
|
|
471
454
|
});
|
|
472
|
-
var
|
|
473
|
-
name: "
|
|
455
|
+
var OrderModel = defineSchemaModel2({
|
|
456
|
+
name: "OrderModel",
|
|
457
|
+
description: "An order",
|
|
474
458
|
fields: {
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
459
|
+
id: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
|
|
460
|
+
orderNumber: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
|
|
461
|
+
buyerId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
|
|
462
|
+
storeId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
|
|
463
|
+
status: { type: OrderStatusEnum, isOptional: false },
|
|
464
|
+
subtotal: { type: ScalarTypeEnum2.Float_unsecure(), isOptional: false },
|
|
465
|
+
shippingTotal: { type: ScalarTypeEnum2.Float_unsecure(), isOptional: false },
|
|
466
|
+
taxTotal: { type: ScalarTypeEnum2.Float_unsecure(), isOptional: false },
|
|
467
|
+
total: { type: ScalarTypeEnum2.Float_unsecure(), isOptional: false },
|
|
468
|
+
currency: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
|
|
469
|
+
items: { type: OrderItemModel, isArray: true, isOptional: true },
|
|
470
|
+
createdAt: { type: ScalarTypeEnum2.DateTime(), isOptional: false }
|
|
484
471
|
}
|
|
485
472
|
});
|
|
486
|
-
var
|
|
487
|
-
name: "
|
|
473
|
+
var CreateOrderInputModel = defineSchemaModel2({
|
|
474
|
+
name: "CreateOrderInput",
|
|
488
475
|
fields: {
|
|
489
|
-
storeId: { type:
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
maxPrice: { type: ScalarTypeEnum3.Float_unsecure(), isOptional: true },
|
|
495
|
-
limit: {
|
|
496
|
-
type: ScalarTypeEnum3.Int_unsecure(),
|
|
497
|
-
isOptional: true,
|
|
498
|
-
defaultValue: 20
|
|
476
|
+
storeId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
|
|
477
|
+
items: {
|
|
478
|
+
type: ScalarTypeEnum2.JSON(),
|
|
479
|
+
isOptional: false,
|
|
480
|
+
description: "Array of {productId, variantId?, quantity}"
|
|
499
481
|
},
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
defaultValue: 0
|
|
504
|
-
}
|
|
482
|
+
shippingAddress: { type: ScalarTypeEnum2.JSON(), isOptional: true },
|
|
483
|
+
billingAddress: { type: ScalarTypeEnum2.JSON(), isOptional: true },
|
|
484
|
+
buyerNote: { type: ScalarTypeEnum2.String_unsecure(), isOptional: true }
|
|
505
485
|
}
|
|
506
486
|
});
|
|
507
|
-
var
|
|
508
|
-
name: "
|
|
487
|
+
var UpdateOrderStatusInputModel = defineSchemaModel2({
|
|
488
|
+
name: "UpdateOrderStatusInput",
|
|
509
489
|
fields: {
|
|
510
|
-
|
|
511
|
-
|
|
490
|
+
orderId: { type: ScalarTypeEnum2.String_unsecure(), isOptional: false },
|
|
491
|
+
status: { type: OrderStatusEnum, isOptional: false },
|
|
492
|
+
trackingNumber: {
|
|
493
|
+
type: ScalarTypeEnum2.String_unsecure(),
|
|
494
|
+
isOptional: true
|
|
495
|
+
},
|
|
496
|
+
trackingUrl: { type: ScalarTypeEnum2.String_unsecure(), isOptional: true },
|
|
497
|
+
note: { type: ScalarTypeEnum2.String_unsecure(), isOptional: true }
|
|
512
498
|
}
|
|
513
499
|
});
|
|
514
500
|
|
|
515
|
-
// src/
|
|
516
|
-
import {
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
} from "@contractspec/lib.contracts-spec/operations";
|
|
520
|
-
var OWNERS2 = ["@example.marketplace"];
|
|
521
|
-
var CreateProductContract = defineCommand2({
|
|
501
|
+
// src/order/order.operations.ts
|
|
502
|
+
import { defineCommand } from "@contractspec/lib.contracts-spec/operations";
|
|
503
|
+
var OWNERS = ["@example.marketplace"];
|
|
504
|
+
var CreateOrderContract = defineCommand({
|
|
522
505
|
meta: {
|
|
523
|
-
key: "marketplace.
|
|
506
|
+
key: "marketplace.order.create",
|
|
524
507
|
version: "1.0.0",
|
|
525
508
|
stability: "stable",
|
|
526
|
-
owners: [...
|
|
527
|
-
tags: ["marketplace", "
|
|
528
|
-
description: "Create a new
|
|
529
|
-
goal: "Allow
|
|
530
|
-
context: "
|
|
509
|
+
owners: [...OWNERS],
|
|
510
|
+
tags: ["marketplace", "order", "create"],
|
|
511
|
+
description: "Create a new order.",
|
|
512
|
+
goal: "Allow buyers to purchase products.",
|
|
513
|
+
context: "Checkout flow."
|
|
531
514
|
},
|
|
532
|
-
io: { input:
|
|
515
|
+
io: { input: CreateOrderInputModel, output: OrderModel },
|
|
533
516
|
policy: { auth: "user" },
|
|
534
517
|
sideEffects: {
|
|
535
518
|
emits: [
|
|
536
519
|
{
|
|
537
|
-
key: "marketplace.
|
|
520
|
+
key: "marketplace.order.created",
|
|
538
521
|
version: "1.0.0",
|
|
539
|
-
when: "
|
|
540
|
-
payload:
|
|
522
|
+
when: "Order is created",
|
|
523
|
+
payload: OrderModel
|
|
541
524
|
}
|
|
542
525
|
],
|
|
543
|
-
audit: ["marketplace.
|
|
526
|
+
audit: ["marketplace.order.created"]
|
|
544
527
|
},
|
|
545
528
|
acceptance: {
|
|
546
529
|
scenarios: [
|
|
547
530
|
{
|
|
548
|
-
key: "create-
|
|
549
|
-
given: ["User is
|
|
550
|
-
when: ["User creates
|
|
551
|
-
then: ["
|
|
531
|
+
key: "create-order-happy-path",
|
|
532
|
+
given: ["User is authenticated"],
|
|
533
|
+
when: ["User creates order with valid items"],
|
|
534
|
+
then: ["Order is created", "OrderCreated event is emitted"]
|
|
552
535
|
}
|
|
553
536
|
],
|
|
554
537
|
examples: [
|
|
555
538
|
{
|
|
556
|
-
key: "create-
|
|
539
|
+
key: "create-basic-order",
|
|
557
540
|
input: {
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
stock: 100,
|
|
561
|
-
storeId: "store-123"
|
|
541
|
+
storeId: "store-123",
|
|
542
|
+
items: [{ productId: "prod-456", quantity: 1, unitPrice: 100 }]
|
|
562
543
|
},
|
|
563
|
-
output: {
|
|
564
|
-
id: "prod-456",
|
|
565
|
-
title: "Classic T-Shirt",
|
|
566
|
-
status: "published"
|
|
567
|
-
}
|
|
544
|
+
output: { id: "order-789", status: "pending", total: 100 }
|
|
568
545
|
}
|
|
569
546
|
]
|
|
570
547
|
}
|
|
571
548
|
});
|
|
572
|
-
var
|
|
549
|
+
var UpdateOrderStatusContract = defineCommand({
|
|
573
550
|
meta: {
|
|
574
|
-
key: "marketplace.
|
|
551
|
+
key: "marketplace.order.updateStatus",
|
|
575
552
|
version: "1.0.0",
|
|
576
553
|
stability: "stable",
|
|
577
|
-
owners: [...
|
|
578
|
-
tags: ["marketplace", "
|
|
579
|
-
description: "
|
|
580
|
-
goal: "
|
|
581
|
-
context: "
|
|
554
|
+
owners: [...OWNERS],
|
|
555
|
+
tags: ["marketplace", "order", "status"],
|
|
556
|
+
description: "Update order status.",
|
|
557
|
+
goal: "Track order fulfillment.",
|
|
558
|
+
context: "Order management."
|
|
582
559
|
},
|
|
583
|
-
io: { input:
|
|
584
|
-
policy: { auth: "
|
|
585
|
-
|
|
586
|
-
|
|
560
|
+
io: { input: UpdateOrderStatusInputModel, output: OrderModel },
|
|
561
|
+
policy: { auth: "user" },
|
|
562
|
+
sideEffects: {
|
|
563
|
+
emits: [
|
|
587
564
|
{
|
|
588
|
-
key: "
|
|
589
|
-
|
|
590
|
-
when:
|
|
591
|
-
|
|
565
|
+
key: "marketplace.order.statusUpdated",
|
|
566
|
+
version: "1.0.0",
|
|
567
|
+
when: "Status changes",
|
|
568
|
+
payload: OrderModel
|
|
569
|
+
}
|
|
570
|
+
],
|
|
571
|
+
audit: ["marketplace.order.statusUpdated"]
|
|
572
|
+
},
|
|
573
|
+
acceptance: {
|
|
574
|
+
scenarios: [
|
|
575
|
+
{
|
|
576
|
+
key: "update-status-happy-path",
|
|
577
|
+
given: ["Order exists"],
|
|
578
|
+
when: ["Seller updates order status"],
|
|
579
|
+
then: ["Status is updated", "OrderStatusUpdated event is emitted"]
|
|
592
580
|
}
|
|
593
581
|
],
|
|
594
582
|
examples: [
|
|
595
583
|
{
|
|
596
|
-
key: "
|
|
597
|
-
input: {
|
|
598
|
-
|
|
584
|
+
key: "mark-shipped",
|
|
585
|
+
input: {
|
|
586
|
+
orderId: "order-789",
|
|
587
|
+
status: "shipped",
|
|
588
|
+
trackingNumber: "TRACK123"
|
|
589
|
+
},
|
|
590
|
+
output: { id: "order-789", status: "shipped" }
|
|
599
591
|
}
|
|
600
592
|
]
|
|
601
593
|
}
|
|
602
594
|
});
|
|
595
|
+
// src/payout/payout.enum.ts
|
|
596
|
+
import { defineEnum as defineEnum2 } from "@contractspec/lib.schema";
|
|
597
|
+
var PayoutStatusEnum = defineEnum2("PayoutStatus", [
|
|
598
|
+
"PENDING",
|
|
599
|
+
"PROCESSING",
|
|
600
|
+
"PAID",
|
|
601
|
+
"FAILED",
|
|
602
|
+
"CANCELLED"
|
|
603
|
+
]);
|
|
603
604
|
|
|
604
|
-
// src/
|
|
605
|
-
import { ScalarTypeEnum as ScalarTypeEnum4, defineSchemaModel as defineSchemaModel4 } from "@contractspec/lib.schema";
|
|
605
|
+
// src/payout/payout.event.ts
|
|
606
606
|
import { defineEvent as defineEvent2 } from "@contractspec/lib.contracts-spec";
|
|
607
|
-
|
|
608
|
-
|
|
607
|
+
import { defineSchemaModel as defineSchemaModel3, ScalarTypeEnum as ScalarTypeEnum3 } from "@contractspec/lib.schema";
|
|
608
|
+
var PayoutCreatedPayload = defineSchemaModel3({
|
|
609
|
+
name: "PayoutCreatedEventPayload",
|
|
610
|
+
fields: {
|
|
611
|
+
payoutId: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false },
|
|
612
|
+
payoutNumber: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false },
|
|
613
|
+
storeId: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false },
|
|
614
|
+
netAmount: { type: ScalarTypeEnum3.Float_unsecure(), isOptional: false },
|
|
615
|
+
currency: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false },
|
|
616
|
+
orderCount: { type: ScalarTypeEnum3.Int_unsecure(), isOptional: false },
|
|
617
|
+
timestamp: { type: ScalarTypeEnum3.DateTime(), isOptional: false }
|
|
618
|
+
}
|
|
619
|
+
});
|
|
620
|
+
var PayoutPaidPayload = defineSchemaModel3({
|
|
621
|
+
name: "PayoutPaidEventPayload",
|
|
622
|
+
fields: {
|
|
623
|
+
payoutId: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false },
|
|
624
|
+
payoutNumber: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false },
|
|
625
|
+
storeId: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false },
|
|
626
|
+
netAmount: { type: ScalarTypeEnum3.Float_unsecure(), isOptional: false },
|
|
627
|
+
paymentReference: {
|
|
628
|
+
type: ScalarTypeEnum3.String_unsecure(),
|
|
629
|
+
isOptional: true
|
|
630
|
+
},
|
|
631
|
+
timestamp: { type: ScalarTypeEnum3.DateTime(), isOptional: false }
|
|
632
|
+
}
|
|
633
|
+
});
|
|
634
|
+
var PayoutCreatedEvent = defineEvent2({
|
|
635
|
+
meta: {
|
|
636
|
+
key: "marketplace.payout.created",
|
|
637
|
+
version: "1.0.0",
|
|
638
|
+
description: "A payout has been created.",
|
|
639
|
+
stability: "experimental",
|
|
640
|
+
owners: ["@marketplace-team"],
|
|
641
|
+
tags: ["marketplace", "payout"]
|
|
642
|
+
},
|
|
643
|
+
payload: PayoutCreatedPayload
|
|
644
|
+
});
|
|
645
|
+
var PayoutPaidEvent = defineEvent2({
|
|
646
|
+
meta: {
|
|
647
|
+
key: "marketplace.payout.paid",
|
|
648
|
+
version: "1.0.0",
|
|
649
|
+
description: "A payout has been sent.",
|
|
650
|
+
stability: "experimental",
|
|
651
|
+
owners: ["@marketplace-team"],
|
|
652
|
+
tags: ["marketplace", "payout"]
|
|
653
|
+
},
|
|
654
|
+
payload: PayoutPaidPayload
|
|
655
|
+
});
|
|
656
|
+
|
|
657
|
+
// src/payout/payout.schema.ts
|
|
658
|
+
import { defineSchemaModel as defineSchemaModel4, ScalarTypeEnum as ScalarTypeEnum4 } from "@contractspec/lib.schema";
|
|
659
|
+
var PayoutModel = defineSchemaModel4({
|
|
660
|
+
name: "PayoutModel",
|
|
661
|
+
description: "A payout to seller",
|
|
609
662
|
fields: {
|
|
610
|
-
|
|
663
|
+
id: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
|
|
664
|
+
payoutNumber: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
|
|
611
665
|
storeId: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
|
|
612
|
-
|
|
613
|
-
|
|
666
|
+
status: { type: PayoutStatusEnum, isOptional: false },
|
|
667
|
+
grossAmount: { type: ScalarTypeEnum4.Float_unsecure(), isOptional: false },
|
|
668
|
+
platformFees: { type: ScalarTypeEnum4.Float_unsecure(), isOptional: false },
|
|
669
|
+
netAmount: { type: ScalarTypeEnum4.Float_unsecure(), isOptional: false },
|
|
614
670
|
currency: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
|
|
615
|
-
|
|
671
|
+
periodStart: { type: ScalarTypeEnum4.DateTime(), isOptional: false },
|
|
672
|
+
periodEnd: { type: ScalarTypeEnum4.DateTime(), isOptional: false },
|
|
673
|
+
orderCount: { type: ScalarTypeEnum4.Int_unsecure(), isOptional: false },
|
|
674
|
+
createdAt: { type: ScalarTypeEnum4.DateTime(), isOptional: false },
|
|
675
|
+
paidAt: { type: ScalarTypeEnum4.DateTime(), isOptional: true }
|
|
616
676
|
}
|
|
617
677
|
});
|
|
618
|
-
var
|
|
619
|
-
name: "
|
|
678
|
+
var ListPayoutsInputModel = defineSchemaModel4({
|
|
679
|
+
name: "ListPayoutsInput",
|
|
620
680
|
fields: {
|
|
621
|
-
productId: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
|
|
622
681
|
storeId: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
|
|
623
|
-
|
|
682
|
+
status: { type: PayoutStatusEnum, isOptional: true },
|
|
683
|
+
limit: {
|
|
684
|
+
type: ScalarTypeEnum4.Int_unsecure(),
|
|
685
|
+
isOptional: true,
|
|
686
|
+
defaultValue: 20
|
|
687
|
+
},
|
|
688
|
+
offset: {
|
|
689
|
+
type: ScalarTypeEnum4.Int_unsecure(),
|
|
690
|
+
isOptional: true,
|
|
691
|
+
defaultValue: 0
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
});
|
|
695
|
+
var ListPayoutsOutputModel = defineSchemaModel4({
|
|
696
|
+
name: "ListPayoutsOutput",
|
|
697
|
+
fields: {
|
|
698
|
+
payouts: { type: PayoutModel, isArray: true, isOptional: false },
|
|
699
|
+
total: { type: ScalarTypeEnum4.Int_unsecure(), isOptional: false },
|
|
700
|
+
totalPending: { type: ScalarTypeEnum4.Float_unsecure(), isOptional: false }
|
|
701
|
+
}
|
|
702
|
+
});
|
|
703
|
+
|
|
704
|
+
// src/payout/payout.operations.ts
|
|
705
|
+
import { defineQuery } from "@contractspec/lib.contracts-spec/operations";
|
|
706
|
+
var OWNERS2 = ["@example.marketplace"];
|
|
707
|
+
var ListPayoutsContract = defineQuery({
|
|
708
|
+
meta: {
|
|
709
|
+
key: "marketplace.payout.list",
|
|
710
|
+
version: "1.0.0",
|
|
711
|
+
stability: "stable",
|
|
712
|
+
owners: [...OWNERS2],
|
|
713
|
+
tags: ["marketplace", "payout", "list"],
|
|
714
|
+
description: "List payouts for a store.",
|
|
715
|
+
goal: "View payout history.",
|
|
716
|
+
context: "Seller dashboard."
|
|
717
|
+
},
|
|
718
|
+
io: { input: ListPayoutsInputModel, output: ListPayoutsOutputModel },
|
|
719
|
+
policy: { auth: "user" },
|
|
720
|
+
acceptance: {
|
|
721
|
+
scenarios: [
|
|
722
|
+
{
|
|
723
|
+
key: "list-payouts-happy-path",
|
|
724
|
+
given: ["Store has payout history"],
|
|
725
|
+
when: ["Seller lists payouts"],
|
|
726
|
+
then: ["List of payouts is returned"]
|
|
727
|
+
}
|
|
728
|
+
],
|
|
729
|
+
examples: [
|
|
730
|
+
{
|
|
731
|
+
key: "list-recent",
|
|
732
|
+
input: { limit: 10, offset: 0 },
|
|
733
|
+
output: { items: [], total: 5, hasMore: false }
|
|
734
|
+
}
|
|
735
|
+
]
|
|
736
|
+
}
|
|
737
|
+
});
|
|
738
|
+
// src/product/product.enum.ts
|
|
739
|
+
import { defineEnum as defineEnum3 } from "@contractspec/lib.schema";
|
|
740
|
+
var ProductStatusEnum = defineEnum3("ProductStatus", [
|
|
741
|
+
"DRAFT",
|
|
742
|
+
"PENDING_REVIEW",
|
|
743
|
+
"ACTIVE",
|
|
744
|
+
"OUT_OF_STOCK",
|
|
745
|
+
"DISCONTINUED",
|
|
746
|
+
"REJECTED"
|
|
747
|
+
]);
|
|
748
|
+
|
|
749
|
+
// src/product/product.event.ts
|
|
750
|
+
import { defineEvent as defineEvent3 } from "@contractspec/lib.contracts-spec";
|
|
751
|
+
import { defineSchemaModel as defineSchemaModel5, ScalarTypeEnum as ScalarTypeEnum5 } from "@contractspec/lib.schema";
|
|
752
|
+
var ProductCreatedPayload = defineSchemaModel5({
|
|
753
|
+
name: "ProductCreatedEventPayload",
|
|
754
|
+
fields: {
|
|
755
|
+
productId: { type: ScalarTypeEnum5.String_unsecure(), isOptional: false },
|
|
756
|
+
storeId: { type: ScalarTypeEnum5.String_unsecure(), isOptional: false },
|
|
757
|
+
name: { type: ScalarTypeEnum5.String_unsecure(), isOptional: false },
|
|
758
|
+
price: { type: ScalarTypeEnum5.Float_unsecure(), isOptional: false },
|
|
759
|
+
currency: { type: ScalarTypeEnum5.String_unsecure(), isOptional: false },
|
|
760
|
+
timestamp: { type: ScalarTypeEnum5.DateTime(), isOptional: false }
|
|
761
|
+
}
|
|
762
|
+
});
|
|
763
|
+
var ProductPublishedPayload = defineSchemaModel5({
|
|
764
|
+
name: "ProductPublishedEventPayload",
|
|
765
|
+
fields: {
|
|
766
|
+
productId: { type: ScalarTypeEnum5.String_unsecure(), isOptional: false },
|
|
767
|
+
storeId: { type: ScalarTypeEnum5.String_unsecure(), isOptional: false },
|
|
768
|
+
timestamp: { type: ScalarTypeEnum5.DateTime(), isOptional: false }
|
|
624
769
|
}
|
|
625
770
|
});
|
|
626
|
-
var InventoryUpdatedPayload =
|
|
771
|
+
var InventoryUpdatedPayload = defineSchemaModel5({
|
|
627
772
|
name: "InventoryUpdatedEventPayload",
|
|
628
773
|
fields: {
|
|
629
|
-
productId: { type:
|
|
630
|
-
variantId: { type:
|
|
774
|
+
productId: { type: ScalarTypeEnum5.String_unsecure(), isOptional: false },
|
|
775
|
+
variantId: { type: ScalarTypeEnum5.String_unsecure(), isOptional: true },
|
|
631
776
|
previousQuantity: {
|
|
632
|
-
type:
|
|
777
|
+
type: ScalarTypeEnum5.Int_unsecure(),
|
|
633
778
|
isOptional: false
|
|
634
779
|
},
|
|
635
|
-
newQuantity: { type:
|
|
636
|
-
reason: { type:
|
|
637
|
-
timestamp: { type:
|
|
780
|
+
newQuantity: { type: ScalarTypeEnum5.Int_unsecure(), isOptional: false },
|
|
781
|
+
reason: { type: ScalarTypeEnum5.String_unsecure(), isOptional: false },
|
|
782
|
+
timestamp: { type: ScalarTypeEnum5.DateTime(), isOptional: false }
|
|
638
783
|
}
|
|
639
784
|
});
|
|
640
|
-
var ProductCreatedEvent =
|
|
785
|
+
var ProductCreatedEvent = defineEvent3({
|
|
641
786
|
meta: {
|
|
642
787
|
key: "marketplace.product.created",
|
|
643
788
|
version: "1.0.0",
|
|
@@ -648,7 +793,7 @@ var ProductCreatedEvent = defineEvent2({
|
|
|
648
793
|
},
|
|
649
794
|
payload: ProductCreatedPayload
|
|
650
795
|
});
|
|
651
|
-
var ProductPublishedEvent =
|
|
796
|
+
var ProductPublishedEvent = defineEvent3({
|
|
652
797
|
meta: {
|
|
653
798
|
key: "marketplace.product.published",
|
|
654
799
|
version: "1.0.0",
|
|
@@ -659,7 +804,7 @@ var ProductPublishedEvent = defineEvent2({
|
|
|
659
804
|
},
|
|
660
805
|
payload: ProductPublishedPayload
|
|
661
806
|
});
|
|
662
|
-
var InventoryUpdatedEvent =
|
|
807
|
+
var InventoryUpdatedEvent = defineEvent3({
|
|
663
808
|
meta: {
|
|
664
809
|
key: "marketplace.inventory.updated",
|
|
665
810
|
version: "1.0.0",
|
|
@@ -670,523 +815,291 @@ var InventoryUpdatedEvent = defineEvent2({
|
|
|
670
815
|
},
|
|
671
816
|
payload: InventoryUpdatedPayload
|
|
672
817
|
});
|
|
673
|
-
// src/order/order.enum.ts
|
|
674
|
-
import { defineEnum as defineEnum3 } from "@contractspec/lib.schema";
|
|
675
|
-
var OrderStatusEnum = defineEnum3("OrderStatus", [
|
|
676
|
-
"PENDING",
|
|
677
|
-
"PAID",
|
|
678
|
-
"PROCESSING",
|
|
679
|
-
"SHIPPED",
|
|
680
|
-
"DELIVERED",
|
|
681
|
-
"COMPLETED",
|
|
682
|
-
"CANCELLED",
|
|
683
|
-
"REFUNDED",
|
|
684
|
-
"PARTIALLY_REFUNDED",
|
|
685
|
-
"DISPUTED"
|
|
686
|
-
]);
|
|
687
818
|
|
|
688
|
-
// src/
|
|
689
|
-
import { defineSchemaModel as
|
|
690
|
-
var
|
|
691
|
-
name: "
|
|
819
|
+
// src/product/product.schema.ts
|
|
820
|
+
import { defineSchemaModel as defineSchemaModel6, ScalarTypeEnum as ScalarTypeEnum6 } from "@contractspec/lib.schema";
|
|
821
|
+
var ProductModel = defineSchemaModel6({
|
|
822
|
+
name: "ProductModel",
|
|
823
|
+
description: "A product listing",
|
|
692
824
|
fields: {
|
|
693
|
-
id: { type:
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
825
|
+
id: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
826
|
+
storeId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
827
|
+
name: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
828
|
+
slug: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
829
|
+
description: { type: ScalarTypeEnum6.String_unsecure(), isOptional: true },
|
|
830
|
+
status: { type: ProductStatusEnum, isOptional: false },
|
|
831
|
+
price: { type: ScalarTypeEnum6.Float_unsecure(), isOptional: false },
|
|
832
|
+
currency: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
833
|
+
quantity: { type: ScalarTypeEnum6.Int_unsecure(), isOptional: false },
|
|
834
|
+
categoryId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: true },
|
|
835
|
+
primaryImageId: {
|
|
836
|
+
type: ScalarTypeEnum6.String_unsecure(),
|
|
837
|
+
isOptional: true
|
|
838
|
+
},
|
|
839
|
+
averageRating: { type: ScalarTypeEnum6.Float_unsecure(), isOptional: false },
|
|
840
|
+
totalSold: { type: ScalarTypeEnum6.Int_unsecure(), isOptional: false },
|
|
841
|
+
createdAt: { type: ScalarTypeEnum6.DateTime(), isOptional: false }
|
|
699
842
|
}
|
|
700
843
|
});
|
|
701
|
-
var
|
|
702
|
-
name: "
|
|
703
|
-
description: "An order",
|
|
844
|
+
var CreateProductInputModel = defineSchemaModel6({
|
|
845
|
+
name: "CreateProductInput",
|
|
704
846
|
fields: {
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
currency: { type: ScalarTypeEnum5.String_unsecure(), isOptional: false },
|
|
715
|
-
items: { type: OrderItemModel, isArray: true, isOptional: true },
|
|
716
|
-
createdAt: { type: ScalarTypeEnum5.DateTime(), isOptional: false }
|
|
847
|
+
storeId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
848
|
+
name: { type: ScalarTypeEnum6.NonEmptyString(), isOptional: false },
|
|
849
|
+
slug: { type: ScalarTypeEnum6.NonEmptyString(), isOptional: false },
|
|
850
|
+
description: { type: ScalarTypeEnum6.String_unsecure(), isOptional: true },
|
|
851
|
+
price: { type: ScalarTypeEnum6.Float_unsecure(), isOptional: false },
|
|
852
|
+
currency: { type: ScalarTypeEnum6.String_unsecure(), isOptional: true },
|
|
853
|
+
quantity: { type: ScalarTypeEnum6.Int_unsecure(), isOptional: true },
|
|
854
|
+
categoryId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: true },
|
|
855
|
+
sku: { type: ScalarTypeEnum6.String_unsecure(), isOptional: true }
|
|
717
856
|
}
|
|
718
857
|
});
|
|
719
|
-
var
|
|
720
|
-
name: "
|
|
858
|
+
var ListProductsInputModel = defineSchemaModel6({
|
|
859
|
+
name: "ListProductsInput",
|
|
721
860
|
fields: {
|
|
722
|
-
storeId: { type:
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
861
|
+
storeId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: true },
|
|
862
|
+
categoryId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: true },
|
|
863
|
+
status: { type: ProductStatusEnum, isOptional: true },
|
|
864
|
+
search: { type: ScalarTypeEnum6.String_unsecure(), isOptional: true },
|
|
865
|
+
minPrice: { type: ScalarTypeEnum6.Float_unsecure(), isOptional: true },
|
|
866
|
+
maxPrice: { type: ScalarTypeEnum6.Float_unsecure(), isOptional: true },
|
|
867
|
+
limit: {
|
|
868
|
+
type: ScalarTypeEnum6.Int_unsecure(),
|
|
869
|
+
isOptional: true,
|
|
870
|
+
defaultValue: 20
|
|
727
871
|
},
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
872
|
+
offset: {
|
|
873
|
+
type: ScalarTypeEnum6.Int_unsecure(),
|
|
874
|
+
isOptional: true,
|
|
875
|
+
defaultValue: 0
|
|
876
|
+
}
|
|
731
877
|
}
|
|
732
878
|
});
|
|
733
|
-
var
|
|
734
|
-
name: "
|
|
879
|
+
var ListProductsOutputModel = defineSchemaModel6({
|
|
880
|
+
name: "ListProductsOutput",
|
|
735
881
|
fields: {
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
trackingNumber: {
|
|
739
|
-
type: ScalarTypeEnum5.String_unsecure(),
|
|
740
|
-
isOptional: true
|
|
741
|
-
},
|
|
742
|
-
trackingUrl: { type: ScalarTypeEnum5.String_unsecure(), isOptional: true },
|
|
743
|
-
note: { type: ScalarTypeEnum5.String_unsecure(), isOptional: true }
|
|
882
|
+
products: { type: ProductModel, isArray: true, isOptional: false },
|
|
883
|
+
total: { type: ScalarTypeEnum6.Int_unsecure(), isOptional: false }
|
|
744
884
|
}
|
|
745
885
|
});
|
|
746
886
|
|
|
747
|
-
// src/
|
|
748
|
-
import {
|
|
887
|
+
// src/product/product.operations.ts
|
|
888
|
+
import {
|
|
889
|
+
defineCommand as defineCommand2,
|
|
890
|
+
defineQuery as defineQuery2
|
|
891
|
+
} from "@contractspec/lib.contracts-spec/operations";
|
|
749
892
|
var OWNERS3 = ["@example.marketplace"];
|
|
750
|
-
var
|
|
893
|
+
var CreateProductContract = defineCommand2({
|
|
751
894
|
meta: {
|
|
752
|
-
key: "marketplace.
|
|
895
|
+
key: "marketplace.product.create",
|
|
753
896
|
version: "1.0.0",
|
|
754
897
|
stability: "stable",
|
|
755
898
|
owners: [...OWNERS3],
|
|
756
|
-
tags: ["marketplace", "
|
|
757
|
-
description: "Create a new
|
|
758
|
-
goal: "Allow
|
|
759
|
-
context: "
|
|
899
|
+
tags: ["marketplace", "product", "create"],
|
|
900
|
+
description: "Create a new product listing.",
|
|
901
|
+
goal: "Allow sellers to list products.",
|
|
902
|
+
context: "Product management."
|
|
760
903
|
},
|
|
761
|
-
io: { input:
|
|
904
|
+
io: { input: CreateProductInputModel, output: ProductModel },
|
|
762
905
|
policy: { auth: "user" },
|
|
763
906
|
sideEffects: {
|
|
764
907
|
emits: [
|
|
765
908
|
{
|
|
766
|
-
key: "marketplace.
|
|
909
|
+
key: "marketplace.product.created",
|
|
767
910
|
version: "1.0.0",
|
|
768
|
-
when: "
|
|
769
|
-
payload:
|
|
911
|
+
when: "Product is created",
|
|
912
|
+
payload: ProductModel
|
|
770
913
|
}
|
|
771
914
|
],
|
|
772
|
-
audit: ["marketplace.
|
|
915
|
+
audit: ["marketplace.product.created"]
|
|
773
916
|
},
|
|
774
917
|
acceptance: {
|
|
775
918
|
scenarios: [
|
|
776
919
|
{
|
|
777
|
-
key: "create-
|
|
778
|
-
given: ["User is
|
|
779
|
-
when: ["User creates
|
|
780
|
-
then: ["
|
|
920
|
+
key: "create-product-happy-path",
|
|
921
|
+
given: ["User is a seller"],
|
|
922
|
+
when: ["User creates a product listing"],
|
|
923
|
+
then: ["Product is created", "ProductCreated event is emitted"]
|
|
781
924
|
}
|
|
782
925
|
],
|
|
783
926
|
examples: [
|
|
784
927
|
{
|
|
785
|
-
key: "create-
|
|
928
|
+
key: "create-t-shirt",
|
|
786
929
|
input: {
|
|
787
|
-
|
|
788
|
-
|
|
930
|
+
title: "Classic T-Shirt",
|
|
931
|
+
price: 25,
|
|
932
|
+
stock: 100,
|
|
933
|
+
storeId: "store-123"
|
|
789
934
|
},
|
|
790
|
-
output: {
|
|
935
|
+
output: {
|
|
936
|
+
id: "prod-456",
|
|
937
|
+
title: "Classic T-Shirt",
|
|
938
|
+
status: "published"
|
|
939
|
+
}
|
|
791
940
|
}
|
|
792
941
|
]
|
|
793
942
|
}
|
|
794
943
|
});
|
|
795
|
-
var
|
|
944
|
+
var ListProductsContract = defineQuery2({
|
|
796
945
|
meta: {
|
|
797
|
-
key: "marketplace.
|
|
946
|
+
key: "marketplace.product.list",
|
|
798
947
|
version: "1.0.0",
|
|
799
948
|
stability: "stable",
|
|
800
949
|
owners: [...OWNERS3],
|
|
801
|
-
tags: ["marketplace", "
|
|
802
|
-
description: "
|
|
803
|
-
goal: "
|
|
804
|
-
context: "
|
|
805
|
-
},
|
|
806
|
-
io: { input: UpdateOrderStatusInputModel, output: OrderModel },
|
|
807
|
-
policy: { auth: "user" },
|
|
808
|
-
sideEffects: {
|
|
809
|
-
emits: [
|
|
810
|
-
{
|
|
811
|
-
key: "marketplace.order.statusUpdated",
|
|
812
|
-
version: "1.0.0",
|
|
813
|
-
when: "Status changes",
|
|
814
|
-
payload: OrderModel
|
|
815
|
-
}
|
|
816
|
-
],
|
|
817
|
-
audit: ["marketplace.order.statusUpdated"]
|
|
950
|
+
tags: ["marketplace", "product", "list"],
|
|
951
|
+
description: "List products with filters.",
|
|
952
|
+
goal: "Browse products on the marketplace.",
|
|
953
|
+
context: "Product catalog, search."
|
|
818
954
|
},
|
|
955
|
+
io: { input: ListProductsInputModel, output: ListProductsOutputModel },
|
|
956
|
+
policy: { auth: "anonymous" },
|
|
819
957
|
acceptance: {
|
|
820
958
|
scenarios: [
|
|
821
959
|
{
|
|
822
|
-
key: "
|
|
823
|
-
given: ["
|
|
824
|
-
when: ["
|
|
825
|
-
then: ["
|
|
960
|
+
key: "list-products-happy-path",
|
|
961
|
+
given: ["Products exist"],
|
|
962
|
+
when: ["User searches for products"],
|
|
963
|
+
then: ["List of products is returned"]
|
|
826
964
|
}
|
|
827
965
|
],
|
|
828
966
|
examples: [
|
|
829
967
|
{
|
|
830
|
-
key: "
|
|
831
|
-
input: {
|
|
832
|
-
|
|
833
|
-
status: "shipped",
|
|
834
|
-
trackingNumber: "TRACK123"
|
|
835
|
-
},
|
|
836
|
-
output: { id: "order-789", status: "shipped" }
|
|
968
|
+
key: "search-t-shirts",
|
|
969
|
+
input: { search: "t-shirt", limit: 20 },
|
|
970
|
+
output: { items: [], total: 50, hasMore: true }
|
|
837
971
|
}
|
|
838
972
|
]
|
|
839
973
|
}
|
|
840
974
|
});
|
|
841
|
-
|
|
842
|
-
// src/order/order.event.ts
|
|
843
|
-
import { ScalarTypeEnum as ScalarTypeEnum6, defineSchemaModel as defineSchemaModel6 } from "@contractspec/lib.schema";
|
|
844
|
-
import { defineEvent as defineEvent3 } from "@contractspec/lib.contracts-spec";
|
|
845
|
-
var OrderCreatedPayload = defineSchemaModel6({
|
|
846
|
-
name: "OrderCreatedEventPayload",
|
|
847
|
-
fields: {
|
|
848
|
-
orderId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
849
|
-
orderNumber: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
850
|
-
buyerId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
851
|
-
storeId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
852
|
-
total: { type: ScalarTypeEnum6.Float_unsecure(), isOptional: false },
|
|
853
|
-
currency: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
854
|
-
itemCount: { type: ScalarTypeEnum6.Int_unsecure(), isOptional: false },
|
|
855
|
-
timestamp: { type: ScalarTypeEnum6.DateTime(), isOptional: false }
|
|
856
|
-
}
|
|
857
|
-
});
|
|
858
|
-
var OrderPaidPayload = defineSchemaModel6({
|
|
859
|
-
name: "OrderPaidEventPayload",
|
|
860
|
-
fields: {
|
|
861
|
-
orderId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
862
|
-
orderNumber: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
863
|
-
total: { type: ScalarTypeEnum6.Float_unsecure(), isOptional: false },
|
|
864
|
-
paymentMethod: {
|
|
865
|
-
type: ScalarTypeEnum6.String_unsecure(),
|
|
866
|
-
isOptional: false
|
|
867
|
-
},
|
|
868
|
-
timestamp: { type: ScalarTypeEnum6.DateTime(), isOptional: false }
|
|
869
|
-
}
|
|
870
|
-
});
|
|
871
|
-
var OrderStatusUpdatedPayload = defineSchemaModel6({
|
|
872
|
-
name: "OrderStatusUpdatedEventPayload",
|
|
873
|
-
fields: {
|
|
874
|
-
orderId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
875
|
-
orderNumber: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
876
|
-
previousStatus: {
|
|
877
|
-
type: ScalarTypeEnum6.String_unsecure(),
|
|
878
|
-
isOptional: false
|
|
879
|
-
},
|
|
880
|
-
newStatus: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
881
|
-
updatedBy: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
882
|
-
timestamp: { type: ScalarTypeEnum6.DateTime(), isOptional: false }
|
|
883
|
-
}
|
|
884
|
-
});
|
|
885
|
-
var OrderShippedPayload = defineSchemaModel6({
|
|
886
|
-
name: "OrderShippedEventPayload",
|
|
887
|
-
fields: {
|
|
888
|
-
orderId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
889
|
-
orderNumber: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
890
|
-
trackingNumber: {
|
|
891
|
-
type: ScalarTypeEnum6.String_unsecure(),
|
|
892
|
-
isOptional: true
|
|
893
|
-
},
|
|
894
|
-
trackingUrl: { type: ScalarTypeEnum6.String_unsecure(), isOptional: true },
|
|
895
|
-
carrier: { type: ScalarTypeEnum6.String_unsecure(), isOptional: true },
|
|
896
|
-
timestamp: { type: ScalarTypeEnum6.DateTime(), isOptional: false }
|
|
897
|
-
}
|
|
898
|
-
});
|
|
899
|
-
var OrderCompletedPayload = defineSchemaModel6({
|
|
900
|
-
name: "OrderCompletedEventPayload",
|
|
901
|
-
fields: {
|
|
902
|
-
orderId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
903
|
-
orderNumber: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
904
|
-
buyerId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
905
|
-
storeId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
|
|
906
|
-
total: { type: ScalarTypeEnum6.Float_unsecure(), isOptional: false },
|
|
907
|
-
sellerPayout: { type: ScalarTypeEnum6.Float_unsecure(), isOptional: false },
|
|
908
|
-
timestamp: { type: ScalarTypeEnum6.DateTime(), isOptional: false }
|
|
909
|
-
}
|
|
910
|
-
});
|
|
911
|
-
var OrderCreatedEvent = defineEvent3({
|
|
912
|
-
meta: {
|
|
913
|
-
key: "marketplace.order.created",
|
|
914
|
-
version: "1.0.0",
|
|
915
|
-
description: "A new order has been created.",
|
|
916
|
-
stability: "experimental",
|
|
917
|
-
owners: ["@marketplace-team"],
|
|
918
|
-
tags: ["marketplace", "order"]
|
|
919
|
-
},
|
|
920
|
-
payload: OrderCreatedPayload
|
|
921
|
-
});
|
|
922
|
-
var OrderPaidEvent = defineEvent3({
|
|
923
|
-
meta: {
|
|
924
|
-
key: "marketplace.order.paid",
|
|
925
|
-
version: "1.0.0",
|
|
926
|
-
description: "An order has been paid.",
|
|
927
|
-
stability: "experimental",
|
|
928
|
-
owners: ["@marketplace-team"],
|
|
929
|
-
tags: ["marketplace", "order"]
|
|
930
|
-
},
|
|
931
|
-
payload: OrderPaidPayload
|
|
932
|
-
});
|
|
933
|
-
var OrderStatusUpdatedEvent = defineEvent3({
|
|
934
|
-
meta: {
|
|
935
|
-
key: "marketplace.order.statusUpdated",
|
|
936
|
-
version: "1.0.0",
|
|
937
|
-
description: "An order status has been updated.",
|
|
938
|
-
stability: "experimental",
|
|
939
|
-
owners: ["@marketplace-team"],
|
|
940
|
-
tags: ["marketplace", "order"]
|
|
941
|
-
},
|
|
942
|
-
payload: OrderStatusUpdatedPayload
|
|
943
|
-
});
|
|
944
|
-
var OrderShippedEvent = defineEvent3({
|
|
945
|
-
meta: {
|
|
946
|
-
key: "marketplace.order.shipped",
|
|
947
|
-
version: "1.0.0",
|
|
948
|
-
description: "An order has been shipped.",
|
|
949
|
-
stability: "experimental",
|
|
950
|
-
owners: ["@marketplace-team"],
|
|
951
|
-
tags: ["marketplace", "order"]
|
|
952
|
-
},
|
|
953
|
-
payload: OrderShippedPayload
|
|
954
|
-
});
|
|
955
|
-
var OrderCompletedEvent = defineEvent3({
|
|
956
|
-
meta: {
|
|
957
|
-
key: "marketplace.order.completed",
|
|
958
|
-
version: "1.0.0",
|
|
959
|
-
description: "An order has been completed.",
|
|
960
|
-
stability: "experimental",
|
|
961
|
-
owners: ["@marketplace-team"],
|
|
962
|
-
tags: ["marketplace", "order"]
|
|
963
|
-
},
|
|
964
|
-
payload: OrderCompletedPayload
|
|
965
|
-
});
|
|
966
|
-
// src/payout/payout.enum.ts
|
|
975
|
+
// src/review/review.enum.ts
|
|
967
976
|
import { defineEnum as defineEnum4 } from "@contractspec/lib.schema";
|
|
968
|
-
var
|
|
977
|
+
var ReviewStatusEnum = defineEnum4("ReviewStatus", [
|
|
969
978
|
"PENDING",
|
|
970
|
-
"
|
|
971
|
-
"
|
|
972
|
-
"
|
|
973
|
-
"CANCELLED"
|
|
979
|
+
"APPROVED",
|
|
980
|
+
"REJECTED",
|
|
981
|
+
"FLAGGED"
|
|
974
982
|
]);
|
|
975
983
|
|
|
976
|
-
// src/
|
|
977
|
-
import { defineSchemaModel as defineSchemaModel7, ScalarTypeEnum as ScalarTypeEnum7 } from "@contractspec/lib.schema";
|
|
978
|
-
var PayoutModel = defineSchemaModel7({
|
|
979
|
-
name: "PayoutModel",
|
|
980
|
-
description: "A payout to seller",
|
|
981
|
-
fields: {
|
|
982
|
-
id: { type: ScalarTypeEnum7.String_unsecure(), isOptional: false },
|
|
983
|
-
payoutNumber: { type: ScalarTypeEnum7.String_unsecure(), isOptional: false },
|
|
984
|
-
storeId: { type: ScalarTypeEnum7.String_unsecure(), isOptional: false },
|
|
985
|
-
status: { type: PayoutStatusEnum, isOptional: false },
|
|
986
|
-
grossAmount: { type: ScalarTypeEnum7.Float_unsecure(), isOptional: false },
|
|
987
|
-
platformFees: { type: ScalarTypeEnum7.Float_unsecure(), isOptional: false },
|
|
988
|
-
netAmount: { type: ScalarTypeEnum7.Float_unsecure(), isOptional: false },
|
|
989
|
-
currency: { type: ScalarTypeEnum7.String_unsecure(), isOptional: false },
|
|
990
|
-
periodStart: { type: ScalarTypeEnum7.DateTime(), isOptional: false },
|
|
991
|
-
periodEnd: { type: ScalarTypeEnum7.DateTime(), isOptional: false },
|
|
992
|
-
orderCount: { type: ScalarTypeEnum7.Int_unsecure(), isOptional: false },
|
|
993
|
-
createdAt: { type: ScalarTypeEnum7.DateTime(), isOptional: false },
|
|
994
|
-
paidAt: { type: ScalarTypeEnum7.DateTime(), isOptional: true }
|
|
995
|
-
}
|
|
996
|
-
});
|
|
997
|
-
var ListPayoutsInputModel = defineSchemaModel7({
|
|
998
|
-
name: "ListPayoutsInput",
|
|
999
|
-
fields: {
|
|
1000
|
-
storeId: { type: ScalarTypeEnum7.String_unsecure(), isOptional: false },
|
|
1001
|
-
status: { type: PayoutStatusEnum, isOptional: true },
|
|
1002
|
-
limit: {
|
|
1003
|
-
type: ScalarTypeEnum7.Int_unsecure(),
|
|
1004
|
-
isOptional: true,
|
|
1005
|
-
defaultValue: 20
|
|
1006
|
-
},
|
|
1007
|
-
offset: {
|
|
1008
|
-
type: ScalarTypeEnum7.Int_unsecure(),
|
|
1009
|
-
isOptional: true,
|
|
1010
|
-
defaultValue: 0
|
|
1011
|
-
}
|
|
1012
|
-
}
|
|
1013
|
-
});
|
|
1014
|
-
var ListPayoutsOutputModel = defineSchemaModel7({
|
|
1015
|
-
name: "ListPayoutsOutput",
|
|
1016
|
-
fields: {
|
|
1017
|
-
payouts: { type: PayoutModel, isArray: true, isOptional: false },
|
|
1018
|
-
total: { type: ScalarTypeEnum7.Int_unsecure(), isOptional: false },
|
|
1019
|
-
totalPending: { type: ScalarTypeEnum7.Float_unsecure(), isOptional: false }
|
|
1020
|
-
}
|
|
1021
|
-
});
|
|
1022
|
-
|
|
1023
|
-
// src/payout/payout.operations.ts
|
|
1024
|
-
import { defineQuery as defineQuery2 } from "@contractspec/lib.contracts-spec/operations";
|
|
1025
|
-
var OWNERS4 = ["@example.marketplace"];
|
|
1026
|
-
var ListPayoutsContract = defineQuery2({
|
|
1027
|
-
meta: {
|
|
1028
|
-
key: "marketplace.payout.list",
|
|
1029
|
-
version: "1.0.0",
|
|
1030
|
-
stability: "stable",
|
|
1031
|
-
owners: [...OWNERS4],
|
|
1032
|
-
tags: ["marketplace", "payout", "list"],
|
|
1033
|
-
description: "List payouts for a store.",
|
|
1034
|
-
goal: "View payout history.",
|
|
1035
|
-
context: "Seller dashboard."
|
|
1036
|
-
},
|
|
1037
|
-
io: { input: ListPayoutsInputModel, output: ListPayoutsOutputModel },
|
|
1038
|
-
policy: { auth: "user" },
|
|
1039
|
-
acceptance: {
|
|
1040
|
-
scenarios: [
|
|
1041
|
-
{
|
|
1042
|
-
key: "list-payouts-happy-path",
|
|
1043
|
-
given: ["Store has payout history"],
|
|
1044
|
-
when: ["Seller lists payouts"],
|
|
1045
|
-
then: ["List of payouts is returned"]
|
|
1046
|
-
}
|
|
1047
|
-
],
|
|
1048
|
-
examples: [
|
|
1049
|
-
{
|
|
1050
|
-
key: "list-recent",
|
|
1051
|
-
input: { limit: 10, offset: 0 },
|
|
1052
|
-
output: { items: [], total: 5, hasMore: false }
|
|
1053
|
-
}
|
|
1054
|
-
]
|
|
1055
|
-
}
|
|
1056
|
-
});
|
|
1057
|
-
|
|
1058
|
-
// src/payout/payout.event.ts
|
|
1059
|
-
import { ScalarTypeEnum as ScalarTypeEnum8, defineSchemaModel as defineSchemaModel8 } from "@contractspec/lib.schema";
|
|
984
|
+
// src/review/review.event.ts
|
|
1060
985
|
import { defineEvent as defineEvent4 } from "@contractspec/lib.contracts-spec";
|
|
1061
|
-
|
|
1062
|
-
|
|
986
|
+
import { defineSchemaModel as defineSchemaModel7, ScalarTypeEnum as ScalarTypeEnum7 } from "@contractspec/lib.schema";
|
|
987
|
+
var ReviewCreatedPayload = defineSchemaModel7({
|
|
988
|
+
name: "ReviewCreatedEventPayload",
|
|
1063
989
|
fields: {
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
storeId: { type:
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
timestamp: { type:
|
|
990
|
+
reviewId: { type: ScalarTypeEnum7.String_unsecure(), isOptional: false },
|
|
991
|
+
productId: { type: ScalarTypeEnum7.String_unsecure(), isOptional: true },
|
|
992
|
+
storeId: { type: ScalarTypeEnum7.String_unsecure(), isOptional: true },
|
|
993
|
+
authorId: { type: ScalarTypeEnum7.String_unsecure(), isOptional: false },
|
|
994
|
+
rating: { type: ScalarTypeEnum7.Int_unsecure(), isOptional: false },
|
|
995
|
+
isVerifiedPurchase: { type: ScalarTypeEnum7.Boolean(), isOptional: false },
|
|
996
|
+
timestamp: { type: ScalarTypeEnum7.DateTime(), isOptional: false }
|
|
1071
997
|
}
|
|
1072
998
|
});
|
|
1073
|
-
var
|
|
1074
|
-
name: "
|
|
999
|
+
var ReviewRespondedPayload = defineSchemaModel7({
|
|
1000
|
+
name: "ReviewRespondedEventPayload",
|
|
1075
1001
|
fields: {
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
paymentReference: {
|
|
1081
|
-
type: ScalarTypeEnum8.String_unsecure(),
|
|
1082
|
-
isOptional: true
|
|
1083
|
-
},
|
|
1084
|
-
timestamp: { type: ScalarTypeEnum8.DateTime(), isOptional: false }
|
|
1002
|
+
reviewId: { type: ScalarTypeEnum7.String_unsecure(), isOptional: false },
|
|
1003
|
+
responseId: { type: ScalarTypeEnum7.String_unsecure(), isOptional: false },
|
|
1004
|
+
authorId: { type: ScalarTypeEnum7.String_unsecure(), isOptional: false },
|
|
1005
|
+
timestamp: { type: ScalarTypeEnum7.DateTime(), isOptional: false }
|
|
1085
1006
|
}
|
|
1086
1007
|
});
|
|
1087
|
-
var
|
|
1008
|
+
var ReviewCreatedEvent = defineEvent4({
|
|
1088
1009
|
meta: {
|
|
1089
|
-
key: "marketplace.
|
|
1010
|
+
key: "marketplace.review.created",
|
|
1090
1011
|
version: "1.0.0",
|
|
1091
|
-
description: "A
|
|
1012
|
+
description: "A review has been created.",
|
|
1092
1013
|
stability: "experimental",
|
|
1093
1014
|
owners: ["@marketplace-team"],
|
|
1094
|
-
tags: ["marketplace", "
|
|
1015
|
+
tags: ["marketplace", "review"]
|
|
1095
1016
|
},
|
|
1096
|
-
payload:
|
|
1017
|
+
payload: ReviewCreatedPayload
|
|
1097
1018
|
});
|
|
1098
|
-
var
|
|
1019
|
+
var ReviewRespondedEvent = defineEvent4({
|
|
1099
1020
|
meta: {
|
|
1100
|
-
key: "marketplace.
|
|
1021
|
+
key: "marketplace.review.responded",
|
|
1101
1022
|
version: "1.0.0",
|
|
1102
|
-
description: "A
|
|
1023
|
+
description: "A seller has responded to a review.",
|
|
1103
1024
|
stability: "experimental",
|
|
1104
1025
|
owners: ["@marketplace-team"],
|
|
1105
|
-
tags: ["marketplace", "
|
|
1026
|
+
tags: ["marketplace", "review"]
|
|
1106
1027
|
},
|
|
1107
|
-
payload:
|
|
1028
|
+
payload: ReviewRespondedPayload
|
|
1108
1029
|
});
|
|
1109
|
-
// src/review/review.enum.ts
|
|
1110
|
-
import { defineEnum as defineEnum5 } from "@contractspec/lib.schema";
|
|
1111
|
-
var ReviewStatusEnum = defineEnum5("ReviewStatus", [
|
|
1112
|
-
"PENDING",
|
|
1113
|
-
"APPROVED",
|
|
1114
|
-
"REJECTED",
|
|
1115
|
-
"FLAGGED"
|
|
1116
|
-
]);
|
|
1117
1030
|
|
|
1118
1031
|
// src/review/review.schema.ts
|
|
1119
|
-
import { defineSchemaModel as
|
|
1120
|
-
var ReviewModel =
|
|
1032
|
+
import { defineSchemaModel as defineSchemaModel8, ScalarTypeEnum as ScalarTypeEnum8 } from "@contractspec/lib.schema";
|
|
1033
|
+
var ReviewModel = defineSchemaModel8({
|
|
1121
1034
|
name: "ReviewModel",
|
|
1122
1035
|
description: "A customer review",
|
|
1123
1036
|
fields: {
|
|
1124
|
-
id: { type:
|
|
1125
|
-
productId: { type:
|
|
1126
|
-
storeId: { type:
|
|
1127
|
-
authorId: { type:
|
|
1128
|
-
rating: { type:
|
|
1129
|
-
title: { type:
|
|
1130
|
-
content: { type:
|
|
1037
|
+
id: { type: ScalarTypeEnum8.String_unsecure(), isOptional: false },
|
|
1038
|
+
productId: { type: ScalarTypeEnum8.String_unsecure(), isOptional: true },
|
|
1039
|
+
storeId: { type: ScalarTypeEnum8.String_unsecure(), isOptional: true },
|
|
1040
|
+
authorId: { type: ScalarTypeEnum8.String_unsecure(), isOptional: false },
|
|
1041
|
+
rating: { type: ScalarTypeEnum8.Int_unsecure(), isOptional: false },
|
|
1042
|
+
title: { type: ScalarTypeEnum8.String_unsecure(), isOptional: true },
|
|
1043
|
+
content: { type: ScalarTypeEnum8.String_unsecure(), isOptional: true },
|
|
1131
1044
|
status: { type: ReviewStatusEnum, isOptional: false },
|
|
1132
|
-
isVerifiedPurchase: { type:
|
|
1133
|
-
helpfulCount: { type:
|
|
1134
|
-
hasResponse: { type:
|
|
1135
|
-
createdAt: { type:
|
|
1045
|
+
isVerifiedPurchase: { type: ScalarTypeEnum8.Boolean(), isOptional: false },
|
|
1046
|
+
helpfulCount: { type: ScalarTypeEnum8.Int_unsecure(), isOptional: false },
|
|
1047
|
+
hasResponse: { type: ScalarTypeEnum8.Boolean(), isOptional: false },
|
|
1048
|
+
createdAt: { type: ScalarTypeEnum8.DateTime(), isOptional: false }
|
|
1136
1049
|
}
|
|
1137
1050
|
});
|
|
1138
|
-
var CreateReviewInputModel =
|
|
1051
|
+
var CreateReviewInputModel = defineSchemaModel8({
|
|
1139
1052
|
name: "CreateReviewInput",
|
|
1140
1053
|
fields: {
|
|
1141
|
-
productId: { type:
|
|
1142
|
-
storeId: { type:
|
|
1143
|
-
orderId: { type:
|
|
1144
|
-
rating: { type:
|
|
1145
|
-
title: { type:
|
|
1146
|
-
content: { type:
|
|
1054
|
+
productId: { type: ScalarTypeEnum8.String_unsecure(), isOptional: true },
|
|
1055
|
+
storeId: { type: ScalarTypeEnum8.String_unsecure(), isOptional: true },
|
|
1056
|
+
orderId: { type: ScalarTypeEnum8.String_unsecure(), isOptional: true },
|
|
1057
|
+
rating: { type: ScalarTypeEnum8.Int_unsecure(), isOptional: false },
|
|
1058
|
+
title: { type: ScalarTypeEnum8.String_unsecure(), isOptional: true },
|
|
1059
|
+
content: { type: ScalarTypeEnum8.String_unsecure(), isOptional: true }
|
|
1147
1060
|
}
|
|
1148
1061
|
});
|
|
1149
|
-
var ListReviewsInputModel =
|
|
1062
|
+
var ListReviewsInputModel = defineSchemaModel8({
|
|
1150
1063
|
name: "ListReviewsInput",
|
|
1151
1064
|
fields: {
|
|
1152
|
-
productId: { type:
|
|
1153
|
-
storeId: { type:
|
|
1065
|
+
productId: { type: ScalarTypeEnum8.String_unsecure(), isOptional: true },
|
|
1066
|
+
storeId: { type: ScalarTypeEnum8.String_unsecure(), isOptional: true },
|
|
1154
1067
|
status: { type: ReviewStatusEnum, isOptional: true },
|
|
1155
|
-
minRating: { type:
|
|
1068
|
+
minRating: { type: ScalarTypeEnum8.Int_unsecure(), isOptional: true },
|
|
1156
1069
|
limit: {
|
|
1157
|
-
type:
|
|
1070
|
+
type: ScalarTypeEnum8.Int_unsecure(),
|
|
1158
1071
|
isOptional: true,
|
|
1159
1072
|
defaultValue: 20
|
|
1160
1073
|
},
|
|
1161
1074
|
offset: {
|
|
1162
|
-
type:
|
|
1075
|
+
type: ScalarTypeEnum8.Int_unsecure(),
|
|
1163
1076
|
isOptional: true,
|
|
1164
1077
|
defaultValue: 0
|
|
1165
1078
|
}
|
|
1166
1079
|
}
|
|
1167
1080
|
});
|
|
1168
|
-
var ListReviewsOutputModel =
|
|
1081
|
+
var ListReviewsOutputModel = defineSchemaModel8({
|
|
1169
1082
|
name: "ListReviewsOutput",
|
|
1170
1083
|
fields: {
|
|
1171
1084
|
reviews: { type: ReviewModel, isArray: true, isOptional: false },
|
|
1172
|
-
total: { type:
|
|
1173
|
-
averageRating: { type:
|
|
1174
|
-
ratingDistribution: { type:
|
|
1085
|
+
total: { type: ScalarTypeEnum8.Int_unsecure(), isOptional: false },
|
|
1086
|
+
averageRating: { type: ScalarTypeEnum8.Float_unsecure(), isOptional: false },
|
|
1087
|
+
ratingDistribution: { type: ScalarTypeEnum8.JSON(), isOptional: false }
|
|
1175
1088
|
}
|
|
1176
1089
|
});
|
|
1177
1090
|
|
|
1178
1091
|
// src/review/review.operations.ts
|
|
1179
1092
|
import {
|
|
1180
|
-
defineCommand as
|
|
1093
|
+
defineCommand as defineCommand3,
|
|
1181
1094
|
defineQuery as defineQuery3
|
|
1182
1095
|
} from "@contractspec/lib.contracts-spec/operations";
|
|
1183
|
-
var
|
|
1184
|
-
var CreateReviewContract =
|
|
1096
|
+
var OWNERS4 = ["@example.marketplace"];
|
|
1097
|
+
var CreateReviewContract = defineCommand3({
|
|
1185
1098
|
meta: {
|
|
1186
1099
|
key: "marketplace.review.create",
|
|
1187
1100
|
version: "1.0.0",
|
|
1188
1101
|
stability: "stable",
|
|
1189
|
-
owners: [...
|
|
1102
|
+
owners: [...OWNERS4],
|
|
1190
1103
|
tags: ["marketplace", "review", "create"],
|
|
1191
1104
|
description: "Create a product/store review.",
|
|
1192
1105
|
goal: "Allow buyers to leave feedback.",
|
|
@@ -1228,7 +1141,7 @@ var ListReviewsContract = defineQuery3({
|
|
|
1228
1141
|
key: "marketplace.review.list",
|
|
1229
1142
|
version: "1.0.0",
|
|
1230
1143
|
stability: "stable",
|
|
1231
|
-
owners: [...
|
|
1144
|
+
owners: [...OWNERS4],
|
|
1232
1145
|
tags: ["marketplace", "review", "list"],
|
|
1233
1146
|
description: "List reviews with filters.",
|
|
1234
1147
|
goal: "Display product/store reviews.",
|
|
@@ -1254,299 +1167,143 @@ var ListReviewsContract = defineQuery3({
|
|
|
1254
1167
|
]
|
|
1255
1168
|
}
|
|
1256
1169
|
});
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1170
|
+
// src/store/store.enum.ts
|
|
1171
|
+
import { defineEnum as defineEnum5 } from "@contractspec/lib.schema";
|
|
1172
|
+
var StoreStatusEnum = defineEnum5("StoreStatus", [
|
|
1173
|
+
"PENDING",
|
|
1174
|
+
"ACTIVE",
|
|
1175
|
+
"SUSPENDED",
|
|
1176
|
+
"CLOSED"
|
|
1177
|
+
]);
|
|
1178
|
+
|
|
1179
|
+
// src/store/store.event.ts
|
|
1180
|
+
import { defineEvent as defineEvent5 } from "@contractspec/lib.contracts-spec";
|
|
1181
|
+
import { defineSchemaModel as defineSchemaModel9, ScalarTypeEnum as ScalarTypeEnum9 } from "@contractspec/lib.schema";
|
|
1182
|
+
var StoreCreatedPayload = defineSchemaModel9({
|
|
1183
|
+
name: "StoreCreatedEventPayload",
|
|
1263
1184
|
fields: {
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
isVerifiedPurchase: { type: ScalarTypeEnum10.Boolean(), isOptional: false },
|
|
1270
|
-
timestamp: { type: ScalarTypeEnum10.DateTime(), isOptional: false }
|
|
1185
|
+
storeId: { type: ScalarTypeEnum9.String_unsecure(), isOptional: false },
|
|
1186
|
+
name: { type: ScalarTypeEnum9.String_unsecure(), isOptional: false },
|
|
1187
|
+
slug: { type: ScalarTypeEnum9.String_unsecure(), isOptional: false },
|
|
1188
|
+
ownerId: { type: ScalarTypeEnum9.String_unsecure(), isOptional: false },
|
|
1189
|
+
timestamp: { type: ScalarTypeEnum9.DateTime(), isOptional: false }
|
|
1271
1190
|
}
|
|
1272
1191
|
});
|
|
1273
|
-
var
|
|
1274
|
-
name: "
|
|
1192
|
+
var StoreStatusChangedPayload = defineSchemaModel9({
|
|
1193
|
+
name: "StoreStatusChangedEventPayload",
|
|
1275
1194
|
fields: {
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1195
|
+
storeId: { type: ScalarTypeEnum9.String_unsecure(), isOptional: false },
|
|
1196
|
+
previousStatus: {
|
|
1197
|
+
type: ScalarTypeEnum9.String_unsecure(),
|
|
1198
|
+
isOptional: false
|
|
1199
|
+
},
|
|
1200
|
+
newStatus: { type: ScalarTypeEnum9.String_unsecure(), isOptional: false },
|
|
1201
|
+
reason: { type: ScalarTypeEnum9.String_unsecure(), isOptional: true },
|
|
1202
|
+
timestamp: { type: ScalarTypeEnum9.DateTime(), isOptional: false }
|
|
1280
1203
|
}
|
|
1281
1204
|
});
|
|
1282
|
-
var
|
|
1205
|
+
var StoreCreatedEvent = defineEvent5({
|
|
1283
1206
|
meta: {
|
|
1284
|
-
key: "marketplace.
|
|
1207
|
+
key: "marketplace.store.created",
|
|
1285
1208
|
version: "1.0.0",
|
|
1286
|
-
description: "A
|
|
1209
|
+
description: "A new seller store has been created.",
|
|
1287
1210
|
stability: "experimental",
|
|
1288
1211
|
owners: ["@marketplace-team"],
|
|
1289
|
-
tags: ["marketplace", "
|
|
1212
|
+
tags: ["marketplace", "store"]
|
|
1290
1213
|
},
|
|
1291
|
-
payload:
|
|
1214
|
+
payload: StoreCreatedPayload
|
|
1292
1215
|
});
|
|
1293
|
-
var
|
|
1216
|
+
var StoreStatusChangedEvent = defineEvent5({
|
|
1294
1217
|
meta: {
|
|
1295
|
-
key: "marketplace.
|
|
1218
|
+
key: "marketplace.store.statusChanged",
|
|
1296
1219
|
version: "1.0.0",
|
|
1297
|
-
description: "A
|
|
1220
|
+
description: "A store status has changed.",
|
|
1298
1221
|
stability: "experimental",
|
|
1299
1222
|
owners: ["@marketplace-team"],
|
|
1300
|
-
tags: ["marketplace", "
|
|
1223
|
+
tags: ["marketplace", "store"]
|
|
1301
1224
|
},
|
|
1302
|
-
payload:
|
|
1225
|
+
payload: StoreStatusChangedPayload
|
|
1303
1226
|
});
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
name: "Fashion Boutique",
|
|
1323
|
-
status: "PENDING",
|
|
1324
|
-
productCount: 0,
|
|
1325
|
-
rating: 0
|
|
1227
|
+
|
|
1228
|
+
// src/store/store.schema.ts
|
|
1229
|
+
import { defineSchemaModel as defineSchemaModel10, ScalarTypeEnum as ScalarTypeEnum10 } from "@contractspec/lib.schema";
|
|
1230
|
+
var StoreModel = defineSchemaModel10({
|
|
1231
|
+
name: "StoreModel",
|
|
1232
|
+
description: "A seller store",
|
|
1233
|
+
fields: {
|
|
1234
|
+
id: { type: ScalarTypeEnum10.String_unsecure(), isOptional: false },
|
|
1235
|
+
name: { type: ScalarTypeEnum10.String_unsecure(), isOptional: false },
|
|
1236
|
+
slug: { type: ScalarTypeEnum10.String_unsecure(), isOptional: false },
|
|
1237
|
+
description: { type: ScalarTypeEnum10.String_unsecure(), isOptional: true },
|
|
1238
|
+
status: { type: StoreStatusEnum, isOptional: false },
|
|
1239
|
+
ownerId: { type: ScalarTypeEnum10.String_unsecure(), isOptional: false },
|
|
1240
|
+
logoFileId: { type: ScalarTypeEnum10.String_unsecure(), isOptional: true },
|
|
1241
|
+
isVerified: { type: ScalarTypeEnum10.Boolean(), isOptional: false },
|
|
1242
|
+
totalProducts: { type: ScalarTypeEnum10.Int_unsecure(), isOptional: false },
|
|
1243
|
+
averageRating: { type: ScalarTypeEnum10.Float_unsecure(), isOptional: false },
|
|
1244
|
+
createdAt: { type: ScalarTypeEnum10.DateTime(), isOptional: false }
|
|
1326
1245
|
}
|
|
1327
|
-
|
|
1328
|
-
var
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
name:
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
},
|
|
1338
|
-
{
|
|
1339
|
-
id: "prod-2",
|
|
1340
|
-
name: "Smart Watch",
|
|
1341
|
-
storeId: "store-1",
|
|
1342
|
-
price: 249.99,
|
|
1343
|
-
currency: "USD",
|
|
1344
|
-
status: "ACTIVE",
|
|
1345
|
-
stock: 50
|
|
1346
|
-
},
|
|
1347
|
-
{
|
|
1348
|
-
id: "prod-3",
|
|
1349
|
-
name: "Garden Tools Set",
|
|
1350
|
-
storeId: "store-2",
|
|
1351
|
-
price: 89.99,
|
|
1352
|
-
currency: "USD",
|
|
1353
|
-
status: "ACTIVE",
|
|
1354
|
-
stock: 30
|
|
1355
|
-
},
|
|
1356
|
-
{
|
|
1357
|
-
id: "prod-4",
|
|
1358
|
-
name: "Indoor Plant Kit",
|
|
1359
|
-
storeId: "store-2",
|
|
1360
|
-
price: 45.99,
|
|
1361
|
-
currency: "USD",
|
|
1362
|
-
status: "ACTIVE",
|
|
1363
|
-
stock: 75
|
|
1364
|
-
},
|
|
1365
|
-
{
|
|
1366
|
-
id: "prod-5",
|
|
1367
|
-
name: "LED Desk Lamp",
|
|
1368
|
-
storeId: "store-1",
|
|
1369
|
-
price: 34.99,
|
|
1370
|
-
currency: "USD",
|
|
1371
|
-
status: "OUT_OF_STOCK",
|
|
1372
|
-
stock: 0
|
|
1246
|
+
});
|
|
1247
|
+
var CreateStoreInputModel = defineSchemaModel10({
|
|
1248
|
+
name: "CreateStoreInput",
|
|
1249
|
+
fields: {
|
|
1250
|
+
name: { type: ScalarTypeEnum10.NonEmptyString(), isOptional: false },
|
|
1251
|
+
slug: { type: ScalarTypeEnum10.NonEmptyString(), isOptional: false },
|
|
1252
|
+
description: { type: ScalarTypeEnum10.String_unsecure(), isOptional: true },
|
|
1253
|
+
email: { type: ScalarTypeEnum10.EmailAddress(), isOptional: true },
|
|
1254
|
+
country: { type: ScalarTypeEnum10.String_unsecure(), isOptional: true },
|
|
1255
|
+
currency: { type: ScalarTypeEnum10.String_unsecure(), isOptional: true }
|
|
1373
1256
|
}
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
customerId: "cust-2",
|
|
1390
|
-
total: 135.98,
|
|
1391
|
-
currency: "USD",
|
|
1392
|
-
status: "SHIPPED",
|
|
1393
|
-
itemCount: 2,
|
|
1394
|
-
createdAt: "2024-01-14T14:00:00Z"
|
|
1257
|
+
});
|
|
1258
|
+
|
|
1259
|
+
// src/store/store.operations.ts
|
|
1260
|
+
import { defineCommand as defineCommand4 } from "@contractspec/lib.contracts-spec/operations";
|
|
1261
|
+
var OWNERS5 = ["@example.marketplace"];
|
|
1262
|
+
var CreateStoreContract = defineCommand4({
|
|
1263
|
+
meta: {
|
|
1264
|
+
key: "marketplace.store.create",
|
|
1265
|
+
version: "1.0.0",
|
|
1266
|
+
stability: "stable",
|
|
1267
|
+
owners: [...OWNERS5],
|
|
1268
|
+
tags: ["marketplace", "store", "create"],
|
|
1269
|
+
description: "Create a new seller store.",
|
|
1270
|
+
goal: "Allow users to become sellers on the marketplace.",
|
|
1271
|
+
context: "Seller onboarding."
|
|
1395
1272
|
},
|
|
1396
|
-
{
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1273
|
+
io: { input: CreateStoreInputModel, output: StoreModel },
|
|
1274
|
+
policy: { auth: "user" },
|
|
1275
|
+
sideEffects: {
|
|
1276
|
+
emits: [
|
|
1277
|
+
{
|
|
1278
|
+
key: "marketplace.store.created",
|
|
1279
|
+
version: "1.0.0",
|
|
1280
|
+
when: "Store is created",
|
|
1281
|
+
payload: StoreModel
|
|
1282
|
+
}
|
|
1283
|
+
],
|
|
1284
|
+
audit: ["marketplace.store.created"]
|
|
1405
1285
|
},
|
|
1406
|
-
{
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
itemCount: 1,
|
|
1414
|
-
createdAt: "2024-01-16T12:00:00Z"
|
|
1415
|
-
}
|
|
1416
|
-
];
|
|
1417
|
-
function formatCurrency(value, currency = "USD") {
|
|
1418
|
-
return new Intl.NumberFormat("en-US", {
|
|
1419
|
-
style: "currency",
|
|
1420
|
-
currency,
|
|
1421
|
-
minimumFractionDigits: 2
|
|
1422
|
-
}).format(value);
|
|
1423
|
-
}
|
|
1424
|
-
var marketplaceDashboardMarkdownRenderer = {
|
|
1425
|
-
target: "markdown",
|
|
1426
|
-
render: async (desc) => {
|
|
1427
|
-
if (desc.source.type !== "component" || desc.source.componentKey !== "MarketplaceDashboard") {
|
|
1428
|
-
throw new Error("marketplaceDashboardMarkdownRenderer: not MarketplaceDashboard");
|
|
1429
|
-
}
|
|
1430
|
-
const stores = mockStores;
|
|
1431
|
-
const products = mockProducts;
|
|
1432
|
-
const orders = mockOrders;
|
|
1433
|
-
const activeStores = stores.filter((s) => s.status === "ACTIVE");
|
|
1434
|
-
const activeProducts = products.filter((p) => p.status === "ACTIVE");
|
|
1435
|
-
const totalRevenue = orders.reduce((sum, o) => sum + o.total, 0);
|
|
1436
|
-
const pendingOrders = orders.filter((o) => o.status === "PENDING" || o.status === "PROCESSING");
|
|
1437
|
-
const lines = [
|
|
1438
|
-
"# Marketplace Dashboard",
|
|
1439
|
-
"",
|
|
1440
|
-
"> Two-sided marketplace overview",
|
|
1441
|
-
"",
|
|
1442
|
-
"## Summary",
|
|
1443
|
-
"",
|
|
1444
|
-
"| Metric | Value |",
|
|
1445
|
-
"|--------|-------|",
|
|
1446
|
-
`| Active Stores | ${activeStores.length} |`,
|
|
1447
|
-
`| Active Products | ${activeProducts.length} |`,
|
|
1448
|
-
`| Total Orders | ${orders.length} |`,
|
|
1449
|
-
`| Total Revenue | ${formatCurrency(totalRevenue)} |`,
|
|
1450
|
-
`| Pending Orders | ${pendingOrders.length} |`,
|
|
1451
|
-
"",
|
|
1452
|
-
"## Top Stores",
|
|
1453
|
-
"",
|
|
1454
|
-
"| Store | Products | Rating | Status |",
|
|
1455
|
-
"|-------|----------|--------|--------|"
|
|
1456
|
-
];
|
|
1457
|
-
for (const store of stores.slice(0, 5)) {
|
|
1458
|
-
lines.push(`| ${store.name} | ${store.productCount} | ⭐ ${store.rating || "N/A"} | ${store.status} |`);
|
|
1459
|
-
}
|
|
1460
|
-
lines.push("");
|
|
1461
|
-
lines.push("## Recent Orders");
|
|
1462
|
-
lines.push("");
|
|
1463
|
-
lines.push("| Order | Items | Total | Status | Date |");
|
|
1464
|
-
lines.push("|-------|-------|-------|--------|------|");
|
|
1465
|
-
for (const order of orders.slice(0, 10)) {
|
|
1466
|
-
const date = new Date(order.createdAt).toLocaleDateString();
|
|
1467
|
-
lines.push(`| ${order.id} | ${order.itemCount} | ${formatCurrency(order.total, order.currency)} | ${order.status} | ${date} |`);
|
|
1468
|
-
}
|
|
1469
|
-
return {
|
|
1470
|
-
mimeType: "text/markdown",
|
|
1471
|
-
body: lines.join(`
|
|
1472
|
-
`)
|
|
1473
|
-
};
|
|
1474
|
-
}
|
|
1475
|
-
};
|
|
1476
|
-
var productCatalogMarkdownRenderer = {
|
|
1477
|
-
target: "markdown",
|
|
1478
|
-
render: async (desc) => {
|
|
1479
|
-
if (desc.source.type !== "component" || desc.source.componentKey !== "ProductCatalog") {
|
|
1480
|
-
throw new Error("productCatalogMarkdownRenderer: not ProductCatalog");
|
|
1481
|
-
}
|
|
1482
|
-
const products = mockProducts;
|
|
1483
|
-
const stores = mockStores;
|
|
1484
|
-
const lines = [
|
|
1485
|
-
"# Product Catalog",
|
|
1486
|
-
"",
|
|
1487
|
-
"> Browse products across all marketplace stores",
|
|
1488
|
-
""
|
|
1489
|
-
];
|
|
1490
|
-
for (const store of stores.filter((s) => s.status === "ACTIVE")) {
|
|
1491
|
-
const storeProducts = products.filter((p) => p.storeId === store.id);
|
|
1492
|
-
if (storeProducts.length === 0)
|
|
1493
|
-
continue;
|
|
1494
|
-
lines.push(`## ${store.name}`);
|
|
1495
|
-
lines.push("");
|
|
1496
|
-
lines.push("| Product | Price | Stock | Status |");
|
|
1497
|
-
lines.push("|---------|-------|-------|--------|");
|
|
1498
|
-
for (const product of storeProducts) {
|
|
1499
|
-
const stockStatus = product.stock > 0 ? `${product.stock} in stock` : "Out of stock";
|
|
1500
|
-
lines.push(`| ${product.name} | ${formatCurrency(product.price, product.currency)} | ${stockStatus} | ${product.status} |`);
|
|
1286
|
+
acceptance: {
|
|
1287
|
+
scenarios: [
|
|
1288
|
+
{
|
|
1289
|
+
key: "create-store-happy-path",
|
|
1290
|
+
given: ["User is authenticated"],
|
|
1291
|
+
when: ["User creates a new store"],
|
|
1292
|
+
then: ["Store is created", "StoreCreated event is emitted"]
|
|
1501
1293
|
}
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
};
|
|
1511
|
-
var orderListMarkdownRenderer = {
|
|
1512
|
-
target: "markdown",
|
|
1513
|
-
render: async (desc) => {
|
|
1514
|
-
if (desc.source.type !== "component" || desc.source.componentKey !== "OrderList") {
|
|
1515
|
-
throw new Error("orderListMarkdownRenderer: not OrderList");
|
|
1516
|
-
}
|
|
1517
|
-
const orders = mockOrders;
|
|
1518
|
-
const stores = mockStores;
|
|
1519
|
-
const lines = [
|
|
1520
|
-
"# Orders",
|
|
1521
|
-
"",
|
|
1522
|
-
"> Manage marketplace orders",
|
|
1523
|
-
"",
|
|
1524
|
-
"| Order ID | Store | Items | Total | Status | Created |",
|
|
1525
|
-
"|----------|-------|-------|-------|--------|---------|"
|
|
1526
|
-
];
|
|
1527
|
-
for (const order of orders) {
|
|
1528
|
-
const store = stores.find((s) => s.id === order.storeId);
|
|
1529
|
-
const date = new Date(order.createdAt).toLocaleDateString();
|
|
1530
|
-
lines.push(`| ${order.id} | ${store?.name ?? "Unknown"} | ${order.itemCount} | ${formatCurrency(order.total, order.currency)} | ${order.status} | ${date} |`);
|
|
1531
|
-
}
|
|
1532
|
-
lines.push("");
|
|
1533
|
-
lines.push("## Order Status Legend");
|
|
1534
|
-
lines.push("");
|
|
1535
|
-
lines.push("- **PENDING**: Awaiting payment confirmation");
|
|
1536
|
-
lines.push("- **PROCESSING**: Being prepared");
|
|
1537
|
-
lines.push("- **SHIPPED**: In transit");
|
|
1538
|
-
lines.push("- **DELIVERED**: Order completed");
|
|
1539
|
-
lines.push("- **CANCELLED**: Order cancelled");
|
|
1540
|
-
return {
|
|
1541
|
-
mimeType: "text/markdown",
|
|
1542
|
-
body: lines.join(`
|
|
1543
|
-
`)
|
|
1544
|
-
};
|
|
1294
|
+
],
|
|
1295
|
+
examples: [
|
|
1296
|
+
{
|
|
1297
|
+
key: "create-fashion-store",
|
|
1298
|
+
input: { name: "Fashion Boutique", category: "clothing" },
|
|
1299
|
+
output: { id: "store-123", status: "active" }
|
|
1300
|
+
}
|
|
1301
|
+
]
|
|
1545
1302
|
}
|
|
1546
|
-
};
|
|
1303
|
+
});
|
|
1547
1304
|
// src/ui/hooks/useMarketplaceData.ts
|
|
1548
|
-
import { useCallback, useEffect, useState } from "react";
|
|
1549
1305
|
import { useTemplateRuntime } from "@contractspec/lib.example-shared-ui";
|
|
1306
|
+
import { useCallback, useEffect, useState } from "react";
|
|
1550
1307
|
"use client";
|
|
1551
1308
|
function useMarketplaceData(projectId = "local-project") {
|
|
1552
1309
|
const { handlers } = useTemplateRuntime();
|
|
@@ -1598,8 +1355,224 @@ function useMarketplaceData(projectId = "local-project") {
|
|
|
1598
1355
|
};
|
|
1599
1356
|
}
|
|
1600
1357
|
|
|
1358
|
+
// src/ui/hooks/index.ts
|
|
1359
|
+
"use client";
|
|
1360
|
+
|
|
1361
|
+
// src/visualizations/catalog.ts
|
|
1362
|
+
import {
|
|
1363
|
+
defineVisualization,
|
|
1364
|
+
VisualizationRegistry
|
|
1365
|
+
} from "@contractspec/lib.contracts-spec/visualizations";
|
|
1366
|
+
var ORDER_LIST_REF = {
|
|
1367
|
+
key: "marketplace.order.list",
|
|
1368
|
+
version: "1.0.0"
|
|
1369
|
+
};
|
|
1370
|
+
var PRODUCT_LIST_REF = {
|
|
1371
|
+
key: "marketplace.product.list",
|
|
1372
|
+
version: "1.0.0"
|
|
1373
|
+
};
|
|
1374
|
+
var META = {
|
|
1375
|
+
version: "1.0.0",
|
|
1376
|
+
domain: "marketplace",
|
|
1377
|
+
stability: "experimental",
|
|
1378
|
+
owners: ["@example.marketplace"],
|
|
1379
|
+
tags: ["marketplace", "visualization", "commerce"]
|
|
1380
|
+
};
|
|
1381
|
+
var MarketplaceOrderStatusVisualization = defineVisualization({
|
|
1382
|
+
meta: {
|
|
1383
|
+
...META,
|
|
1384
|
+
key: "marketplace.visualization.order-status",
|
|
1385
|
+
title: "Order Status Breakdown",
|
|
1386
|
+
description: "Distribution of current order states.",
|
|
1387
|
+
goal: "Expose delivery and backlog mix at a glance.",
|
|
1388
|
+
context: "Marketplace operations overview."
|
|
1389
|
+
},
|
|
1390
|
+
source: { primary: ORDER_LIST_REF, resultPath: "data" },
|
|
1391
|
+
visualization: {
|
|
1392
|
+
kind: "pie",
|
|
1393
|
+
nameDimension: "status",
|
|
1394
|
+
valueMeasure: "orders",
|
|
1395
|
+
dimensions: [
|
|
1396
|
+
{ key: "status", label: "Status", dataPath: "status", type: "category" }
|
|
1397
|
+
],
|
|
1398
|
+
measures: [
|
|
1399
|
+
{ key: "orders", label: "Orders", dataPath: "orders", format: "number" }
|
|
1400
|
+
],
|
|
1401
|
+
table: { caption: "Order counts by status." }
|
|
1402
|
+
}
|
|
1403
|
+
});
|
|
1404
|
+
var MarketplaceCategoryValueVisualization = defineVisualization({
|
|
1405
|
+
meta: {
|
|
1406
|
+
...META,
|
|
1407
|
+
key: "marketplace.visualization.category-value",
|
|
1408
|
+
title: "Category Value Comparison",
|
|
1409
|
+
description: "Catalog value by product category derived from current pricing and stock.",
|
|
1410
|
+
goal: "Compare where the marketplace catalog is concentrated.",
|
|
1411
|
+
context: "Merchandising overview."
|
|
1412
|
+
},
|
|
1413
|
+
source: { primary: PRODUCT_LIST_REF, resultPath: "data" },
|
|
1414
|
+
visualization: {
|
|
1415
|
+
kind: "cartesian",
|
|
1416
|
+
variant: "bar",
|
|
1417
|
+
xDimension: "category",
|
|
1418
|
+
yMeasures: ["catalogValue"],
|
|
1419
|
+
dimensions: [
|
|
1420
|
+
{
|
|
1421
|
+
key: "category",
|
|
1422
|
+
label: "Category",
|
|
1423
|
+
dataPath: "category",
|
|
1424
|
+
type: "category"
|
|
1425
|
+
}
|
|
1426
|
+
],
|
|
1427
|
+
measures: [
|
|
1428
|
+
{
|
|
1429
|
+
key: "catalogValue",
|
|
1430
|
+
label: "Catalog Value",
|
|
1431
|
+
dataPath: "catalogValue",
|
|
1432
|
+
format: "currency",
|
|
1433
|
+
color: "#1d4ed8"
|
|
1434
|
+
}
|
|
1435
|
+
],
|
|
1436
|
+
table: { caption: "Catalog value by product category." }
|
|
1437
|
+
}
|
|
1438
|
+
});
|
|
1439
|
+
var MarketplaceOrderActivityVisualization = defineVisualization({
|
|
1440
|
+
meta: {
|
|
1441
|
+
...META,
|
|
1442
|
+
key: "marketplace.visualization.order-activity",
|
|
1443
|
+
title: "Recent Order Activity",
|
|
1444
|
+
description: "Daily order volume from recent order creation timestamps.",
|
|
1445
|
+
goal: "Show recent order activity trends.",
|
|
1446
|
+
context: "Commerce operations trend monitoring."
|
|
1447
|
+
},
|
|
1448
|
+
source: { primary: ORDER_LIST_REF, resultPath: "data" },
|
|
1449
|
+
visualization: {
|
|
1450
|
+
kind: "cartesian",
|
|
1451
|
+
variant: "line",
|
|
1452
|
+
xDimension: "day",
|
|
1453
|
+
yMeasures: ["orders"],
|
|
1454
|
+
dimensions: [{ key: "day", label: "Day", dataPath: "day", type: "time" }],
|
|
1455
|
+
measures: [
|
|
1456
|
+
{
|
|
1457
|
+
key: "orders",
|
|
1458
|
+
label: "Orders",
|
|
1459
|
+
dataPath: "orders",
|
|
1460
|
+
format: "number",
|
|
1461
|
+
color: "#0f766e"
|
|
1462
|
+
}
|
|
1463
|
+
],
|
|
1464
|
+
table: { caption: "Daily order counts." }
|
|
1465
|
+
}
|
|
1466
|
+
});
|
|
1467
|
+
var MarketplaceVisualizationSpecs = [
|
|
1468
|
+
MarketplaceOrderStatusVisualization,
|
|
1469
|
+
MarketplaceCategoryValueVisualization,
|
|
1470
|
+
MarketplaceOrderActivityVisualization
|
|
1471
|
+
];
|
|
1472
|
+
var MarketplaceVisualizationRegistry = new VisualizationRegistry([
|
|
1473
|
+
...MarketplaceVisualizationSpecs
|
|
1474
|
+
]);
|
|
1475
|
+
var MarketplaceVisualizationRefs = MarketplaceVisualizationSpecs.map((spec) => ({
|
|
1476
|
+
key: spec.meta.key,
|
|
1477
|
+
version: spec.meta.version
|
|
1478
|
+
}));
|
|
1479
|
+
|
|
1480
|
+
// src/visualizations/selectors.ts
|
|
1481
|
+
function toDayKey(value) {
|
|
1482
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
1483
|
+
return date.toISOString().slice(0, 10);
|
|
1484
|
+
}
|
|
1485
|
+
function createMarketplaceVisualizationItems(products, orders) {
|
|
1486
|
+
const orderStatus = new Map;
|
|
1487
|
+
const orderActivity = new Map;
|
|
1488
|
+
const categoryValue = new Map;
|
|
1489
|
+
for (const order of orders) {
|
|
1490
|
+
orderStatus.set(order.status, (orderStatus.get(order.status) ?? 0) + 1);
|
|
1491
|
+
const day = toDayKey(order.createdAt);
|
|
1492
|
+
orderActivity.set(day, (orderActivity.get(day) ?? 0) + 1);
|
|
1493
|
+
}
|
|
1494
|
+
for (const product of products) {
|
|
1495
|
+
const category = product.category ?? "Uncategorized";
|
|
1496
|
+
categoryValue.set(category, (categoryValue.get(category) ?? 0) + product.price * product.stock);
|
|
1497
|
+
}
|
|
1498
|
+
return [
|
|
1499
|
+
{
|
|
1500
|
+
key: "marketplace-order-status",
|
|
1501
|
+
spec: MarketplaceOrderStatusVisualization,
|
|
1502
|
+
data: {
|
|
1503
|
+
data: Array.from(orderStatus.entries()).map(([status, count]) => ({
|
|
1504
|
+
status,
|
|
1505
|
+
orders: count
|
|
1506
|
+
}))
|
|
1507
|
+
},
|
|
1508
|
+
title: "Order Status Breakdown",
|
|
1509
|
+
description: "Status mix across the current order set.",
|
|
1510
|
+
height: 260
|
|
1511
|
+
},
|
|
1512
|
+
{
|
|
1513
|
+
key: "marketplace-category-value",
|
|
1514
|
+
spec: MarketplaceCategoryValueVisualization,
|
|
1515
|
+
data: {
|
|
1516
|
+
data: Array.from(categoryValue.entries()).sort(([, left], [, right]) => right - left).map(([category, value]) => ({
|
|
1517
|
+
category,
|
|
1518
|
+
catalogValue: value
|
|
1519
|
+
}))
|
|
1520
|
+
},
|
|
1521
|
+
title: "Category Value Comparison",
|
|
1522
|
+
description: "Derived from current product pricing and stock."
|
|
1523
|
+
},
|
|
1524
|
+
{
|
|
1525
|
+
key: "marketplace-order-activity",
|
|
1526
|
+
spec: MarketplaceOrderActivityVisualization,
|
|
1527
|
+
data: {
|
|
1528
|
+
data: Array.from(orderActivity.entries()).sort(([left], [right]) => left.localeCompare(right)).map(([day, count]) => ({ day, orders: count }))
|
|
1529
|
+
},
|
|
1530
|
+
title: "Recent Order Activity",
|
|
1531
|
+
description: "Daily order count from current order history."
|
|
1532
|
+
}
|
|
1533
|
+
];
|
|
1534
|
+
}
|
|
1535
|
+
// src/ui/MarketplaceDashboard.visualizations.tsx
|
|
1536
|
+
import {
|
|
1537
|
+
VisualizationCard,
|
|
1538
|
+
VisualizationGrid
|
|
1539
|
+
} from "@contractspec/lib.design-system";
|
|
1540
|
+
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
1541
|
+
"use client";
|
|
1542
|
+
function MarketplaceVisualizationOverview({
|
|
1543
|
+
products,
|
|
1544
|
+
orders
|
|
1545
|
+
}) {
|
|
1546
|
+
const items = createMarketplaceVisualizationItems(products, orders);
|
|
1547
|
+
return /* @__PURE__ */ jsxDEV("section", {
|
|
1548
|
+
className: "space-y-3",
|
|
1549
|
+
children: [
|
|
1550
|
+
/* @__PURE__ */ jsxDEV("div", {
|
|
1551
|
+
children: [
|
|
1552
|
+
/* @__PURE__ */ jsxDEV("h3", {
|
|
1553
|
+
className: "font-semibold text-lg",
|
|
1554
|
+
children: "Commerce Visualizations"
|
|
1555
|
+
}, undefined, false, undefined, this),
|
|
1556
|
+
/* @__PURE__ */ jsxDEV("p", {
|
|
1557
|
+
className: "text-muted-foreground text-sm",
|
|
1558
|
+
children: "Order and catalog trends exposed through shared visualization contracts."
|
|
1559
|
+
}, undefined, false, undefined, this)
|
|
1560
|
+
]
|
|
1561
|
+
}, undefined, true, undefined, this),
|
|
1562
|
+
/* @__PURE__ */ jsxDEV(VisualizationGrid, {
|
|
1563
|
+
children: items.map((item) => /* @__PURE__ */ jsxDEV(VisualizationCard, {
|
|
1564
|
+
data: item.data,
|
|
1565
|
+
description: item.description,
|
|
1566
|
+
height: item.height,
|
|
1567
|
+
spec: item.spec,
|
|
1568
|
+
title: item.title
|
|
1569
|
+
}, item.key, false, undefined, this))
|
|
1570
|
+
}, undefined, false, undefined, this)
|
|
1571
|
+
]
|
|
1572
|
+
}, undefined, true, undefined, this);
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1601
1575
|
// src/ui/MarketplaceDashboard.tsx
|
|
1602
|
-
import { useState as useState2 } from "react";
|
|
1603
1576
|
import {
|
|
1604
1577
|
Button,
|
|
1605
1578
|
ErrorState,
|
|
@@ -1607,7 +1580,8 @@ import {
|
|
|
1607
1580
|
StatCard,
|
|
1608
1581
|
StatCardGroup
|
|
1609
1582
|
} from "@contractspec/lib.design-system";
|
|
1610
|
-
import {
|
|
1583
|
+
import { useState as useState2 } from "react";
|
|
1584
|
+
import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
|
|
1611
1585
|
"use client";
|
|
1612
1586
|
var STATUS_COLORS = {
|
|
1613
1587
|
ACTIVE: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400",
|
|
@@ -1622,7 +1596,7 @@ var STATUS_COLORS = {
|
|
|
1622
1596
|
DELIVERED: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400",
|
|
1623
1597
|
CANCELLED: "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400"
|
|
1624
1598
|
};
|
|
1625
|
-
function
|
|
1599
|
+
function formatCurrency(value, currency = "USD") {
|
|
1626
1600
|
return new Intl.NumberFormat("en-US", {
|
|
1627
1601
|
style: "currency",
|
|
1628
1602
|
currency,
|
|
@@ -1639,32 +1613,32 @@ function MarketplaceDashboard() {
|
|
|
1639
1613
|
{ id: "orders", label: "Orders", icon: "\uD83D\uDED2" }
|
|
1640
1614
|
];
|
|
1641
1615
|
if (loading) {
|
|
1642
|
-
return /* @__PURE__ */
|
|
1616
|
+
return /* @__PURE__ */ jsxDEV2(LoaderBlock, {
|
|
1643
1617
|
label: "Loading Marketplace..."
|
|
1644
1618
|
}, undefined, false, undefined, this);
|
|
1645
1619
|
}
|
|
1646
1620
|
if (error) {
|
|
1647
|
-
return /* @__PURE__ */
|
|
1621
|
+
return /* @__PURE__ */ jsxDEV2(ErrorState, {
|
|
1648
1622
|
title: "Failed to load Marketplace",
|
|
1649
1623
|
description: error.message,
|
|
1650
1624
|
onRetry: refetch,
|
|
1651
1625
|
retryLabel: "Retry"
|
|
1652
1626
|
}, undefined, false, undefined, this);
|
|
1653
1627
|
}
|
|
1654
|
-
return /* @__PURE__ */
|
|
1628
|
+
return /* @__PURE__ */ jsxDEV2("div", {
|
|
1655
1629
|
className: "space-y-6",
|
|
1656
1630
|
children: [
|
|
1657
|
-
/* @__PURE__ */
|
|
1631
|
+
/* @__PURE__ */ jsxDEV2("div", {
|
|
1658
1632
|
className: "flex items-center justify-between",
|
|
1659
1633
|
children: [
|
|
1660
|
-
/* @__PURE__ */
|
|
1661
|
-
className: "text-2xl
|
|
1634
|
+
/* @__PURE__ */ jsxDEV2("h2", {
|
|
1635
|
+
className: "font-bold text-2xl",
|
|
1662
1636
|
children: "Marketplace"
|
|
1663
1637
|
}, undefined, false, undefined, this),
|
|
1664
|
-
/* @__PURE__ */
|
|
1638
|
+
/* @__PURE__ */ jsxDEV2(Button, {
|
|
1665
1639
|
onClick: () => alert("Create store modal"),
|
|
1666
1640
|
children: [
|
|
1667
|
-
/* @__PURE__ */
|
|
1641
|
+
/* @__PURE__ */ jsxDEV2("span", {
|
|
1668
1642
|
className: "mr-2",
|
|
1669
1643
|
children: "+"
|
|
1670
1644
|
}, undefined, false, undefined, this),
|
|
@@ -1673,108 +1647,112 @@ function MarketplaceDashboard() {
|
|
|
1673
1647
|
}, undefined, true, undefined, this)
|
|
1674
1648
|
]
|
|
1675
1649
|
}, undefined, true, undefined, this),
|
|
1676
|
-
/* @__PURE__ */
|
|
1650
|
+
/* @__PURE__ */ jsxDEV2(StatCardGroup, {
|
|
1677
1651
|
children: [
|
|
1678
|
-
/* @__PURE__ */
|
|
1652
|
+
/* @__PURE__ */ jsxDEV2(StatCard, {
|
|
1679
1653
|
label: "Stores",
|
|
1680
1654
|
value: stats.totalStores,
|
|
1681
1655
|
hint: `${stats.activeStores} active`
|
|
1682
1656
|
}, undefined, false, undefined, this),
|
|
1683
|
-
/* @__PURE__ */
|
|
1657
|
+
/* @__PURE__ */ jsxDEV2(StatCard, {
|
|
1684
1658
|
label: "Products",
|
|
1685
1659
|
value: stats.totalProducts,
|
|
1686
1660
|
hint: "listed"
|
|
1687
1661
|
}, undefined, false, undefined, this),
|
|
1688
|
-
/* @__PURE__ */
|
|
1662
|
+
/* @__PURE__ */ jsxDEV2(StatCard, {
|
|
1689
1663
|
label: "Orders",
|
|
1690
1664
|
value: stats.totalOrders,
|
|
1691
1665
|
hint: `${stats.pendingOrders} pending`
|
|
1692
1666
|
}, undefined, false, undefined, this),
|
|
1693
|
-
/* @__PURE__ */
|
|
1667
|
+
/* @__PURE__ */ jsxDEV2(StatCard, {
|
|
1694
1668
|
label: "Revenue",
|
|
1695
|
-
value:
|
|
1669
|
+
value: formatCurrency(stats.totalRevenue),
|
|
1696
1670
|
hint: "total"
|
|
1697
1671
|
}, undefined, false, undefined, this)
|
|
1698
1672
|
]
|
|
1699
1673
|
}, undefined, true, undefined, this),
|
|
1700
|
-
/* @__PURE__ */
|
|
1701
|
-
|
|
1674
|
+
/* @__PURE__ */ jsxDEV2(MarketplaceVisualizationOverview, {
|
|
1675
|
+
orders,
|
|
1676
|
+
products
|
|
1677
|
+
}, undefined, false, undefined, this),
|
|
1678
|
+
/* @__PURE__ */ jsxDEV2("nav", {
|
|
1679
|
+
className: "flex gap-1 rounded-lg bg-muted p-1",
|
|
1702
1680
|
role: "tablist",
|
|
1703
|
-
children: tabs.map((tab) => /* @__PURE__ */
|
|
1681
|
+
children: tabs.map((tab) => /* @__PURE__ */ jsxDEV2(Button, {
|
|
1704
1682
|
type: "button",
|
|
1705
1683
|
role: "tab",
|
|
1706
1684
|
"aria-selected": activeTab === tab.id,
|
|
1707
1685
|
onClick: () => setActiveTab(tab.id),
|
|
1708
|
-
className: `flex flex-1 items-center justify-center gap-2 rounded-md px-4 py-2 text-sm
|
|
1686
|
+
className: `flex flex-1 items-center justify-center gap-2 rounded-md px-4 py-2 font-medium text-sm transition-colors ${activeTab === tab.id ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"}`,
|
|
1709
1687
|
children: [
|
|
1710
|
-
/* @__PURE__ */
|
|
1688
|
+
/* @__PURE__ */ jsxDEV2("span", {
|
|
1711
1689
|
children: tab.icon
|
|
1712
1690
|
}, undefined, false, undefined, this),
|
|
1713
1691
|
tab.label
|
|
1714
1692
|
]
|
|
1715
1693
|
}, tab.id, true, undefined, this))
|
|
1716
1694
|
}, undefined, false, undefined, this),
|
|
1717
|
-
/* @__PURE__ */
|
|
1695
|
+
/* @__PURE__ */ jsxDEV2("div", {
|
|
1718
1696
|
className: "min-h-[400px]",
|
|
1719
1697
|
role: "tabpanel",
|
|
1720
1698
|
children: [
|
|
1721
|
-
activeTab === "stores" && /* @__PURE__ */
|
|
1722
|
-
className: "
|
|
1723
|
-
children: /* @__PURE__ */
|
|
1699
|
+
activeTab === "stores" && /* @__PURE__ */ jsxDEV2("div", {
|
|
1700
|
+
className: "rounded-lg border border-border",
|
|
1701
|
+
children: /* @__PURE__ */ jsxDEV2("table", {
|
|
1724
1702
|
className: "w-full",
|
|
1725
1703
|
children: [
|
|
1726
|
-
/* @__PURE__ */
|
|
1727
|
-
className: "border-border bg-muted/30
|
|
1728
|
-
children: /* @__PURE__ */
|
|
1704
|
+
/* @__PURE__ */ jsxDEV2("thead", {
|
|
1705
|
+
className: "border-border border-b bg-muted/30",
|
|
1706
|
+
children: /* @__PURE__ */ jsxDEV2("tr", {
|
|
1729
1707
|
children: [
|
|
1730
|
-
/* @__PURE__ */
|
|
1731
|
-
className: "px-4 py-3 text-left text-sm
|
|
1708
|
+
/* @__PURE__ */ jsxDEV2("th", {
|
|
1709
|
+
className: "px-4 py-3 text-left font-medium text-sm",
|
|
1732
1710
|
children: "Store"
|
|
1733
1711
|
}, undefined, false, undefined, this),
|
|
1734
|
-
/* @__PURE__ */
|
|
1735
|
-
className: "px-4 py-3 text-left text-sm
|
|
1712
|
+
/* @__PURE__ */ jsxDEV2("th", {
|
|
1713
|
+
className: "px-4 py-3 text-left font-medium text-sm",
|
|
1736
1714
|
children: "Status"
|
|
1737
1715
|
}, undefined, false, undefined, this),
|
|
1738
|
-
/* @__PURE__ */
|
|
1739
|
-
className: "px-4 py-3 text-left text-sm
|
|
1716
|
+
/* @__PURE__ */ jsxDEV2("th", {
|
|
1717
|
+
className: "px-4 py-3 text-left font-medium text-sm",
|
|
1740
1718
|
children: "Rating"
|
|
1741
1719
|
}, undefined, false, undefined, this),
|
|
1742
|
-
/* @__PURE__ */
|
|
1743
|
-
className: "px-4 py-3 text-left text-sm
|
|
1720
|
+
/* @__PURE__ */ jsxDEV2("th", {
|
|
1721
|
+
className: "px-4 py-3 text-left font-medium text-sm",
|
|
1744
1722
|
children: "Reviews"
|
|
1745
1723
|
}, undefined, false, undefined, this)
|
|
1746
1724
|
]
|
|
1747
1725
|
}, undefined, true, undefined, this)
|
|
1748
1726
|
}, undefined, false, undefined, this),
|
|
1749
|
-
/* @__PURE__ */
|
|
1750
|
-
className: "divide-
|
|
1727
|
+
/* @__PURE__ */ jsxDEV2("tbody", {
|
|
1728
|
+
className: "divide-y divide-border",
|
|
1751
1729
|
children: [
|
|
1752
|
-
stores.map((store) => /* @__PURE__ */
|
|
1730
|
+
stores.map((store) => /* @__PURE__ */ jsxDEV2("tr", {
|
|
1753
1731
|
className: "hover:bg-muted/50",
|
|
1754
1732
|
children: [
|
|
1755
|
-
/* @__PURE__ */
|
|
1733
|
+
/* @__PURE__ */ jsxDEV2("td", {
|
|
1756
1734
|
className: "px-4 py-3",
|
|
1757
1735
|
children: [
|
|
1758
|
-
/* @__PURE__ */
|
|
1736
|
+
/* @__PURE__ */ jsxDEV2("div", {
|
|
1759
1737
|
className: "font-medium",
|
|
1760
1738
|
children: store.name
|
|
1761
1739
|
}, undefined, false, undefined, this),
|
|
1762
|
-
/* @__PURE__ */
|
|
1740
|
+
/* @__PURE__ */ jsxDEV2("div", {
|
|
1763
1741
|
className: "text-muted-foreground text-sm",
|
|
1764
1742
|
children: store.description
|
|
1765
1743
|
}, undefined, false, undefined, this)
|
|
1766
1744
|
]
|
|
1767
1745
|
}, undefined, true, undefined, this),
|
|
1768
|
-
/* @__PURE__ */
|
|
1746
|
+
/* @__PURE__ */ jsxDEV2("td", {
|
|
1769
1747
|
className: "px-4 py-3",
|
|
1770
|
-
children: /* @__PURE__ */
|
|
1771
|
-
className: `inline-flex rounded-full px-2 py-0.5 text-xs
|
|
1748
|
+
children: /* @__PURE__ */ jsxDEV2("span", {
|
|
1749
|
+
className: `inline-flex rounded-full px-2 py-0.5 font-medium text-xs ${STATUS_COLORS[store.status] ?? ""}`,
|
|
1772
1750
|
children: store.status
|
|
1773
1751
|
}, undefined, false, undefined, this)
|
|
1774
1752
|
}, undefined, false, undefined, this),
|
|
1775
|
-
/* @__PURE__ */
|
|
1753
|
+
/* @__PURE__ */ jsxDEV2("td", {
|
|
1776
1754
|
className: "px-4 py-3",
|
|
1777
|
-
children: /* @__PURE__ */
|
|
1755
|
+
children: /* @__PURE__ */ jsxDEV2("span", {
|
|
1778
1756
|
className: "flex items-center gap-1",
|
|
1779
1757
|
children: [
|
|
1780
1758
|
"⭐ ",
|
|
@@ -1782,8 +1760,8 @@ function MarketplaceDashboard() {
|
|
|
1782
1760
|
]
|
|
1783
1761
|
}, undefined, true, undefined, this)
|
|
1784
1762
|
}, undefined, false, undefined, this),
|
|
1785
|
-
/* @__PURE__ */
|
|
1786
|
-
className: "
|
|
1763
|
+
/* @__PURE__ */ jsxDEV2("td", {
|
|
1764
|
+
className: "px-4 py-3 text-muted-foreground text-sm",
|
|
1787
1765
|
children: [
|
|
1788
1766
|
store.reviewCount,
|
|
1789
1767
|
" reviews"
|
|
@@ -1791,10 +1769,10 @@ function MarketplaceDashboard() {
|
|
|
1791
1769
|
}, undefined, true, undefined, this)
|
|
1792
1770
|
]
|
|
1793
1771
|
}, store.id, true, undefined, this)),
|
|
1794
|
-
stores.length === 0 && /* @__PURE__ */
|
|
1795
|
-
children: /* @__PURE__ */
|
|
1772
|
+
stores.length === 0 && /* @__PURE__ */ jsxDEV2("tr", {
|
|
1773
|
+
children: /* @__PURE__ */ jsxDEV2("td", {
|
|
1796
1774
|
colSpan: 4,
|
|
1797
|
-
className: "
|
|
1775
|
+
className: "px-4 py-8 text-center text-muted-foreground",
|
|
1798
1776
|
children: "No stores found"
|
|
1799
1777
|
}, undefined, false, undefined, this)
|
|
1800
1778
|
}, undefined, false, undefined, this)
|
|
@@ -1803,74 +1781,74 @@ function MarketplaceDashboard() {
|
|
|
1803
1781
|
]
|
|
1804
1782
|
}, undefined, true, undefined, this)
|
|
1805
1783
|
}, undefined, false, undefined, this),
|
|
1806
|
-
activeTab === "products" && /* @__PURE__ */
|
|
1807
|
-
className: "
|
|
1808
|
-
children: /* @__PURE__ */
|
|
1784
|
+
activeTab === "products" && /* @__PURE__ */ jsxDEV2("div", {
|
|
1785
|
+
className: "rounded-lg border border-border",
|
|
1786
|
+
children: /* @__PURE__ */ jsxDEV2("table", {
|
|
1809
1787
|
className: "w-full",
|
|
1810
1788
|
children: [
|
|
1811
|
-
/* @__PURE__ */
|
|
1812
|
-
className: "border-border bg-muted/30
|
|
1813
|
-
children: /* @__PURE__ */
|
|
1789
|
+
/* @__PURE__ */ jsxDEV2("thead", {
|
|
1790
|
+
className: "border-border border-b bg-muted/30",
|
|
1791
|
+
children: /* @__PURE__ */ jsxDEV2("tr", {
|
|
1814
1792
|
children: [
|
|
1815
|
-
/* @__PURE__ */
|
|
1816
|
-
className: "px-4 py-3 text-left text-sm
|
|
1793
|
+
/* @__PURE__ */ jsxDEV2("th", {
|
|
1794
|
+
className: "px-4 py-3 text-left font-medium text-sm",
|
|
1817
1795
|
children: "Product"
|
|
1818
1796
|
}, undefined, false, undefined, this),
|
|
1819
|
-
/* @__PURE__ */
|
|
1820
|
-
className: "px-4 py-3 text-left text-sm
|
|
1797
|
+
/* @__PURE__ */ jsxDEV2("th", {
|
|
1798
|
+
className: "px-4 py-3 text-left font-medium text-sm",
|
|
1821
1799
|
children: "Price"
|
|
1822
1800
|
}, undefined, false, undefined, this),
|
|
1823
|
-
/* @__PURE__ */
|
|
1824
|
-
className: "px-4 py-3 text-left text-sm
|
|
1801
|
+
/* @__PURE__ */ jsxDEV2("th", {
|
|
1802
|
+
className: "px-4 py-3 text-left font-medium text-sm",
|
|
1825
1803
|
children: "Stock"
|
|
1826
1804
|
}, undefined, false, undefined, this),
|
|
1827
|
-
/* @__PURE__ */
|
|
1828
|
-
className: "px-4 py-3 text-left text-sm
|
|
1805
|
+
/* @__PURE__ */ jsxDEV2("th", {
|
|
1806
|
+
className: "px-4 py-3 text-left font-medium text-sm",
|
|
1829
1807
|
children: "Status"
|
|
1830
1808
|
}, undefined, false, undefined, this)
|
|
1831
1809
|
]
|
|
1832
1810
|
}, undefined, true, undefined, this)
|
|
1833
1811
|
}, undefined, false, undefined, this),
|
|
1834
|
-
/* @__PURE__ */
|
|
1835
|
-
className: "divide-
|
|
1812
|
+
/* @__PURE__ */ jsxDEV2("tbody", {
|
|
1813
|
+
className: "divide-y divide-border",
|
|
1836
1814
|
children: [
|
|
1837
|
-
products.map((product) => /* @__PURE__ */
|
|
1815
|
+
products.map((product) => /* @__PURE__ */ jsxDEV2("tr", {
|
|
1838
1816
|
className: "hover:bg-muted/50",
|
|
1839
1817
|
children: [
|
|
1840
|
-
/* @__PURE__ */
|
|
1818
|
+
/* @__PURE__ */ jsxDEV2("td", {
|
|
1841
1819
|
className: "px-4 py-3",
|
|
1842
1820
|
children: [
|
|
1843
|
-
/* @__PURE__ */
|
|
1821
|
+
/* @__PURE__ */ jsxDEV2("div", {
|
|
1844
1822
|
className: "font-medium",
|
|
1845
1823
|
children: product.name
|
|
1846
1824
|
}, undefined, false, undefined, this),
|
|
1847
|
-
/* @__PURE__ */
|
|
1825
|
+
/* @__PURE__ */ jsxDEV2("div", {
|
|
1848
1826
|
className: "text-muted-foreground text-sm",
|
|
1849
1827
|
children: product.category
|
|
1850
1828
|
}, undefined, false, undefined, this)
|
|
1851
1829
|
]
|
|
1852
1830
|
}, undefined, true, undefined, this),
|
|
1853
|
-
/* @__PURE__ */
|
|
1831
|
+
/* @__PURE__ */ jsxDEV2("td", {
|
|
1854
1832
|
className: "px-4 py-3 font-mono",
|
|
1855
|
-
children:
|
|
1833
|
+
children: formatCurrency(product.price, product.currency)
|
|
1856
1834
|
}, undefined, false, undefined, this),
|
|
1857
|
-
/* @__PURE__ */
|
|
1835
|
+
/* @__PURE__ */ jsxDEV2("td", {
|
|
1858
1836
|
className: "px-4 py-3",
|
|
1859
1837
|
children: product.stock
|
|
1860
1838
|
}, undefined, false, undefined, this),
|
|
1861
|
-
/* @__PURE__ */
|
|
1839
|
+
/* @__PURE__ */ jsxDEV2("td", {
|
|
1862
1840
|
className: "px-4 py-3",
|
|
1863
|
-
children: /* @__PURE__ */
|
|
1864
|
-
className: `inline-flex rounded-full px-2 py-0.5 text-xs
|
|
1841
|
+
children: /* @__PURE__ */ jsxDEV2("span", {
|
|
1842
|
+
className: `inline-flex rounded-full px-2 py-0.5 font-medium text-xs ${STATUS_COLORS[product.status] ?? ""}`,
|
|
1865
1843
|
children: product.status
|
|
1866
1844
|
}, undefined, false, undefined, this)
|
|
1867
1845
|
}, undefined, false, undefined, this)
|
|
1868
1846
|
]
|
|
1869
1847
|
}, product.id, true, undefined, this)),
|
|
1870
|
-
products.length === 0 && /* @__PURE__ */
|
|
1871
|
-
children: /* @__PURE__ */
|
|
1848
|
+
products.length === 0 && /* @__PURE__ */ jsxDEV2("tr", {
|
|
1849
|
+
children: /* @__PURE__ */ jsxDEV2("td", {
|
|
1872
1850
|
colSpan: 4,
|
|
1873
|
-
className: "
|
|
1851
|
+
className: "px-4 py-8 text-center text-muted-foreground",
|
|
1874
1852
|
children: "No products found"
|
|
1875
1853
|
}, undefined, false, undefined, this)
|
|
1876
1854
|
}, undefined, false, undefined, this)
|
|
@@ -1879,73 +1857,73 @@ function MarketplaceDashboard() {
|
|
|
1879
1857
|
]
|
|
1880
1858
|
}, undefined, true, undefined, this)
|
|
1881
1859
|
}, undefined, false, undefined, this),
|
|
1882
|
-
activeTab === "orders" && /* @__PURE__ */
|
|
1883
|
-
className: "
|
|
1884
|
-
children: /* @__PURE__ */
|
|
1860
|
+
activeTab === "orders" && /* @__PURE__ */ jsxDEV2("div", {
|
|
1861
|
+
className: "rounded-lg border border-border",
|
|
1862
|
+
children: /* @__PURE__ */ jsxDEV2("table", {
|
|
1885
1863
|
className: "w-full",
|
|
1886
1864
|
children: [
|
|
1887
|
-
/* @__PURE__ */
|
|
1888
|
-
className: "border-border bg-muted/30
|
|
1889
|
-
children: /* @__PURE__ */
|
|
1865
|
+
/* @__PURE__ */ jsxDEV2("thead", {
|
|
1866
|
+
className: "border-border border-b bg-muted/30",
|
|
1867
|
+
children: /* @__PURE__ */ jsxDEV2("tr", {
|
|
1890
1868
|
children: [
|
|
1891
|
-
/* @__PURE__ */
|
|
1892
|
-
className: "px-4 py-3 text-left text-sm
|
|
1869
|
+
/* @__PURE__ */ jsxDEV2("th", {
|
|
1870
|
+
className: "px-4 py-3 text-left font-medium text-sm",
|
|
1893
1871
|
children: "Order ID"
|
|
1894
1872
|
}, undefined, false, undefined, this),
|
|
1895
|
-
/* @__PURE__ */
|
|
1896
|
-
className: "px-4 py-3 text-left text-sm
|
|
1873
|
+
/* @__PURE__ */ jsxDEV2("th", {
|
|
1874
|
+
className: "px-4 py-3 text-left font-medium text-sm",
|
|
1897
1875
|
children: "Customer"
|
|
1898
1876
|
}, undefined, false, undefined, this),
|
|
1899
|
-
/* @__PURE__ */
|
|
1900
|
-
className: "px-4 py-3 text-left text-sm
|
|
1877
|
+
/* @__PURE__ */ jsxDEV2("th", {
|
|
1878
|
+
className: "px-4 py-3 text-left font-medium text-sm",
|
|
1901
1879
|
children: "Total"
|
|
1902
1880
|
}, undefined, false, undefined, this),
|
|
1903
|
-
/* @__PURE__ */
|
|
1904
|
-
className: "px-4 py-3 text-left text-sm
|
|
1881
|
+
/* @__PURE__ */ jsxDEV2("th", {
|
|
1882
|
+
className: "px-4 py-3 text-left font-medium text-sm",
|
|
1905
1883
|
children: "Status"
|
|
1906
1884
|
}, undefined, false, undefined, this),
|
|
1907
|
-
/* @__PURE__ */
|
|
1908
|
-
className: "px-4 py-3 text-left text-sm
|
|
1885
|
+
/* @__PURE__ */ jsxDEV2("th", {
|
|
1886
|
+
className: "px-4 py-3 text-left font-medium text-sm",
|
|
1909
1887
|
children: "Date"
|
|
1910
1888
|
}, undefined, false, undefined, this)
|
|
1911
1889
|
]
|
|
1912
1890
|
}, undefined, true, undefined, this)
|
|
1913
1891
|
}, undefined, false, undefined, this),
|
|
1914
|
-
/* @__PURE__ */
|
|
1915
|
-
className: "divide-
|
|
1892
|
+
/* @__PURE__ */ jsxDEV2("tbody", {
|
|
1893
|
+
className: "divide-y divide-border",
|
|
1916
1894
|
children: [
|
|
1917
|
-
orders.map((order) => /* @__PURE__ */
|
|
1895
|
+
orders.map((order) => /* @__PURE__ */ jsxDEV2("tr", {
|
|
1918
1896
|
className: "hover:bg-muted/50",
|
|
1919
1897
|
children: [
|
|
1920
|
-
/* @__PURE__ */
|
|
1898
|
+
/* @__PURE__ */ jsxDEV2("td", {
|
|
1921
1899
|
className: "px-4 py-3 font-mono text-sm",
|
|
1922
1900
|
children: order.id
|
|
1923
1901
|
}, undefined, false, undefined, this),
|
|
1924
|
-
/* @__PURE__ */
|
|
1902
|
+
/* @__PURE__ */ jsxDEV2("td", {
|
|
1925
1903
|
className: "px-4 py-3 text-sm",
|
|
1926
1904
|
children: order.customerId
|
|
1927
1905
|
}, undefined, false, undefined, this),
|
|
1928
|
-
/* @__PURE__ */
|
|
1906
|
+
/* @__PURE__ */ jsxDEV2("td", {
|
|
1929
1907
|
className: "px-4 py-3 font-mono",
|
|
1930
|
-
children:
|
|
1908
|
+
children: formatCurrency(order.total, order.currency)
|
|
1931
1909
|
}, undefined, false, undefined, this),
|
|
1932
|
-
/* @__PURE__ */
|
|
1910
|
+
/* @__PURE__ */ jsxDEV2("td", {
|
|
1933
1911
|
className: "px-4 py-3",
|
|
1934
|
-
children: /* @__PURE__ */
|
|
1935
|
-
className: `inline-flex rounded-full px-2 py-0.5 text-xs
|
|
1912
|
+
children: /* @__PURE__ */ jsxDEV2("span", {
|
|
1913
|
+
className: `inline-flex rounded-full px-2 py-0.5 font-medium text-xs ${STATUS_COLORS[order.status] ?? ""}`,
|
|
1936
1914
|
children: order.status
|
|
1937
1915
|
}, undefined, false, undefined, this)
|
|
1938
1916
|
}, undefined, false, undefined, this),
|
|
1939
|
-
/* @__PURE__ */
|
|
1940
|
-
className: "
|
|
1917
|
+
/* @__PURE__ */ jsxDEV2("td", {
|
|
1918
|
+
className: "px-4 py-3 text-muted-foreground text-sm",
|
|
1941
1919
|
children: order.createdAt.toLocaleDateString()
|
|
1942
1920
|
}, undefined, false, undefined, this)
|
|
1943
1921
|
]
|
|
1944
1922
|
}, order.id, true, undefined, this)),
|
|
1945
|
-
orders.length === 0 && /* @__PURE__ */
|
|
1946
|
-
children: /* @__PURE__ */
|
|
1923
|
+
orders.length === 0 && /* @__PURE__ */ jsxDEV2("tr", {
|
|
1924
|
+
children: /* @__PURE__ */ jsxDEV2("td", {
|
|
1947
1925
|
colSpan: 5,
|
|
1948
|
-
className: "
|
|
1926
|
+
className: "px-4 py-8 text-center text-muted-foreground",
|
|
1949
1927
|
children: "No orders found"
|
|
1950
1928
|
}, undefined, false, undefined, this)
|
|
1951
1929
|
}, undefined, false, undefined, this)
|
|
@@ -1960,13 +1938,267 @@ function MarketplaceDashboard() {
|
|
|
1960
1938
|
}, undefined, true, undefined, this);
|
|
1961
1939
|
}
|
|
1962
1940
|
|
|
1963
|
-
// src/ui/
|
|
1964
|
-
|
|
1941
|
+
// src/ui/renderers/marketplace.markdown.ts
|
|
1942
|
+
var mockStores = [
|
|
1943
|
+
{
|
|
1944
|
+
id: "store-1",
|
|
1945
|
+
name: "Tech Gadgets Store",
|
|
1946
|
+
status: "ACTIVE",
|
|
1947
|
+
productCount: 45,
|
|
1948
|
+
rating: 4.8
|
|
1949
|
+
},
|
|
1950
|
+
{
|
|
1951
|
+
id: "store-2",
|
|
1952
|
+
name: "Home & Garden",
|
|
1953
|
+
status: "ACTIVE",
|
|
1954
|
+
productCount: 120,
|
|
1955
|
+
rating: 4.5
|
|
1956
|
+
},
|
|
1957
|
+
{
|
|
1958
|
+
id: "store-3",
|
|
1959
|
+
name: "Fashion Boutique",
|
|
1960
|
+
status: "PENDING",
|
|
1961
|
+
productCount: 0,
|
|
1962
|
+
rating: 0
|
|
1963
|
+
}
|
|
1964
|
+
];
|
|
1965
|
+
var mockProducts = [
|
|
1966
|
+
{
|
|
1967
|
+
id: "prod-1",
|
|
1968
|
+
name: "Wireless Earbuds",
|
|
1969
|
+
storeId: "store-1",
|
|
1970
|
+
category: "Electronics",
|
|
1971
|
+
price: 79.99,
|
|
1972
|
+
currency: "USD",
|
|
1973
|
+
status: "ACTIVE",
|
|
1974
|
+
stock: 150
|
|
1975
|
+
},
|
|
1976
|
+
{
|
|
1977
|
+
id: "prod-2",
|
|
1978
|
+
name: "Smart Watch",
|
|
1979
|
+
storeId: "store-1",
|
|
1980
|
+
category: "Wearables",
|
|
1981
|
+
price: 249.99,
|
|
1982
|
+
currency: "USD",
|
|
1983
|
+
status: "ACTIVE",
|
|
1984
|
+
stock: 50
|
|
1985
|
+
},
|
|
1986
|
+
{
|
|
1987
|
+
id: "prod-3",
|
|
1988
|
+
name: "Garden Tools Set",
|
|
1989
|
+
storeId: "store-2",
|
|
1990
|
+
category: "Garden",
|
|
1991
|
+
price: 89.99,
|
|
1992
|
+
currency: "USD",
|
|
1993
|
+
status: "ACTIVE",
|
|
1994
|
+
stock: 30
|
|
1995
|
+
},
|
|
1996
|
+
{
|
|
1997
|
+
id: "prod-4",
|
|
1998
|
+
name: "Indoor Plant Kit",
|
|
1999
|
+
storeId: "store-2",
|
|
2000
|
+
category: "Garden",
|
|
2001
|
+
price: 45.99,
|
|
2002
|
+
currency: "USD",
|
|
2003
|
+
status: "ACTIVE",
|
|
2004
|
+
stock: 75
|
|
2005
|
+
},
|
|
2006
|
+
{
|
|
2007
|
+
id: "prod-5",
|
|
2008
|
+
name: "LED Desk Lamp",
|
|
2009
|
+
storeId: "store-1",
|
|
2010
|
+
category: "Home Office",
|
|
2011
|
+
price: 34.99,
|
|
2012
|
+
currency: "USD",
|
|
2013
|
+
status: "OUT_OF_STOCK",
|
|
2014
|
+
stock: 0
|
|
2015
|
+
}
|
|
2016
|
+
];
|
|
2017
|
+
var mockOrders = [
|
|
2018
|
+
{
|
|
2019
|
+
id: "ord-1",
|
|
2020
|
+
storeId: "store-1",
|
|
2021
|
+
customerId: "cust-1",
|
|
2022
|
+
total: 329.98,
|
|
2023
|
+
currency: "USD",
|
|
2024
|
+
status: "DELIVERED",
|
|
2025
|
+
itemCount: 2,
|
|
2026
|
+
createdAt: "2024-01-15T10:00:00Z"
|
|
2027
|
+
},
|
|
2028
|
+
{
|
|
2029
|
+
id: "ord-2",
|
|
2030
|
+
storeId: "store-2",
|
|
2031
|
+
customerId: "cust-2",
|
|
2032
|
+
total: 135.98,
|
|
2033
|
+
currency: "USD",
|
|
2034
|
+
status: "SHIPPED",
|
|
2035
|
+
itemCount: 2,
|
|
2036
|
+
createdAt: "2024-01-14T14:00:00Z"
|
|
2037
|
+
},
|
|
2038
|
+
{
|
|
2039
|
+
id: "ord-3",
|
|
2040
|
+
storeId: "store-1",
|
|
2041
|
+
customerId: "cust-3",
|
|
2042
|
+
total: 79.99,
|
|
2043
|
+
currency: "USD",
|
|
2044
|
+
status: "PROCESSING",
|
|
2045
|
+
itemCount: 1,
|
|
2046
|
+
createdAt: "2024-01-16T08:00:00Z"
|
|
2047
|
+
},
|
|
2048
|
+
{
|
|
2049
|
+
id: "ord-4",
|
|
2050
|
+
storeId: "store-2",
|
|
2051
|
+
customerId: "cust-4",
|
|
2052
|
+
total: 45.99,
|
|
2053
|
+
currency: "USD",
|
|
2054
|
+
status: "PENDING",
|
|
2055
|
+
itemCount: 1,
|
|
2056
|
+
createdAt: "2024-01-16T12:00:00Z"
|
|
2057
|
+
}
|
|
2058
|
+
];
|
|
2059
|
+
function formatCurrency2(value, currency = "USD") {
|
|
2060
|
+
return new Intl.NumberFormat("en-US", {
|
|
2061
|
+
style: "currency",
|
|
2062
|
+
currency,
|
|
2063
|
+
minimumFractionDigits: 2
|
|
2064
|
+
}).format(value);
|
|
2065
|
+
}
|
|
2066
|
+
var marketplaceDashboardMarkdownRenderer = {
|
|
2067
|
+
target: "markdown",
|
|
2068
|
+
render: async (desc) => {
|
|
2069
|
+
if (desc.source.type !== "component" || desc.source.componentKey !== "MarketplaceDashboard") {
|
|
2070
|
+
throw new Error("marketplaceDashboardMarkdownRenderer: not MarketplaceDashboard");
|
|
2071
|
+
}
|
|
2072
|
+
const stores = mockStores;
|
|
2073
|
+
const products = mockProducts;
|
|
2074
|
+
const orders = mockOrders;
|
|
2075
|
+
const visualizationItems = createMarketplaceVisualizationItems(products, orders);
|
|
2076
|
+
const activeStores = stores.filter((s) => s.status === "ACTIVE");
|
|
2077
|
+
const activeProducts = products.filter((p) => p.status === "ACTIVE");
|
|
2078
|
+
const totalRevenue = orders.reduce((sum, o) => sum + o.total, 0);
|
|
2079
|
+
const pendingOrders = orders.filter((o) => o.status === "PENDING" || o.status === "PROCESSING");
|
|
2080
|
+
const lines = [
|
|
2081
|
+
"# Marketplace Dashboard",
|
|
2082
|
+
"",
|
|
2083
|
+
"> Two-sided marketplace overview",
|
|
2084
|
+
"",
|
|
2085
|
+
"## Summary",
|
|
2086
|
+
"",
|
|
2087
|
+
"| Metric | Value |",
|
|
2088
|
+
"|--------|-------|",
|
|
2089
|
+
`| Active Stores | ${activeStores.length} |`,
|
|
2090
|
+
`| Active Products | ${activeProducts.length} |`,
|
|
2091
|
+
`| Total Orders | ${orders.length} |`,
|
|
2092
|
+
`| Total Revenue | ${formatCurrency2(totalRevenue)} |`,
|
|
2093
|
+
`| Pending Orders | ${pendingOrders.length} |`,
|
|
2094
|
+
"",
|
|
2095
|
+
"## Visualization Overview",
|
|
2096
|
+
""
|
|
2097
|
+
];
|
|
2098
|
+
for (const item of visualizationItems) {
|
|
2099
|
+
lines.push(`- **${item.title}** via \`${item.spec.meta.key}\``);
|
|
2100
|
+
}
|
|
2101
|
+
lines.push("");
|
|
2102
|
+
lines.push("## Top Stores");
|
|
2103
|
+
lines.push("");
|
|
2104
|
+
lines.push("| Store | Products | Rating | Status |");
|
|
2105
|
+
lines.push("|-------|----------|--------|--------|");
|
|
2106
|
+
for (const store of stores.slice(0, 5)) {
|
|
2107
|
+
lines.push(`| ${store.name} | ${store.productCount} | ⭐ ${store.rating || "N/A"} | ${store.status} |`);
|
|
2108
|
+
}
|
|
2109
|
+
lines.push("");
|
|
2110
|
+
lines.push("## Recent Orders");
|
|
2111
|
+
lines.push("");
|
|
2112
|
+
lines.push("| Order | Items | Total | Status | Date |");
|
|
2113
|
+
lines.push("|-------|-------|-------|--------|------|");
|
|
2114
|
+
for (const order of orders.slice(0, 10)) {
|
|
2115
|
+
const date = new Date(order.createdAt).toLocaleDateString();
|
|
2116
|
+
lines.push(`| ${order.id} | ${order.itemCount} | ${formatCurrency2(order.total, order.currency)} | ${order.status} | ${date} |`);
|
|
2117
|
+
}
|
|
2118
|
+
return {
|
|
2119
|
+
mimeType: "text/markdown",
|
|
2120
|
+
body: lines.join(`
|
|
2121
|
+
`)
|
|
2122
|
+
};
|
|
2123
|
+
}
|
|
2124
|
+
};
|
|
2125
|
+
var productCatalogMarkdownRenderer = {
|
|
2126
|
+
target: "markdown",
|
|
2127
|
+
render: async (desc) => {
|
|
2128
|
+
if (desc.source.type !== "component" || desc.source.componentKey !== "ProductCatalog") {
|
|
2129
|
+
throw new Error("productCatalogMarkdownRenderer: not ProductCatalog");
|
|
2130
|
+
}
|
|
2131
|
+
const products = mockProducts;
|
|
2132
|
+
const stores = mockStores;
|
|
2133
|
+
const lines = [
|
|
2134
|
+
"# Product Catalog",
|
|
2135
|
+
"",
|
|
2136
|
+
"> Browse products across all marketplace stores",
|
|
2137
|
+
""
|
|
2138
|
+
];
|
|
2139
|
+
for (const store of stores.filter((s) => s.status === "ACTIVE")) {
|
|
2140
|
+
const storeProducts = products.filter((p) => p.storeId === store.id);
|
|
2141
|
+
if (storeProducts.length === 0)
|
|
2142
|
+
continue;
|
|
2143
|
+
lines.push(`## ${store.name}`);
|
|
2144
|
+
lines.push("");
|
|
2145
|
+
lines.push("| Product | Price | Stock | Status |");
|
|
2146
|
+
lines.push("|---------|-------|-------|--------|");
|
|
2147
|
+
for (const product of storeProducts) {
|
|
2148
|
+
const stockStatus = product.stock > 0 ? `${product.stock} in stock` : "Out of stock";
|
|
2149
|
+
lines.push(`| ${product.name} | ${formatCurrency2(product.price, product.currency)} | ${stockStatus} | ${product.status} |`);
|
|
2150
|
+
}
|
|
2151
|
+
lines.push("");
|
|
2152
|
+
}
|
|
2153
|
+
return {
|
|
2154
|
+
mimeType: "text/markdown",
|
|
2155
|
+
body: lines.join(`
|
|
2156
|
+
`)
|
|
2157
|
+
};
|
|
2158
|
+
}
|
|
2159
|
+
};
|
|
2160
|
+
var orderListMarkdownRenderer = {
|
|
2161
|
+
target: "markdown",
|
|
2162
|
+
render: async (desc) => {
|
|
2163
|
+
if (desc.source.type !== "component" || desc.source.componentKey !== "OrderList") {
|
|
2164
|
+
throw new Error("orderListMarkdownRenderer: not OrderList");
|
|
2165
|
+
}
|
|
2166
|
+
const orders = mockOrders;
|
|
2167
|
+
const stores = mockStores;
|
|
2168
|
+
const lines = [
|
|
2169
|
+
"# Orders",
|
|
2170
|
+
"",
|
|
2171
|
+
"> Manage marketplace orders",
|
|
2172
|
+
"",
|
|
2173
|
+
"| Order ID | Store | Items | Total | Status | Created |",
|
|
2174
|
+
"|----------|-------|-------|-------|--------|---------|"
|
|
2175
|
+
];
|
|
2176
|
+
for (const order of orders) {
|
|
2177
|
+
const store = stores.find((s) => s.id === order.storeId);
|
|
2178
|
+
const date = new Date(order.createdAt).toLocaleDateString();
|
|
2179
|
+
lines.push(`| ${order.id} | ${store?.name ?? "Unknown"} | ${order.itemCount} | ${formatCurrency2(order.total, order.currency)} | ${order.status} | ${date} |`);
|
|
2180
|
+
}
|
|
2181
|
+
lines.push("");
|
|
2182
|
+
lines.push("## Order Status Legend");
|
|
2183
|
+
lines.push("");
|
|
2184
|
+
lines.push("- **PENDING**: Awaiting payment confirmation");
|
|
2185
|
+
lines.push("- **PROCESSING**: Being prepared");
|
|
2186
|
+
lines.push("- **SHIPPED**: In transit");
|
|
2187
|
+
lines.push("- **DELIVERED**: Order completed");
|
|
2188
|
+
lines.push("- **CANCELLED**: Order cancelled");
|
|
2189
|
+
return {
|
|
2190
|
+
mimeType: "text/markdown",
|
|
2191
|
+
body: lines.join(`
|
|
2192
|
+
`)
|
|
2193
|
+
};
|
|
2194
|
+
}
|
|
2195
|
+
};
|
|
1965
2196
|
export {
|
|
1966
2197
|
useMarketplaceData,
|
|
1967
2198
|
productCatalogMarkdownRenderer,
|
|
1968
2199
|
orderListMarkdownRenderer,
|
|
1969
2200
|
marketplaceDashboardMarkdownRenderer,
|
|
2201
|
+
createMarketplaceVisualizationItems,
|
|
1970
2202
|
createMarketplaceHandlers,
|
|
1971
2203
|
UpdateOrderStatusInputModel,
|
|
1972
2204
|
UpdateOrderStatusContract,
|
|
@@ -1994,7 +2226,13 @@ export {
|
|
|
1994
2226
|
OrderItemModel,
|
|
1995
2227
|
OrderCreatedEvent,
|
|
1996
2228
|
OrderCompletedEvent,
|
|
2229
|
+
MarketplaceVisualizationSpecs,
|
|
2230
|
+
MarketplaceVisualizationRegistry,
|
|
2231
|
+
MarketplaceVisualizationRefs,
|
|
2232
|
+
MarketplaceOrderStatusVisualization,
|
|
2233
|
+
MarketplaceOrderActivityVisualization,
|
|
1997
2234
|
MarketplaceDashboard,
|
|
2235
|
+
MarketplaceCategoryValueVisualization,
|
|
1998
2236
|
ListReviewsOutputModel,
|
|
1999
2237
|
ListReviewsInputModel,
|
|
2000
2238
|
ListReviewsContract,
|