@actuate-media/cms-core 0.13.0 → 0.15.0

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 (73) hide show
  1. package/LICENSE +21 -21
  2. package/dist/__tests__/api/api-key-auth.test.d.ts +2 -0
  3. package/dist/__tests__/api/api-key-auth.test.d.ts.map +1 -0
  4. package/dist/__tests__/api/api-key-auth.test.js +254 -0
  5. package/dist/__tests__/api/api-key-auth.test.js.map +1 -0
  6. package/dist/__tests__/api/public-seo.test.d.ts +2 -0
  7. package/dist/__tests__/api/public-seo.test.d.ts.map +1 -0
  8. package/dist/__tests__/api/public-seo.test.js +341 -0
  9. package/dist/__tests__/api/public-seo.test.js.map +1 -0
  10. package/dist/__tests__/security/api-key-enhanced.test.d.ts +2 -0
  11. package/dist/__tests__/security/api-key-enhanced.test.d.ts.map +1 -0
  12. package/dist/__tests__/security/api-key-enhanced.test.js +110 -0
  13. package/dist/__tests__/security/api-key-enhanced.test.js.map +1 -0
  14. package/dist/__tests__/seo/page-meta.test.d.ts +2 -0
  15. package/dist/__tests__/seo/page-meta.test.d.ts.map +1 -0
  16. package/dist/__tests__/seo/page-meta.test.js +204 -0
  17. package/dist/__tests__/seo/page-meta.test.js.map +1 -0
  18. package/dist/api/handler-factory.d.ts.map +1 -1
  19. package/dist/api/handler-factory.js +20 -2
  20. package/dist/api/handler-factory.js.map +1 -1
  21. package/dist/api/handlers.d.ts.map +1 -1
  22. package/dist/api/handlers.js +764 -31
  23. package/dist/api/handlers.js.map +1 -1
  24. package/dist/config/types.d.ts +75 -0
  25. package/dist/config/types.d.ts.map +1 -1
  26. package/dist/security/api-key-enhanced.d.ts +48 -5
  27. package/dist/security/api-key-enhanced.d.ts.map +1 -1
  28. package/dist/security/api-key-enhanced.js +60 -9
  29. package/dist/security/api-key-enhanced.js.map +1 -1
  30. package/dist/seo/index.d.ts +2 -0
  31. package/dist/seo/index.d.ts.map +1 -1
  32. package/dist/seo/index.js +1 -0
  33. package/dist/seo/index.js.map +1 -1
  34. package/dist/seo/page-meta.d.ts +79 -0
  35. package/dist/seo/page-meta.d.ts.map +1 -0
  36. package/dist/seo/page-meta.js +209 -0
  37. package/dist/seo/page-meta.js.map +1 -0
  38. package/generated/browser.ts +109 -0
  39. package/generated/client.ts +133 -0
  40. package/generated/commonInputTypes.ts +709 -0
  41. package/generated/enums.ts +125 -0
  42. package/generated/internal/class.ts +376 -0
  43. package/generated/internal/prismaNamespace.ts +2617 -0
  44. package/generated/internal/prismaNamespaceBrowser.ts +611 -0
  45. package/generated/models/ApiKey.ts +1550 -0
  46. package/generated/models/AuditLog.ts +1206 -0
  47. package/generated/models/BackupRecord.ts +1250 -0
  48. package/generated/models/ContentLock.ts +1472 -0
  49. package/generated/models/ContentTemplate.ts +1416 -0
  50. package/generated/models/Document.ts +3005 -0
  51. package/generated/models/Folder.ts +1904 -0
  52. package/generated/models/FormSubmission.ts +1200 -0
  53. package/generated/models/InAppNotification.ts +1457 -0
  54. package/generated/models/Media.ts +2340 -0
  55. package/generated/models/MediaUsage.ts +1472 -0
  56. package/generated/models/OAuthAccount.ts +1463 -0
  57. package/generated/models/Redirect.ts +1284 -0
  58. package/generated/models/Session.ts +1492 -0
  59. package/generated/models/Site.ts +1206 -0
  60. package/generated/models/User.ts +3513 -0
  61. package/generated/models/Version.ts +1511 -0
  62. package/generated/models/WorkflowState.ts +1514 -0
  63. package/generated/models.ts +29 -0
  64. package/package.json +1 -1
  65. package/prisma/cms-schema.prisma +306 -306
  66. package/prisma/migrations/0001_init/migration.sql +384 -384
  67. package/prisma/migrations/0002_folders/migration.sql +39 -39
  68. package/prisma/migrations/0003_search_and_webhooks/migration.sql +50 -50
  69. package/prisma/migrations/0004_script_tags/migration.sql +21 -21
  70. package/prisma/migrations/0005_password_reset_tokens/migration.sql +20 -20
  71. package/prisma/migrations/0006_page_builder/migration.sql +38 -38
  72. package/prisma/migrations/migration_lock.toml +3 -3
  73. package/prisma/schema.prisma +549 -549
