@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,198 @@
1
+ import { defineModel } from '@stacksjs/orm'
2
+ import { schema } from '@stacksjs/validation'
3
+
4
+ export default defineModel({
5
+ name: 'Order',
6
+ table: 'orders',
7
+ primaryKey: 'id',
8
+ autoIncrement: true,
9
+
10
+ traits: {
11
+ useUuid: true,
12
+ useTimestamps: true,
13
+ useSearch: {
14
+ displayable: ['id', 'customerId', 'status', 'totalAmount', 'orderType', 'createdAt'],
15
+ searchable: ['id', 'customerId', 'status', 'orderType'],
16
+ sortable: ['createdAt', 'updatedAt', 'totalAmount', 'estimatedDeliveryTime'],
17
+ filterable: ['status', 'orderType', 'customerId'],
18
+ },
19
+
20
+ useSeeder: {
21
+ count: 20,
22
+ },
23
+
24
+ useApi: {
25
+ uri: 'orders',
26
+ middleware: ['auth'],
27
+ },
28
+
29
+ observe: true,
30
+ },
31
+
32
+ hasMany: ['OrderItem', 'Payment', 'LicenseKey', 'DeliveryStop'],
33
+ belongsTo: ['Customer', 'Coupon'],
34
+
35
+ attributes: {
36
+ status: {
37
+ order: 2,
38
+ fillable: true,
39
+ validation: {
40
+ rule: schema.string().required(),
41
+ },
42
+ /*
43
+ * The canonical vocabulary is `OrderStatus` in
44
+ * `commerce/src/orders/events.ts`, which is what `canTransition` and
45
+ * `emitForStatus` are keyed on. The factory used to generate
46
+ * PREPARING / READY / CANCELED, none of which are in that union, so
47
+ * seeded orders could not legally transition anywhere.
48
+ *
49
+ * The column stays a free string rather than an enum: existing
50
+ * databases hold the old spellings, and adding a CHECK constraint here
51
+ * would fail their next migration rather than fix their data.
52
+ */
53
+ factory: faker => faker.helpers.arrayElement(['PENDING', 'PROCESSING', 'SHIPPED', 'OUT_FOR_DELIVERY', 'DELIVERED']),
54
+ },
55
+
56
+ totalAmount: {
57
+ order: 3,
58
+ fillable: true,
59
+ validation: {
60
+ rule: schema.number().required().min(0),
61
+ },
62
+ factory: faker => faker.number.int({ min: 100, max: 2000 }),
63
+ },
64
+
65
+ currency: {
66
+ order: 4,
67
+ fillable: true,
68
+ default: 'USD',
69
+ validation: {
70
+ rule: schema.string().required().max(3),
71
+ },
72
+ factory: faker => faker.helpers.arrayElement(['USD', 'EUR', 'GBP', 'CAD', 'AUD']),
73
+ },
74
+
75
+ taxAmount: {
76
+ default: 0,
77
+ order: 5,
78
+ fillable: true,
79
+ validation: {
80
+ rule: schema.number().min(0),
81
+ },
82
+ factory: faker => faker.number.int({ min: 10, max: 200 }),
83
+ },
84
+
85
+ discountAmount: {
86
+ default: 0,
87
+ order: 6,
88
+ fillable: true,
89
+ validation: {
90
+ rule: schema.number().min(0),
91
+ },
92
+ factory: faker => faker.number.int({ min: 0, max: 150 }),
93
+ },
94
+
95
+ deliveryFee: {
96
+ default: 0,
97
+ order: 7,
98
+ fillable: true,
99
+ validation: {
100
+ rule: schema.number().min(0),
101
+ },
102
+ factory: faker => faker.number.int({ min: 0, max: 100 }),
103
+ },
104
+
105
+ tipAmount: {
106
+ default: 0,
107
+ order: 8,
108
+ fillable: true,
109
+ validation: {
110
+ rule: schema.number().min(0),
111
+ },
112
+ factory: faker => faker.number.int({ min: 0, max: 200 }),
113
+ },
114
+
115
+ orderType: {
116
+ order: 9,
117
+ fillable: true,
118
+ validation: {
119
+ rule: schema.string().required(),
120
+ },
121
+ factory: faker => faker.helpers.arrayElement(['DINE_IN', 'TAKEOUT', 'DELIVERY']),
122
+ },
123
+
124
+ deliveryAddress: {
125
+ order: 10,
126
+ fillable: true,
127
+ validation: {
128
+ rule: schema.string(),
129
+ },
130
+ factory: faker => faker.location.streetAddress(),
131
+ },
132
+
133
+ specialInstructions: {
134
+ order: 11,
135
+ fillable: true,
136
+ validation: {
137
+ rule: schema.string(),
138
+ },
139
+ factory: faker => faker.helpers.maybe(() => faker.lorem.sentence(), { probability: 0.3 }),
140
+ },
141
+
142
+ estimatedDeliveryTime: {
143
+ order: 12,
144
+ fillable: true,
145
+ validation: {
146
+ rule: schema.string(),
147
+ },
148
+ factory: (faker) => {
149
+ const now = new Date()
150
+ const futureDate = new Date(now.getTime() + faker.number.int({ min: 15, max: 120 }) * 60000)
151
+ return futureDate.toISOString()
152
+ },
153
+ },
154
+
155
+ /**
156
+ * Unguessable handle for the customer-facing tracking page.
157
+ *
158
+ * A tracking URL is opened from an SMS, on a phone, by someone who is not
159
+ * signed in, so it authorises on possession of this token. Sequential
160
+ * order ids would let anyone walk the table.
161
+ */
162
+ trackingToken: {
163
+ order: 13,
164
+ unique: true,
165
+ fillable: true,
166
+ validation: { rule: schema.string().max(64) },
167
+ factory: faker => faker.string.alphanumeric({ length: 32 }),
168
+ },
169
+
170
+ /** Geocoded delivery destination, so the map has somewhere to point. */
171
+ deliveryLatitude: {
172
+ order: 14,
173
+ fillable: true,
174
+ validation: { rule: schema.number().min(-90).max(90) },
175
+ factory: faker => faker.location.latitude(),
176
+ },
177
+
178
+ deliveryLongitude: {
179
+ order: 15,
180
+ fillable: true,
181
+ validation: { rule: schema.number().min(-180).max(180) },
182
+ factory: faker => faker.location.longitude(),
183
+ },
184
+
185
+ appliedCouponId: {
186
+ order: 16,
187
+ fillable: true,
188
+ validation: {
189
+ rule: schema.string(),
190
+ },
191
+ factory: faker => faker.helpers.maybe(() => faker.string.uuid(), { probability: 0.2 }),
192
+ },
193
+ },
194
+
195
+ dashboard: {
196
+ highlight: true,
197
+ },
198
+ } as const)
@@ -0,0 +1,34 @@
1
+ import { defineModel } from '@stacksjs/orm'
2
+ import { schema } from '@stacksjs/validation'
3
+
4
+ export default defineModel({
5
+ name: 'OrderIdempotency',
6
+ table: 'order_idempotency',
7
+ primaryKey: 'id',
8
+ autoIncrement: true,
9
+
10
+ traits: {
11
+ useTimestamps: true,
12
+ },
13
+
14
+ dashboard: { enabled: false },
15
+
16
+ belongsTo: ['Order'],
17
+
18
+ attributes: {
19
+ idempotencyKey: {
20
+ fillable: true,
21
+ unique: true,
22
+ validation: {
23
+ rule: schema.string().required().max(255),
24
+ },
25
+ },
26
+ orderId: {
27
+ required: true,
28
+ fillable: true,
29
+ validation: {
30
+ rule: schema.number().required(),
31
+ },
32
+ },
33
+ },
34
+ } as const)
@@ -0,0 +1,51 @@
1
+ import { defineModel } from '@stacksjs/orm'
2
+ import { schema } from '@stacksjs/validation'
3
+
4
+ export default defineModel({
5
+ name: 'OrderItem',
6
+ table: 'order_items',
7
+ primaryKey: 'id',
8
+ autoIncrement: true,
9
+
10
+ traits: {
11
+ useTimestamps: true,
12
+ },
13
+
14
+ belongsTo: ['Order', 'Product'],
15
+
16
+ attributes: {
17
+ quantity: {
18
+ default: 1,
19
+ order: 3,
20
+ fillable: true,
21
+ validation: {
22
+ rule: schema.number().required().min(1),
23
+ message: {
24
+ min: 'Quantity must be at least 1',
25
+ },
26
+ },
27
+ factory: faker => faker.number.int({ min: 1, max: 5 }),
28
+ },
29
+
30
+ price: {
31
+ order: 4,
32
+ fillable: true,
33
+ validation: {
34
+ rule: schema.number().required().min(0),
35
+ message: {
36
+ min: 'Price cannot be negative',
37
+ },
38
+ },
39
+ factory: faker => faker.number.int({ min: 5, max: 50 }),
40
+ },
41
+
42
+ special_instructions: {
43
+ order: 5,
44
+ fillable: true,
45
+ validation: {
46
+ rule: schema.string(),
47
+ },
48
+ factory: faker => faker.lorem.sentence(),
49
+ },
50
+ },
51
+ } as const)
@@ -0,0 +1,182 @@
1
+ import { defineModel } from '@stacksjs/orm'
2
+ import { schema } from '@stacksjs/validation'
3
+
4
+ export default defineModel({
5
+ name: 'Payment',
6
+ table: 'payments',
7
+ primaryKey: 'id',
8
+ autoIncrement: true,
9
+
10
+ traits: {
11
+ useUuid: true,
12
+ useTimestamps: true,
13
+ useSearch: {
14
+ displayable: ['id', 'orderId', 'customerId', 'amount', 'method', 'status', 'date'],
15
+ searchable: ['orderId', 'customerId', 'referenceNumber'],
16
+ sortable: ['amount', 'createdAt'],
17
+ filterable: ['method', 'status', 'date'],
18
+ },
19
+
20
+ useSeeder: {
21
+ count: 50,
22
+ },
23
+
24
+ useApi: {
25
+ uri: 'payments',
26
+ middleware: ['auth'],
27
+ },
28
+
29
+ observe: true,
30
+ },
31
+
32
+ belongsTo: ['Order', 'Customer'],
33
+
34
+ attributes: {
35
+ amount: {
36
+ order: 3,
37
+ fillable: true,
38
+ validation: {
39
+ rule: schema.number().required().min(1),
40
+ },
41
+ factory: faker => faker.number.int({ min: 1000, max: 50000 }),
42
+ },
43
+
44
+ method: {
45
+ order: 4,
46
+ fillable: true,
47
+ validation: {
48
+ rule: schema.enum([
49
+ 'cash',
50
+ 'creditCard',
51
+ 'debitCard',
52
+ 'paypal',
53
+ 'applePay',
54
+ 'googlePay',
55
+ 'bankTransfer',
56
+ 'giftCard',
57
+ ]).required(),
58
+ },
59
+ factory: faker => faker.helpers.arrayElement([
60
+ 'cash',
61
+ 'creditCard',
62
+ 'debitCard',
63
+ 'paypal',
64
+ 'applePay',
65
+ 'googlePay',
66
+ 'bankTransfer',
67
+ 'giftCard',
68
+ ]),
69
+ },
70
+
71
+ status: {
72
+ order: 5,
73
+ fillable: true,
74
+ default: 'pending',
75
+ validation: {
76
+ rule: schema.enum([
77
+ 'pending',
78
+ 'processing',
79
+ 'completed',
80
+ 'failed',
81
+ 'refunded',
82
+ 'partiallyRefunded',
83
+ 'succeeded',
84
+ ]).required(),
85
+ },
86
+ factory: faker => faker.helpers.arrayElement([
87
+ 'pending',
88
+ 'processing',
89
+ 'completed',
90
+ 'failed',
91
+ ]),
92
+ },
93
+
94
+ currency: {
95
+ order: 7,
96
+ fillable: true,
97
+ default: 'USD',
98
+ validation: {
99
+ rule: schema.string().required().max(3),
100
+ },
101
+ factory: faker => faker.helpers.arrayElement(['USD', 'EUR', 'GBP', 'CAD', 'AUD']),
102
+ },
103
+
104
+ referenceNumber: {
105
+ order: 8,
106
+ fillable: true,
107
+ validation: {
108
+ rule: schema.string(),
109
+ },
110
+ factory: faker => faker.string.alphanumeric(16).toUpperCase(),
111
+ },
112
+
113
+ cardLastFour: {
114
+ order: 9,
115
+ fillable: true,
116
+ validation: {
117
+ rule: schema.string().max(4),
118
+ },
119
+ factory: faker => faker.helpers.maybe(() => faker.string.numeric(4), { probability: 0.7 }),
120
+ },
121
+
122
+ cardBrand: {
123
+ order: 10,
124
+ fillable: true,
125
+ validation: {
126
+ rule: schema.string(),
127
+ },
128
+ factory: faker => faker.helpers.maybe(() => faker.helpers.arrayElement(['Visa', 'Mastercard', 'Amex', 'Discover']), { probability: 0.7 }),
129
+ },
130
+
131
+ billingEmail: {
132
+ order: 11,
133
+ fillable: true,
134
+ validation: {
135
+ rule: schema.string().email(),
136
+ },
137
+ factory: faker => faker.helpers.maybe(() => faker.internet.email(), { probability: 0.8 }),
138
+ },
139
+
140
+ transactionId: {
141
+ order: 12,
142
+ unique: true,
143
+ fillable: true,
144
+ foreignKey: false, // This is a payment processor transaction ID string, not a FK to transactions table
145
+ validation: {
146
+ rule: schema.string(),
147
+ },
148
+ factory: faker => faker.helpers.maybe(() => faker.string.uuid(), { probability: 0.9 }),
149
+ },
150
+
151
+ paymentProvider: {
152
+ order: 13,
153
+ fillable: true,
154
+ validation: {
155
+ rule: schema.string(),
156
+ },
157
+ factory: faker => faker.helpers.maybe(() => faker.helpers.arrayElement(['stripe', 'paypal', 'square', 'braintree', 'authorizeNet']), { probability: 0.9 }),
158
+ },
159
+
160
+ refundAmount: {
161
+ order: 14,
162
+ fillable: true,
163
+ default: 0,
164
+ validation: {
165
+ rule: schema.number().min(0),
166
+ },
167
+ },
168
+
169
+ notes: {
170
+ order: 15,
171
+ fillable: true,
172
+ validation: {
173
+ rule: schema.string(),
174
+ },
175
+ factory: faker => faker.helpers.maybe(() => faker.lorem.sentence(), { probability: 0.3 }),
176
+ },
177
+ },
178
+
179
+ dashboard: {
180
+ highlight: true,
181
+ },
182
+ } as const)
@@ -0,0 +1,112 @@
1
+ import { defineModel } from '@stacksjs/orm'
2
+ import { schema } from '@stacksjs/validation'
3
+
4
+ /**
5
+ * A fund-a-need pledge.
6
+ *
7
+ * Fund-a-need is the part of a benefit auction that is not an auction: the room
8
+ * is asked to give at fixed levels and nobody competes for anything. It shares
9
+ * the auction only for the tally board, which is why a pledge has an amount and
10
+ * a level but no lot, no increment and no winner.
11
+ */
12
+ export default defineModel({
13
+ name: 'Pledge',
14
+ table: 'pledges',
15
+ primaryKey: 'id',
16
+ autoIncrement: true,
17
+
18
+ traits: {
19
+ useUuid: true,
20
+ useTimestamps: true,
21
+
22
+ useSearch: {
23
+ displayable: ['id', 'donorName', 'amount', 'level', 'status'],
24
+ searchable: ['donorName', 'donorEmail', 'level'],
25
+ sortable: ['createdAt', 'amount'],
26
+ filterable: ['status', 'level'],
27
+ },
28
+
29
+ useApi: {
30
+ uri: 'pledges',
31
+ middleware: ['auth'],
32
+ },
33
+
34
+ observe: true,
35
+ },
36
+
37
+ belongsTo: ['Auction'],
38
+
39
+ indexes: [
40
+ { name: 'pledges_auction_id_index', columns: ['auction_id'] },
41
+ { name: 'pledges_status_index', columns: ['status'] },
42
+ ],
43
+
44
+ attributes: {
45
+ donorName: {
46
+ order: 1,
47
+ fillable: true,
48
+ validation: {
49
+ rule: schema.string().required().max(160),
50
+ message: {
51
+ required: 'Donor name is required',
52
+ },
53
+ },
54
+ factory: faker => faker.person.fullName(),
55
+ },
56
+
57
+ donorEmail: {
58
+ order: 2,
59
+ fillable: true,
60
+ validation: {
61
+ rule: schema.string().email().required(),
62
+ message: {
63
+ required: 'Donor email is required',
64
+ },
65
+ },
66
+ factory: faker => faker.internet.email().toLowerCase(),
67
+ },
68
+
69
+ /** The gift, in cents. */
70
+ amount: {
71
+ order: 3,
72
+ fillable: true,
73
+ validation: {
74
+ rule: schema.number().required().min(1),
75
+ message: {
76
+ required: 'A pledge amount is required',
77
+ },
78
+ },
79
+ factory: faker => faker.helpers.arrayElement([25000, 50000, 100000, 250000, 500000]),
80
+ },
81
+
82
+ /** The paddle-raise tier this came from, for the tally board. */
83
+ level: {
84
+ order: 4,
85
+ fillable: true,
86
+ validation: {
87
+ rule: schema.string().max(40),
88
+ },
89
+ factory: faker => faker.helpers.arrayElement(['250', '500', '1000', '2500', '5000']),
90
+ },
91
+
92
+ /**
93
+ * Pledges made from the room are good the moment a paddle goes up; pledges
94
+ * taken online are often confirmed by staff afterwards. Only `confirmed`
95
+ * money counts toward a total anybody reports.
96
+ */
97
+ status: {
98
+ default: 'confirmed',
99
+ order: 5,
100
+ fillable: true,
101
+ validation: {
102
+ rule: schema.enum(['pending', 'confirmed', 'cancelled']).required(),
103
+ },
104
+ factory: () => 'confirmed',
105
+ },
106
+ },
107
+
108
+ dashboard: {
109
+ icon: 'i-hugeicons-give-blood',
110
+ label: 'Pledges',
111
+ },
112
+ } as const)
@@ -0,0 +1,120 @@
1
+ import { defineModel } from '@stacksjs/orm'
2
+ import { schema } from '@stacksjs/validation'
3
+
4
+ export default defineModel({
5
+ name: 'PrintDevice',
6
+ table: 'print_devices',
7
+ primaryKey: 'id',
8
+ autoIncrement: true,
9
+ hasMany: ['Receipt'],
10
+ traits: {
11
+ useUuid: true,
12
+ useTimestamps: true,
13
+ useSearch: {
14
+ displayable: ['id', 'name', 'macAddress', 'location', 'terminal', 'status', 'lastPing', 'printCount'],
15
+ searchable: ['name', 'macAddress', 'location', 'terminal'],
16
+ sortable: ['lastPing', 'printCount'],
17
+ filterable: ['status'],
18
+ },
19
+
20
+ useSeeder: {
21
+ count: 5,
22
+ },
23
+
24
+ useApi: {
25
+ uri: 'print-devices',
26
+ middleware: ['auth'],
27
+ },
28
+
29
+ observe: true,
30
+ },
31
+
32
+ attributes: {
33
+ name: {
34
+ order: 1,
35
+ fillable: true,
36
+ validation: {
37
+ rule: schema.string().required().max(100),
38
+ message: {
39
+ max: 'Device name must have a maximum of 100 characters',
40
+ },
41
+ },
42
+ factory: faker => faker.company.name(),
43
+ },
44
+
45
+ macAddress: {
46
+ order: 2,
47
+ fillable: true,
48
+ validation: {
49
+ rule: schema.string().required().max(50),
50
+ message: {
51
+ max: 'MAC address must have a maximum of 50 characters',
52
+ },
53
+ },
54
+ factory: faker => faker.internet.mac(),
55
+ },
56
+
57
+ location: {
58
+ order: 3,
59
+ fillable: true,
60
+ validation: {
61
+ rule: schema.string().required().max(100),
62
+ message: {
63
+ max: 'Location must have a maximum of 100 characters',
64
+ },
65
+ },
66
+ factory: faker => faker.location.streetAddress(),
67
+ },
68
+
69
+ terminal: {
70
+ order: 4,
71
+ fillable: true,
72
+ validation: {
73
+ rule: schema.string().required().max(50),
74
+ message: {
75
+ max: 'Terminal must have a maximum of 50 characters',
76
+ },
77
+ },
78
+ factory: faker => faker.string.alphanumeric(10),
79
+ },
80
+
81
+ status: {
82
+ order: 5,
83
+ fillable: true,
84
+ validation: {
85
+ rule: schema.enum(['online', 'offline', 'warning']).required(),
86
+ },
87
+ factory: faker => faker.helpers.arrayElement(['online', 'offline', 'warning']),
88
+ },
89
+
90
+ lastPing: {
91
+ order: 6,
92
+ fillable: true,
93
+ default: 0,
94
+ validation: {
95
+ rule: schema.unix(),
96
+ message: {
97
+ invalid: 'Invalid timestamp format',
98
+ },
99
+ },
100
+ factory: faker => faker.date.recent().getTime(),
101
+ },
102
+
103
+ printCount: {
104
+ order: 7,
105
+ fillable: true,
106
+ default: 0,
107
+ validation: {
108
+ rule: schema.number().min(0),
109
+ message: {
110
+ min: 'Print count cannot be negative',
111
+ },
112
+ },
113
+ factory: faker => faker.number.int({ min: 0, max: 1000 }),
114
+ },
115
+ },
116
+
117
+ dashboard: {
118
+ highlight: true,
119
+ },
120
+ } as const)