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