ReviewOS

also looking at this

loghqorg/loghq

Promote: give the subscribe action a model it can call

#18
Merged glennmichael123 wants to merge main into production
2 files +144 -0
app/Models/SubscriberEmail.tsadded+55-0
Changes to app/Models/SubscriberEmail.ts
@@ -0,0 +1,55 @@
1import { defineModel } from '@stacksjs/orm'
2import { schema } from '@stacksjs/validation'
3
4export default defineModel({
5 name: 'SubscriberEmail',
6 table: 'subscriber_emails',
7 primaryKey: 'id',
8 autoIncrement: true,
9 belongsTo: ['Subscriber'],
10
11 traits: {
12 useUuid: true,
13 useTimestamps: true,
14 useApi: {
15 uri: 'subscriber-emails',
16 routes: ['index', 'show'],
17 // SubscriberEmail rows are PII (email + signup source). Without
18 // this gate, anyone can scrape the list at GET /api/subscriber-emails.
19 // Apps that genuinely want a public list (e.g. a transparency
20 // page) can override the model in `app/Models/`.
21 middleware: ['auth'],
22 },
23 },
24
25 attributes: {
26 email: {
27 required: true,
28 fillable: true,
29 validation: {
30 rule: schema.string().email().max(255),
31 message: {
32 string: 'email must be a string',
33 required: 'email is required',
34 email: 'email must be a valid email address',
35 max: 'email must have a maximum of 255 characters',
36 },
37 },
38 factory: faker => faker.internet.email(),
39 },
40
41 source: {
42 required: false,
43 fillable: true,
44 default: 'homepage',
45 validation: {
46 rule: schema.string().max(100),
47 message: {
48 string: 'source must be a string',
49 max: 'source must have a maximum of 100 characters',
50 },
51 },
52 factory: faker => faker.helpers.arrayElement(['homepage', 'blog', 'landing-page', 'api', 'import']),
53 },
54 },
55} as const)