@contractspec/example.marketplace 3.7.5 → 3.7.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +63 -131
  2. package/dist/browser/entities/index.js +470 -470
  3. package/dist/browser/index.js +945 -944
  4. package/dist/browser/order/index.js +155 -155
  5. package/dist/browser/order/order.event.js +1 -1
  6. package/dist/browser/payout/index.js +71 -71
  7. package/dist/browser/payout/payout.event.js +1 -1
  8. package/dist/browser/product/index.js +104 -104
  9. package/dist/browser/product/product.event.js +1 -1
  10. package/dist/browser/review/index.js +75 -75
  11. package/dist/browser/review/review.event.js +1 -1
  12. package/dist/browser/store/index.js +68 -68
  13. package/dist/browser/store/store.event.js +1 -1
  14. package/dist/browser/ui/MarketplaceDashboard.js +35 -35
  15. package/dist/browser/ui/hooks/index.js +1 -1
  16. package/dist/browser/ui/hooks/useMarketplaceData.js +1 -1
  17. package/dist/browser/ui/index.js +285 -284
  18. package/dist/entities/index.d.ts +110 -110
  19. package/dist/entities/index.js +470 -470
  20. package/dist/index.d.ts +3 -3
  21. package/dist/index.js +945 -944
  22. package/dist/node/entities/index.js +470 -470
  23. package/dist/node/index.js +945 -944
  24. package/dist/node/order/index.js +155 -155
  25. package/dist/node/order/order.event.js +1 -1
  26. package/dist/node/payout/index.js +71 -71
  27. package/dist/node/payout/payout.event.js +1 -1
  28. package/dist/node/product/index.js +104 -104
  29. package/dist/node/product/product.event.js +1 -1
  30. package/dist/node/review/index.js +75 -75
  31. package/dist/node/review/review.event.js +1 -1
  32. package/dist/node/store/index.js +68 -68
  33. package/dist/node/store/store.event.js +1 -1
  34. package/dist/node/ui/MarketplaceDashboard.js +35 -35
  35. package/dist/node/ui/hooks/index.js +1 -1
  36. package/dist/node/ui/hooks/useMarketplaceData.js +1 -1
  37. package/dist/node/ui/index.js +285 -284
  38. package/dist/order/index.d.ts +2 -2
  39. package/dist/order/index.js +155 -155
  40. package/dist/order/order.event.js +1 -1
  41. package/dist/payout/index.d.ts +2 -2
  42. package/dist/payout/index.js +71 -71
  43. package/dist/payout/payout.event.js +1 -1
  44. package/dist/product/index.d.ts +2 -2
  45. package/dist/product/index.js +104 -104
  46. package/dist/product/product.event.js +1 -1
  47. package/dist/review/index.d.ts +2 -2
  48. package/dist/review/index.js +75 -75
  49. package/dist/review/review.event.js +1 -1
  50. package/dist/store/index.d.ts +2 -2
  51. package/dist/store/index.js +68 -68
  52. package/dist/store/store.event.js +1 -1
  53. package/dist/ui/MarketplaceDashboard.js +35 -35
  54. package/dist/ui/hooks/index.d.ts +1 -1
  55. package/dist/ui/hooks/index.js +1 -1
  56. package/dist/ui/hooks/useMarketplaceData.js +1 -1
  57. package/dist/ui/index.d.ts +2 -2
  58. package/dist/ui/index.js +285 -284
  59. package/dist/ui/renderers/index.d.ts +1 -1
  60. package/package.json +10 -10
@@ -1,249 +1,11 @@
1
- // src/entities/store.ts
1
+ // src/entities/order.ts
2
2
  import {
3
3
  defineEntity,
4
4
  defineEntityEnum,
5
5
  field,
6
6
  index
7
7
  } from "@contractspec/lib.schema";
