@stacksjs/orm 0.72.16 → 0.72.18

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 (102) hide show
  1. package/dist/index.d.ts +97 -97
  2. package/dist/index.js +7 -7
  3. package/dist/models/Activity.ts +95 -0
  4. package/dist/models/AnalyticsEvent.ts +70 -0
  5. package/dist/models/Automation.ts +23 -0
  6. package/dist/models/AutomationRun.ts +26 -0
  7. package/dist/models/Board.ts +104 -0
  8. package/dist/models/BoardColumn.ts +88 -0
  9. package/dist/models/Campaign.ts +321 -0
  10. package/dist/models/CampaignSend.ts +191 -0
  11. package/dist/models/CampaignVariant.ts +25 -0
  12. package/dist/models/Card.ts +118 -0
  13. package/dist/models/CardComment.ts +68 -0
  14. package/dist/models/Comment.ts +109 -0
  15. package/dist/models/CommunicationSuppression.ts +22 -0
  16. package/dist/models/ConsentEvent.ts +30 -0
  17. package/dist/models/Content/Author.ts +109 -0
  18. package/dist/models/Content/Menu.ts +56 -0
  19. package/dist/models/Content/MenuItem.ts +91 -0
  20. package/dist/models/Content/Page.ts +205 -0
  21. package/dist/models/Content/PageRevision.ts +86 -0
  22. package/dist/models/Content/Post.ts +230 -0
  23. package/dist/models/Content/Redirect.ts +80 -0
  24. package/dist/models/Deployment.ts +117 -0
  25. package/dist/models/EmailIdempotency.ts +64 -0
  26. package/dist/models/EmailList.ts +134 -0
  27. package/dist/models/EmailListSubscriber.ts +91 -0
  28. package/dist/models/EmailSuppression.ts +52 -0
  29. package/dist/models/EmailWebhookEvent.ts +51 -0
  30. package/dist/models/Error.ts +77 -0
  31. package/dist/models/FailedJob.ts +84 -0
  32. package/dist/models/Forms/Form.ts +91 -0
  33. package/dist/models/Forms/FormField.ts +127 -0
  34. package/dist/models/Forms/FormSubmission.ts +114 -0
  35. package/dist/models/Job.ts +69 -0
  36. package/dist/models/Label.ts +67 -0
  37. package/dist/models/Log.ts +134 -0
  38. package/dist/models/MagicLinkToken.ts +97 -0
  39. package/dist/models/MailPreference.ts +213 -0
  40. package/dist/models/Notification.ts +68 -0
  41. package/dist/models/NotificationDelivery.ts +102 -0
  42. package/dist/models/PaymentMethod.ts +98 -0
  43. package/dist/models/PaymentProduct.ts +91 -0
  44. package/dist/models/PaymentTransaction.ts +78 -0
  45. package/dist/models/QueryLog.ts +182 -0
  46. package/dist/models/README.md +31 -0
  47. package/dist/models/Release.ts +90 -0
  48. package/dist/models/Request.ts +133 -0
  49. package/dist/models/SenderDomain.ts +22 -0
  50. package/dist/models/Site.ts +112 -0
  51. package/dist/models/SiteDomain.ts +74 -0
  52. package/dist/models/SmsOptOut.ts +65 -0
  53. package/dist/models/SocialAccount.ts +70 -0
  54. package/dist/models/SocialPost.ts +144 -0
  55. package/dist/models/Subscriber.ts +89 -0
  56. package/dist/models/SubscriberEmail.ts +55 -0
  57. package/dist/models/Subscription.ts +153 -0
  58. package/dist/models/Tag.ts +105 -0
  59. package/dist/models/Team.ts +75 -0
  60. package/dist/models/TeamInvitation.ts +159 -0
  61. package/dist/models/TeamMember.ts +88 -0
  62. package/dist/models/UsageEvent.ts +24 -0
  63. package/dist/models/User.ts +142 -0
  64. package/dist/models/commerce/Auction.ts +173 -0
  65. package/dist/models/commerce/AuctionItem.ts +204 -0
  66. package/dist/models/commerce/Bid.ts +129 -0
  67. package/dist/models/commerce/Cart.ts +140 -0
  68. package/dist/models/commerce/CartItem.ts +138 -0
  69. package/dist/models/commerce/Category.ts +125 -0
  70. package/dist/models/commerce/Coupon.ts +186 -0
  71. package/dist/models/commerce/Customer.ts +132 -0
  72. package/dist/models/commerce/DeliveryRoute.ts +127 -0
  73. package/dist/models/commerce/DeliveryStop.ts +166 -0
  74. package/dist/models/commerce/DigitalDelivery.ts +106 -0
  75. package/dist/models/commerce/Driver.ts +168 -0
  76. package/dist/models/commerce/DriverPing.ts +103 -0
  77. package/dist/models/commerce/GiftCard.ts +195 -0
  78. package/dist/models/commerce/LicenseKey.ts +89 -0
  79. package/dist/models/commerce/LoyaltyPoint.ts +108 -0
  80. package/dist/models/commerce/LoyaltyReward.ts +129 -0
  81. package/dist/models/commerce/Manufacturer.ts +90 -0
  82. package/dist/models/commerce/Order.ts +198 -0
  83. package/dist/models/commerce/OrderIdempotency.ts +34 -0
  84. package/dist/models/commerce/OrderItem.ts +51 -0
  85. package/dist/models/commerce/Payment.ts +182 -0
  86. package/dist/models/commerce/Pledge.ts +112 -0
  87. package/dist/models/commerce/PrintDevice.ts +120 -0
  88. package/dist/models/commerce/Product.ts +153 -0
  89. package/dist/models/commerce/ProductUnit.ts +113 -0
  90. package/dist/models/commerce/ProductVariant.ts +111 -0
  91. package/dist/models/commerce/Receipt.ts +144 -0
  92. package/dist/models/commerce/Review.ts +171 -0
  93. package/dist/models/commerce/ShippingMethod.ts +102 -0
  94. package/dist/models/commerce/ShippingRate.ts +79 -0
  95. package/dist/models/commerce/ShippingZone.ts +116 -0
  96. package/dist/models/commerce/TaxRate.ts +167 -0
  97. package/dist/models/commerce/Transaction.ts +127 -0
  98. package/dist/models/commerce/WaitlistProduct.ts +151 -0
  99. package/dist/models/commerce/WaitlistRestaurant.ts +189 -0
  100. package/dist/models/realtime/Websocket.ts +78 -0
  101. package/dist/password-policy.ts +46 -0
  102. package/package.json +4 -4