@@ -1,549 +1,549 @@
1
- generator client {
2
- provider = "prisma-client"
3
- output = "../generated"
4
- previewFeatures = ["fullTextSearchPostgres"]
5
- }
6
-
7
- datasource db {
8
- provider = "postgresql"
9
- }
10
-
11
- // ─── Enums ──────────────────────────────────────────────────────────
12
-
13
- enum DocumentStatus {
14
- DRAFT
15
- PUBLISHED
16
- ARCHIVED
17
- SCHEDULED
18
- SCHEDULED_UNPUBLISH
19
- }
20
-
21
- enum UserRole {
22
- ADMIN
23
- EDITOR
24
- AUTHOR
25
- CLIENT
26
- }
27
-
28
- enum ChangeType {
29
- CREATE
30
- UPDATE
31
- PUBLISH
32
- RESTORE
33
- DELETE
34
- }
35
-
36
- enum AuditEvent {
37
- login_success
38
- login_failed
39
- logout
40
- password_change
41
- password_reset_request
42
- password_reset_complete
43
- totp_enabled
44
- totp_disabled
45
- api_key_created
46
- api_key_revoked
47
- document_created
48
- document_updated
49
- document_published
50
- document_deleted
51
- media_uploaded
52
- media_deleted
53
- user_created
54
- user_updated
55
- user_deactivated
56
- settings_changed
57
- version_restored
58
- export_requested
59
- import_completed
60
- }
61
-
62
- enum NotificationType {
63
- DOCUMENT_PUBLISHED
64
- DOCUMENT_ASSIGNED
65
- REVIEW_REQUESTED
66
- REVIEW_APPROVED
67
- COMMENT_ADDED
68
- SYSTEM_ALERT
69
- WORKFLOW_STEP
70
- }
71
-
72
- enum OrderStatus {
73
- PENDING
74
- CONFIRMED
75
- PROCESSING
76
- SHIPPED
77
- DELIVERED
78
- CANCELLED
79
- REFUNDED
80
- }
81
-
82
- enum PaymentStatus {
83
- PENDING
84
- AUTHORIZED
85
- CAPTURED
86
- FAILED
87
- REFUNDED
88
- PARTIALLY_REFUNDED
89
- }
90
-
91
- enum WorkflowStage {
92
- DRAFT
93
- IN_REVIEW
94
- APPROVED
95
- PUBLISHED
96
- ARCHIVED
97
- }
98
-
99
- enum DiscountType {
100
- PERCENTAGE
101
- FIXED_AMOUNT
102
- FREE_SHIPPING
103
- }
104
-
105
- enum ProductType {
106
- PHYSICAL
107
- DIGITAL
108
- SUBSCRIPTION
109
- BUNDLE
110
- }
111
-
112
- // ─── Models ─────────────────────────────────────────────────────────
113
-
114
- model User {
115
- id String @id @default(cuid())
116
- email String @unique
117
- name String
118
- avatarUrl String?
119
- role UserRole @default(AUTHOR)
120
- passwordHash String?
121
- totpSecret String?
122
- totpEnabled Boolean @default(false)
123
- backupCodes Json?
124
- authProvider String?
125
- isActive Boolean @default(true)
126
- isApproved Boolean @default(false)
127
- emailVerified Boolean @default(false)
128
- lastLoginAt DateTime?
129
- createdAt DateTime @default(now())
130
- updatedAt DateTime @updatedAt
131
-
132
- sessions Session[]
133
- oauthAccounts OAuthAccount[]
134
- apiKeys ApiKey[]
135
- documents Document[] @relation("CreatedDocuments")
136
- updatedDocuments Document[] @relation("UpdatedDocuments")
137
- versions Version[]
138
- media Media[]
139
- contentLocks ContentLock[]
140
- notifications InAppNotification[]
141
- contentTemplates ContentTemplate[]
142
- workflowAssigned WorkflowState[]
143
- passwordResetTokens PasswordResetToken[]
144
-
145
- @@map("actuate_users")
146
- }
147
-
148
- model OAuthAccount {
149
- id String @id @default(cuid())
150
- userId String
151
- provider String
152
- providerAccountId String
153
- accessToken String?
154
- refreshToken String?
155
- expiresAt DateTime?
156
- createdAt DateTime @default(now())
157
-
158
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
159
-
160
- @@unique([provider, providerAccountId])
161
- @@map("actuate_oauth_accounts")
162
- }
163
-
164
- model Session {
165
- id String @id @default(cuid())
166
- userId String
167
- token String @unique
168
- expiresAt DateTime
169
- revokedAt DateTime?
170
- ipAddress String?
171
- userAgent String?
172
- fingerprintHash String?
173
- createdAt DateTime @default(now())
174
-
175
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
176
-
177
- @@index([userId])
178
- @@index([expiresAt])
179
- @@map("actuate_sessions")
180
- }
181
-
182
- model ApiKey {
183
- id String @id @default(cuid())
184
- name String
185
- keyHash String @unique
186
- keyPrefix String
187
- userId String
188
- scopes Json
189
- ipRestrictions Json?
190
- expiresAt DateTime?
191
- lastUsedAt DateTime?
192
- revokedAt DateTime?
193
- createdAt DateTime @default(now())
194
-
195
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
196
-
197
- @@map("actuate_api_keys")
198
- }
199
-
200
- model AuditLog {
201
- id String @id @default(cuid())
202
- event String
203
- userId String?
204
- ipAddress String?
205
- userAgent String?
206
- details Json?
207
- timestamp DateTime @default(now())
208
-
209
- @@index([event])
210
- @@index([userId])
211
- @@index([timestamp])
212
- @@map("actuate_audit_logs")
213
- }
214
-
215
- model Folder {
216
- id String @id @default(cuid())
217
- name String
218
- scope String
219
- parentId String?
220
- position Int @default(0)
221
- createdAt DateTime @default(now())
222
- updatedAt DateTime @updatedAt
223
-
224
- parent Folder? @relation("FolderTree", fields: [parentId], references: [id], onDelete: Cascade)
225
- children Folder[] @relation("FolderTree")
226
-
227
- documents Document[]
228
- media Media[]
229
-
230
- @@index([scope])
231
- @@index([parentId])
232
- @@map("actuate_folders")
233
- }
234
-
235
- model Document {
236
- id String @id @default(cuid())
237
- collection String
238
- title String?
239
- slug String?
240
- data Json
241
- status DocumentStatus @default(DRAFT)
242
- locale String?
243
- localeGroupId String?
244
- createdById String
245
- updatedById String
246
- publishedAt DateTime?
247
- scheduledAt DateTime?
248
- scheduledUnpublishAt DateTime?
249
- deletedAt DateTime?
250
- searchVector String?
251
- plainText String?
252
- contentHash String?
253
- structuredData Json?
254
- contentGraph Json?
255
- siteId String?
256
- templateId String?
257
- workflowStage WorkflowStage @default(DRAFT)
258
- reviewerId String?
259
- reviewNote String?
260
- folderId String?
261
- createdAt DateTime @default(now())
262
- updatedAt DateTime @updatedAt
263
-
264
- createdBy User @relation("CreatedDocuments", fields: [createdById], references: [id])
265
- updatedBy User @relation("UpdatedDocuments", fields: [updatedById], references: [id])
266
- folder Folder? @relation(fields: [folderId], references: [id], onDelete: SetNull)
267
- versions Version[]
268
- mediaUsages MediaUsage[]
269
- contentLocks ContentLock[]
270
-
271
- @@unique([collection, slug])
272
- @@index([collection])
273
- @@index([status])
274
- @@index([deletedAt])
275
- @@index([publishedAt])
276
- @@index([folderId])
277
- @@index([scheduledAt])
278
- @@index([localeGroupId])
279
- @@index([createdById])
280
- @@map("actuate_documents")
281
- }
282
-
283
- model Version {
284
- id String @id @default(cuid())
285
- documentId String
286
- data Json
287
- changedById String
288
- changeType ChangeType
289
- createdAt DateTime @default(now())
290
-
291
- document Document @relation(fields: [documentId], references: [id], onDelete: Cascade)
292
- changedBy User @relation(fields: [changedById], references: [id])
293
-
294
- @@index([documentId])
295
- @@map("actuate_versions")
296
- }
297
-
298
- model Media {
299
- id String @id @default(cuid())
300
- filename String
301
- storageKey String @unique
302
- mimeType String
303
- fileSize Int
304
- width Int?
305
- height Int?
306
- altText String?
307
- title String?
308
- uploadedById String
309
- focalPointX Float?
310
- focalPointY Float?
311
- blurHash String?
312
- aiAltText String?
313
- aiTags Json?
314
- aiDescription String?
315
- folderId String?
316
- createdAt DateTime @default(now())
317
- updatedAt DateTime @updatedAt
318
-
319
- uploadedBy User @relation(fields: [uploadedById], references: [id])
320
- folder Folder? @relation(fields: [folderId], references: [id], onDelete: SetNull)
321
- mediaUsages MediaUsage[]
322
-
323
- @@index([folderId])
324
- @@map("actuate_media")
325
- }
326
-
327
- model MediaUsage {
328
- id String @id @default(cuid())
329
- mediaId String
330
- documentId String
331
- fieldName String
332
- createdAt DateTime @default(now())
333
-
334
- media Media @relation(fields: [mediaId], references: [id], onDelete: Cascade)
335
- document Document @relation(fields: [documentId], references: [id], onDelete: Cascade)
336
-
337
- @@unique([mediaId, documentId, fieldName])
338
- @@index([documentId])
339
- @@map("actuate_media_usages")
340
- }
341
-
342
- model ContentLock {
343
- id String @id @default(cuid())
344
- documentId String
345
- userId String
346
- lockedAt DateTime @default(now())
347
- expiresAt DateTime
348
-
349
- document Document @relation(fields: [documentId], references: [id], onDelete: Cascade)
350
- user User @relation(fields: [userId], references: [id])
351
-
352
- @@map("actuate_content_locks")
353
- }
354
-
355
- model InAppNotification {
356
- id String @id @default(cuid())
357
- userId String
358
- type String
359
- title String
360
- message String?
361
- link String?
362
- read Boolean @default(false)
363
- createdAt DateTime @default(now())
364
-
365
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
366
-
367
- @@map("actuate_notifications")
368
- }
369
-
370
- model ContentTemplate {
371
- id String @id @default(cuid())
372
- name String
373
- collection String
374
- templateData Json
375
- createdById String
376
- createdAt DateTime @default(now())
377
- updatedAt DateTime @updatedAt
378
-
379
- createdBy User @relation(fields: [createdById], references: [id])
380
-
381
- @@map("actuate_content_templates")
382
- }
383
-
384
- model Site {
385
- id String @id @default(cuid())
386
- domain String @unique
387
- name String
388
- configOverrides Json?
389
- isDefault Boolean @default(false)
390
- createdAt DateTime @default(now())
391
- updatedAt DateTime @updatedAt
392
-
393
- @@map("actuate_sites")
394
- }
395
-
396
- model WorkflowState {
397
- id String @id @default(cuid())
398
- documentId String @unique
399
- currentStep Int @default(0)
400
- assignedToId String?
401
- status String @default("pending")
402
- definition Json
403
- createdAt DateTime @default(now())
404
- updatedAt DateTime @updatedAt
405
-
406
- assignedTo User? @relation(fields: [assignedToId], references: [id])
407
-
408
- @@map("actuate_workflow_states")
409
- }
410
-
411
- model Redirect {
412
- id String @id @default(cuid())
413
- source String
414
- destination String
415
- statusCode Int @default(301)
416
- isRegex Boolean @default(false)
417
- notes String?
418
- createdAt DateTime @default(now())
419
- updatedAt DateTime @updatedAt
420
-
421
- @@unique([source])
422
- @@map("actuate_redirects")
423
- }
424
-
425
- model FormSubmission {
426
- id String @id @default(cuid())
427
- formId String
428
- data Json
429
- attribution Json?
430
- status String @default("new")
431
- submittedAt DateTime @default(now())
432
- createdAt DateTime @default(now())
433
-
434
- @@index([formId])
435
- @@index([status])
436
- @@map("actuate_form_submissions")
437
- }
438
-
439
- model BackupRecord {
440
- id String @id @default(cuid())
441
- filename String
442
- storageKey String
443
- sizeBytes Int
444
- type String
445
- metadata Json?
446
- createdAt DateTime @default(now())
447
-
448
- @@map("actuate_backup_records")
449
- }
450
-
451
- model WebhookEndpoint {
452
- id String @id @default(cuid())
453
- url String
454
- events Json
455
- secret String
456
- active Boolean @default(true)
457
- name String?
458
- createdAt DateTime @default(now())
459
- updatedAt DateTime @updatedAt
460
-
461
- deliveries WebhookDeliveryLog[]
462
-
463
- @@map("actuate_webhook_endpoints")
464
- }
465
-
466
- model WebhookDeliveryLog {
467
- id String @id @default(cuid())
468
- endpointId String
469
- event String
470
- payload Json
471
- status String @default("pending")
472
- attempts Int @default(0)
473
- maxAttempts Int @default(3)
474
- lastAttemptAt DateTime?
475
- nextRetryAt DateTime?
476
- responseStatus Int?
477
- responseBody String?
478
- createdAt DateTime @default(now())
479
-
480
- endpoint WebhookEndpoint @relation(fields: [endpointId], references: [id], onDelete: Cascade)
481
-
482
- @@index([endpointId])
483
- @@index([status])
484
- @@index([nextRetryAt])
485
- @@map("actuate_webhook_deliveries")
486
- }
487
-
488
- model PasswordResetToken {
489
- id String @id @default(cuid())
490
- userId String
491
- tokenHash String
492
- expiresAt DateTime
493
- usedAt DateTime?
494
- createdAt DateTime @default(now())
495
-
496
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
497
-
498
- @@index([tokenHash])
499
- @@index([userId])
500
- @@map("actuate_password_reset_tokens")
501
- }
502
-
503
- model ScriptTag {
504
- id String @id @default(cuid())
505
- name String
506
- code String @db.Text
507
- placement String
508
- scope String
509
- targetPaths String[]
510
- priority Int @default(100)
511
- enabled Boolean @default(true)
512
- createdAt DateTime @default(now())
513
- updatedAt DateTime @updatedAt
514
-
515
- @@index([enabled])
516
- @@index([placement])
517
- @@map("actuate_script_tags")
518
- }
519
-
520
- model PageTemplate {
521
- id String @id @default(cuid())
522
- name String
523
- description String?
524
- category String @default("content")
525
- tree Json
526
- thumbnail String?
527
- builtIn Boolean @default(false)
528
- createdAt DateTime @default(now())
529
- updatedAt DateTime @updatedAt
530
-
531
- @@index([category])
532
- @@index([builtIn])
533
- @@map("actuate_page_templates")
534
- }
535
-
536
- model SavedSection {
537
- id String @id @default(cuid())
538
- name String
539
- description String?
540
- category String @default("content")
541
- tree Json
542
- thumbnail String?
543
- usageCount Int @default(0)
544
- createdAt DateTime @default(now())
545
- updatedAt DateTime @updatedAt
546
-
547
- @@index([category])
548
- @@map("actuate_saved_sections")
549
- }
1
+ generator client {
2
+ provider = "prisma-client"
3
+ output = "../generated"
4
+ previewFeatures = ["fullTextSearchPostgres"]
5
+ }
6
+
7
+ datasource db {
8
+ provider = "postgresql"
9
+ }
10
+
11
+ // ─── Enums ──────────────────────────────────────────────────────────
12
+
13
+ enum DocumentStatus {
14
+ DRAFT
15
+ PUBLISHED
16
+ ARCHIVED
17
+ SCHEDULED
18
+ SCHEDULED_UNPUBLISH
19
+ }
20
+
21
+ enum UserRole {
22
+ ADMIN
23
+ EDITOR
24
+ AUTHOR
25
+ CLIENT
26
+ }
27
+
28
+ enum ChangeType {
29
+ CREATE
30
+ UPDATE
31
+ PUBLISH
32
+ RESTORE
33
+ DELETE
34
+ }
35
+
36
+ enum AuditEvent {
37
+ login_success
38
+ login_failed
39
+ logout
40
+ password_change
41
+ password_reset_request
42
+ password_reset_complete
43
+ totp_enabled
44
+ totp_disabled
45
+ api_key_created
46
+ api_key_revoked
47
+ document_created
48
+ document_updated
49
+ document_published
50
+ document_deleted
51
+ media_uploaded
52
+ media_deleted
53
+ user_created
54
+ user_updated
55
+ user_deactivated
56
+ settings_changed
57
+ version_restored
58
+ export_requested
59
+ import_completed
60
+ }
61
+
62
+ enum NotificationType {
63
+ DOCUMENT_PUBLISHED
64
+ DOCUMENT_ASSIGNED
65
+ REVIEW_REQUESTED
66
+ REVIEW_APPROVED
67
+ COMMENT_ADDED
68
+ SYSTEM_ALERT
69
+ WORKFLOW_STEP
70
+ }
71
+
72
+ enum OrderStatus {
73
+ PENDING
74
+ CONFIRMED
75
+ PROCESSING
76
+ SHIPPED
77
+ DELIVERED
78
+ CANCELLED
79
+ REFUNDED
80
+ }
81
+
82
+ enum PaymentStatus {
83
+ PENDING
84
+ AUTHORIZED
85
+ CAPTURED
86
+ FAILED
87
+ REFUNDED
88
+ PARTIALLY_REFUNDED
89
+ }
90
+
91
+ enum WorkflowStage {
92
+ DRAFT
93
+ IN_REVIEW
94
+ APPROVED
95
+ PUBLISHED
96
+ ARCHIVED
97
+ }
98
+
99
+ enum DiscountType {
100
+ PERCENTAGE
101
+ FIXED_AMOUNT
102
+ FREE_SHIPPING
103
+ }
104
+
105
+ enum ProductType {
106
+ PHYSICAL
107
+ DIGITAL
108
+ SUBSCRIPTION
109
+ BUNDLE
110
+ }
111
+
112
+ // ─── Models ─────────────────────────────────────────────────────────
113
+
114
+ model User {
115
+ id String @id @default(cuid())
116
+ email String @unique
117
+ name String
118
+ avatarUrl String?
119
+ role UserRole @default(AUTHOR)
120
+ passwordHash String?
121
+ totpSecret String?
122
+ totpEnabled Boolean @default(false)
123
+ backupCodes Json?
124
+ authProvider String?
125
+ isActive Boolean @default(true)
126
+ isApproved Boolean @default(false)
127
+ emailVerified Boolean @default(false)
128
+ lastLoginAt DateTime?
129
+ createdAt DateTime @default(now())
130
+ updatedAt DateTime @updatedAt
131
+
132
+ sessions Session[]
133
+ oauthAccounts OAuthAccount[]
134
+ apiKeys ApiKey[]
135
+ documents Document[] @relation("CreatedDocuments")
136
+ updatedDocuments Document[] @relation("UpdatedDocuments")
137
+ versions Version[]
138
+ media Media[]
139
+ contentLocks ContentLock[]
140
+ notifications InAppNotification[]
141
+ contentTemplates ContentTemplate[]
142
+ workflowAssigned WorkflowState[]
143
+ passwordResetTokens PasswordResetToken[]
144
+
145
+ @@map("actuate_users")
146
+ }
147
+
148
+ model OAuthAccount {
149
+ id String @id @default(cuid())
150
+ userId String
151
+ provider String
152
+ providerAccountId String
153
+ accessToken String?
154
+ refreshToken String?
155
+ expiresAt DateTime?
156
+ createdAt DateTime @default(now())
157
+
158
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
159
+
160
+ @@unique([provider, providerAccountId])
161
+ @@map("actuate_oauth_accounts")
162
+ }
163
+
164
+ model Session {
165
+ id String @id @default(cuid())
166
+ userId String
167
+ token String @unique
168
+ expiresAt DateTime
169
+ revokedAt DateTime?
170
+ ipAddress String?
171
+ userAgent String?
172
+ fingerprintHash String?
173
+ createdAt DateTime @default(now())
174
+
175
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
176
+
177
+ @@index([userId])
178
+ @@index([expiresAt])
179
+ @@map("actuate_sessions")
180
+ }
181
+
182
+ model ApiKey {
183
+ id String @id @default(cuid())
184
+ name String
185
+ keyHash String @unique
186
+ keyPrefix String
187
+ userId String
188
+ scopes Json
189
+ ipRestrictions Json?
190
+ expiresAt DateTime?
191
+ lastUsedAt DateTime?
192
+ revokedAt DateTime?
193
+ createdAt DateTime @default(now())
194
+
195
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
196
+
197
+ @@map("actuate_api_keys")
198
+ }
199
+
200
+ model AuditLog {
201
+ id String @id @default(cuid())
202
+ event String
203
+ userId String?
204
+ ipAddress String?
205
+ userAgent String?
206
+ details Json?
207
+ timestamp DateTime @default(now())
208
+
209
+ @@index([event])
210
+ @@index([userId])
211
+ @@index([timestamp])
212
+ @@map("actuate_audit_logs")
213
+ }
214
+
215
+ model Folder {
216
+ id String @id @default(cuid())
217
+ name String
218
+ scope String
219
+ parentId String?
220
+ position Int @default(0)
221
+ createdAt DateTime @default(now())
222
+ updatedAt DateTime @updatedAt
223
+
224
+ parent Folder? @relation("FolderTree", fields: [parentId], references: [id], onDelete: Cascade)
225
+ children Folder[] @relation("FolderTree")
226
+
227
+ documents Document[]
228
+ media Media[]
229
+
230
+ @@index([scope])
231
+ @@index([parentId])
232
+ @@map("actuate_folders")
233
+ }
234
+
235
+ model Document {
236
+ id String @id @default(cuid())
237
+ collection String
238
+ title String?
239
+ slug String?
240
+ data Json
241
+ status DocumentStatus @default(DRAFT)
242
+ locale String?
243
+ localeGroupId String?
244
+ createdById String
245
+ updatedById String
246
+ publishedAt DateTime?
247
+ scheduledAt DateTime?
248
+ scheduledUnpublishAt DateTime?
249
+ deletedAt DateTime?
250
+ searchVector String?
251
+ plainText String?
252
+ contentHash String?
253
+ structuredData Json?
254
+ contentGraph Json?
255
+ siteId String?
256
+ templateId String?
257
+ workflowStage WorkflowStage @default(DRAFT)
258
+ reviewerId String?
259
+ reviewNote String?
260
+ folderId String?
261
+ createdAt DateTime @default(now())
262
+ updatedAt DateTime @updatedAt
263
+
264
+ createdBy User @relation("CreatedDocuments", fields: [createdById], references: [id])
265
+ updatedBy User @relation("UpdatedDocuments", fields: [updatedById], references: [id])
266
+ folder Folder? @relation(fields: [folderId], references: [id], onDelete: SetNull)
267
+ versions Version[]
268
+ mediaUsages MediaUsage[]
269
+ contentLocks ContentLock[]
270
+
271
+ @@unique([collection, slug])
272
+ @@index([collection])
273
+ @@index([status])
274
+ @@index([deletedAt])
275
+ @@index([publishedAt])
276
+ @@index([folderId])
277
+ @@index([scheduledAt])
278
+ @@index([localeGroupId])
279
+ @@index([createdById])
280
+ @@map("actuate_documents")
281
+ }
282
+
283
+ model Version {
284
+ id String @id @default(cuid())
285
+ documentId String
286
+ data Json
287
+ changedById String
288
+ changeType ChangeType
289
+ createdAt DateTime @default(now())
290
+
291
+ document Document @relation(fields: [documentId], references: [id], onDelete: Cascade)
292
+ changedBy User @relation(fields: [changedById], references: [id])
293
+
294
+ @@index([documentId])
295
+ @@map("actuate_versions")
296
+ }
297
+
298
+ model Media {
299
+ id String @id @default(cuid())
300
+ filename String
301
+ storageKey String @unique
302
+ mimeType String
303
+ fileSize Int
304
+ width Int?
305
+ height Int?
306
+ altText String?
307
+ title String?
308
+ uploadedById String
309
+ focalPointX Float?
310
+ focalPointY Float?
311
+ blurHash String?
312
+ aiAltText String?
313
+ aiTags Json?
314
+ aiDescription String?
315
+ folderId String?
316
+ createdAt DateTime @default(now())
317
+ updatedAt DateTime @updatedAt
318
+
319
+ uploadedBy User @relation(fields: [uploadedById], references: [id])
320
+ folder Folder? @relation(fields: [folderId], references: [id], onDelete: SetNull)
321
+ mediaUsages MediaUsage[]
322
+
323
+ @@index([folderId])
324
+ @@map("actuate_media")
325
+ }
326
+
327
+ model MediaUsage {
328
+ id String @id @default(cuid())
329
+ mediaId String
330
+ documentId String
331
+ fieldName String
332
+ createdAt DateTime @default(now())
333
+
334
+ media Media @relation(fields: [mediaId], references: [id], onDelete: Cascade)
335
+ document Document @relation(fields: [documentId], references: [id], onDelete: Cascade)
336
+
337
+ @@unique([mediaId, documentId, fieldName])
338
+ @@index([documentId])
339
+ @@map("actuate_media_usages")
340
+ }
341
+
342
+ model ContentLock {
343
+ id String @id @default(cuid())
344
+ documentId String
345
+ userId String
346
+ lockedAt DateTime @default(now())
347
+ expiresAt DateTime
348
+
349
+ document Document @relation(fields: [documentId], references: [id], onDelete: Cascade)
350
+ user User @relation(fields: [userId], references: [id])
351
+
352
+ @@map("actuate_content_locks")
353
+ }
354
+
355
+ model InAppNotification {
356
+ id String @id @default(cuid())
357
+ userId String
358
+ type String
359
+ title String
360
+ message String?
361
+ link String?
362
+ read Boolean @default(false)
363
+ createdAt DateTime @default(now())
364
+
365
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
366
+
367
+ @@map("actuate_notifications")
368
+ }
369
+
370
+ model ContentTemplate {
371
+ id String @id @default(cuid())
372
+ name String
373
+ collection String
374
+ templateData Json
375
+ createdById String
376
+ createdAt DateTime @default(now())
377
+ updatedAt DateTime @updatedAt
378
+
379
+ createdBy User @relation(fields: [createdById], references: [id])
380
+
381
+ @@map("actuate_content_templates")
382
+ }
383
+
384
+ model Site {
385
+ id String @id @default(cuid())
386
+ domain String @unique
387
+ name String
388
+ configOverrides Json?
389
+ isDefault Boolean @default(false)
390
+ createdAt DateTime @default(now())
391
+ updatedAt DateTime @updatedAt
392
+
393
+ @@map("actuate_sites")
394
+ }
395
+
396
+ model WorkflowState {
397
+ id String @id @default(cuid())
398
+ documentId String @unique
399
+ currentStep Int @default(0)
400
+ assignedToId String?
401
+ status String @default("pending")
402
+ definition Json
403
+ createdAt DateTime @default(now())
404
+ updatedAt DateTime @updatedAt
405
+
406
+ assignedTo User? @relation(fields: [assignedToId], references: [id])
407
+
408
+ @@map("actuate_workflow_states")
409
+ }
410
+
411
+ model Redirect {
412
+ id String @id @default(cuid())
413
+ source String
414
+ destination String
415
+ statusCode Int @default(301)
416
+ isRegex Boolean @default(false)
417
+ notes String?
418
+ createdAt DateTime @default(now())
419
+ updatedAt DateTime @updatedAt
420
+
421
+ @@unique([source])
422
+ @@map("actuate_redirects")
423
+ }
424
+
425
+ model FormSubmission {
426
+ id String @id @default(cuid())
427
+ formId String
428
+ data Json
429
+ attribution Json?
430
+ status String @default("new")
431
+ submittedAt DateTime @default(now())
432
+ createdAt DateTime @default(now())
433
+
434
+ @@index([formId])
435
+ @@index([status])
436
+ @@map("actuate_form_submissions")
437
+ }
438
+
439
+ model BackupRecord {
440
+ id String @id @default(cuid())
441
+ filename String
442
+ storageKey String
443
+ sizeBytes Int
444
+ type String
445
+ metadata Json?
446
+ createdAt DateTime @default(now())
447
+
448
+ @@map("actuate_backup_records")
449
+ }
450
+
451
+ model WebhookEndpoint {
452
+ id String @id @default(cuid())
453
+ url String
454
+ events Json
455
+ secret String
456
+ active Boolean @default(true)
457
+ name String?
458
+ createdAt DateTime @default(now())
459
+ updatedAt DateTime @updatedAt
460
+
461
+ deliveries WebhookDeliveryLog[]
462
+
463
+ @@map("actuate_webhook_endpoints")
464
+ }
465
+
466
+ model WebhookDeliveryLog {
467
+ id String @id @default(cuid())
468
+ endpointId String
469
+ event String
470
+ payload Json
471
+ status String @default("pending")
472
+ attempts Int @default(0)
473
+ maxAttempts Int @default(3)
474
+ lastAttemptAt DateTime?
475
+ nextRetryAt DateTime?
476
+ responseStatus Int?
477
+ responseBody String?
478
+ createdAt DateTime @default(now())
479
+
480
+ endpoint WebhookEndpoint @relation(fields: [endpointId], references: [id], onDelete: Cascade)
481
+
482
+ @@index([endpointId])
483
+ @@index([status])
484
+ @@index([nextRetryAt])
485
+ @@map("actuate_webhook_deliveries")
486
+ }
487
+
488
+ model PasswordResetToken {
489
+ id String @id @default(cuid())
490
+ userId String
491
+ tokenHash String
492
+ expiresAt DateTime
493
+ usedAt DateTime?
494
+ createdAt DateTime @default(now())
495
+
496
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
497
+
498
+ @@index([tokenHash])
499
+ @@index([userId])
500
+ @@map("actuate_password_reset_tokens")
501
+ }
502
+
503
+ model ScriptTag {
504
+ id String @id @default(cuid())
505
+ name String
506
+ code String @db.Text
507
+ placement String
508
+ scope String
509
+ targetPaths String[]
510
+ priority Int @default(100)
511
+ enabled Boolean @default(true)
512
+ createdAt DateTime @default(now())
513
+ updatedAt DateTime @updatedAt
514
+
515
+ @@index([enabled])
516
+ @@index([placement])
517
+ @@map("actuate_script_tags")
518
+ }
519
+
520
+ model PageTemplate {
521
+ id String @id @default(cuid())
522
+ name String
523
+ description String?
524
+ category String @default("content")
525
+ tree Json
526
+ thumbnail String?
527
+ builtIn Boolean @default(false)
528
+ createdAt DateTime @default(now())
529
+ updatedAt DateTime @updatedAt
530
+
531
+ @@index([category])
532
+ @@index([builtIn])
533
+ @@map("actuate_page_templates")
534
+ }
535
+
536
+ model SavedSection {
537
+ id String @id @default(cuid())
538
+ name String
539
+ description String?
540
+ category String @default("content")
541
+ tree Json
542
+ thumbnail String?
543
+ usageCount Int @default(0)
544
+ createdAt DateTime @default(now())
545
+ updatedAt DateTime @updatedAt
546
+
547
+ @@index([category])
548
+ @@map("actuate_saved_sections")
549
+ }