@stacksjs/orm 0.72.16 → 0.72.17

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 (101) hide show
  1. package/dist/index.d.ts +97 -97
  2. package/dist/models/Activity.ts +95 -0
  3. package/dist/models/AnalyticsEvent.ts +70 -0
  4. package/dist/models/Automation.ts +23 -0
  5. package/dist/models/AutomationRun.ts +26 -0
  6. package/dist/models/Board.ts +104 -0
  7. package/dist/models/BoardColumn.ts +88 -0
  8. package/dist/models/Campaign.ts +321 -0
  9. package/dist/models/CampaignSend.ts +191 -0
  10. package/dist/models/CampaignVariant.ts +25 -0
  11. package/dist/models/Card.ts +118 -0
  12. package/dist/models/CardComment.ts +68 -0
  13. package/dist/models/Comment.ts +109 -0
  14. package/dist/models/CommunicationSuppression.ts +22 -0
  15. package/dist/models/ConsentEvent.ts +30 -0
  16. package/dist/models/Content/Author.ts +109 -0
  17. package/dist/models/Content/Menu.ts +56 -0
  18. package/dist/models/Content/MenuItem.ts +91 -0
  19. package/dist/models/Content/Page.ts +205 -0
  20. package/dist/models/Content/PageRevision.ts +86 -0
  21. package/dist/models/Content/Post.ts +230 -0
  22. package/dist/models/Content/Redirect.ts +80 -0
  23. package/dist/models/Deployment.ts +117 -0
  24. package/dist/models/EmailIdempotency.ts +64 -0
  25. package/dist/models/EmailList.ts +134 -0
  26. package/dist/models/EmailListSubscriber.ts +91 -0
  27. package/dist/models/EmailSuppression.ts +52 -0
  28. package/dist/models/EmailWebhookEvent.ts +51 -0
  29. package/dist/models/Error.ts +77 -0
  30. package/dist/models/FailedJob.ts +84 -0
  31. package/dist/models/Forms/Form.ts +91 -0
  32. package/dist/models/Forms/FormField.ts +127 -0
  33. package/dist/models/Forms/FormSubmission.ts +114 -0
  34. package/dist/models/Job.ts +69 -0
  35. package/dist/models/Label.ts +67 -0
  36. package/dist/models/Log.ts +134 -0
  37. package/dist/models/MagicLinkToken.ts +97 -0
  38. package/dist/models/MailPreference.ts +213 -0
  39. package/dist/models/Notification.ts +68 -0
  40. package/dist/models/NotificationDelivery.ts +102 -0
  41. package/dist/models/PaymentMethod.ts +98 -0
  42. package/dist/models/PaymentProduct.ts +91 -0
  43. package/dist/models/PaymentTransaction.ts +78 -0
  44. package/dist/models/QueryLog.ts +182 -0
  45. package/dist/models/README.md +31 -0
  46. package/dist/models/Release.ts +90 -0
  47. package/dist/models/Request.ts +133 -0
  48. package/dist/models/SenderDomain.ts +22 -0
  49. package/dist/models/Site.ts +112 -0
  50. package/dist/models/SiteDomain.ts +74 -0
  51. package/dist/models/SmsOptOut.ts +65 -0
  52. package/dist/models/SocialAccount.ts +70 -0
  53. package/dist/models/SocialPost.ts +144 -0
  54. package/dist/models/Subscriber.ts +89 -0
  55. package/dist/models/SubscriberEmail.ts +55 -0
  56. package/dist/models/Subscription.ts +153 -0
  57. package/dist/models/Tag.ts +105 -0
  58. package/dist/models/Team.ts +75 -0
  59. package/dist/models/TeamInvitation.ts +159 -0
  60. package/dist/models/TeamMember.ts +88 -0
  61. package/dist/models/UsageEvent.ts +24 -0
  62. package/dist/models/User.ts +142 -0
  63. package/dist/models/commerce/Auction.ts +173 -0
  64. package/dist/models/commerce/AuctionItem.ts +204 -0
  65. package/dist/models/commerce/Bid.ts +129 -0
  66. package/dist/models/commerce/Cart.ts +140 -0
  67. package/dist/models/commerce/CartItem.ts +138 -0
  68. package/dist/models/commerce/Category.ts +125 -0
  69. package/dist/models/commerce/Coupon.ts +186 -0
  70. package/dist/models/commerce/Customer.ts +132 -0
  71. package/dist/models/commerce/DeliveryRoute.ts +127 -0
  72. package/dist/models/commerce/DeliveryStop.ts +166 -0
  73. package/dist/models/commerce/DigitalDelivery.ts +106 -0
  74. package/dist/models/commerce/Driver.ts +168 -0
  75. package/dist/models/commerce/DriverPing.ts +103 -0
  76. package/dist/models/commerce/GiftCard.ts +195 -0
  77. package/dist/models/commerce/LicenseKey.ts +89 -0
  78. package/dist/models/commerce/LoyaltyPoint.ts +108 -0
  79. package/dist/models/commerce/LoyaltyReward.ts +129 -0
  80. package/dist/models/commerce/Manufacturer.ts +90 -0
  81. package/dist/models/commerce/Order.ts +198 -0
  82. package/dist/models/commerce/OrderIdempotency.ts +34 -0
  83. package/dist/models/commerce/OrderItem.ts +51 -0
  84. package/dist/models/commerce/Payment.ts +182 -0
  85. package/dist/models/commerce/Pledge.ts +112 -0
  86. package/dist/models/commerce/PrintDevice.ts +120 -0
  87. package/dist/models/commerce/Product.ts +153 -0
  88. package/dist/models/commerce/ProductUnit.ts +113 -0
  89. package/dist/models/commerce/ProductVariant.ts +111 -0
  90. package/dist/models/commerce/Receipt.ts +144 -0
  91. package/dist/models/commerce/Review.ts +171 -0
  92. package/dist/models/commerce/ShippingMethod.ts +102 -0
  93. package/dist/models/commerce/ShippingRate.ts +79 -0
  94. package/dist/models/commerce/ShippingZone.ts +116 -0
  95. package/dist/models/commerce/TaxRate.ts +167 -0
  96. package/dist/models/commerce/Transaction.ts +127 -0
  97. package/dist/models/commerce/WaitlistProduct.ts +151 -0
  98. package/dist/models/commerce/WaitlistRestaurant.ts +189 -0
  99. package/dist/models/realtime/Websocket.ts +78 -0
  100. package/dist/password-policy.ts +46 -0
  101. package/package.json +4 -4