8
- var StoreStatusEnum = defineEntityEnum({
9
- name: "StoreStatus",
10
- values: ["PENDING", "ACTIVE", "SUSPENDED", "CLOSED"],
11
- schema: "marketplace",
12
- description: "Status of a store."
13
- });
14
- var StoreTypeEnum = defineEntityEnum({
15
- name: "StoreType",
16
- values: ["INDIVIDUAL", "BUSINESS", "ENTERPRISE"],
17
- schema: "marketplace",
18
- description: "Type of store account."
19
- });
20
- var StoreEntity = defineEntity({
21
- name: "Store",
22
- description: "A seller storefront on the marketplace.",
23
- schema: "marketplace",
24
- map: "store",
25
- fields: {
26
- id: field.id({ description: "Unique store ID" }),
27
- name: field.string({ description: "Store display name" }),
28
- slug: field.string({ description: "URL-friendly identifier" }),
29
- description: field.string({ isOptional: true }),
30
- status: field.enum("StoreStatus", { default: "PENDING" }),
31
- type: field.enum("StoreType", { default: "INDIVIDUAL" }),
32
- ownerId: field.foreignKey({ description: "Store owner user ID" }),
33
- organizationId: field.foreignKey({ isOptional: true }),
34
- logoFileId: field.string({
35
- isOptional: true,
36
- description: "Logo file reference"
37
- }),
38
- bannerFileId: field.string({
39
- isOptional: true,
40
- description: "Banner file reference"
41
- }),
42
- email: field.string({ isOptional: true }),
43
- phone: field.string({ isOptional: true }),
44
- website: field.string({ isOptional: true }),
45
- country: field.string({ isOptional: true }),
46
- currency: field.string({ default: '"USD"' }),
47
- timezone: field.string({ isOptional: true }),
48
- commissionRate: field.decimal({
49
- default: 0.1,
50
- description: "Platform commission rate (e.g., 0.1 = 10%)"
51
- }),
52
- isVerified: field.boolean({ default: false }),
53
- verifiedAt: field.dateTime({ isOptional: true }),
54
- settings: field.json({ isOptional: true }),
55
- metadata: field.json({ isOptional: true }),
56
- totalProducts: field.int({ default: 0 }),
57
- totalOrders: field.int({ default: 0 }),
58
- totalRevenue: field.decimal({ default: 0 }),
59
- averageRating: field.decimal({ default: 0 }),
60
- createdAt: field.createdAt(),
61
- updatedAt: field.updatedAt(),
62
- products: field.hasMany("Product"),
63
- orders: field.hasMany("Order"),
64
- payouts: field.hasMany("Payout")
65
- },
66
- indexes: [
67
- index.unique(["slug"]),
68
- index.on(["ownerId"]),
69
- index.on(["status"]),
70
- index.on(["country", "status"]),
71
- index.on(["averageRating"])
72
- ],
73
- enums: [StoreStatusEnum, StoreTypeEnum]
74
- });
75
- var StoreCategoryEntity = defineEntity({
76
- name: "StoreCategory",
77
- description: "Category assignment for stores.",
78
- schema: "marketplace",
79
- map: "store_category",
80
- fields: {
81
- id: field.id(),
82
- storeId: field.foreignKey(),
83
- categoryId: field.foreignKey(),
84
- isPrimary: field.boolean({ default: false }),
85
- createdAt: field.createdAt(),
86
- store: field.belongsTo("Store", ["storeId"], ["id"], {
87
- onDelete: "Cascade"
88
- })
89
- },
90
- indexes: [index.unique(["storeId", "categoryId"]), index.on(["categoryId"])]
91
- });
92
-
93
- // src/entities/product.ts
94
- import {
95
- defineEntity as defineEntity2,
96
- defineEntityEnum as defineEntityEnum2,
97
- field as field2,
98
- index as index2
99
- } from "@contractspec/lib.schema";
100
- var ProductStatusEnum = defineEntityEnum2({
101
- name: "ProductStatus",
102
- values: [
103
- "DRAFT",
104
- "PENDING_REVIEW",
105
- "ACTIVE",
106
- "OUT_OF_STOCK",
107
- "DISCONTINUED",
108
- "REJECTED"
109
- ],
110
- schema: "marketplace",
111
- description: "Status of a product listing."
112
- });
113
- var ProductTypeEnum = defineEntityEnum2({
114
- name: "ProductType",
115
- values: ["PHYSICAL", "DIGITAL", "SERVICE", "SUBSCRIPTION"],
116
- schema: "marketplace",
117
- description: "Type of product."
118
- });
119
- var ProductEntity = defineEntity2({
120
- name: "Product",
121
- description: "A product listing on the marketplace.",
122
- schema: "marketplace",
123
- map: "product",
124
- fields: {
125
- id: field2.id({ description: "Unique product ID" }),
126
- storeId: field2.foreignKey(),
127
- name: field2.string({ description: "Product name" }),
128
- slug: field2.string({ description: "URL-friendly identifier" }),
129
- description: field2.string({ isOptional: true }),
130
- shortDescription: field2.string({ isOptional: true }),
131
- status: field2.enum("ProductStatus", { default: "DRAFT" }),
132
- type: field2.enum("ProductType", { default: "PHYSICAL" }),
133
- price: field2.decimal({ description: "Base price" }),
134
- compareAtPrice: field2.decimal({
135
- isOptional: true,
136
- description: "Original price for showing discounts"
137
- }),
138
- currency: field2.string({ default: '"USD"' }),
139
- sku: field2.string({ isOptional: true }),
140
- barcode: field2.string({ isOptional: true }),
141
- quantity: field2.int({ default: 0 }),
142
- trackInventory: field2.boolean({ default: true }),
143
- allowBackorder: field2.boolean({ default: false }),
144
- lowStockThreshold: field2.int({ default: 5 }),
145
- weight: field2.decimal({ isOptional: true }),
146
- weightUnit: field2.string({ default: '"kg"' }),
147
- categoryId: field2.string({ isOptional: true }),
148
- tags: field2.string({ isArray: true }),
149
- primaryImageId: field2.string({ isOptional: true }),
150
- seoTitle: field2.string({ isOptional: true }),
151
- seoDescription: field2.string({ isOptional: true }),
152
- attributes: field2.json({
153
- isOptional: true,
154
- description: "Custom product attributes"
155
- }),
156
- reviewCount: field2.int({ default: 0 }),
157
- averageRating: field2.decimal({ default: 0 }),
158
- totalSold: field2.int({ default: 0 }),
159
- createdAt: field2.createdAt(),
160
- updatedAt: field2.updatedAt(),
161
- publishedAt: field2.dateTime({ isOptional: true }),
162
- store: field2.belongsTo("Store", ["storeId"], ["id"]),
163
- variants: field2.hasMany("ProductVariant"),
164
- orderItems: field2.hasMany("OrderItem"),
165
- reviews: field2.hasMany("Review")
166
- },
167
- indexes: [
168
- index2.unique(["storeId", "slug"]),
169
- index2.on(["storeId", "status"]),
170
- index2.on(["status", "publishedAt"]),
171
- index2.on(["categoryId", "status"]),
172
- index2.on(["averageRating"]),
173
- index2.on(["totalSold"]),
174
- index2.on(["price"])
175
- ],
176
- enums: [ProductStatusEnum, ProductTypeEnum]
177
- });
178
- var ProductVariantEntity = defineEntity2({
179
- name: "ProductVariant",
180
- description: "A variant of a product with specific options.",
181
- schema: "marketplace",
182
- map: "product_variant",
183
- fields: {
184
- id: field2.id(),
185
- productId: field2.foreignKey(),
186
- name: field2.string({ description: 'Variant name (e.g., "Large / Blue")' }),
187
- options: field2.json({
188
- description: 'Variant options (e.g., {size: "L", color: "Blue"})'
189
- }),
190
- price: field2.decimal({ description: "Variant-specific price" }),
191
- compareAtPrice: field2.decimal({ isOptional: true }),
192
- sku: field2.string({ isOptional: true }),
193
- barcode: field2.string({ isOptional: true }),
194
- quantity: field2.int({ default: 0 }),
195
- imageId: field2.string({ isOptional: true }),
196
- isActive: field2.boolean({ default: true }),
197
- position: field2.int({ default: 0 }),
198
- createdAt: field2.createdAt(),
199
- updatedAt: field2.updatedAt(),
200
- product: field2.belongsTo("Product", ["productId"], ["id"], {
201
- onDelete: "Cascade"
202
- })
203
- },
204
- indexes: [
205
- index2.on(["productId", "sku"]),
206
- index2.on(["productId", "position"]),
207
- index2.on(["barcode"])
208
- ]
209
- });
210
- var CategoryEntity = defineEntity2({
211
- name: "Category",
212
- description: "Product category for organization.",
213
- schema: "marketplace",
214
- map: "category",
215
- fields: {
216
- id: field2.id(),
217
- name: field2.string(),
218
- slug: field2.string(),
219
- description: field2.string({ isOptional: true }),
220
- parentId: field2.string({ isOptional: true }),
221
- path: field2.string({ description: "Full path for hierarchical queries" }),
222
- level: field2.int({ default: 0 }),
223
- position: field2.int({ default: 0 }),
224
- imageId: field2.string({ isOptional: true }),
225
- isActive: field2.boolean({ default: true }),
226
- createdAt: field2.createdAt(),
227
- updatedAt: field2.updatedAt(),
228
- parent: field2.belongsTo("Category", ["parentId"], ["id"]),
229
- children: field2.hasMany("Category")
230
- },
231
- indexes: [
232
- index2.unique(["slug"]),
233
- index2.on(["parentId", "position"]),
234
- index2.on(["path"]),
235
- index2.on(["isActive"])
236
- ]
237
- });
238
-
239
- // src/entities/order.ts
240
- import {
241
- defineEntity as defineEntity3,
242
- defineEntityEnum as defineEntityEnum3,
243
- field as field3,
244
- index as index3
245
- } from "@contractspec/lib.schema";
246
- var OrderStatusEnum = defineEntityEnum3({
8
+ var OrderStatusEnum = defineEntityEnum({
247
9
  name: "OrderStatus",
248
10
  values: [
249
11
  "PENDING",
@@ -260,7 +22,7 @@ var OrderStatusEnum = defineEntityEnum3({
260
22
  schema: "marketplace",
261
23
  description: "Status of an order."
262
24
  });
263
- var PaymentStatusEnum = defineEntityEnum3({
25
+ var PaymentStatusEnum = defineEntityEnum({
264
26
  name: "PaymentStatus",
265
27
  values: [
266
28
  "PENDING",
@@ -273,384 +35,622 @@ var PaymentStatusEnum = defineEntityEnum3({
273
35
  schema: "marketplace",
274
36
  description: "Status of payment."
275
37
  });
276
- var OrderEntity = defineEntity3({
38
+ var OrderEntity = defineEntity({
277
39
  name: "Order",
278
40
  description: "A purchase order on the marketplace.",
279
41
  schema: "marketplace",
280
42
  map: "order",
281
43
  fields: {
282
- id: field3.id({ description: "Unique order ID" }),
283
- orderNumber: field3.string({ description: "Human-readable order number" }),
284
- buyerId: field3.foreignKey({ description: "Buyer user ID" }),
285
- storeId: field3.foreignKey({ description: "Seller store ID" }),
286
- status: field3.enum("OrderStatus", { default: "PENDING" }),
287
- paymentStatus: field3.enum("PaymentStatus", { default: "PENDING" }),
288
- subtotal: field3.decimal({ description: "Sum of item prices" }),
289
- shippingTotal: field3.decimal({ default: 0 }),
290
- taxTotal: field3.decimal({ default: 0 }),
291
- discountTotal: field3.decimal({ default: 0 }),
292
- total: field3.decimal({ description: "Final total" }),
293
- currency: field3.string({ default: '"USD"' }),
294
- platformFee: field3.decimal({ description: "Platform commission amount" }),
295
- sellerPayout: field3.decimal({ description: "Amount due to seller" }),
296
- shippingAddress: field3.json({ isOptional: true }),
297
- billingAddress: field3.json({ isOptional: true }),
298
- shippingMethod: field3.string({ isOptional: true }),
299
- trackingNumber: field3.string({ isOptional: true }),
300
- trackingUrl: field3.string({ isOptional: true }),
301
- paymentMethod: field3.string({ isOptional: true }),
302
- paymentIntentId: field3.string({ isOptional: true }),
303
- buyerNote: field3.string({ isOptional: true }),
304
- sellerNote: field3.string({ isOptional: true }),
305
- internalNote: field3.string({ isOptional: true }),
306
- createdAt: field3.createdAt(),
307
- updatedAt: field3.updatedAt(),
308
- paidAt: field3.dateTime({ isOptional: true }),
309
- shippedAt: field3.dateTime({ isOptional: true }),
310
- deliveredAt: field3.dateTime({ isOptional: true }),
311
- completedAt: field3.dateTime({ isOptional: true }),
312
- cancelledAt: field3.dateTime({ isOptional: true }),
313
- store: field3.belongsTo("Store", ["storeId"], ["id"]),
314
- items: field3.hasMany("OrderItem"),
315
- refunds: field3.hasMany("Refund")
44
+ id: field.id({ description: "Unique order ID" }),
45
+ orderNumber: field.string({ description: "Human-readable order number" }),
46
+ buyerId: field.foreignKey({ description: "Buyer user ID" }),
47
+ storeId: field.foreignKey({ description: "Seller store ID" }),
48
+ status: field.enum("OrderStatus", { default: "PENDING" }),
49
+ paymentStatus: field.enum("PaymentStatus", { default: "PENDING" }),
50
+ subtotal: field.decimal({ description: "Sum of item prices" }),
51
+ shippingTotal: field.decimal({ default: 0 }),
52
+ taxTotal: field.decimal({ default: 0 }),
53
+ discountTotal: field.decimal({ default: 0 }),
54
+ total: field.decimal({ description: "Final total" }),
55
+ currency: field.string({ default: '"USD"' }),
56
+ platformFee: field.decimal({ description: "Platform commission amount" }),
57
+ sellerPayout: field.decimal({ description: "Amount due to seller" }),
58
+ shippingAddress: field.json({ isOptional: true }),
59
+ billingAddress: field.json({ isOptional: true }),
60
+ shippingMethod: field.string({ isOptional: true }),
61
+ trackingNumber: field.string({ isOptional: true }),
62
+ trackingUrl: field.string({ isOptional: true }),
63
+ paymentMethod: field.string({ isOptional: true }),
64
+ paymentIntentId: field.string({ isOptional: true }),
65
+ buyerNote: field.string({ isOptional: true }),
66
+ sellerNote: field.string({ isOptional: true }),
67
+ internalNote: field.string({ isOptional: true }),
68
+ createdAt: field.createdAt(),
69
+ updatedAt: field.updatedAt(),
70
+ paidAt: field.dateTime({ isOptional: true }),
71
+ shippedAt: field.dateTime({ isOptional: true }),
72
+ deliveredAt: field.dateTime({ isOptional: true }),
73
+ completedAt: field.dateTime({ isOptional: true }),
74
+ cancelledAt: field.dateTime({ isOptional: true }),
75
+ store: field.belongsTo("Store", ["storeId"], ["id"]),
76
+ items: field.hasMany("OrderItem"),
77
+ refunds: field.hasMany("Refund")
316
78
  },
317
79
  indexes: [
318
- index3.unique(["orderNumber"]),
319
- index3.on(["buyerId", "status"]),
320
- index3.on(["storeId", "status"]),
321
- index3.on(["status", "createdAt"]),
322
- index3.on(["paymentStatus"]),
323
- index3.on(["createdAt"])
80
+ index.unique(["orderNumber"]),
81
+ index.on(["buyerId", "status"]),
82
+ index.on(["storeId", "status"]),
83
+ index.on(["status", "createdAt"]),
84
+ index.on(["paymentStatus"]),
85
+ index.on(["createdAt"])
324
86
  ],
325
87
  enums: [OrderStatusEnum, PaymentStatusEnum]
326
88
  });
327
- var OrderItemEntity = defineEntity3({
89
+ var OrderItemEntity = defineEntity({
328
90
  name: "OrderItem",
329
91
  description: "An item within an order.",
330
92
  schema: "marketplace",
331
93
  map: "order_item",
332
94
  fields: {
333
- id: field3.id(),
334
- orderId: field3.foreignKey(),
335
- productId: field3.foreignKey(),
336
- variantId: field3.string({ isOptional: true }),
337
- productName: field3.string(),
338
- variantName: field3.string({ isOptional: true }),
339
- sku: field3.string({ isOptional: true }),
340
- unitPrice: field3.decimal(),
341
- quantity: field3.int(),
342
- subtotal: field3.decimal(),
343
- quantityFulfilled: field3.int({ default: 0 }),
344
- quantityRefunded: field3.int({ default: 0 }),
345
- createdAt: field3.createdAt(),
346
- updatedAt: field3.updatedAt(),
347
- order: field3.belongsTo("Order", ["orderId"], ["id"], {
95
+ id: field.id(),
96
+ orderId: field.foreignKey(),
97
+ productId: field.foreignKey(),
98
+ variantId: field.string({ isOptional: true }),
99
+ productName: field.string(),
100
+ variantName: field.string({ isOptional: true }),
101
+ sku: field.string({ isOptional: true }),
102
+ unitPrice: field.decimal(),
103
+ quantity: field.int(),
104
+ subtotal: field.decimal(),
105
+ quantityFulfilled: field.int({ default: 0 }),
106
+ quantityRefunded: field.int({ default: 0 }),
107
+ createdAt: field.createdAt(),
108
+ updatedAt: field.updatedAt(),
109
+ order: field.belongsTo("Order", ["orderId"], ["id"], {
348
110
  onDelete: "Cascade"
349
111
  }),
350
- product: field3.belongsTo("Product", ["productId"], ["id"])
112
+ product: field.belongsTo("Product", ["productId"], ["id"])
351
113
  },
352
- indexes: [index3.on(["orderId"]), index3.on(["productId"])]
114
+ indexes: [index.on(["orderId"]), index.on(["productId"])]
353
115
  });
354
- var RefundEntity = defineEntity3({
116
+ var RefundEntity = defineEntity({
355
117
  name: "Refund",
356
118
  description: "A refund for an order.",
357
119
  schema: "marketplace",
358
120
  map: "refund",
359
121
  fields: {
360
- id: field3.id(),
361
- orderId: field3.foreignKey(),
362
- amount: field3.decimal(),
363
- currency: field3.string(),
364
- reason: field3.string(),
365
- notes: field3.string({ isOptional: true }),
366
- status: field3.string({ default: '"PENDING"' }),
367
- refundId: field3.string({
122
+ id: field.id(),
123
+ orderId: field.foreignKey(),
124
+ amount: field.decimal(),
125
+ currency: field.string(),
126
+ reason: field.string(),
127
+ notes: field.string({ isOptional: true }),
128
+ status: field.string({ default: '"PENDING"' }),
129
+ refundId: field.string({
368
130
  isOptional: true,
369
131
  description: "Payment provider refund ID"
370
132
  }),
371
- issuedBy: field3.foreignKey({ description: "User who issued the refund" }),
372
- createdAt: field3.createdAt(),
373
- processedAt: field3.dateTime({ isOptional: true }),
374
- order: field3.belongsTo("Order", ["orderId"], ["id"]),
375
- items: field3.hasMany("RefundItem")
133
+ issuedBy: field.foreignKey({ description: "User who issued the refund" }),
134
+ createdAt: field.createdAt(),
135
+ processedAt: field.dateTime({ isOptional: true }),
136
+ order: field.belongsTo("Order", ["orderId"], ["id"]),
137
+ items: field.hasMany("RefundItem")
376
138
  },
377
- indexes: [index3.on(["orderId"]), index3.on(["status"])]
139
+ indexes: [index.on(["orderId"]), index.on(["status"])]
378
140
  });
379
- var RefundItemEntity = defineEntity3({
141
+ var RefundItemEntity = defineEntity({
380
142
  name: "RefundItem",
381
143
  description: "An item within a refund.",
382
144
  schema: "marketplace",
383
145
  map: "refund_item",
384
146
  fields: {
385
- id: field3.id(),
386
- refundId: field3.foreignKey(),
387
- orderItemId: field3.foreignKey(),
388
- quantity: field3.int(),
389
- amount: field3.decimal(),
390
- createdAt: field3.createdAt(),
391
- refund: field3.belongsTo("Refund", ["refundId"], ["id"], {
147
+ id: field.id(),
148
+ refundId: field.foreignKey(),
149
+ orderItemId: field.foreignKey(),
150
+ quantity: field.int(),
151
+ amount: field.decimal(),
152
+ createdAt: field.createdAt(),
153
+ refund: field.belongsTo("Refund", ["refundId"], ["id"], {
392
154
  onDelete: "Cascade"
393
155
  }),
394
- orderItem: field3.belongsTo("OrderItem", ["orderItemId"], ["id"])
156
+ orderItem: field.belongsTo("OrderItem", ["orderItemId"], ["id"])
395
157
  },
396
- indexes: [index3.on(["refundId"]), index3.on(["orderItemId"])]
158
+ indexes: [index.on(["refundId"]), index.on(["orderItemId"])]
397
159
  });
398
160
 
399
161
  // src/entities/payout.ts
400
162
  import {
401
- defineEntity as defineEntity4,
402
- defineEntityEnum as defineEntityEnum4,
403
- field as field4,
404
- index as index4
163
+ defineEntity as defineEntity2,
164
+ defineEntityEnum as defineEntityEnum2,
165
+ field as field2,
166
+ index as index2
405
167
  } from "@contractspec/lib.schema";
406
- var PayoutStatusEnum = defineEntityEnum4({
168
+ var PayoutStatusEnum = defineEntityEnum2({
407
169
  name: "PayoutStatus",
408
170
  values: ["PENDING", "PROCESSING", "PAID", "FAILED", "CANCELLED"],
409
171
  schema: "marketplace",
410
172
  description: "Status of a payout."
411
173
  });
412
- var PayoutScheduleEnum = defineEntityEnum4({
174
+ var PayoutScheduleEnum = defineEntityEnum2({
413
175
  name: "PayoutSchedule",
414
176
  values: ["DAILY", "WEEKLY", "BIWEEKLY", "MONTHLY", "MANUAL"],
415
177
  schema: "marketplace",
416
178
  description: "Payout schedule frequency."
417
179
  });
418
- var PayoutEntity = defineEntity4({
180
+ var PayoutEntity = defineEntity2({
419
181
  name: "Payout",
420
182
  description: "A payout to a seller.",
421
183
  schema: "marketplace",
422
184
  map: "payout",
423
185
  fields: {
424
- id: field4.id({ description: "Unique payout ID" }),
425
- storeId: field4.foreignKey(),
426
- payoutNumber: field4.string({ description: "Human-readable payout number" }),
427
- status: field4.enum("PayoutStatus", { default: "PENDING" }),
428
- grossAmount: field4.decimal({ description: "Total before fees" }),
429
- platformFees: field4.decimal({ description: "Platform fees deducted" }),
430
- otherDeductions: field4.decimal({ default: 0 }),
431
- netAmount: field4.decimal({ description: "Final payout amount" }),
432
- currency: field4.string({ default: '"USD"' }),
433
- periodStart: field4.dateTime({ description: "Start of payout period" }),
434
- periodEnd: field4.dateTime({ description: "End of payout period" }),
435
- paymentMethod: field4.string({ isOptional: true }),
436
- paymentReference: field4.string({ isOptional: true }),
437
- bankAccountId: field4.string({ isOptional: true }),
438
- bankAccountLast4: field4.string({ isOptional: true }),
439
- notes: field4.string({ isOptional: true }),
440
- failureReason: field4.string({ isOptional: true }),
441
- orderCount: field4.int({ default: 0 }),
442
- createdAt: field4.createdAt(),
443
- updatedAt: field4.updatedAt(),
444
- scheduledAt: field4.dateTime({ isOptional: true }),
445
- processedAt: field4.dateTime({ isOptional: true }),
446
- paidAt: field4.dateTime({ isOptional: true }),
447
- store: field4.belongsTo("Store", ["storeId"], ["id"]),
448
- items: field4.hasMany("PayoutItem")
186
+ id: field2.id({ description: "Unique payout ID" }),
187
+ storeId: field2.foreignKey(),
188
+ payoutNumber: field2.string({ description: "Human-readable payout number" }),
189
+ status: field2.enum("PayoutStatus", { default: "PENDING" }),
190
+ grossAmount: field2.decimal({ description: "Total before fees" }),
191
+ platformFees: field2.decimal({ description: "Platform fees deducted" }),
192
+ otherDeductions: field2.decimal({ default: 0 }),
193
+ netAmount: field2.decimal({ description: "Final payout amount" }),
194
+ currency: field2.string({ default: '"USD"' }),
195
+ periodStart: field2.dateTime({ description: "Start of payout period" }),
196
+ periodEnd: field2.dateTime({ description: "End of payout period" }),
197
+ paymentMethod: field2.string({ isOptional: true }),
198
+ paymentReference: field2.string({ isOptional: true }),
199
+ bankAccountId: field2.string({ isOptional: true }),
200
+ bankAccountLast4: field2.string({ isOptional: true }),
201
+ notes: field2.string({ isOptional: true }),
202
+ failureReason: field2.string({ isOptional: true }),
203
+ orderCount: field2.int({ default: 0 }),
204
+ createdAt: field2.createdAt(),
205
+ updatedAt: field2.updatedAt(),
206
+ scheduledAt: field2.dateTime({ isOptional: true }),
207
+ processedAt: field2.dateTime({ isOptional: true }),
208
+ paidAt: field2.dateTime({ isOptional: true }),
209
+ store: field2.belongsTo("Store", ["storeId"], ["id"]),
210
+ items: field2.hasMany("PayoutItem")
449
211
  },
450
212
  indexes: [
451
- index4.unique(["payoutNumber"]),
452
- index4.on(["storeId", "status"]),
453
- index4.on(["status", "scheduledAt"]),
454
- index4.on(["periodStart", "periodEnd"])
213
+ index2.unique(["payoutNumber"]),
214
+ index2.on(["storeId", "status"]),
215
+ index2.on(["status", "scheduledAt"]),
216
+ index2.on(["periodStart", "periodEnd"])
455
217
  ],
456
218
  enums: [PayoutStatusEnum]
457
219
  });
458
- var PayoutItemEntity = defineEntity4({
220
+ var PayoutItemEntity = defineEntity2({
459
221
  name: "PayoutItem",
460
222
  description: "An order included in a payout.",
461
223
  schema: "marketplace",
462
224
  map: "payout_item",
463
225
  fields: {
464
- id: field4.id(),
465
- payoutId: field4.foreignKey(),
466
- orderId: field4.foreignKey(),
467
- orderTotal: field4.decimal(),
468
- platformFee: field4.decimal(),
469
- netAmount: field4.decimal(),
470
- createdAt: field4.createdAt(),
471
- payout: field4.belongsTo("Payout", ["payoutId"], ["id"], {
226
+ id: field2.id(),
227
+ payoutId: field2.foreignKey(),
228
+ orderId: field2.foreignKey(),
229
+ orderTotal: field2.decimal(),
230
+ platformFee: field2.decimal(),
231
+ netAmount: field2.decimal(),
232
+ createdAt: field2.createdAt(),
233
+ payout: field2.belongsTo("Payout", ["payoutId"], ["id"], {
472
234
  onDelete: "Cascade"
473
235
  }),
474
- order: field4.belongsTo("Order", ["orderId"], ["id"])
236
+ order: field2.belongsTo("Order", ["orderId"], ["id"])
475
237
  },
476
- indexes: [index4.on(["payoutId"]), index4.on(["orderId"])]
238
+ indexes: [index2.on(["payoutId"]), index2.on(["orderId"])]
477
239
  });
478
- var BankAccountEntity = defineEntity4({
240
+ var BankAccountEntity = defineEntity2({
479
241
  name: "BankAccount",
480
242
  description: "A bank account for receiving payouts.",
481
243
  schema: "marketplace",
482
244
  map: "bank_account",
483
245
  fields: {
484
- id: field4.id(),
485
- storeId: field4.foreignKey(),
486
- accountHolderName: field4.string(),
487
- accountType: field4.string({ default: '"CHECKING"' }),
488
- bankName: field4.string({ isOptional: true }),
489
- last4: field4.string({ description: "Last 4 digits of account" }),
490
- routingLast4: field4.string({ isOptional: true }),
491
- externalId: field4.string({
246
+ id: field2.id(),
247
+ storeId: field2.foreignKey(),
248
+ accountHolderName: field2.string(),
249
+ accountType: field2.string({ default: '"CHECKING"' }),
250
+ bankName: field2.string({ isOptional: true }),
251
+ last4: field2.string({ description: "Last 4 digits of account" }),
252
+ routingLast4: field2.string({ isOptional: true }),
253
+ externalId: field2.string({
492
254
  isOptional: true,
493
255
  description: "External provider account ID"
494
256
  }),
495
- isDefault: field4.boolean({ default: false }),
496
- isVerified: field4.boolean({ default: false }),
497
- createdAt: field4.createdAt(),
498
- updatedAt: field4.updatedAt(),
499
- verifiedAt: field4.dateTime({ isOptional: true }),
500
- store: field4.belongsTo("Store", ["storeId"], ["id"])
257
+ isDefault: field2.boolean({ default: false }),
258
+ isVerified: field2.boolean({ default: false }),
259
+ createdAt: field2.createdAt(),
260
+ updatedAt: field2.updatedAt(),
261
+ verifiedAt: field2.dateTime({ isOptional: true }),
262
+ store: field2.belongsTo("Store", ["storeId"], ["id"])
501
263
  },
502
- indexes: [index4.on(["storeId", "isDefault"]), index4.on(["externalId"])]
264
+ indexes: [index2.on(["storeId", "isDefault"]), index2.on(["externalId"])]
503
265
  });
504
- var PayoutSettingsEntity = defineEntity4({
266
+ var PayoutSettingsEntity = defineEntity2({
505
267
  name: "PayoutSettings",
506
268
  description: "Payout configuration for a store.",
507
269
  schema: "marketplace",
508
270
  map: "payout_settings",
509
271
  fields: {
510
- id: field4.id(),
511
- storeId: field4.foreignKey(),
512
- schedule: field4.enum("PayoutSchedule", { default: "WEEKLY" }),
513
- dayOfWeek: field4.int({
272
+ id: field2.id(),
273
+ storeId: field2.foreignKey(),
274
+ schedule: field2.enum("PayoutSchedule", { default: "WEEKLY" }),
275
+ dayOfWeek: field2.int({
514
276
  isOptional: true,
515
277
  description: "Day for weekly/biweekly (0=Sunday)"
516
278
  }),
517
- dayOfMonth: field4.int({
279
+ dayOfMonth: field2.int({
518
280
  isOptional: true,
519
281
  description: "Day for monthly (1-28)"
520
282
  }),
521
- minimumPayout: field4.decimal({
283
+ minimumPayout: field2.decimal({
522
284
  default: 50,
523
285
  description: "Minimum amount for payout"
524
286
  }),
525
- defaultBankAccountId: field4.string({ isOptional: true }),
526
- createdAt: field4.createdAt(),
527
- updatedAt: field4.updatedAt(),
528
- store: field4.belongsTo("Store", ["storeId"], ["id"])
287
+ defaultBankAccountId: field2.string({ isOptional: true }),
288
+ createdAt: field2.createdAt(),
289
+ updatedAt: field2.updatedAt(),
290
+ store: field2.belongsTo("Store", ["storeId"], ["id"])
529
291
  },
530
- indexes: [index4.unique(["storeId"])],
292
+ indexes: [index2.unique(["storeId"])],
531
293
  enums: [PayoutScheduleEnum]
532
294
  });
533
295
 
296
+ // src/entities/product.ts
297
+ import {
298
+ defineEntity as defineEntity3,
299
+ defineEntityEnum as defineEntityEnum3,
300
+ field as field3,
301
+ index as index3
302
+ } from "@contractspec/lib.schema";
303
+ var ProductStatusEnum = defineEntityEnum3({
304
+ name: "ProductStatus",
305
+ values: [
306
+ "DRAFT",
307
+ "PENDING_REVIEW",
308
+ "ACTIVE",
309
+ "OUT_OF_STOCK",
310
+ "DISCONTINUED",
311
+ "REJECTED"
312
+ ],
313
+ schema: "marketplace",
314
+ description: "Status of a product listing."
315
+ });
316
+ var ProductTypeEnum = defineEntityEnum3({
317
+ name: "ProductType",
318
+ values: ["PHYSICAL", "DIGITAL", "SERVICE", "SUBSCRIPTION"],
319
+ schema: "marketplace",
320
+ description: "Type of product."
321
+ });
322
+ var ProductEntity = defineEntity3({
323
+ name: "Product",
324
+ description: "A product listing on the marketplace.",
325
+ schema: "marketplace",
326
+ map: "product",
327
+ fields: {
328
+ id: field3.id({ description: "Unique product ID" }),
329
+ storeId: field3.foreignKey(),
330
+ name: field3.string({ description: "Product name" }),
331
+ slug: field3.string({ description: "URL-friendly identifier" }),
332
+ description: field3.string({ isOptional: true }),
333
+ shortDescription: field3.string({ isOptional: true }),
334
+ status: field3.enum("ProductStatus", { default: "DRAFT" }),
335
+ type: field3.enum("ProductType", { default: "PHYSICAL" }),
336
+ price: field3.decimal({ description: "Base price" }),
337
+ compareAtPrice: field3.decimal({
338
+ isOptional: true,
339
+ description: "Original price for showing discounts"
340
+ }),
341
+ currency: field3.string({ default: '"USD"' }),
342
+ sku: field3.string({ isOptional: true }),
343
+ barcode: field3.string({ isOptional: true }),
344
+ quantity: field3.int({ default: 0 }),
345
+ trackInventory: field3.boolean({ default: true }),
346
+ allowBackorder: field3.boolean({ default: false }),
347
+ lowStockThreshold: field3.int({ default: 5 }),
348
+ weight: field3.decimal({ isOptional: true }),
349
+ weightUnit: field3.string({ default: '"kg"' }),
350
+ categoryId: field3.string({ isOptional: true }),
351
+ tags: field3.string({ isArray: true }),
352
+ primaryImageId: field3.string({ isOptional: true }),
353
+ seoTitle: field3.string({ isOptional: true }),
354
+ seoDescription: field3.string({ isOptional: true }),
355
+ attributes: field3.json({
356
+ isOptional: true,
357
+ description: "Custom product attributes"
358
+ }),
359
+ reviewCount: field3.int({ default: 0 }),
360
+ averageRating: field3.decimal({ default: 0 }),
361
+ totalSold: field3.int({ default: 0 }),
362
+ createdAt: field3.createdAt(),
363
+ updatedAt: field3.updatedAt(),
364
+ publishedAt: field3.dateTime({ isOptional: true }),
365
+ store: field3.belongsTo("Store", ["storeId"], ["id"]),
366
+ variants: field3.hasMany("ProductVariant"),
367
+ orderItems: field3.hasMany("OrderItem"),
368
+ reviews: field3.hasMany("Review")
369
+ },
370
+ indexes: [
371
+ index3.unique(["storeId", "slug"]),
372
+ index3.on(["storeId", "status"]),
373
+ index3.on(["status", "publishedAt"]),
374
+ index3.on(["categoryId", "status"]),
375
+ index3.on(["averageRating"]),
376
+ index3.on(["totalSold"]),
377
+ index3.on(["price"])
378
+ ],
379
+ enums: [ProductStatusEnum, ProductTypeEnum]
380
+ });
381
+ var ProductVariantEntity = defineEntity3({
382
+ name: "ProductVariant",
383
+ description: "A variant of a product with specific options.",
384
+ schema: "marketplace",
385
+ map: "product_variant",
386
+ fields: {
387
+ id: field3.id(),
388
+ productId: field3.foreignKey(),
389
+ name: field3.string({ description: 'Variant name (e.g., "Large / Blue")' }),
390
+ options: field3.json({
391
+ description: 'Variant options (e.g., {size: "L", color: "Blue"})'
392
+ }),
393
+ price: field3.decimal({ description: "Variant-specific price" }),
394
+ compareAtPrice: field3.decimal({ isOptional: true }),
395
+ sku: field3.string({ isOptional: true }),
396
+ barcode: field3.string({ isOptional: true }),
397
+ quantity: field3.int({ default: 0 }),
398
+ imageId: field3.string({ isOptional: true }),
399
+ isActive: field3.boolean({ default: true }),
400
+ position: field3.int({ default: 0 }),
401
+ createdAt: field3.createdAt(),
402
+ updatedAt: field3.updatedAt(),
403
+ product: field3.belongsTo("Product", ["productId"], ["id"], {
404
+ onDelete: "Cascade"
405
+ })
406
+ },
407
+ indexes: [
408
+ index3.on(["productId", "sku"]),
409
+ index3.on(["productId", "position"]),
410
+ index3.on(["barcode"])
411
+ ]
412
+ });
413
+ var CategoryEntity = defineEntity3({
414
+ name: "Category",
415
+ description: "Product category for organization.",
416
+ schema: "marketplace",
417
+ map: "category",
418
+ fields: {
419
+ id: field3.id(),
420
+ name: field3.string(),
421
+ slug: field3.string(),
422
+ description: field3.string({ isOptional: true }),
423
+ parentId: field3.string({ isOptional: true }),
424
+ path: field3.string({ description: "Full path for hierarchical queries" }),
425
+ level: field3.int({ default: 0 }),
426
+ position: field3.int({ default: 0 }),
427
+ imageId: field3.string({ isOptional: true }),
428
+ isActive: field3.boolean({ default: true }),
429
+ createdAt: field3.createdAt(),
430
+ updatedAt: field3.updatedAt(),
431
+ parent: field3.belongsTo("Category", ["parentId"], ["id"]),
432
+ children: field3.hasMany("Category")
433
+ },
434
+ indexes: [
435
+ index3.unique(["slug"]),
436
+ index3.on(["parentId", "position"]),
437
+ index3.on(["path"]),
438
+ index3.on(["isActive"])
439
+ ]
440
+ });
441
+
534
442
  // src/entities/review.ts
535
443
  import {
536
- defineEntity as defineEntity5,
537
- defineEntityEnum as defineEntityEnum5,
538
- field as field5,
539
- index as index5
444
+ defineEntity as defineEntity4,
445
+ defineEntityEnum as defineEntityEnum4,
446
+ field as field4,
447
+ index as index4
540
448
  } from "@contractspec/lib.schema";
541
- var ReviewStatusEnum = defineEntityEnum5({
449
+ var ReviewStatusEnum = defineEntityEnum4({
542
450
  name: "ReviewStatus",
543
451
  values: ["PENDING", "APPROVED", "REJECTED", "FLAGGED"],
544
452
  schema: "marketplace",
545
453
  description: "Status of a review."
546
454
  });
547
- var ReviewTypeEnum = defineEntityEnum5({
455
+ var ReviewTypeEnum = defineEntityEnum4({
548
456
  name: "ReviewType",
549
457
  values: ["PRODUCT", "STORE", "ORDER"],
550
458
  schema: "marketplace",
551
459
  description: "Type of review."
552
460
  });
553
- var ReviewEntity = defineEntity5({
461
+ var ReviewEntity = defineEntity4({
554
462
  name: "Review",
555
463
  description: "A customer review on the marketplace.",
556
464
  schema: "marketplace",
557
465
  map: "review",
558
466
  fields: {
559
- id: field5.id({ description: "Unique review ID" }),
560
- type: field5.enum("ReviewType", { default: "PRODUCT" }),
561
- productId: field5.string({ isOptional: true }),
562
- storeId: field5.string({ isOptional: true }),
563
- orderId: field5.string({ isOptional: true }),
564
- orderItemId: field5.string({ isOptional: true }),
565
- authorId: field5.foreignKey({ description: "Reviewer user ID" }),
566
- rating: field5.int({ description: "Rating 1-5" }),
567
- title: field5.string({ isOptional: true }),
568
- content: field5.string({ isOptional: true }),
569
- isVerifiedPurchase: field5.boolean({ default: false }),
570
- status: field5.enum("ReviewStatus", { default: "PENDING" }),
571
- hasMedia: field5.boolean({ default: false }),
572
- helpfulCount: field5.int({ default: 0 }),
573
- notHelpfulCount: field5.int({ default: 0 }),
574
- moderatedBy: field5.string({ isOptional: true }),
575
- moderatedAt: field5.dateTime({ isOptional: true }),
576
- moderationNote: field5.string({ isOptional: true }),
577
- hasResponse: field5.boolean({ default: false }),
578
- createdAt: field5.createdAt(),
579
- updatedAt: field5.updatedAt(),
580
- product: field5.belongsTo("Product", ["productId"], ["id"]),
581
- store: field5.belongsTo("Store", ["storeId"], ["id"]),
582
- responses: field5.hasMany("ReviewResponse"),
583
- votes: field5.hasMany("ReviewVote")
467
+ id: field4.id({ description: "Unique review ID" }),
468
+ type: field4.enum("ReviewType", { default: "PRODUCT" }),
469
+ productId: field4.string({ isOptional: true }),
470
+ storeId: field4.string({ isOptional: true }),
471
+ orderId: field4.string({ isOptional: true }),
472
+ orderItemId: field4.string({ isOptional: true }),
473
+ authorId: field4.foreignKey({ description: "Reviewer user ID" }),
474
+ rating: field4.int({ description: "Rating 1-5" }),
475
+ title: field4.string({ isOptional: true }),
476
+ content: field4.string({ isOptional: true }),
477
+ isVerifiedPurchase: field4.boolean({ default: false }),
478
+ status: field4.enum("ReviewStatus", { default: "PENDING" }),
479
+ hasMedia: field4.boolean({ default: false }),
480
+ helpfulCount: field4.int({ default: 0 }),
481
+ notHelpfulCount: field4.int({ default: 0 }),
482
+ moderatedBy: field4.string({ isOptional: true }),
483
+ moderatedAt: field4.dateTime({ isOptional: true }),
484
+ moderationNote: field4.string({ isOptional: true }),
485
+ hasResponse: field4.boolean({ default: false }),
486
+ createdAt: field4.createdAt(),
487
+ updatedAt: field4.updatedAt(),
488
+ product: field4.belongsTo("Product", ["productId"], ["id"]),
489
+ store: field4.belongsTo("Store", ["storeId"], ["id"]),
490
+ responses: field4.hasMany("ReviewResponse"),
491
+ votes: field4.hasMany("ReviewVote")
584
492
  },
585
493
  indexes: [
586
- index5.on(["productId", "status", "createdAt"]),
587
- index5.on(["storeId", "status", "createdAt"]),
588
- index5.on(["authorId"]),
589
- index5.on(["orderId"]),
590
- index5.on(["status"]),
591
- index5.on(["rating"]),
592
- index5.on(["isVerifiedPurchase", "status"])
494
+ index4.on(["productId", "status", "createdAt"]),
495
+ index4.on(["storeId", "status", "createdAt"]),
496
+ index4.on(["authorId"]),
497
+ index4.on(["orderId"]),
498
+ index4.on(["status"]),
499
+ index4.on(["rating"]),
500
+ index4.on(["isVerifiedPurchase", "status"])
593
501
  ],
594
502
  enums: [ReviewStatusEnum, ReviewTypeEnum]
595
503
  });
596
- var ReviewResponseEntity = defineEntity5({
504
+ var ReviewResponseEntity = defineEntity4({
597
505
  name: "ReviewResponse",
598
506
  description: "A seller response to a review.",
599
507
  schema: "marketplace",
600
508
  map: "review_response",
601
509
  fields: {
602
- id: field5.id(),
603
- reviewId: field5.foreignKey(),
604
- authorId: field5.foreignKey(),
605
- content: field5.string(),
606
- createdAt: field5.createdAt(),
607
- updatedAt: field5.updatedAt(),
608
- review: field5.belongsTo("Review", ["reviewId"], ["id"], {
510
+ id: field4.id(),
511
+ reviewId: field4.foreignKey(),
512
+ authorId: field4.foreignKey(),
513
+ content: field4.string(),
514
+ createdAt: field4.createdAt(),
515
+ updatedAt: field4.updatedAt(),
516
+ review: field4.belongsTo("Review", ["reviewId"], ["id"], {
609
517
  onDelete: "Cascade"
610
518
  })
611
519
  },
612
- indexes: [index5.on(["reviewId"]), index5.on(["authorId"])]
520
+ indexes: [index4.on(["reviewId"]), index4.on(["authorId"])]
613
521
  });
614
- var ReviewVoteEntity = defineEntity5({
522
+ var ReviewVoteEntity = defineEntity4({
615
523
  name: "ReviewVote",
616
524
  description: "A helpfulness vote on a review.",
617
525
  schema: "marketplace",
618
526
  map: "review_vote",
619
527
  fields: {
620
- id: field5.id(),
621
- reviewId: field5.foreignKey(),
622
- userId: field5.foreignKey(),
623
- isHelpful: field5.boolean(),
624
- createdAt: field5.createdAt(),
625
- review: field5.belongsTo("Review", ["reviewId"], ["id"], {
528
+ id: field4.id(),
529
+ reviewId: field4.foreignKey(),
530
+ userId: field4.foreignKey(),
531
+ isHelpful: field4.boolean(),
532
+ createdAt: field4.createdAt(),
533
+ review: field4.belongsTo("Review", ["reviewId"], ["id"], {
626
534
  onDelete: "Cascade"
627
535
  })
628
536
  },
629
- indexes: [index5.unique(["reviewId", "userId"]), index5.on(["userId"])]
537
+ indexes: [index4.unique(["reviewId", "userId"]), index4.on(["userId"])]
630
538
  });
631
- var ReviewReportEntity = defineEntity5({
539
+ var ReviewReportEntity = defineEntity4({
632
540
  name: "ReviewReport",
633
541
  description: "A report/flag on a review.",
634
542
  schema: "marketplace",
635
543
  map: "review_report",
636
544
  fields: {
637
- id: field5.id(),
638
- reviewId: field5.foreignKey(),
639
- reporterId: field5.foreignKey(),
640
- reason: field5.string({ description: "Report reason category" }),
641
- details: field5.string({ isOptional: true }),
642
- status: field5.string({ default: '"PENDING"' }),
643
- resolvedBy: field5.string({ isOptional: true }),
644
- resolvedAt: field5.dateTime({ isOptional: true }),
645
- resolution: field5.string({ isOptional: true }),
545
+ id: field4.id(),
546
+ reviewId: field4.foreignKey(),
547
+ reporterId: field4.foreignKey(),
548
+ reason: field4.string({ description: "Report reason category" }),
549
+ details: field4.string({ isOptional: true }),
550
+ status: field4.string({ default: '"PENDING"' }),
551
+ resolvedBy: field4.string({ isOptional: true }),
552
+ resolvedAt: field4.dateTime({ isOptional: true }),
553
+ resolution: field4.string({ isOptional: true }),
554
+ createdAt: field4.createdAt(),
555
+ review: field4.belongsTo("Review", ["reviewId"], ["id"])
556
+ },
557
+ indexes: [
558
+ index4.on(["reviewId"]),
559
+ index4.on(["status"]),
560
+ index4.on(["reporterId"])
561
+ ]
562
+ });
563
+
564
+ // src/entities/store.ts
565
+ import {
566
+ defineEntity as defineEntity5,
567
+ defineEntityEnum as defineEntityEnum5,
568
+ field as field5,
569
+ index as index5
570
+ } from "@contractspec/lib.schema";
571
+ var StoreStatusEnum = defineEntityEnum5({
572
+ name: "StoreStatus",
573
+ values: ["PENDING", "ACTIVE", "SUSPENDED", "CLOSED"],
574
+ schema: "marketplace",
575
+ description: "Status of a store."
576
+ });
577
+ var StoreTypeEnum = defineEntityEnum5({
578
+ name: "StoreType",
579
+ values: ["INDIVIDUAL", "BUSINESS", "ENTERPRISE"],
580
+ schema: "marketplace",
581
+ description: "Type of store account."
582
+ });
583
+ var StoreEntity = defineEntity5({
584
+ name: "Store",
585
+ description: "A seller storefront on the marketplace.",
586
+ schema: "marketplace",
587
+ map: "store",
588
+ fields: {
589
+ id: field5.id({ description: "Unique store ID" }),
590
+ name: field5.string({ description: "Store display name" }),
591
+ slug: field5.string({ description: "URL-friendly identifier" }),
592
+ description: field5.string({ isOptional: true }),
593
+ status: field5.enum("StoreStatus", { default: "PENDING" }),
594
+ type: field5.enum("StoreType", { default: "INDIVIDUAL" }),
595
+ ownerId: field5.foreignKey({ description: "Store owner user ID" }),
596
+ organizationId: field5.foreignKey({ isOptional: true }),
597
+ logoFileId: field5.string({
598
+ isOptional: true,
599
+ description: "Logo file reference"
600
+ }),
601
+ bannerFileId: field5.string({
602
+ isOptional: true,
603
+ description: "Banner file reference"
604
+ }),
605
+ email: field5.string({ isOptional: true }),
606
+ phone: field5.string({ isOptional: true }),
607
+ website: field5.string({ isOptional: true }),
608
+ country: field5.string({ isOptional: true }),
609
+ currency: field5.string({ default: '"USD"' }),
610
+ timezone: field5.string({ isOptional: true }),
611
+ commissionRate: field5.decimal({
612
+ default: 0.1,
613
+ description: "Platform commission rate (e.g., 0.1 = 10%)"
614
+ }),
615
+ isVerified: field5.boolean({ default: false }),
616
+ verifiedAt: field5.dateTime({ isOptional: true }),
617
+ settings: field5.json({ isOptional: true }),
618
+ metadata: field5.json({ isOptional: true }),
619
+ totalProducts: field5.int({ default: 0 }),
620
+ totalOrders: field5.int({ default: 0 }),
621
+ totalRevenue: field5.decimal({ default: 0 }),
622
+ averageRating: field5.decimal({ default: 0 }),
646
623
  createdAt: field5.createdAt(),
647
- review: field5.belongsTo("Review", ["reviewId"], ["id"])
624
+ updatedAt: field5.updatedAt(),
625
+ products: field5.hasMany("Product"),
626
+ orders: field5.hasMany("Order"),
627
+ payouts: field5.hasMany("Payout")
648
628
  },
649
629
  indexes: [
650
- index5.on(["reviewId"]),
630
+ index5.unique(["slug"]),
631
+ index5.on(["ownerId"]),
651
632
  index5.on(["status"]),
652
- index5.on(["reporterId"])
653
- ]
633
+ index5.on(["country", "status"]),
634
+ index5.on(["averageRating"])
635
+ ],
636
+ enums: [StoreStatusEnum, StoreTypeEnum]
637
+ });
638
+ var StoreCategoryEntity = defineEntity5({
639
+ name: "StoreCategory",
640
+ description: "Category assignment for stores.",
641
+ schema: "marketplace",
642
+ map: "store_category",
643
+ fields: {
644
+ id: field5.id(),
645
+ storeId: field5.foreignKey(),
646
+ categoryId: field5.foreignKey(),
647
+ isPrimary: field5.boolean({ default: false }),
648
+ createdAt: field5.createdAt(),
649
+ store: field5.belongsTo("Store", ["storeId"], ["id"], {
650
+ onDelete: "Cascade"
651
+ })
652
+ },
653
+ indexes: [index5.unique(["storeId", "categoryId"]), index5.on(["categoryId"])]
654
654
  });
655
655
  // src/entities/index.ts
656
656
  var marketplaceEntities = [