@@ -0,0 +1,129 @@
1
+ import { defineModel } from '@stacksjs/orm'
2
+ import { schema } from '@stacksjs/validation'
3
+
4
+ /**
5
+ * One bid on one lot.
6
+ *
7
+ * Bidders are identified by name and email rather than by a user account: a
8
+ * benefit auction is bid on by grandparents on borrowed phones, and requiring
9
+ * a signup between them and their paddle costs the school real money.
10
+ *
11
+ * `maxAmount` is the private proxy ceiling. It must never be selected into a
12
+ * template or an API response - the whole mechanism depends on nobody being
13
+ * able to see how far the other side is willing to go. `hidden` keeps it out of
14
+ * the generated CRUD responses; the queries in `@stacksjs/auctions` that feed
15
+ * the public catalogue select columns explicitly for the same reason.
16
+ */
17
+ export default defineModel({
18
+ name: 'Bid',
19
+ table: 'bids',
20
+ primaryKey: 'id',
21
+ autoIncrement: true,
22
+
23
+ traits: {
24
+ useUuid: true,
25
+ useTimestamps: true,
26
+
27
+ useSearch: {
28
+ displayable: ['id', 'bidderName', 'amount', 'status', 'placedAt'],
29
+ searchable: ['bidderName', 'bidderEmail'],
30
+ sortable: ['placedAt', 'amount'],
31
+ filterable: ['status'],
32
+ },
33
+
34
+ // Read is authenticated: the bid history of a lot is staff information
35
+ // while the auction is live. Writes never come through generated CRUD -
36
+ // a bid has to go through the engine, so the app owns that route.
37
+ useApi: {
38
+ uri: 'bids',
39
+ routes: ['index', 'show'],
40
+ middleware: ['auth'],
41
+ },
42
+
43
+ observe: true,
44
+ },
45
+
46
+ belongsTo: ['Auction', 'AuctionItem'],
47
+
48
+ indexes: [
49
+ { name: 'bids_auction_item_id_index', columns: ['auction_item_id'] },
50
+ { name: 'bids_auction_id_index', columns: ['auction_id'] },
51
+ { name: 'bids_bidder_email_index', columns: ['bidder_email'] },
52
+ { name: 'bids_status_index', columns: ['status'] },
53
+ ],
54
+
55
+ attributes: {
56
+ bidderName: {
57
+ order: 1,
58
+ fillable: true,
59
+ validation: {
60
+ rule: schema.string().required().max(160),
61
+ message: {
62
+ required: 'Your name is required',
63
+ },
64
+ },
65
+ factory: faker => faker.person.fullName(),
66
+ },
67
+
68
+ bidderEmail: {
69
+ order: 2,
70
+ fillable: true,
71
+ validation: {
72
+ rule: schema.string().email().required(),
73
+ message: {
74
+ required: 'Your email is required',
75
+ email: 'That does not look like an email address',
76
+ },
77
+ },
78
+ factory: faker => faker.internet.email().toLowerCase(),
79
+ },
80
+
81
+ /** The public number: what this bidder is currently committed to, in cents. */
82
+ amount: {
83
+ order: 3,
84
+ fillable: true,
85
+ validation: {
86
+ rule: schema.number().required().min(1),
87
+ message: {
88
+ required: 'A bid amount is required',
89
+ },
90
+ },
91
+ factory: faker => faker.number.int({ min: 5000, max: 200000 }),
92
+ },
93
+
94
+ /** The private ceiling, in cents. Null means "this amount only". */
95
+ maxAmount: {
96
+ order: 4,
97
+ fillable: true,
98
+ hidden: true,
99
+ validation: {
100
+ rule: schema.number().min(1),
101
+ },
102
+ factory: () => null,
103
+ },
104
+
105
+ status: {
106
+ default: 'leading',
107
+ order: 5,
108
+ fillable: true,
109
+ validation: {
110
+ rule: schema.enum(['leading', 'outbid', 'won', 'lost', 'invalid']).required(),
111
+ },
112
+ factory: () => 'outbid',
113
+ },
114
+
115
+ placedAt: {
116
+ order: 6,
117
+ fillable: true,
118
+ validation: {
119
+ rule: schema.date().required(),
120
+ },
121
+ factory: faker => faker.date.recent().toISOString(),
122
+ },
123
+ },
124
+
125
+ dashboard: {
126
+ icon: 'i-hugeicons-hand-pointing-right-01',
127
+ label: 'Bids',
128
+ },
129
+ } as const)
@@ -0,0 +1,140 @@
1
+ import { defineModel } from '@stacksjs/orm'
2
+ import { schema } from '@stacksjs/validation'
3
+
4
+ export default defineModel({
5
+ name: 'Cart',
6
+ table: 'carts',
7
+ primaryKey: 'id',
8
+ autoIncrement: true,
9
+
10
+ traits: {
11
+ useUuid: true,
12
+ useTimestamps: true,
13
+ useSearch: {
14
+ displayable: ['id', 'customerId', 'status', 'totalItems', 'subtotal', 'total', 'expiresAt'],
15
+ searchable: ['id', 'customerId', 'status'],
16
+ sortable: ['createdAt', 'updatedAt', 'expiresAt', 'total'],
17
+ filterable: ['status', 'customerId'],
18
+ },
19
+
20
+ useSeeder: {
21
+ count: 10,
22
+ },
23
+
24
+ useApi: {
25
+ uri: 'carts',
26
+ middleware: ['auth'],
27
+ },
28
+
29
+ observe: true,
30
+ },
31
+
32
+ hasMany: ['CartItem'],
33
+ belongsTo: ['Customer', 'Coupon'],
34
+
35
+ attributes: {
36
+ status: {
37
+ default: 'active',
38
+ order: 1,
39
+ fillable: true,
40
+ validation: {
41
+ rule: schema.enum(['active', 'abandoned', 'converted', 'expired']),
42
+ },
43
+ factory: faker => faker.helpers.arrayElement(['active', 'abandoned', 'converted', 'expired']),
44
+ },
45
+
46
+ totalItems: {
47
+ default: 0,
48
+ order: 2,
49
+ fillable: true,
50
+ validation: {
51
+ rule: schema.number().min(0),
52
+ },
53
+ factory: faker => faker.number.int({ min: 0, max: 20 }),
54
+ },
55
+
56
+ subtotal: {
57
+ default: 0,
58
+ order: 3,
59
+ fillable: true,
60
+ validation: {
61
+ rule: schema.number().min(0),
62
+ },
63
+ factory: faker => faker.number.int({ min: 0, max: 1000 }),
64
+ },
65
+
66
+ taxAmount: {
67
+ default: 0,
68
+ order: 4,
69
+ fillable: true,
70
+ validation: {
71
+ rule: schema.number().min(0),
72
+ },
73
+ factory: faker => faker.number.int({ min: 0, max: 200 }),
74
+ },
75
+
76
+ discountAmount: {
77
+ default: 0,
78
+ order: 5,
79
+ fillable: true,
80
+ validation: {
81
+ rule: schema.number().min(0),
82
+ },
83
+ factory: faker => faker.number.int({ min: 0, max: 100 }),
84
+ },
85
+
86
+ total: {
87
+ default: 0,
88
+ order: 6,
89
+ fillable: true,
90
+ validation: {
91
+ rule: schema.number().min(0),
92
+ },
93
+ factory: faker => faker.number.int({ min: 0, max: 1200 }),
94
+ },
95
+
96
+ expiresAt: {
97
+ order: 7,
98
+ fillable: true,
99
+ validation: {
100
+ rule: schema.timestamp().required(),
101
+ },
102
+ factory: (faker) => {
103
+ const date = faker.date.past()
104
+ return date.toISOString().slice(0, 19).replace('T', ' ')
105
+ },
106
+ },
107
+
108
+ currency: {
109
+ default: 'USD',
110
+ order: 8,
111
+ fillable: true,
112
+ validation: {
113
+ rule: schema.string().max(3),
114
+ },
115
+ factory: faker => faker.helpers.arrayElement(['USD', 'EUR', 'GBP', 'JPY', 'AUD']),
116
+ },
117
+
118
+ notes: {
119
+ order: 9,
120
+ fillable: true,
121
+ validation: {
122
+ rule: schema.string().max(1000),
123
+ },
124
+ factory: faker => faker.lorem.sentence(),
125
+ },
126
+
127
+ appliedCouponId: {
128
+ order: 10,
129
+ fillable: true,
130
+ validation: {
131
+ rule: schema.string().required(),
132
+ },
133
+ factory: () => 'test-coupon-id',
134
+ },
135
+ },
136
+
137
+ dashboard: {
138
+ highlight: true,
139
+ },
140
+ } as const)
@@ -0,0 +1,138 @@
1
+ import { defineModel } from '@stacksjs/orm'
2
+ import { schema } from '@stacksjs/validation'
3
+
4
+ export default defineModel({
5
+ name: 'CartItem',
6
+ table: 'cart_items',
7
+ primaryKey: 'id',
8
+ autoIncrement: true,
9
+
10
+ traits: {
11
+ useUuid: true,
12
+ useTimestamps: true,
13
+ useSearch: {
14
+ displayable: ['id', 'cartId', 'productId', 'quantity', 'unitPrice', 'totalPrice'],
15
+ searchable: ['id', 'cartId', 'productId'],
16
+ sortable: ['createdAt', 'updatedAt', 'quantity', 'unitPrice'],
17
+ filterable: ['cartId', 'productId'],
18
+ },
19
+
20
+ useSeeder: {
21
+ count: 50,
22
+ },
23
+
24
+ useApi: {
25
+ uri: 'cart-items',
26
+ middleware: ['auth'],
27
+ },
28
+
29
+ observe: true,
30
+ },
31
+
32
+ belongsTo: ['Cart'],
33
+
34
+ attributes: {
35
+ quantity: {
36
+ order: 1,
37
+ fillable: true,
38
+ validation: {
39
+ rule: schema.number().required().min(1),
40
+ },
41
+ factory: faker => faker.number.int({ min: 1, max: 10 }),
42
+ },
43
+
44
+ unitPrice: {
45
+ order: 2,
46
+ fillable: true,
47
+ validation: {
48
+ rule: schema.number().required().min(0),
49
+ },
50
+ factory: faker => faker.number.int({ min: 1, max: 1000 }),
51
+ },
52
+
53
+ totalPrice: {
54
+ order: 3,
55
+ fillable: true,
56
+ validation: {
57
+ rule: schema.number().required().min(0),
58
+ },
59
+ factory: faker => faker.number.int({ min: 1, max: 1000 }),
60
+ },
61
+
62
+ taxRate: {
63
+ order: 4,
64
+ fillable: true,
65
+ validation: {
66
+ rule: schema.number().min(0).max(100),
67
+ },
68
+ factory: faker => faker.number.int({ min: 0, max: 20 }),
69
+ },
70
+
71
+ taxAmount: {
72
+ order: 5,
73
+ fillable: true,
74
+ validation: {
75
+ rule: schema.number().min(0),
76
+ },
77
+ factory: faker => faker.number.int({ min: 0, max: 50 }),
78
+ },
79
+
80
+ discountPercentage: {
81
+ order: 6,
82
+ fillable: true,
83
+ validation: {
84
+ rule: schema.number().min(0).max(100),
85
+ },
86
+ factory: faker => faker.number.int({ min: 0, max: 50 }),
87
+ },
88
+
89
+ discountAmount: {
90
+ order: 7,
91
+ fillable: true,
92
+ validation: {
93
+ rule: schema.number().min(0),
94
+ },
95
+ factory: faker => faker.number.int({ min: 0, max: 25 }),
96
+ },
97
+
98
+ productName: {
99
+ order: 8,
100
+ fillable: true,
101
+ validation: {
102
+ rule: schema.string().required().max(255),
103
+ },
104
+ factory: faker => faker.commerce.productName(),
105
+ },
106
+
107
+ productSku: {
108
+ order: 9,
109
+ fillable: true,
110
+ validation: {
111
+ rule: schema.string().max(100),
112
+ },
113
+ factory: faker => faker.string.alphanumeric(10),
114
+ },
115
+
116
+ productImage: {
117
+ order: 10,
118
+ fillable: true,
119
+ validation: {
120
+ rule: schema.string().max(255),
121
+ },
122
+ factory: faker => faker.image.url(),
123
+ },
124
+
125
+ notes: {
126
+ order: 11,
127
+ fillable: true,
128
+ validation: {
129
+ rule: schema.string().max(500),
130
+ },
131
+ factory: faker => faker.lorem.sentence(),
132
+ },
133
+ },
134
+
135
+ dashboard: {
136
+ highlight: true,
137
+ },
138
+ } as const)
@@ -0,0 +1,125 @@
1
+ import { defineModel } from '@stacksjs/orm'
2
+ import { slug } from '@stacksjs/strings'
3
+ import { schema } from '@stacksjs/validation'
4
+
5
+ export default defineModel({
6
+ name: 'Category',
7
+ table: 'categories',
8
+ primaryKey: 'id',
9
+ autoIncrement: true,
10
+
11
+ traits: {
12
+ useUuid: true,
13
+ useTimestamps: true,
14
+ useSearch: {
15
+ displayable: ['id', 'name', 'description', 'isActive', 'parentCategoryId', 'displayOrder'],
16
+ searchable: ['name', 'description'],
17
+ sortable: ['displayOrder', 'createdAt', 'updatedAt'],
18
+ filterable: ['parentCategoryId', 'isActive'],
19
+ },
20
+
21
+ useSeeder: {
22
+ count: 10,
23
+ },
24
+
25
+ useApi: {
26
+ // Public catalog: anyone may browse, only authenticated callers may
27
+ // write. Declared explicitly because the trait now defaults BOTH sides to
28
+ // `auth` — an undeclared read route is how a customer list leaks
29
+ // (stacksjs/stacks#2224). Behaviour here is unchanged.
30
+ middleware: { read: [], write: ['auth'] },
31
+ uri: 'product-categories',
32
+ },
33
+
34
+ observe: true,
35
+ },
36
+
37
+ hasMany: ['Product'],
38
+ belongsToMany: {
39
+ posts: {
40
+ model: 'Post',
41
+ table: 'categorizable_models',
42
+ foreignKey: 'category_id',
43
+ relatedKey: 'categorizable_id',
44
+ pivot: {
45
+ columns: {
46
+ categorizable_type: { default: 'posts' },
47
+ },
48
+ timestamps: true,
49
+ uniques: [['category_id', 'categorizable_id', 'categorizable_type']],
50
+ },
51
+ },
52
+ },
53
+
54
+ attributes: {
55
+ name: {
56
+ order: 1,
57
+ fillable: true,
58
+ validation: {
59
+ rule: schema.string().required().max(50),
60
+ message: {
61
+ max: 'Name must have a maximum of 50 characters',
62
+ },
63
+ },
64
+ factory: faker => faker.commerce.department(),
65
+ },
66
+
67
+ description: {
68
+ order: 2,
69
+ fillable: true,
70
+ validation: {
71
+ rule: schema.string(),
72
+ },
73
+ factory: faker => faker.commerce.productDescription(),
74
+ },
75
+
76
+ slug: {
77
+ order: 3,
78
+ fillable: true,
79
+ validation: {
80
+ rule: schema.string().required(),
81
+ },
82
+ factory: faker => slug(faker.commerce.department()),
83
+ },
84
+
85
+ imageUrl: {
86
+ order: 3,
87
+ fillable: true,
88
+ validation: {
89
+ rule: schema.string(),
90
+ },
91
+ factory: faker => faker.image.url(),
92
+ },
93
+
94
+ isActive: {
95
+ order: 4,
96
+ fillable: true,
97
+ validation: {
98
+ rule: schema.boolean(),
99
+ },
100
+ factory: () => true,
101
+ },
102
+
103
+ parentCategoryId: {
104
+ order: 5,
105
+ fillable: true,
106
+ validation: {
107
+ rule: schema.string(),
108
+ },
109
+ factory: () => null, // Most categories won't have a parent
110
+ },
111
+
112
+ displayOrder: {
113
+ order: 6,
114
+ fillable: true,
115
+ validation: {
116
+ rule: schema.number().required(),
117
+ },
118
+ factory: faker => faker.number.int({ min: 1, max: 100 }),
119
+ },
120
+ },
121
+
122
+ dashboard: {
123
+ highlight: true,
124
+ },
125
+ } as const)
@@ -0,0 +1,186 @@
1
+ import { defineModel } from '@stacksjs/orm'
2
+ import { schema } from '@stacksjs/validation'
3
+
4
+ export default defineModel({
5
+ name: 'Coupon',
6
+ table: 'coupons',
7
+ primaryKey: 'id',
8
+ autoIncrement: true,
9
+
10
+ traits: {
11
+ useUuid: true,
12
+ useTimestamps: true,
13
+ useSearch: {
14
+ displayable: ['id', 'code', 'discountType', 'discountValue', 'startDate', 'endDate'],
15
+ searchable: ['code', 'description', 'discountType'],
16
+ sortable: ['createdAt', 'startDate', 'endDate', 'discountValue', 'usageCount'],
17
+ filterable: ['discountType'],
18
+ },
19
+
20
+ useSeeder: {
21
+ count: 15,
22
+ },
23
+
24
+ useApi: {
25
+ uri: 'coupons',
26
+ middleware: ['auth'],
27
+ },
28
+
29
+ observe: true,
30
+ },
31
+
32
+ belongsTo: ['Product'],
33
+ hasMany: ['Order'],
34
+
35
+ attributes: {
36
+ code: {
37
+ unique: true,
38
+ order: 1,
39
+ fillable: true,
40
+ validation: {
41
+ rule: schema.string().required().max(50),
42
+ message: {
43
+ max: 'Code must have a maximum of 50 characters',
44
+ },
45
+ },
46
+ factory: faker => faker.string.alphanumeric(8).toUpperCase(),
47
+ },
48
+
49
+ description: {
50
+ order: 2,
51
+ fillable: true,
52
+ validation: {
53
+ rule: schema.string(),
54
+ },
55
+ factory: faker => faker.commerce.productDescription(),
56
+ },
57
+
58
+ status: {
59
+ default: 'Active',
60
+ order: 3,
61
+ fillable: true,
62
+ validation: {
63
+ rule: schema.enum(['Active', 'Scheduled', 'Expired']).required(),
64
+ message: {
65
+ required: 'Status is required',
66
+ },
67
+ },
68
+ factory: faker => faker.helpers.arrayElement(['Active', 'Scheduled', 'Expired']),
69
+ },
70
+
71
+ isActive: {
72
+ order: 4,
73
+ fillable: true,
74
+ default: true,
75
+ validation: {
76
+ rule: schema.boolean().required(),
77
+ },
78
+ factory: () => true,
79
+ },
80
+
81
+ discountType: {
82
+ order: 5,
83
+ fillable: true,
84
+ validation: {
85
+ rule: schema.enum(['fixed_amount', 'percentage']).required(),
86
+ message: {
87
+ required: 'Discount type is required',
88
+ },
89
+ },
90
+ factory: faker => faker.helpers.arrayElement(['fixed_amount', 'percentage']),
91
+ },
92
+
93
+ discountValue: {
94
+ order: 6,
95
+ fillable: true,
96
+ validation: {
97
+ rule: schema.number().required().min(0.01),
98
+ message: {
99
+ required: 'Discount value is required',
100
+ min: 'Discount value must be greater than 0.01',
101
+ },
102
+ },
103
+ factory: faker => faker.number.int({ min: 5, max: 50 }),
104
+ },
105
+
106
+ minOrderAmount: {
107
+ order: 7,
108
+ fillable: true,
109
+ validation: {
110
+ rule: schema.number().min(0),
111
+ message: {
112
+ min: 'Min order amount must be greater than 0',
113
+ },
114
+ },
115
+ factory: faker => faker.number.int({ min: 0, max: 50 }),
116
+ },
117
+
118
+ maxDiscountAmount: {
119
+ order: 8,
120
+ fillable: true,
121
+ validation: {
122
+ rule: schema.number().min(0),
123
+ message: {
124
+ min: 'Max discount amount must be greater than 0',
125
+ },
126
+ },
127
+ factory: faker => faker.number.int({ min: 5, max: 100 }),
128
+ },
129
+
130
+ freeProductId: {
131
+ order: 9,
132
+ fillable: true,
133
+ validation: {
134
+ rule: schema.string(),
135
+ },
136
+ factory: faker => faker.string.uuid(),
137
+ },
138
+
139
+ usageLimit: {
140
+ order: 10,
141
+ fillable: true,
142
+ validation: {
143
+ rule: schema.number().min(1),
144
+ message: {
145
+ min: 'Usage limit must be greater than 1',
146
+ },
147
+ },
148
+ factory: faker => faker.number.int({ min: 1, max: 100 }),
149
+ },
150
+
151
+ usageCount: {
152
+ default: 0,
153
+ order: 11,
154
+ fillable: true,
155
+ validation: {
156
+ rule: schema.number().min(0),
157
+ message: {
158
+ min: 'Usage count must be greater than 0',
159
+ },
160
+ },
161
+ factory: faker => faker.number.int({ min: 0, max: 50 }),
162
+ },
163
+
164
+ startDate: {
165
+ order: 12,
166
+ fillable: true,
167
+ validation: {
168
+ rule: schema.date(),
169
+ },
170
+ factory: faker => faker.date.recent().toISOString().slice(0, 10),
171
+ },
172
+
173
+ endDate: {
174
+ order: 13,
175
+ fillable: true,
176
+ validation: {
177
+ rule: schema.date(),
178
+ },
179
+ factory: faker => faker.date.future().toISOString().slice(0, 10),
180
+ },
181
+ },
182
+
183
+ dashboard: {
184
+ highlight: true,
185
+ },
186
+ } as const)