@@ -0,0 +1,64 @@
1
+ import { defineModel } from '@stacksjs/orm'
2
+ import { schema } from '@stacksjs/validation'
3
+
4
+ export default defineModel({
5
+ name: 'EmailIdempotency',
6
+ table: 'email_idempotency',
7
+ primaryKey: 'id',
8
+ autoIncrement: true,
9
+
10
+ traits: {
11
+ useTimestamps: true,
12
+ useApi: {
13
+ uri: 'email-idempotency',
14
+ routes: ['index', 'show', 'destroy'],
15
+ middleware: ['auth'],
16
+ },
17
+ },
18
+
19
+ attributes: {
20
+ idempotencyKey: {
21
+ required: true,
22
+ hidden: true,
23
+ unique: true,
24
+ validation: {
25
+ rule: schema.string().required().max(255),
26
+ },
27
+ },
28
+ messageId: {
29
+ required: false,
30
+ validation: {
31
+ rule: schema.string().max(512),
32
+ },
33
+ },
34
+ recipient: {
35
+ required: false,
36
+ hidden: true,
37
+ validation: {
38
+ rule: schema.string().max(2000),
39
+ },
40
+ },
41
+ subject: {
42
+ required: false,
43
+ hidden: true,
44
+ validation: {
45
+ rule: schema.string().max(998),
46
+ },
47
+ },
48
+ provider: {
49
+ required: false,
50
+ validation: {
51
+ rule: schema.string().max(100),
52
+ },
53
+ },
54
+ success: {
55
+ required: true,
56
+ default: true,
57
+ validation: {
58
+ rule: schema.boolean(),
59
+ },
60
+ },
61
+ },
62
+
63
+ dashboard: { enabled: false },
64
+ } as const)
@@ -0,0 +1,134 @@
1
+ import { defineModel } from '@stacksjs/orm'
2
+ import { schema } from '@stacksjs/validation'
3
+
4
+ export default defineModel({
5
+ name: 'EmailList',
6
+ table: 'email_lists',
7
+ primaryKey: 'id',
8
+ autoIncrement: true,
9
+ hasMany: ['EmailListSubscriber', 'Campaign', 'CampaignSend'],
10
+
11
+ traits: {
12
+ useUuid: true,
13
+ useTimestamps: true,
14
+ useSeeder: {
15
+ count: 8,
16
+ },
17
+ useApi: {
18
+ uri: 'email-lists',
19
+ routes: ['index', 'store', 'show', 'update', 'destroy'],
20
+ middleware: ['auth'],
21
+ },
22
+ useSearch: {
23
+ displayable: ['id', 'name', 'slug', 'description', 'status', 'subscriberCount', 'activeCount'],
24
+ searchable: ['name', 'slug', 'description'],
25
+ sortable: ['name', 'status', 'subscriberCount', 'createdAt', 'updatedAt'],
26
+ filterable: ['status', 'isPublic', 'doubleOptIn'],
27
+ },
28
+ observe: true,
29
+ },
30
+
31
+ attributes: {
32
+ name: {
33
+ required: true,
34
+ fillable: true,
35
+ validation: {
36
+ rule: schema.string().min(2).max(100),
37
+ },
38
+ factory: faker => faker.helpers.arrayElement([
39
+ 'Newsletter Subscribers', 'VIP Customers', 'Product Updates',
40
+ 'Beta Testers', 'Blog Subscribers', 'Marketing List',
41
+ 'Enterprise Leads', 'Event Attendees',
42
+ ]),
43
+ },
44
+
45
+ slug: {
46
+ unique: true,
47
+ required: false,
48
+ fillable: true,
49
+ validation: {
50
+ rule: schema.string().max(120),
51
+ },
52
+ factory: faker => faker.helpers.slugify(faker.lorem.words(2)).toLowerCase(),
53
+ },
54
+
55
+ description: {
56
+ required: false,
57
+ fillable: true,
58
+ validation: {
59
+ rule: schema.string().max(500),
60
+ },
61
+ factory: faker => faker.lorem.sentence(),
62
+ },
63
+
64
+ subscriberCount: {
65
+ required: false,
66
+ fillable: true,
67
+ default: 0,
68
+ validation: {
69
+ rule: schema.number().min(0),
70
+ },
71
+ factory: faker => faker.number.int({ min: 100, max: 25000 }),
72
+ },
73
+
74
+ activeCount: {
75
+ required: false,
76
+ fillable: true,
77
+ default: 0,
78
+ validation: {
79
+ rule: schema.number().min(0),
80
+ },
81
+ factory: faker => faker.number.int({ min: 50, max: 20000 }),
82
+ },
83
+
84
+ unsubscribedCount: {
85
+ required: false,
86
+ fillable: true,
87
+ default: 0,
88
+ validation: {
89
+ rule: schema.number().min(0),
90
+ },
91
+ factory: faker => faker.number.int({ min: 0, max: 500 }),
92
+ },
93
+
94
+ bouncedCount: {
95
+ required: false,
96
+ fillable: true,
97
+ default: 0,
98
+ validation: {
99
+ rule: schema.number().min(0),
100
+ },
101
+ factory: faker => faker.number.int({ min: 0, max: 100 }),
102
+ },
103
+
104
+ status: {
105
+ required: true,
106
+ fillable: true,
107
+ default: 'active',
108
+ validation: {
109
+ rule: schema.enum(['active', 'inactive', 'archived']),
110
+ },
111
+ factory: faker => faker.helpers.arrayElement(['active', 'active', 'active', 'inactive']),
112
+ },
113
+
114
+ isPublic: {
115
+ required: false,
116
+ fillable: true,
117
+ default: 1,
118
+ validation: {
119
+ rule: schema.number(),
120
+ },
121
+ factory: faker => faker.number.int({ min: 0, max: 1 }),
122
+ },
123
+
124
+ doubleOptIn: {
125
+ required: false,
126
+ fillable: true,
127
+ default: 1,
128
+ validation: {
129
+ rule: schema.number(),
130
+ },
131
+ factory: () => 1,
132
+ },
133
+ },
134
+ } as const)
@@ -0,0 +1,91 @@
1
+ import { defineModel } from '@stacksjs/orm'
2
+ import { schema } from '@stacksjs/validation'
3
+
4
+ /**
5
+ * Pivot row between Subscriber and EmailList.
6
+ *
7
+ * One subscriber can be on many lists; the subscribers.email unique
8
+ * constraint stays intact because membership lives here. Each pivot
9
+ * row carries its own UUID, which doubles as the per-list unsubscribe
10
+ * token — that lets a recipient drop "Weekly Digest" via one link
11
+ * without dropping every other list (or transactional mail).
12
+ */
13
+ export default defineModel({
14
+ name: 'EmailListSubscriber',
15
+ table: 'email_list_subscribers',
16
+ primaryKey: 'id',
17
+ autoIncrement: true,
18
+ belongsTo: ['EmailList', 'Subscriber'],
19
+
20
+ traits: {
21
+ useUuid: true,
22
+ useTimestamps: true,
23
+ useApi: {
24
+ uri: 'email-list-subscribers',
25
+ routes: ['index', 'show'],
26
+ // The pivot leaks list-membership PII (which addresses are on
27
+ // which list, signup source, status). Auth-gate it. Public
28
+ // unsubscribe goes through the dedicated token route, not this
29
+ // CRUD surface.
30
+ middleware: ['auth'],
31
+ },
32
+ },
33
+
34
+ attributes: {
35
+ emailListId: {
36
+ required: true,
37
+ fillable: true,
38
+ validation: {
39
+ rule: schema.number(),
40
+ },
41
+ factory: faker => faker.number.int({ min: 1, max: 8 }),
42
+ },
43
+
44
+ subscriberId: {
45
+ required: true,
46
+ fillable: true,
47
+ validation: {
48
+ rule: schema.number(),
49
+ },
50
+ factory: faker => faker.number.int({ min: 1, max: 100 }),
51
+ },
52
+
53
+ status: {
54
+ required: true,
55
+ fillable: true,
56
+ default: 'subscribed',
57
+ validation: {
58
+ rule: schema.enum(['subscribed', 'unsubscribed', 'pending', 'bounced']),
59
+ },
60
+ factory: faker => faker.helpers.arrayElement(['subscribed', 'subscribed', 'subscribed', 'unsubscribed']),
61
+ },
62
+
63
+ source: {
64
+ required: false,
65
+ fillable: true,
66
+ default: 'api',
67
+ validation: {
68
+ rule: schema.string().max(100),
69
+ },
70
+ factory: faker => faker.helpers.arrayElement(['homepage', 'blog', 'landing-page', 'api', 'import']),
71
+ },
72
+
73
+ subscribedAt: {
74
+ required: false,
75
+ fillable: true,
76
+ validation: {
77
+ rule: schema.timestamp(),
78
+ },
79
+ factory: faker => faker.date.recent({ days: 90 }).toISOString().slice(0, 19).replace('T', ' '),
80
+ },
81
+
82
+ unsubscribedAt: {
83
+ required: false,
84
+ fillable: true,
85
+ validation: {
86
+ rule: schema.timestamp(),
87
+ },
88
+ factory: () => null,
89
+ },
90
+ },
91
+ } as const)
@@ -0,0 +1,52 @@
1
+ import { defineModel } from '@stacksjs/orm'
2
+ import { schema } from '@stacksjs/validation'
3
+
4
+ export default defineModel({
5
+ name: 'EmailSuppression',
6
+ table: 'email_suppressions',
7
+ primaryKey: 'id',
8
+ autoIncrement: true,
9
+
10
+ indexes: [
11
+ {
12
+ name: 'email_suppressions_email_type_unique',
13
+ columns: ['email', 'type'],
14
+ unique: true,
15
+ },
16
+ ],
17
+
18
+ traits: {
19
+ useTimestamps: true,
20
+ useApi: {
21
+ uri: 'email-suppressions',
22
+ routes: ['index', 'show', 'destroy'],
23
+ middleware: ['auth'],
24
+ },
25
+ },
26
+
27
+ attributes: {
28
+ email: {
29
+ required: true,
30
+ fillable: true,
31
+ validation: {
32
+ rule: schema.string().email().required().max(320),
33
+ },
34
+ },
35
+ type: {
36
+ required: true,
37
+ fillable: true,
38
+ validation: {
39
+ rule: schema.enum(['bounce', 'complaint', 'unsubscribe', 'manual']),
40
+ },
41
+ },
42
+ reason: {
43
+ required: false,
44
+ fillable: true,
45
+ validation: {
46
+ rule: schema.string().max(2000),
47
+ },
48
+ },
49
+ },
50
+
51
+ dashboard: { enabled: false },
52
+ } 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: 'EmailWebhookEvent',
6
+ table: 'email_webhook_events',
7
+ primaryKey: 'id',
8
+ autoIncrement: true,
9
+
10
+ indexes: [
11
+ {
12
+ name: 'email_webhook_events_provider_event_unique',
13
+ columns: ['provider', 'event_id'],
14
+ unique: true,
15
+ },
16
+ ],
17
+
18
+ traits: {
19
+ useTimestamps: true,
20
+ useApi: {
21
+ uri: 'email-webhook-events',
22
+ routes: ['index', 'show', 'destroy'],
23
+ middleware: ['auth'],
24
+ },
25
+ },
26
+
27
+ attributes: {
28
+ provider: {
29
+ required: true,
30
+ fillable: true,
31
+ validation: {
32
+ rule: schema.enum(['mailgun', 'postmark', 'ses', 'sendgrid']),
33
+ },
34
+ },
35
+ eventId: {
36
+ required: true,
37
+ hidden: true,
38
+ validation: {
39
+ rule: schema.string().required().max(512),
40
+ },
41
+ },
42
+ processedAt: {
43
+ required: true,
44
+ validation: {
45
+ rule: schema.timestamp().required(),
46
+ },
47
+ },
48
+ },
49
+
50
+ dashboard: { enabled: false },
51
+ } as const)
@@ -0,0 +1,77 @@
1
+ import { defineModel } from '@stacksjs/orm'
2
+ import { schema } from '@stacksjs/validation'
3
+
4
+ export default defineModel({
5
+ name: 'Error',
6
+ table: 'errors',
7
+ primaryKey: 'id',
8
+ autoIncrement: true,
9
+
10
+ indexes: [
11
+ {
12
+ name: 'errors_created_at_index',
13
+ columns: ['created_at'],
14
+ },
15
+ ],
16
+
17
+ traits: {
18
+ useTimestamps: true,
19
+ },
20
+
21
+ attributes: {
22
+ type: {
23
+ fillable: true,
24
+ validation: {
25
+ rule: schema.string().required().max(255),
26
+ message: {
27
+ max: 'type must have a maximum of 255 characters',
28
+ },
29
+ },
30
+ factory: faker => faker.system.fileType(),
31
+ },
32
+
33
+ message: {
34
+ fillable: true,
35
+ validation: {
36
+ rule: schema.string().required(),
37
+ message: {
38
+ string: 'message must be a string',
39
+ },
40
+ },
41
+ factory: faker => faker.lorem.sentence(),
42
+ },
43
+
44
+ stack: {
45
+ fillable: true,
46
+ validation: {
47
+ rule: schema.string(),
48
+ message: {
49
+ string: 'stack must be a text',
50
+ },
51
+ },
52
+ factory: faker => faker.system.filePath(),
53
+ },
54
+
55
+ status: {
56
+ fillable: true,
57
+ validation: {
58
+ rule: schema.number(),
59
+ message: {
60
+ string: 'status must be a number',
61
+ },
62
+ },
63
+ factory: faker => faker.number.int({ min: 400, max: 500 }),
64
+ },
65
+
66
+ additional_info: {
67
+ fillable: true,
68
+ validation: {
69
+ rule: schema.string(),
70
+ message: {
71
+ string: 'additional_info must be a text',
72
+ },
73
+ },
74
+ factory: faker => faker.lorem.paragraph(),
75
+ },
76
+ },
77
+ } as const)
@@ -0,0 +1,84 @@
1
+ import { defineModel } from '@stacksjs/orm'
2
+ import { schema } from '@stacksjs/validation'
3
+
4
+ export default defineModel({
5
+ name: 'FailedJob',
6
+ table: 'failed_jobs',
7
+ primaryKey: 'id',
8
+ autoIncrement: true,
9
+
10
+ traits: {
11
+ useUuid: true,
12
+ useTimestamps: true,
13
+ },
14
+
15
+ attributes: {
16
+ connection: {
17
+ fillable: true,
18
+ validation: {
19
+ rule: schema.string().required().max(100),
20
+ message: {
21
+ max: 'Connection must have a maximum of 100 characters',
22
+ string: 'Connection must be a string',
23
+ },
24
+ },
25
+ factory: () => 'default',
26
+ },
27
+
28
+ queue: {
29
+ fillable: true,
30
+ validation: {
31
+ rule: schema.string().required().max(255),
32
+ message: {
33
+ max: 'Queue must have a maximum of 255 characters',
34
+ },
35
+ },
36
+ factory: () => 'default',
37
+ },
38
+
39
+ payload: {
40
+ fillable: true,
41
+ validation: {
42
+ rule: schema.string().required(),
43
+ },
44
+ factory: faker => faker.lorem.sentence(),
45
+ },
46
+
47
+ exception: {
48
+ fillable: true,
49
+ validation: {
50
+ rule: schema.string().required(),
51
+ },
52
+ factory: faker => faker.lorem.sentence(),
53
+ },
54
+
55
+ attempts: {
56
+ fillable: true,
57
+ validation: {
58
+ rule: schema.number().min(0),
59
+ },
60
+ },
61
+
62
+ maxAttempts: {
63
+ fillable: true,
64
+ validation: {
65
+ rule: schema.number().min(1),
66
+ },
67
+ },
68
+
69
+ durationMs: {
70
+ fillable: true,
71
+ validation: {
72
+ rule: schema.number().min(0),
73
+ },
74
+ },
75
+
76
+ failed_at: {
77
+ fillable: true,
78
+ validation: {
79
+ rule: schema.date(),
80
+ },
81
+ factory: () => '2024-12-23 13:32:19',
82
+ },
83
+ },
84
+ } as const)
@@ -0,0 +1,91 @@
1
+ import { defineModel } from '@stacksjs/orm'
2
+ import { schema } from '@stacksjs/validation'
3
+
4
+ /**
5
+ * A user-defined form: inquiry, permission slip, event registration,
6
+ * donation. Fields are FormField rows; submissions are FormSubmission rows.
7
+ *
8
+ * The `useApi` surface is the ADMIN builder surface. The public render and
9
+ * submit endpoints live in `@stacksjs/forms` routes, keyed by uuid, and only
10
+ * ever serve `status: 'active'` forms.
11
+ */
12
+ export default defineModel({
13
+ name: 'Form',
14
+ table: 'forms',
15
+ primaryKey: 'id',
16
+ autoIncrement: true,
17
+
18
+ indexes: [
19
+ {
20
+ name: 'forms_site_handle_unique',
21
+ columns: ['site_id', 'handle'],
22
+ unique: true,
23
+ },
24
+ ],
25
+
26
+ traits: {
27
+ useUuid: true,
28
+ useTimestamps: true,
29
+ useApi: {
30
+ middleware: ['auth'],
31
+ uri: 'forms',
32
+ routes: ['index', 'store', 'show', 'update', 'destroy'],
33
+ },
34
+ useSearch: {
35
+ displayable: ['id', 'name', 'handle', 'status'],
36
+ searchable: ['name', 'handle'],
37
+ filterable: ['status'],
38
+ },
39
+ },
40
+
41
+ belongsTo: ['Site'],
42
+ hasMany: ['FormField', 'FormSubmission'],
43
+
44
+ attributes: {
45
+ name: {
46
+ required: true,
47
+ order: 1,
48
+ fillable: true,
49
+ validation: {
50
+ rule: schema.string().min(2).max(255),
51
+ },
52
+ factory: faker => `${faker.lorem.words(2)} form`,
53
+ },
54
+
55
+ handle: {
56
+ required: true,
57
+ order: 2,
58
+ fillable: true,
59
+ validation: {
60
+ rule: schema.string().min(2).max(64).matches(/^[a-z0-9-]+$/),
61
+ },
62
+ factory: faker => faker.lorem.slug(),
63
+ },
64
+
65
+ status: {
66
+ required: false,
67
+ order: 3,
68
+ fillable: true,
69
+ default: 'draft',
70
+ validation: {
71
+ rule: schema.enum(['draft', 'active', 'closed'] as const),
72
+ },
73
+ factory: () => 'active',
74
+ },
75
+
76
+ /**
77
+ * JSON settings: { submitLabel?, confirmation: { type: 'message'|'redirect',
78
+ * value }, notifyEmails: string[], emailField?, nameField?,
79
+ * payment?: { mode: 'fixed'|'user_amount'|'field_sum', amountCents?, currency? } }
80
+ */
81
+ settings: {
82
+ required: false,
83
+ order: 4,
84
+ fillable: true,
85
+ validation: {
86
+ rule: schema.json(),
87
+ },
88
+ factory: () => JSON.stringify({}),
89
+ },
90
+ },
91
+ } as const)