Skip to content

Commit 91d6ac1

Browse files
chore: wip
1 parent a3e6d4f commit 91d6ac1

File tree

1 file changed

+206
-0
lines changed

1 file changed

+206
-0
lines changed
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
import type { Model } from '@stacksjs/types'
2+
import { schema } from '@stacksjs/validation'
3+
4+
export default {
5+
name: 'ProductReview',
6+
table: 'product_reviews',
7+
primaryKey: 'id',
8+
autoIncrement: false, // Using UUID instead of auto-increment
9+
10+
traits: {
11+
useUuid: true,
12+
useTimestamps: true,
13+
useSearch: {
14+
displayable: ['id', 'product_id', 'user_id', 'rating', 'title', 'content', 'is_verified_purchase', 'is_approved'],
15+
searchable: ['title', 'content', 'product_id', 'user_id'],
16+
sortable: ['rating', 'created_at', 'updated_at', 'helpful_votes'],
17+
filterable: ['product_id', 'user_id', 'rating', 'is_verified_purchase', 'is_approved'],
18+
},
19+
20+
useSeeder: {
21+
count: 50,
22+
},
23+
24+
useApi: {
25+
uri: 'product-reviews',
26+
routes: ['index', 'store', 'show'],
27+
},
28+
29+
observe: true,
30+
},
31+
32+
belongsTo: ['Product', 'User'],
33+
34+
attributes: {
35+
product_id: {
36+
required: true,
37+
order: 1,
38+
fillable: true,
39+
validation: {
40+
rule: schema.string().uuid(),
41+
message: {
42+
uuid: 'Product ID must be a valid UUID',
43+
},
44+
},
45+
factory: faker => faker.string.uuid(),
46+
},
47+
48+
user_id: {
49+
required: true,
50+
order: 2,
51+
fillable: true,
52+
validation: {
53+
rule: schema.number(),
54+
},
55+
factory: faker => faker.number.int({ min: 1, max: 1000 }),
56+
},
57+
58+
rating: {
59+
required: true,
60+
order: 3,
61+
fillable: true,
62+
validation: {
63+
rule: schema.number().min(1).max(5),
64+
message: {
65+
min: 'Rating must be at least 1',
66+
max: 'Rating cannot be more than 5',
67+
},
68+
},
69+
factory: faker => faker.number.int({ min: 1, max: 5 }),
70+
},
71+
72+
title: {
73+
required: true,
74+
order: 4,
75+
fillable: true,
76+
validation: {
77+
rule: schema.string().maxLength(100),
78+
message: {
79+
maxLength: 'Title must have a maximum of 100 characters',
80+
},
81+
},
82+
factory: faker => faker.lorem.sentence({ min: 3, max: 8 }),
83+
},
84+
85+
content: {
86+
required: true,
87+
order: 5,
88+
fillable: true,
89+
validation: {
90+
rule: schema.string().maxLength(2000),
91+
message: {
92+
maxLength: 'Review content must have a maximum of 2000 characters',
93+
},
94+
},
95+
factory: faker => faker.lorem.paragraphs({ min: 1, max: 3 }),
96+
},
97+
98+
is_verified_purchase: {
99+
required: false,
100+
order: 6,
101+
fillable: true,
102+
validation: {
103+
rule: schema.boolean(),
104+
},
105+
factory: faker => faker.datatype.boolean({ probability: 0.7 }),
106+
},
107+
108+
is_approved: {
109+
required: false,
110+
order: 7,
111+
fillable: true,
112+
validation: {
113+
rule: schema.boolean(),
114+
},
115+
factory: faker => faker.datatype.boolean({ probability: 0.9 }),
116+
},
117+
118+
helpful_votes: {
119+
required: false,
120+
order: 8,
121+
fillable: true,
122+
validation: {
123+
rule: schema.number().min(0),
124+
},
125+
factory: faker => faker.number.int({ min: 0, max: 200 }),
126+
},
127+
128+
unhelpful_votes: {
129+
required: false,
130+
order: 9,
131+
fillable: true,
132+
validation: {
133+
rule: schema.number().min(0),
134+
},
135+
factory: faker => faker.number.int({ min: 0, max: 50 }),
136+
},
137+
138+
purchase_date: {
139+
required: false,
140+
order: 10,
141+
fillable: true,
142+
validation: {
143+
rule: schema.string(),
144+
},
145+
factory: faker => faker.date.past({ years: 1 }).toISOString(),
146+
},
147+
148+
images: {
149+
required: false,
150+
order: 11,
151+
fillable: true,
152+
validation: {
153+
rule: schema.string(),
154+
},
155+
factory: (faker) => {
156+
const hasImages = faker.datatype.boolean({ probability: 0.3 })
157+
if (hasImages) {
158+
const imageCount = faker.number.int({ min: 1, max: 5 })
159+
const images = Array.from({ length: imageCount }, () => faker.image.url())
160+
return JSON.stringify(images)
161+
}
162+
return JSON.stringify([])
163+
},
164+
},
165+
166+
pros: {
167+
required: false,
168+
order: 12,
169+
fillable: true,
170+
validation: {
171+
rule: schema.string(),
172+
},
173+
factory: (faker) => {
174+
const hasPros = faker.datatype.boolean({ probability: 0.7 })
175+
if (hasPros) {
176+
const count = faker.number.int({ min: 1, max: 4 })
177+
const pros = Array.from({ length: count }, () => faker.lorem.sentence({ min: 3, max: 8 }))
178+
return JSON.stringify(pros)
179+
}
180+
return JSON.stringify([])
181+
},
182+
},
183+
184+
cons: {
185+
required: false,
186+
order: 13,
187+
fillable: true,
188+
validation: {
189+
rule: schema.string(),
190+
},
191+
factory: (faker) => {
192+
const hasCons = faker.datatype.boolean({ probability: 0.6 })
193+
if (hasCons) {
194+
const count = faker.number.int({ min: 0, max: 3 })
195+
const cons = Array.from({ length: count }, () => faker.lorem.sentence({ min: 3, max: 8 }))
196+
return JSON.stringify(cons)
197+
}
198+
return JSON.stringify([])
199+
},
200+
},
201+
},
202+
203+
dashboard: {
204+
highlight: true,
205+
},
206+
} satisfies Model

0 commit comments

Comments
 (0)