@contractspec/example.marketplace 1.56.1 → 1.58.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/docs/index.js +103 -0
- package/dist/browser/docs/marketplace.docblock.js +103 -0
- package/dist/browser/entities/index.js +721 -0
- package/dist/browser/entities/order.js +167 -0
- package/dist/browser/entities/payout.js +142 -0
- package/dist/browser/entities/product.js +152 -0
- package/dist/browser/entities/review.js +129 -0
- package/dist/browser/entities/store.js +97 -0
- package/dist/browser/example.js +42 -0
- package/dist/browser/handlers/index.js +303 -0
- package/dist/browser/handlers/marketplace.handlers.js +303 -0
- package/dist/browser/index.js +2016 -0
- package/dist/browser/marketplace.capability.js +40 -0
- package/dist/browser/marketplace.feature.js +137 -0
- package/dist/browser/order/index.js +307 -0
- package/dist/browser/order/order.enum.js +17 -0
- package/dist/browser/order/order.event.js +131 -0
- package/dist/browser/order/order.operations.js +172 -0
- package/dist/browser/order/order.presentation.js +153 -0
- package/dist/browser/order/order.schema.js +79 -0
- package/dist/browser/payout/index.js +152 -0
- package/dist/browser/payout/payout.enum.js +12 -0
- package/dist/browser/payout/payout.event.js +55 -0
- package/dist/browser/payout/payout.operations.js +94 -0
- package/dist/browser/payout/payout.presentation.js +111 -0
- package/dist/browser/payout/payout.schema.js +61 -0
- package/dist/browser/product/index.js +249 -0
- package/dist/browser/product/product.enum.js +13 -0
- package/dist/browser/product/product.event.js +74 -0
- package/dist/browser/product/product.operations.js +171 -0
- package/dist/browser/product/product.presentation.js +158 -0
- package/dist/browser/product/product.schema.js +84 -0
- package/dist/browser/review/index.js +206 -0
- package/dist/browser/review/review.enum.js +11 -0
- package/dist/browser/review/review.event.js +50 -0
- package/dist/browser/review/review.operations.js +152 -0
- package/dist/browser/review/review.presentation.js +123 -0
- package/dist/browser/review/review.schema.js +74 -0
- package/dist/browser/seeders/index.js +12 -0
- package/dist/browser/store/index.js +142 -0
- package/dist/browser/store/store.enum.js +11 -0
- package/dist/browser/store/store.event.js +52 -0
- package/dist/browser/store/store.operations.js +88 -0
- package/dist/browser/store/store.presentation.js +94 -0
- package/dist/browser/store/store.schema.js +43 -0
- package/dist/browser/tests/operations.test-spec.js +139 -0
- package/dist/browser/ui/MarketplaceDashboard.js +418 -0
- package/dist/browser/ui/hooks/index.js +59 -0
- package/dist/browser/ui/hooks/useMarketplaceData.js +56 -0
- package/dist/browser/ui/index.js +668 -0
- package/dist/browser/ui/renderers/index.js +248 -0
- package/dist/browser/ui/renderers/marketplace.markdown.js +248 -0
- package/dist/docs/index.d.ts +2 -1
- package/dist/docs/index.d.ts.map +1 -0
- package/dist/docs/index.js +104 -1
- package/dist/docs/marketplace.docblock.d.ts +2 -1
- package/dist/docs/marketplace.docblock.d.ts.map +1 -0
- package/dist/docs/marketplace.docblock.js +46 -57
- package/dist/entities/index.d.ts +302 -307
- package/dist/entities/index.d.ts.map +1 -1
- package/dist/entities/index.js +719 -43
- package/dist/entities/order.d.ts +77 -82
- package/dist/entities/order.d.ts.map +1 -1
- package/dist/entities/order.js +162 -167
- package/dist/entities/payout.d.ts +64 -69
- package/dist/entities/payout.d.ts.map +1 -1
- package/dist/entities/payout.js +137 -156
- package/dist/entities/product.d.ts +69 -74
- package/dist/entities/product.d.ts.map +1 -1
- package/dist/entities/product.js +148 -156
- package/dist/entities/review.d.ts +55 -60
- package/dist/entities/review.d.ts.map +1 -1
- package/dist/entities/review.js +124 -146
- package/dist/entities/store.d.ts +40 -45
- package/dist/entities/store.d.ts.map +1 -1
- package/dist/entities/store.js +94 -106
- package/dist/example.d.ts +2 -6
- package/dist/example.d.ts.map +1 -1
- package/dist/example.js +40 -55
- package/dist/handlers/index.d.ts +2 -2
- package/dist/handlers/index.d.ts.map +1 -0
- package/dist/handlers/index.js +304 -3
- package/dist/handlers/marketplace.handlers.d.ts +138 -138
- package/dist/handlers/marketplace.handlers.d.ts.map +1 -1
- package/dist/handlers/marketplace.handlers.js +284 -309
- package/dist/index.d.ts +13 -31
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2017 -32
- package/dist/marketplace.capability.d.ts +3 -8
- package/dist/marketplace.capability.d.ts.map +1 -1
- package/dist/marketplace.capability.js +41 -34
- package/dist/marketplace.feature.d.ts +1 -7
- package/dist/marketplace.feature.d.ts.map +1 -1
- package/dist/marketplace.feature.js +136 -313
- package/dist/node/docs/index.js +103 -0
- package/dist/node/docs/marketplace.docblock.js +103 -0
- package/dist/node/entities/index.js +721 -0
- package/dist/node/entities/order.js +167 -0
- package/dist/node/entities/payout.js +142 -0
- package/dist/node/entities/product.js +152 -0
- package/dist/node/entities/review.js +129 -0
- package/dist/node/entities/store.js +97 -0
- package/dist/node/example.js +42 -0
- package/dist/node/handlers/index.js +303 -0
- package/dist/node/handlers/marketplace.handlers.js +303 -0
- package/dist/node/index.js +2016 -0
- package/dist/node/marketplace.capability.js +40 -0
- package/dist/node/marketplace.feature.js +137 -0
- package/dist/node/order/index.js +307 -0
- package/dist/node/order/order.enum.js +17 -0
- package/dist/node/order/order.event.js +131 -0
- package/dist/node/order/order.operations.js +172 -0
- package/dist/node/order/order.presentation.js +153 -0
- package/dist/node/order/order.schema.js +79 -0
- package/dist/node/payout/index.js +152 -0
- package/dist/node/payout/payout.enum.js +12 -0
- package/dist/node/payout/payout.event.js +55 -0
- package/dist/node/payout/payout.operations.js +94 -0
- package/dist/node/payout/payout.presentation.js +111 -0
- package/dist/node/payout/payout.schema.js +61 -0
- package/dist/node/product/index.js +249 -0
- package/dist/node/product/product.enum.js +13 -0
- package/dist/node/product/product.event.js +74 -0
- package/dist/node/product/product.operations.js +171 -0
- package/dist/node/product/product.presentation.js +158 -0
- package/dist/node/product/product.schema.js +84 -0
- package/dist/node/review/index.js +206 -0
- package/dist/node/review/review.enum.js +11 -0
- package/dist/node/review/review.event.js +50 -0
- package/dist/node/review/review.operations.js +152 -0
- package/dist/node/review/review.presentation.js +123 -0
- package/dist/node/review/review.schema.js +74 -0
- package/dist/node/seeders/index.js +12 -0
- package/dist/node/store/index.js +142 -0
- package/dist/node/store/store.enum.js +11 -0
- package/dist/node/store/store.event.js +52 -0
- package/dist/node/store/store.operations.js +88 -0
- package/dist/node/store/store.presentation.js +94 -0
- package/dist/node/store/store.schema.js +43 -0
- package/dist/node/tests/operations.test-spec.js +139 -0
- package/dist/node/ui/MarketplaceDashboard.js +418 -0
- package/dist/node/ui/hooks/index.js +59 -0
- package/dist/node/ui/hooks/useMarketplaceData.js +56 -0
- package/dist/node/ui/index.js +668 -0
- package/dist/node/ui/renderers/index.js +248 -0
- package/dist/node/ui/renderers/marketplace.markdown.js +248 -0
- package/dist/order/index.d.ts +8 -5
- package/dist/order/index.d.ts.map +1 -0
- package/dist/order/index.js +307 -5
- package/dist/order/order.enum.d.ts +1 -6
- package/dist/order/order.enum.d.ts.map +1 -1
- package/dist/order/order.enum.js +16 -20
- package/dist/order/order.event.d.ts +133 -139
- package/dist/order/order.event.d.ts.map +1 -1
- package/dist/order/order.event.js +121 -205
- package/dist/order/order.operations.d.ts +291 -297
- package/dist/order/order.operations.d.ts.map +1 -1
- package/dist/order/order.operations.js +169 -115
- package/dist/order/order.presentation.d.ts +3 -8
- package/dist/order/order.presentation.d.ts.map +1 -1
- package/dist/order/order.presentation.js +149 -81
- package/dist/order/order.schema.d.ts +143 -148
- package/dist/order/order.schema.d.ts.map +1 -1
- package/dist/order/order.schema.js +75 -150
- package/dist/payout/index.d.ts +8 -5
- package/dist/payout/index.d.ts.map +1 -0
- package/dist/payout/index.js +152 -5
- package/dist/payout/payout.enum.d.ts +1 -6
- package/dist/payout/payout.enum.d.ts.map +1 -1
- package/dist/payout/payout.enum.js +11 -15
- package/dist/payout/payout.event.d.ts +54 -60
- package/dist/payout/payout.event.d.ts.map +1 -1
- package/dist/payout/payout.event.js +51 -87
- package/dist/payout/payout.operations.d.ts +82 -88
- package/dist/payout/payout.operations.d.ts.map +1 -1
- package/dist/payout/payout.operations.js +92 -50
- package/dist/payout/payout.presentation.d.ts +2 -7
- package/dist/payout/payout.presentation.d.ts.map +1 -1
- package/dist/payout/payout.presentation.js +108 -56
- package/dist/payout/payout.schema.d.ts +139 -144
- package/dist/payout/payout.schema.d.ts.map +1 -1
- package/dist/payout/payout.schema.js +58 -112
- package/dist/product/index.d.ts +8 -5
- package/dist/product/index.d.ts.map +1 -0
- package/dist/product/index.js +249 -5
- package/dist/product/product.enum.d.ts +1 -6
- package/dist/product/product.enum.d.ts.map +1 -1
- package/dist/product/product.enum.js +12 -16
- package/dist/product/product.event.d.ts +63 -69
- package/dist/product/product.event.d.ts.map +1 -1
- package/dist/product/product.event.js +68 -113
- package/dist/product/product.operations.d.ts +225 -231
- package/dist/product/product.operations.d.ts.map +1 -1
- package/dist/product/product.operations.js +168 -104
- package/dist/product/product.presentation.d.ts +3 -8
- package/dist/product/product.presentation.d.ts.map +1 -1
- package/dist/product/product.presentation.js +154 -81
- package/dist/product/product.schema.d.ts +196 -201
- package/dist/product/product.schema.d.ts.map +1 -1
- package/dist/product/product.schema.js +80 -171
- package/dist/review/index.d.ts +8 -5
- package/dist/review/index.d.ts.map +1 -0
- package/dist/review/index.js +206 -5
- package/dist/review/review.enum.d.ts +1 -6
- package/dist/review/review.enum.d.ts.map +1 -1
- package/dist/review/review.enum.js +10 -14
- package/dist/review/review.event.d.ts +46 -52
- package/dist/review/review.event.d.ts.map +1 -1
- package/dist/review/review.event.js +46 -79
- package/dist/review/review.operations.d.ts +190 -196
- package/dist/review/review.operations.d.ts.map +1 -1
- package/dist/review/review.operations.js +149 -102
- package/dist/review/review.presentation.d.ts +2 -7
- package/dist/review/review.presentation.d.ts.map +1 -1
- package/dist/review/review.presentation.js +120 -56
- package/dist/review/review.schema.d.ts +164 -169
- package/dist/review/review.schema.d.ts.map +1 -1
- package/dist/review/review.schema.js +70 -151
- package/dist/seeders/index.d.ts +4 -8
- package/dist/seeders/index.d.ts.map +1 -1
- package/dist/seeders/index.js +11 -16
- package/dist/store/index.d.ts +8 -5
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +142 -5
- package/dist/store/store.enum.d.ts +1 -6
- package/dist/store/store.enum.d.ts.map +1 -1
- package/dist/store/store.enum.js +10 -14
- package/dist/store/store.event.d.ts +42 -48
- package/dist/store/store.event.d.ts.map +1 -1
- package/dist/store/store.event.js +48 -75
- package/dist/store/store.operations.d.ts +98 -104
- package/dist/store/store.operations.d.ts.map +1 -1
- package/dist/store/store.operations.js +86 -58
- package/dist/store/store.presentation.d.ts +2 -7
- package/dist/store/store.presentation.d.ts.map +1 -1
- package/dist/store/store.presentation.js +91 -56
- package/dist/store/store.schema.d.ts +70 -75
- package/dist/store/store.schema.d.ts.map +1 -1
- package/dist/store/store.schema.js +41 -90
- package/dist/tests/operations.test-spec.d.ts +5 -10
- package/dist/tests/operations.test-spec.d.ts.map +1 -1
- package/dist/tests/operations.test-spec.js +134 -146
- package/dist/ui/MarketplaceDashboard.d.ts +1 -6
- package/dist/ui/MarketplaceDashboard.d.ts.map +1 -1
- package/dist/ui/MarketplaceDashboard.js +413 -313
- package/dist/ui/hooks/index.d.ts +2 -2
- package/dist/ui/hooks/index.d.ts.map +1 -0
- package/dist/ui/hooks/index.js +59 -4
- package/dist/ui/hooks/useMarketplaceData.d.ts +16 -20
- package/dist/ui/hooks/useMarketplaceData.d.ts.map +1 -1
- package/dist/ui/hooks/useMarketplaceData.js +53 -60
- package/dist/ui/index.d.ts +7 -6
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +668 -5
- package/dist/ui/renderers/index.d.ts +2 -2
- package/dist/ui/renderers/index.d.ts.map +1 -0
- package/dist/ui/renderers/index.js +249 -3
- package/dist/ui/renderers/marketplace.markdown.d.ts +13 -15
- package/dist/ui/renderers/marketplace.markdown.d.ts.map +1 -1
- package/dist/ui/renderers/marketplace.markdown.js +241 -236
- package/package.json +529 -110
- package/dist/docs/marketplace.docblock.js.map +0 -1
- package/dist/entities/index.js.map +0 -1
- package/dist/entities/order.js.map +0 -1
- package/dist/entities/payout.js.map +0 -1
- package/dist/entities/product.js.map +0 -1
- package/dist/entities/review.js.map +0 -1
- package/dist/entities/store.js.map +0 -1
- package/dist/example.js.map +0 -1
- package/dist/handlers/marketplace.handlers.js.map +0 -1
- package/dist/marketplace.capability.js.map +0 -1
- package/dist/marketplace.feature.js.map +0 -1
- package/dist/order/order.enum.js.map +0 -1
- package/dist/order/order.event.js.map +0 -1
- package/dist/order/order.operations.js.map +0 -1
- package/dist/order/order.presentation.js.map +0 -1
- package/dist/order/order.schema.js.map +0 -1
- package/dist/payout/payout.enum.js.map +0 -1
- package/dist/payout/payout.event.js.map +0 -1
- package/dist/payout/payout.operations.js.map +0 -1
- package/dist/payout/payout.presentation.js.map +0 -1
- package/dist/payout/payout.schema.js.map +0 -1
- package/dist/product/product.enum.js.map +0 -1
- package/dist/product/product.event.js.map +0 -1
- package/dist/product/product.operations.js.map +0 -1
- package/dist/product/product.presentation.js.map +0 -1
- package/dist/product/product.schema.js.map +0 -1
- package/dist/review/review.enum.js.map +0 -1
- package/dist/review/review.event.js.map +0 -1
- package/dist/review/review.operations.js.map +0 -1
- package/dist/review/review.presentation.js.map +0 -1
- package/dist/review/review.schema.js.map +0 -1
- package/dist/seeders/index.js.map +0 -1
- package/dist/store/store.enum.js.map +0 -1
- package/dist/store/store.event.js.map +0 -1
- package/dist/store/store.operations.js.map +0 -1
- package/dist/store/store.presentation.js.map +0 -1
- package/dist/store/store.schema.js.map +0 -1
- package/dist/tests/operations.test-spec.js.map +0 -1
- package/dist/ui/MarketplaceDashboard.js.map +0 -1
- package/dist/ui/hooks/useMarketplaceData.js.map +0 -1
- package/dist/ui/renderers/marketplace.markdown.js.map +0 -1
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// src/example.ts
|
|
2
|
+
import { defineExample } from "@contractspec/lib.contracts";
|
|
3
|
+
var example = defineExample({
|
|
4
|
+
meta: {
|
|
5
|
+
key: "marketplace",
|
|
6
|
+
version: "1.0.0",
|
|
7
|
+
title: "Marketplace (2-sided)",
|
|
8
|
+
description: "Two-sided marketplace with stores, products, orders, payouts, and reviews (multi-actor flows).",
|
|
9
|
+
kind: "template",
|
|
10
|
+
visibility: "public",
|
|
11
|
+
stability: "experimental",
|
|
12
|
+
owners: ["@platform.core"],
|
|
13
|
+
tags: ["marketplace", "orders", "payouts", "reviews"]
|
|
14
|
+
},
|
|
15
|
+
docs: {
|
|
16
|
+
rootDocId: "docs.examples.marketplace",
|
|
17
|
+
goalDocId: "docs.examples.marketplace.goal",
|
|
18
|
+
usageDocId: "docs.examples.marketplace.usage",
|
|
19
|
+
constraintsDocId: "docs.examples.marketplace.constraints"
|
|
20
|
+
},
|
|
21
|
+
entrypoints: {
|
|
22
|
+
packageName: "@contractspec/example.marketplace",
|
|
23
|
+
feature: "./feature",
|
|
24
|
+
contracts: "./contracts",
|
|
25
|
+
presentations: "./presentations",
|
|
26
|
+
handlers: "./handlers",
|
|
27
|
+
docs: "./docs"
|
|
28
|
+
},
|
|
29
|
+
surfaces: {
|
|
30
|
+
templates: true,
|
|
31
|
+
sandbox: {
|
|
32
|
+
enabled: true,
|
|
33
|
+
modes: ["playground", "specs", "builder", "markdown", "evolution"]
|
|
34
|
+
},
|
|
35
|
+
studio: { enabled: true, installable: true },
|
|
36
|
+
mcp: { enabled: true }
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
var example_default = example;
|
|
40
|
+
export {
|
|
41
|
+
example_default as default
|
|
42
|
+
};
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
// src/handlers/marketplace.handlers.ts
|
|
2
|
+
import { web } from "@contractspec/lib.runtime-sandbox";
|
|
3
|
+
var { generateId } = web;
|
|
4
|
+
function rowToStore(row) {
|
|
5
|
+
return {
|
|
6
|
+
id: row.id,
|
|
7
|
+
projectId: row.projectId,
|
|
8
|
+
organizationId: row.organizationId,
|
|
9
|
+
name: row.name,
|
|
10
|
+
description: row.description ?? undefined,
|
|
11
|
+
status: row.status,
|
|
12
|
+
rating: row.rating,
|
|
13
|
+
reviewCount: row.reviewCount,
|
|
14
|
+
createdAt: new Date(row.createdAt),
|
|
15
|
+
updatedAt: new Date(row.updatedAt)
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function rowToProduct(row) {
|
|
19
|
+
return {
|
|
20
|
+
id: row.id,
|
|
21
|
+
storeId: row.storeId,
|
|
22
|
+
name: row.name,
|
|
23
|
+
description: row.description ?? undefined,
|
|
24
|
+
price: row.price,
|
|
25
|
+
currency: row.currency,
|
|
26
|
+
status: row.status,
|
|
27
|
+
stock: row.stock,
|
|
28
|
+
category: row.category ?? undefined,
|
|
29
|
+
imageUrl: row.imageUrl ?? undefined,
|
|
30
|
+
createdAt: new Date(row.createdAt),
|
|
31
|
+
updatedAt: new Date(row.updatedAt)
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function rowToOrder(row) {
|
|
35
|
+
return {
|
|
36
|
+
id: row.id,
|
|
37
|
+
projectId: row.projectId,
|
|
38
|
+
storeId: row.storeId,
|
|
39
|
+
customerId: row.customerId,
|
|
40
|
+
status: row.status,
|
|
41
|
+
total: row.total,
|
|
42
|
+
currency: row.currency,
|
|
43
|
+
shippingAddress: row.shippingAddress ?? undefined,
|
|
44
|
+
createdAt: new Date(row.createdAt),
|
|
45
|
+
updatedAt: new Date(row.updatedAt)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function rowToOrderItem(row) {
|
|
49
|
+
return {
|
|
50
|
+
id: row.id,
|
|
51
|
+
orderId: row.orderId,
|
|
52
|
+
productId: row.productId,
|
|
53
|
+
quantity: row.quantity,
|
|
54
|
+
price: row.price,
|
|
55
|
+
createdAt: new Date(row.createdAt)
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function rowToPayout(row) {
|
|
59
|
+
return {
|
|
60
|
+
id: row.id,
|
|
61
|
+
storeId: row.storeId,
|
|
62
|
+
amount: row.amount,
|
|
63
|
+
currency: row.currency,
|
|
64
|
+
status: row.status,
|
|
65
|
+
processedAt: row.processedAt ? new Date(row.processedAt) : undefined,
|
|
66
|
+
createdAt: new Date(row.createdAt)
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function rowToReview(row) {
|
|
70
|
+
return {
|
|
71
|
+
id: row.id,
|
|
72
|
+
productId: row.productId,
|
|
73
|
+
customerId: row.customerId,
|
|
74
|
+
orderId: row.orderId ?? undefined,
|
|
75
|
+
rating: row.rating,
|
|
76
|
+
comment: row.comment ?? undefined,
|
|
77
|
+
createdAt: new Date(row.createdAt)
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function createMarketplaceHandlers(db) {
|
|
81
|
+
async function listStores(input) {
|
|
82
|
+
const { projectId, status, search, limit = 20, offset = 0 } = input;
|
|
83
|
+
let whereClause = "WHERE projectId = ?";
|
|
84
|
+
const params = [projectId];
|
|
85
|
+
if (status && status !== "all") {
|
|
86
|
+
whereClause += " AND status = ?";
|
|
87
|
+
params.push(status);
|
|
88
|
+
}
|
|
89
|
+
if (search) {
|
|
90
|
+
whereClause += " AND name LIKE ?";
|
|
91
|
+
params.push(`%${search}%`);
|
|
92
|
+
}
|
|
93
|
+
const countResult = (await db.query(`SELECT COUNT(*) as count FROM marketplace_store ${whereClause}`, params)).rows;
|
|
94
|
+
const total = countResult[0]?.count ?? 0;
|
|
95
|
+
const rows = (await db.query(`SELECT * FROM marketplace_store ${whereClause} ORDER BY rating DESC LIMIT ? OFFSET ?`, [...params, limit, offset])).rows;
|
|
96
|
+
return {
|
|
97
|
+
stores: rows.map(rowToStore),
|
|
98
|
+
total
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
async function createStore(input, context) {
|
|
102
|
+
const id = generateId("store");
|
|
103
|
+
const now = new Date().toISOString();
|
|
104
|
+
await db.execute(`INSERT INTO marketplace_store (id, projectId, organizationId, name, description, status, rating, reviewCount, createdAt, updatedAt)
|
|
105
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
106
|
+
id,
|
|
107
|
+
context.projectId,
|
|
108
|
+
context.organizationId,
|
|
109
|
+
input.name,
|
|
110
|
+
input.description ?? null,
|
|
111
|
+
"PENDING",
|
|
112
|
+
0,
|
|
113
|
+
0,
|
|
114
|
+
now,
|
|
115
|
+
now
|
|
116
|
+
]);
|
|
117
|
+
const rows = (await db.query(`SELECT * FROM marketplace_store WHERE id = ?`, [id])).rows;
|
|
118
|
+
return rowToStore(rows[0]);
|
|
119
|
+
}
|
|
120
|
+
async function listProducts(input) {
|
|
121
|
+
const { storeId, status, category, search, limit = 20, offset = 0 } = input;
|
|
122
|
+
let whereClause = "WHERE 1=1";
|
|
123
|
+
const params = [];
|
|
124
|
+
if (storeId) {
|
|
125
|
+
whereClause += " AND storeId = ?";
|
|
126
|
+
params.push(storeId);
|
|
127
|
+
}
|
|
128
|
+
if (status && status !== "all") {
|
|
129
|
+
whereClause += " AND status = ?";
|
|
130
|
+
params.push(status);
|
|
131
|
+
}
|
|
132
|
+
if (category) {
|
|
133
|
+
whereClause += " AND category = ?";
|
|
134
|
+
params.push(category);
|
|
135
|
+
}
|
|
136
|
+
if (search) {
|
|
137
|
+
whereClause += " AND name LIKE ?";
|
|
138
|
+
params.push(`%${search}%`);
|
|
139
|
+
}
|
|
140
|
+
const countResult = (await db.query(`SELECT COUNT(*) as count FROM marketplace_product ${whereClause}`, params)).rows;
|
|
141
|
+
const total = countResult[0]?.count ?? 0;
|
|
142
|
+
const rows = (await db.query(`SELECT * FROM marketplace_product ${whereClause} ORDER BY createdAt DESC LIMIT ? OFFSET ?`, [...params, limit, offset])).rows;
|
|
143
|
+
return {
|
|
144
|
+
products: rows.map(rowToProduct),
|
|
145
|
+
total
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
async function addProduct(input) {
|
|
149
|
+
const id = generateId("prod");
|
|
150
|
+
const now = new Date().toISOString();
|
|
151
|
+
await db.execute(`INSERT INTO marketplace_product (id, storeId, name, description, price, currency, status, stock, category, imageUrl, createdAt, updatedAt)
|
|
152
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
153
|
+
id,
|
|
154
|
+
input.storeId,
|
|
155
|
+
input.name,
|
|
156
|
+
input.description ?? null,
|
|
157
|
+
input.price,
|
|
158
|
+
input.currency ?? "USD",
|
|
159
|
+
"DRAFT",
|
|
160
|
+
input.stock ?? 0,
|
|
161
|
+
input.category ?? null,
|
|
162
|
+
input.imageUrl ?? null,
|
|
163
|
+
now,
|
|
164
|
+
now
|
|
165
|
+
]);
|
|
166
|
+
const rows = (await db.query(`SELECT * FROM marketplace_product WHERE id = ?`, [id])).rows;
|
|
167
|
+
return rowToProduct(rows[0]);
|
|
168
|
+
}
|
|
169
|
+
async function listOrders(input) {
|
|
170
|
+
const {
|
|
171
|
+
projectId,
|
|
172
|
+
storeId,
|
|
173
|
+
customerId,
|
|
174
|
+
status,
|
|
175
|
+
limit = 20,
|
|
176
|
+
offset = 0
|
|
177
|
+
} = input;
|
|
178
|
+
let whereClause = "WHERE projectId = ?";
|
|
179
|
+
const params = [projectId];
|
|
180
|
+
if (storeId) {
|
|
181
|
+
whereClause += " AND storeId = ?";
|
|
182
|
+
params.push(storeId);
|
|
183
|
+
}
|
|
184
|
+
if (customerId) {
|
|
185
|
+
whereClause += " AND customerId = ?";
|
|
186
|
+
params.push(customerId);
|
|
187
|
+
}
|
|
188
|
+
if (status && status !== "all") {
|
|
189
|
+
whereClause += " AND status = ?";
|
|
190
|
+
params.push(status);
|
|
191
|
+
}
|
|
192
|
+
const countResult = (await db.query(`SELECT COUNT(*) as count FROM marketplace_order ${whereClause}`, params)).rows;
|
|
193
|
+
const total = countResult[0]?.count ?? 0;
|
|
194
|
+
const revenueResult = (await db.query(`SELECT COALESCE(SUM(total), 0) as revenue FROM marketplace_order ${whereClause}`, params)).rows;
|
|
195
|
+
const totalRevenue = revenueResult[0]?.revenue ?? 0;
|
|
196
|
+
const rows = (await db.query(`SELECT * FROM marketplace_order ${whereClause} ORDER BY createdAt DESC LIMIT ? OFFSET ?`, [...params, limit, offset])).rows;
|
|
197
|
+
return {
|
|
198
|
+
orders: rows.map(rowToOrder),
|
|
199
|
+
total,
|
|
200
|
+
totalRevenue
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
async function placeOrder(input, context) {
|
|
204
|
+
const orderId = generateId("order");
|
|
205
|
+
const now = new Date().toISOString();
|
|
206
|
+
let total = 0;
|
|
207
|
+
const itemsToCreate = [];
|
|
208
|
+
for (const item of input.items) {
|
|
209
|
+
const products = (await db.query(`SELECT * FROM marketplace_product WHERE id = ?`, [
|
|
210
|
+
item.productId
|
|
211
|
+
])).rows;
|
|
212
|
+
if (!products[0]) {
|
|
213
|
+
throw new Error(`Product not found: ${item.productId}`);
|
|
214
|
+
}
|
|
215
|
+
const itemPrice = products[0].price * item.quantity;
|
|
216
|
+
total += itemPrice;
|
|
217
|
+
itemsToCreate.push({
|
|
218
|
+
productId: item.productId,
|
|
219
|
+
quantity: item.quantity,
|
|
220
|
+
price: products[0].price
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
await db.execute(`INSERT INTO marketplace_order (id, projectId, storeId, customerId, status, total, currency, shippingAddress, createdAt, updatedAt)
|
|
224
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
225
|
+
orderId,
|
|
226
|
+
context.projectId,
|
|
227
|
+
input.storeId,
|
|
228
|
+
context.customerId,
|
|
229
|
+
"PENDING",
|
|
230
|
+
total,
|
|
231
|
+
"USD",
|
|
232
|
+
input.shippingAddress ?? null,
|
|
233
|
+
now,
|
|
234
|
+
now
|
|
235
|
+
]);
|
|
236
|
+
for (const item of itemsToCreate) {
|
|
237
|
+
await db.execute(`INSERT INTO marketplace_order_item (id, orderId, productId, quantity, price, createdAt)
|
|
238
|
+
VALUES (?, ?, ?, ?, ?, ?)`, [
|
|
239
|
+
generateId("orditem"),
|
|
240
|
+
orderId,
|
|
241
|
+
item.productId,
|
|
242
|
+
item.quantity,
|
|
243
|
+
item.price,
|
|
244
|
+
now
|
|
245
|
+
]);
|
|
246
|
+
}
|
|
247
|
+
const rows = (await db.query(`SELECT * FROM marketplace_order WHERE id = ?`, [orderId])).rows;
|
|
248
|
+
return rowToOrder(rows[0]);
|
|
249
|
+
}
|
|
250
|
+
async function getOrderItems(orderId) {
|
|
251
|
+
const rows = (await db.query(`SELECT * FROM marketplace_order_item WHERE orderId = ?`, [
|
|
252
|
+
orderId
|
|
253
|
+
])).rows;
|
|
254
|
+
return rows.map(rowToOrderItem);
|
|
255
|
+
}
|
|
256
|
+
async function updateOrderStatus(orderId, status) {
|
|
257
|
+
const now = new Date().toISOString();
|
|
258
|
+
await db.execute(`UPDATE marketplace_order SET status = ?, updatedAt = ? WHERE id = ?`, [status, now, orderId]);
|
|
259
|
+
const rows = (await db.query(`SELECT * FROM marketplace_order WHERE id = ?`, [orderId])).rows;
|
|
260
|
+
return rowToOrder(rows[0]);
|
|
261
|
+
}
|
|
262
|
+
async function listPayouts(storeId) {
|
|
263
|
+
const rows = (await db.query(`SELECT * FROM marketplace_payout WHERE storeId = ? ORDER BY createdAt DESC`, [storeId])).rows;
|
|
264
|
+
return rows.map(rowToPayout);
|
|
265
|
+
}
|
|
266
|
+
async function listReviews(productId) {
|
|
267
|
+
const rows = (await db.query(`SELECT * FROM marketplace_review WHERE productId = ? ORDER BY createdAt DESC`, [productId])).rows;
|
|
268
|
+
return rows.map(rowToReview);
|
|
269
|
+
}
|
|
270
|
+
async function submitReview(input) {
|
|
271
|
+
const id = generateId("review");
|
|
272
|
+
const now = new Date().toISOString();
|
|
273
|
+
await db.execute(`INSERT INTO marketplace_review (id, productId, customerId, orderId, rating, comment, createdAt)
|
|
274
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`, [
|
|
275
|
+
id,
|
|
276
|
+
input.productId,
|
|
277
|
+
input.customerId,
|
|
278
|
+
input.orderId ?? null,
|
|
279
|
+
input.rating,
|
|
280
|
+
input.comment ?? null,
|
|
281
|
+
now,
|
|
282
|
+
now
|
|
283
|
+
]);
|
|
284
|
+
const rows = (await db.query(`SELECT * FROM marketplace_review WHERE id = ?`, [id])).rows;
|
|
285
|
+
return rowToReview(rows[0]);
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
listStores,
|
|
289
|
+
createStore,
|
|
290
|
+
listProducts,
|
|
291
|
+
addProduct,
|
|
292
|
+
listOrders,
|
|
293
|
+
placeOrder,
|
|
294
|
+
getOrderItems,
|
|
295
|
+
updateOrderStatus,
|
|
296
|
+
listPayouts,
|
|
297
|
+
listReviews,
|
|
298
|
+
submitReview
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
export {
|
|
302
|
+
createMarketplaceHandlers
|
|
303
|
+
};
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
// src/handlers/marketplace.handlers.ts
|
|
2
|
+
import { web } from "@contractspec/lib.runtime-sandbox";
|
|
3
|
+
var { generateId } = web;
|
|
4
|
+
function rowToStore(row) {
|
|
5
|
+
return {
|
|
6
|
+
id: row.id,
|
|
7
|
+
projectId: row.projectId,
|
|
8
|
+
organizationId: row.organizationId,
|
|
9
|
+
name: row.name,
|
|
10
|
+
description: row.description ?? undefined,
|
|
11
|
+
status: row.status,
|
|
12
|
+
rating: row.rating,
|
|
13
|
+
reviewCount: row.reviewCount,
|
|
14
|
+
createdAt: new Date(row.createdAt),
|
|
15
|
+
updatedAt: new Date(row.updatedAt)
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function rowToProduct(row) {
|
|
19
|
+
return {
|
|
20
|
+
id: row.id,
|
|
21
|
+
storeId: row.storeId,
|
|
22
|
+
name: row.name,
|
|
23
|
+
description: row.description ?? undefined,
|
|
24
|
+
price: row.price,
|
|
25
|
+
currency: row.currency,
|
|
26
|
+
status: row.status,
|
|
27
|
+
stock: row.stock,
|
|
28
|
+
category: row.category ?? undefined,
|
|
29
|
+
imageUrl: row.imageUrl ?? undefined,
|
|
30
|
+
createdAt: new Date(row.createdAt),
|
|
31
|
+
updatedAt: new Date(row.updatedAt)
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function rowToOrder(row) {
|
|
35
|
+
return {
|
|
36
|
+
id: row.id,
|
|
37
|
+
projectId: row.projectId,
|
|
38
|
+
storeId: row.storeId,
|
|
39
|
+
customerId: row.customerId,
|
|
40
|
+
status: row.status,
|
|
41
|
+
total: row.total,
|
|
42
|
+
currency: row.currency,
|
|
43
|
+
shippingAddress: row.shippingAddress ?? undefined,
|
|
44
|
+
createdAt: new Date(row.createdAt),
|
|
45
|
+
updatedAt: new Date(row.updatedAt)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function rowToOrderItem(row) {
|
|
49
|
+
return {
|
|
50
|
+
id: row.id,
|
|
51
|
+
orderId: row.orderId,
|
|
52
|
+
productId: row.productId,
|
|
53
|
+
quantity: row.quantity,
|
|
54
|
+
price: row.price,
|
|
55
|
+
createdAt: new Date(row.createdAt)
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function rowToPayout(row) {
|
|
59
|
+
return {
|
|
60
|
+
id: row.id,
|
|
61
|
+
storeId: row.storeId,
|
|
62
|
+
amount: row.amount,
|
|
63
|
+
currency: row.currency,
|
|
64
|
+
status: row.status,
|
|
65
|
+
processedAt: row.processedAt ? new Date(row.processedAt) : undefined,
|
|
66
|
+
createdAt: new Date(row.createdAt)
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function rowToReview(row) {
|
|
70
|
+
return {
|
|
71
|
+
id: row.id,
|
|
72
|
+
productId: row.productId,
|
|
73
|
+
customerId: row.customerId,
|
|
74
|
+
orderId: row.orderId ?? undefined,
|
|
75
|
+
rating: row.rating,
|
|
76
|
+
comment: row.comment ?? undefined,
|
|
77
|
+
createdAt: new Date(row.createdAt)
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function createMarketplaceHandlers(db) {
|
|
81
|
+
async function listStores(input) {
|
|
82
|
+
const { projectId, status, search, limit = 20, offset = 0 } = input;
|
|
83
|
+
let whereClause = "WHERE projectId = ?";
|
|
84
|
+
const params = [projectId];
|
|
85
|
+
if (status && status !== "all") {
|
|
86
|
+
whereClause += " AND status = ?";
|
|
87
|
+
params.push(status);
|
|
88
|
+
}
|
|
89
|
+
if (search) {
|
|
90
|
+
whereClause += " AND name LIKE ?";
|
|
91
|
+
params.push(`%${search}%`);
|
|
92
|
+
}
|
|
93
|
+
const countResult = (await db.query(`SELECT COUNT(*) as count FROM marketplace_store ${whereClause}`, params)).rows;
|
|
94
|
+
const total = countResult[0]?.count ?? 0;
|
|
95
|
+
const rows = (await db.query(`SELECT * FROM marketplace_store ${whereClause} ORDER BY rating DESC LIMIT ? OFFSET ?`, [...params, limit, offset])).rows;
|
|
96
|
+
return {
|
|
97
|
+
stores: rows.map(rowToStore),
|
|
98
|
+
total
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
async function createStore(input, context) {
|
|
102
|
+
const id = generateId("store");
|
|
103
|
+
const now = new Date().toISOString();
|
|
104
|
+
await db.execute(`INSERT INTO marketplace_store (id, projectId, organizationId, name, description, status, rating, reviewCount, createdAt, updatedAt)
|
|
105
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
106
|
+
id,
|
|
107
|
+
context.projectId,
|
|
108
|
+
context.organizationId,
|
|
109
|
+
input.name,
|
|
110
|
+
input.description ?? null,
|
|
111
|
+
"PENDING",
|
|
112
|
+
0,
|
|
113
|
+
0,
|
|
114
|
+
now,
|
|
115
|
+
now
|
|
116
|
+
]);
|
|
117
|
+
const rows = (await db.query(`SELECT * FROM marketplace_store WHERE id = ?`, [id])).rows;
|
|
118
|
+
return rowToStore(rows[0]);
|
|
119
|
+
}
|
|
120
|
+
async function listProducts(input) {
|
|
121
|
+
const { storeId, status, category, search, limit = 20, offset = 0 } = input;
|
|
122
|
+
let whereClause = "WHERE 1=1";
|
|
123
|
+
const params = [];
|
|
124
|
+
if (storeId) {
|
|
125
|
+
whereClause += " AND storeId = ?";
|
|
126
|
+
params.push(storeId);
|
|
127
|
+
}
|
|
128
|
+
if (status && status !== "all") {
|
|
129
|
+
whereClause += " AND status = ?";
|
|
130
|
+
params.push(status);
|
|
131
|
+
}
|
|
132
|
+
if (category) {
|
|
133
|
+
whereClause += " AND category = ?";
|
|
134
|
+
params.push(category);
|
|
135
|
+
}
|
|
136
|
+
if (search) {
|
|
137
|
+
whereClause += " AND name LIKE ?";
|
|
138
|
+
params.push(`%${search}%`);
|
|
139
|
+
}
|
|
140
|
+
const countResult = (await db.query(`SELECT COUNT(*) as count FROM marketplace_product ${whereClause}`, params)).rows;
|
|
141
|
+
const total = countResult[0]?.count ?? 0;
|
|
142
|
+
const rows = (await db.query(`SELECT * FROM marketplace_product ${whereClause} ORDER BY createdAt DESC LIMIT ? OFFSET ?`, [...params, limit, offset])).rows;
|
|
143
|
+
return {
|
|
144
|
+
products: rows.map(rowToProduct),
|
|
145
|
+
total
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
async function addProduct(input) {
|
|
149
|
+
const id = generateId("prod");
|
|
150
|
+
const now = new Date().toISOString();
|
|
151
|
+
await db.execute(`INSERT INTO marketplace_product (id, storeId, name, description, price, currency, status, stock, category, imageUrl, createdAt, updatedAt)
|
|
152
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
153
|
+
id,
|
|
154
|
+
input.storeId,
|
|
155
|
+
input.name,
|
|
156
|
+
input.description ?? null,
|
|
157
|
+
input.price,
|
|
158
|
+
input.currency ?? "USD",
|
|
159
|
+
"DRAFT",
|
|
160
|
+
input.stock ?? 0,
|
|
161
|
+
input.category ?? null,
|
|
162
|
+
input.imageUrl ?? null,
|
|
163
|
+
now,
|
|
164
|
+
now
|
|
165
|
+
]);
|
|
166
|
+
const rows = (await db.query(`SELECT * FROM marketplace_product WHERE id = ?`, [id])).rows;
|
|
167
|
+
return rowToProduct(rows[0]);
|
|
168
|
+
}
|
|
169
|
+
async function listOrders(input) {
|
|
170
|
+
const {
|
|
171
|
+
projectId,
|
|
172
|
+
storeId,
|
|
173
|
+
customerId,
|
|
174
|
+
status,
|
|
175
|
+
limit = 20,
|
|
176
|
+
offset = 0
|
|
177
|
+
} = input;
|
|
178
|
+
let whereClause = "WHERE projectId = ?";
|
|
179
|
+
const params = [projectId];
|
|
180
|
+
if (storeId) {
|
|
181
|
+
whereClause += " AND storeId = ?";
|
|
182
|
+
params.push(storeId);
|
|
183
|
+
}
|
|
184
|
+
if (customerId) {
|
|
185
|
+
whereClause += " AND customerId = ?";
|
|
186
|
+
params.push(customerId);
|
|
187
|
+
}
|
|
188
|
+
if (status && status !== "all") {
|
|
189
|
+
whereClause += " AND status = ?";
|
|
190
|
+
params.push(status);
|
|
191
|
+
}
|
|
192
|
+
const countResult = (await db.query(`SELECT COUNT(*) as count FROM marketplace_order ${whereClause}`, params)).rows;
|
|
193
|
+
const total = countResult[0]?.count ?? 0;
|
|
194
|
+
const revenueResult = (await db.query(`SELECT COALESCE(SUM(total), 0) as revenue FROM marketplace_order ${whereClause}`, params)).rows;
|
|
195
|
+
const totalRevenue = revenueResult[0]?.revenue ?? 0;
|
|
196
|
+
const rows = (await db.query(`SELECT * FROM marketplace_order ${whereClause} ORDER BY createdAt DESC LIMIT ? OFFSET ?`, [...params, limit, offset])).rows;
|
|
197
|
+
return {
|
|
198
|
+
orders: rows.map(rowToOrder),
|
|
199
|
+
total,
|
|
200
|
+
totalRevenue
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
async function placeOrder(input, context) {
|
|
204
|
+
const orderId = generateId("order");
|
|
205
|
+
const now = new Date().toISOString();
|
|
206
|
+
let total = 0;
|
|
207
|
+
const itemsToCreate = [];
|
|
208
|
+
for (const item of input.items) {
|
|
209
|
+
const products = (await db.query(`SELECT * FROM marketplace_product WHERE id = ?`, [
|
|
210
|
+
item.productId
|
|
211
|
+
])).rows;
|
|
212
|
+
if (!products[0]) {
|
|
213
|
+
throw new Error(`Product not found: ${item.productId}`);
|
|
214
|
+
}
|
|
215
|
+
const itemPrice = products[0].price * item.quantity;
|
|
216
|
+
total += itemPrice;
|
|
217
|
+
itemsToCreate.push({
|
|
218
|
+
productId: item.productId,
|
|
219
|
+
quantity: item.quantity,
|
|
220
|
+
price: products[0].price
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
await db.execute(`INSERT INTO marketplace_order (id, projectId, storeId, customerId, status, total, currency, shippingAddress, createdAt, updatedAt)
|
|
224
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
225
|
+
orderId,
|
|
226
|
+
context.projectId,
|
|
227
|
+
input.storeId,
|
|
228
|
+
context.customerId,
|
|
229
|
+
"PENDING",
|
|
230
|
+
total,
|
|
231
|
+
"USD",
|
|
232
|
+
input.shippingAddress ?? null,
|
|
233
|
+
now,
|
|
234
|
+
now
|
|
235
|
+
]);
|
|
236
|
+
for (const item of itemsToCreate) {
|
|
237
|
+
await db.execute(`INSERT INTO marketplace_order_item (id, orderId, productId, quantity, price, createdAt)
|
|
238
|
+
VALUES (?, ?, ?, ?, ?, ?)`, [
|
|
239
|
+
generateId("orditem"),
|
|
240
|
+
orderId,
|
|
241
|
+
item.productId,
|
|
242
|
+
item.quantity,
|
|
243
|
+
item.price,
|
|
244
|
+
now
|
|
245
|
+
]);
|
|
246
|
+
}
|
|
247
|
+
const rows = (await db.query(`SELECT * FROM marketplace_order WHERE id = ?`, [orderId])).rows;
|
|
248
|
+
return rowToOrder(rows[0]);
|
|
249
|
+
}
|
|
250
|
+
async function getOrderItems(orderId) {
|
|
251
|
+
const rows = (await db.query(`SELECT * FROM marketplace_order_item WHERE orderId = ?`, [
|
|
252
|
+
orderId
|
|
253
|
+
])).rows;
|
|
254
|
+
return rows.map(rowToOrderItem);
|
|
255
|
+
}
|
|
256
|
+
async function updateOrderStatus(orderId, status) {
|
|
257
|
+
const now = new Date().toISOString();
|
|
258
|
+
await db.execute(`UPDATE marketplace_order SET status = ?, updatedAt = ? WHERE id = ?`, [status, now, orderId]);
|
|
259
|
+
const rows = (await db.query(`SELECT * FROM marketplace_order WHERE id = ?`, [orderId])).rows;
|
|
260
|
+
return rowToOrder(rows[0]);
|
|
261
|
+
}
|
|
262
|
+
async function listPayouts(storeId) {
|
|
263
|
+
const rows = (await db.query(`SELECT * FROM marketplace_payout WHERE storeId = ? ORDER BY createdAt DESC`, [storeId])).rows;
|
|
264
|
+
return rows.map(rowToPayout);
|
|
265
|
+
}
|
|
266
|
+
async function listReviews(productId) {
|
|
267
|
+
const rows = (await db.query(`SELECT * FROM marketplace_review WHERE productId = ? ORDER BY createdAt DESC`, [productId])).rows;
|
|
268
|
+
return rows.map(rowToReview);
|
|
269
|
+
}
|
|
270
|
+
async function submitReview(input) {
|
|
271
|
+
const id = generateId("review");
|
|
272
|
+
const now = new Date().toISOString();
|
|
273
|
+
await db.execute(`INSERT INTO marketplace_review (id, productId, customerId, orderId, rating, comment, createdAt)
|
|
274
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`, [
|
|
275
|
+
id,
|
|
276
|
+
input.productId,
|
|
277
|
+
input.customerId,
|
|
278
|
+
input.orderId ?? null,
|
|
279
|
+
input.rating,
|
|
280
|
+
input.comment ?? null,
|
|
281
|
+
now,
|
|
282
|
+
now
|
|
283
|
+
]);
|
|
284
|
+
const rows = (await db.query(`SELECT * FROM marketplace_review WHERE id = ?`, [id])).rows;
|
|
285
|
+
return rowToReview(rows[0]);
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
listStores,
|
|
289
|
+
createStore,
|
|
290
|
+
listProducts,
|
|
291
|
+
addProduct,
|
|
292
|
+
listOrders,
|
|
293
|
+
placeOrder,
|
|
294
|
+
getOrderItems,
|
|
295
|
+
updateOrderStatus,
|
|
296
|
+
listPayouts,
|
|
297
|
+
listReviews,
|
|
298
|
+
submitReview
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
export {
|
|
302
|
+
createMarketplaceHandlers
|
|
303
|
+
};
|