@actuate-media/cms-core 0.51.0 → 0.51.1

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.
@@ -5,13 +5,19 @@ CREATE SCHEMA IF NOT EXISTS "public";
5
5
  CREATE TYPE "DocumentStatus" AS ENUM ('DRAFT', 'PUBLISHED', 'ARCHIVED', 'SCHEDULED', 'SCHEDULED_UNPUBLISH');
6
6
 
7
7
  -- CreateEnum
8
- CREATE TYPE "UserRole" AS ENUM ('ADMIN', 'EDITOR', 'AUTHOR', 'CLIENT');
8
+ CREATE TYPE "UserRole" AS ENUM ('ADMIN', 'EDITOR', 'AUTHOR', 'CLIENT', 'OWNER', 'VIEWER');
9
9
 
10
10
  -- CreateEnum
11
- CREATE TYPE "ChangeType" AS ENUM ('CREATE', 'UPDATE', 'PUBLISH', 'RESTORE');
11
+ CREATE TYPE "InviteStatus" AS ENUM ('PENDING', 'ACCEPTED', 'EXPIRED', 'CANCELLED');
12
12
 
13
13
  -- CreateEnum
14
- CREATE TYPE "AuditEvent" AS ENUM ('login_success', 'login_failed', 'logout', 'password_change', 'password_reset_request', 'password_reset_complete', 'totp_enabled', 'totp_disabled', 'api_key_created', 'api_key_revoked', 'document_created', 'document_updated', 'document_published', 'document_deleted', 'media_uploaded', 'media_deleted', 'user_created', 'user_updated', 'user_deactivated', 'settings_changed', 'export_requested', 'import_completed');
14
+ CREATE TYPE "ChangeType" AS ENUM ('CREATE', 'UPDATE', 'PUBLISH', 'RESTORE', 'DELETE');
15
+
16
+ -- CreateEnum
17
+ CREATE TYPE "AuditEvent" AS ENUM ('login_success', 'login_failed', 'logout', 'password_change', 'password_reset_request', 'password_reset_complete', 'totp_enabled', 'totp_disabled', 'api_key_created', 'api_key_revoked', 'document_created', 'document_updated', 'document_published', 'document_deleted', 'media_uploaded', 'media_deleted', 'user_created', 'user_updated', 'user_deactivated', 'settings_changed', 'version_restored', 'export_requested', 'import_completed');
18
+
19
+ -- CreateEnum
20
+ CREATE TYPE "ContentIssueType" AS ENUM ('MISSING_META_DESCRIPTION', 'MISSING_ALT_TEXT', 'BROKEN_INTERNAL_LINK', 'OUTDATED_CONTENT');
15
21
 
16
22
  -- CreateEnum
17
23
  CREATE TYPE "NotificationType" AS ENUM ('DOCUMENT_PUBLISHED', 'DOCUMENT_ASSIGNED', 'REVIEW_REQUESTED', 'REVIEW_APPROVED', 'COMMENT_ADDED', 'SYSTEM_ALERT', 'WORKFLOW_STEP');
@@ -22,12 +28,30 @@ CREATE TYPE "OrderStatus" AS ENUM ('PENDING', 'CONFIRMED', 'PROCESSING', 'SHIPPE
22
28
  -- CreateEnum
23
29
  CREATE TYPE "PaymentStatus" AS ENUM ('PENDING', 'AUTHORIZED', 'CAPTURED', 'FAILED', 'REFUNDED', 'PARTIALLY_REFUNDED');
24
30
 
31
+ -- CreateEnum
32
+ CREATE TYPE "WorkflowStage" AS ENUM ('DRAFT', 'IN_REVIEW', 'APPROVED', 'PUBLISHED', 'ARCHIVED');
33
+
25
34
  -- CreateEnum
26
35
  CREATE TYPE "DiscountType" AS ENUM ('PERCENTAGE', 'FIXED_AMOUNT', 'FREE_SHIPPING');
27
36
 
28
37
  -- CreateEnum
29
38
  CREATE TYPE "ProductType" AS ENUM ('PHYSICAL', 'DIGITAL', 'SUBSCRIPTION', 'BUNDLE');
30
39
 
40
+ -- CreateEnum
41
+ CREATE TYPE "MediaStatus" AS ENUM ('PROCESSING', 'READY', 'FAILED');
42
+
43
+ -- CreateEnum
44
+ CREATE TYPE "SeoAuditStatus" AS ENUM ('RUNNING', 'COMPLETED', 'FAILED');
45
+
46
+ -- CreateEnum
47
+ CREATE TYPE "SeoIssueSeverity" AS ENUM ('critical', 'warning', 'info');
48
+
49
+ -- CreateEnum
50
+ CREATE TYPE "SeoIssueStatus" AS ENUM ('open', 'ignored', 'resolved', 'recurring');
51
+
52
+ -- CreateEnum
53
+ CREATE TYPE "SeoIssueCategory" AS ENUM ('content', 'technical', 'redirects', 'media', 'performance', 'schema', 'social', 'indexing');
54
+
31
55
  -- CreateTable
32
56
  CREATE TABLE "actuate_users" (
33
57
  "id" TEXT NOT NULL,
@@ -37,6 +61,8 @@ CREATE TABLE "actuate_users" (
37
61
  "role" "UserRole" NOT NULL DEFAULT 'AUTHOR',
38
62
  "passwordHash" TEXT,
39
63
  "totpSecret" TEXT,
64
+ "totpEnabled" BOOLEAN NOT NULL DEFAULT false,
65
+ "backupCodes" JSONB,
40
66
  "authProvider" TEXT,
41
67
  "isActive" BOOLEAN NOT NULL DEFAULT true,
42
68
  "isApproved" BOOLEAN NOT NULL DEFAULT false,
@@ -44,6 +70,14 @@ CREATE TABLE "actuate_users" (
44
70
  "lastLoginAt" TIMESTAMP(3),
45
71
  "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
46
72
  "updatedAt" TIMESTAMP(3) NOT NULL,
73
+ "suspendedAt" TIMESTAMP(3),
74
+ "lockedAt" TIMESTAMP(3),
75
+ "forcePasswordReset" BOOLEAN NOT NULL DEFAULT false,
76
+ "mfaRequired" BOOLEAN NOT NULL DEFAULT false,
77
+ "failedLoginCount" INTEGER NOT NULL DEFAULT 0,
78
+ "lastActiveAt" TIMESTAMP(3),
79
+ "invitedById" TEXT,
80
+ "acceptedInviteAt" TIMESTAMP(3),
47
81
 
48
82
  CONSTRAINT "actuate_users_pkey" PRIMARY KEY ("id")
49
83
  );
@@ -107,10 +141,25 @@ CREATE TABLE "actuate_audit_logs" (
107
141
  CONSTRAINT "actuate_audit_logs_pkey" PRIMARY KEY ("id")
108
142
  );
109
143
 
144
+ -- CreateTable
145
+ CREATE TABLE "actuate_folders" (
146
+ "id" TEXT NOT NULL,
147
+ "name" TEXT NOT NULL,
148
+ "scope" TEXT NOT NULL,
149
+ "parentId" TEXT,
150
+ "position" INTEGER NOT NULL DEFAULT 0,
151
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
152
+ "updatedAt" TIMESTAMP(3) NOT NULL,
153
+
154
+ CONSTRAINT "actuate_folders_pkey" PRIMARY KEY ("id")
155
+ );
156
+
110
157
  -- CreateTable
111
158
  CREATE TABLE "actuate_documents" (
112
159
  "id" TEXT NOT NULL,
113
160
  "collection" TEXT NOT NULL,
161
+ "title" TEXT,
162
+ "slug" TEXT,
114
163
  "data" JSONB NOT NULL,
115
164
  "status" "DocumentStatus" NOT NULL DEFAULT 'DRAFT',
116
165
  "locale" TEXT,
@@ -128,6 +177,10 @@ CREATE TABLE "actuate_documents" (
128
177
  "contentGraph" JSONB,
129
178
  "siteId" TEXT,
130
179
  "templateId" TEXT,
180
+ "workflowStage" "WorkflowStage" NOT NULL DEFAULT 'DRAFT',
181
+ "reviewerId" TEXT,
182
+ "reviewNote" TEXT,
183
+ "folderId" TEXT,
131
184
  "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
132
185
  "updatedAt" TIMESTAMP(3) NOT NULL,
133
186
 
@@ -164,8 +217,21 @@ CREATE TABLE "actuate_media" (
164
217
  "aiAltText" TEXT,
165
218
  "aiTags" JSONB,
166
219
  "aiDescription" TEXT,
220
+ "folderId" TEXT,
167
221
  "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
168
222
  "updatedAt" TIMESTAMP(3) NOT NULL,
223
+ "originalFileName" TEXT,
224
+ "caption" TEXT,
225
+ "description" TEXT,
226
+ "focusKeyword" TEXT,
227
+ "tags" JSONB,
228
+ "publicUrl" TEXT,
229
+ "storageProvider" TEXT,
230
+ "durationSeconds" DOUBLE PRECISION,
231
+ "thumbnailUrl" TEXT,
232
+ "responsiveVariants" JSONB,
233
+ "status" "MediaStatus" NOT NULL DEFAULT 'READY',
234
+ "deletedAt" TIMESTAMP(3),
169
235
 
170
236
  CONSTRAINT "actuate_media_pkey" PRIMARY KEY ("id")
171
237
  );
@@ -254,25 +320,180 @@ CREATE TABLE "actuate_redirects" (
254
320
  "statusCode" INTEGER NOT NULL DEFAULT 301,
255
321
  "isRegex" BOOLEAN NOT NULL DEFAULT false,
256
322
  "notes" TEXT,
323
+ "enabled" BOOLEAN NOT NULL DEFAULT true,
324
+ "priority" INTEGER NOT NULL DEFAULT 0,
325
+ "preserveQuery" BOOLEAN NOT NULL DEFAULT false,
326
+ "source_kind" TEXT NOT NULL DEFAULT 'manual',
327
+ "hits" INTEGER NOT NULL DEFAULT 0,
328
+ "lastHitAt" TIMESTAMP(3),
329
+ "createdById" TEXT,
257
330
  "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
258
331
  "updatedAt" TIMESTAMP(3) NOT NULL,
259
332
 
260
333
  CONSTRAINT "actuate_redirects_pkey" PRIMARY KEY ("id")
261
334
  );
262
335
 
336
+ -- CreateTable
337
+ CREATE TABLE "actuate_seo_audit_runs" (
338
+ "id" TEXT NOT NULL,
339
+ "status" "SeoAuditStatus" NOT NULL DEFAULT 'RUNNING',
340
+ "scope" TEXT NOT NULL DEFAULT 'full',
341
+ "startedById" TEXT,
342
+ "startedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
343
+ "finishedAt" TIMESTAMP(3),
344
+ "siteScoreBefore" INTEGER,
345
+ "siteScoreAfter" INTEGER,
346
+ "pagesScanned" INTEGER NOT NULL DEFAULT 0,
347
+ "issuesFound" INTEGER NOT NULL DEFAULT 0,
348
+ "criticalCount" INTEGER NOT NULL DEFAULT 0,
349
+ "warningCount" INTEGER NOT NULL DEFAULT 0,
350
+ "infoCount" INTEGER NOT NULL DEFAULT 0,
351
+ "errorMessage" TEXT,
352
+ "metadata" JSONB,
353
+
354
+ CONSTRAINT "actuate_seo_audit_runs_pkey" PRIMARY KEY ("id")
355
+ );
356
+
357
+ -- CreateTable
358
+ CREATE TABLE "actuate_seo_issues" (
359
+ "id" TEXT NOT NULL,
360
+ "auditRunId" TEXT,
361
+ "issueKey" TEXT NOT NULL,
362
+ "entityType" TEXT,
363
+ "entityId" TEXT,
364
+ "entityTitle" TEXT,
365
+ "url" TEXT,
366
+ "severity" "SeoIssueSeverity" NOT NULL,
367
+ "category" "SeoIssueCategory" NOT NULL,
368
+ "type" TEXT NOT NULL,
369
+ "title" TEXT NOT NULL,
370
+ "description" TEXT,
371
+ "impact" TEXT,
372
+ "recommendation" TEXT,
373
+ "status" "SeoIssueStatus" NOT NULL DEFAULT 'open',
374
+ "fixable" BOOLEAN NOT NULL DEFAULT false,
375
+ "fixActionType" TEXT,
376
+ "relatedEntityIds" JSONB,
377
+ "source" TEXT NOT NULL DEFAULT 'audit',
378
+ "firstDetectedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
379
+ "lastDetectedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
380
+ "resolvedAt" TIMESTAMP(3),
381
+ "resolvedById" TEXT,
382
+ "metadata" JSONB,
383
+
384
+ CONSTRAINT "actuate_seo_issues_pkey" PRIMARY KEY ("id")
385
+ );
386
+
387
+ -- CreateTable
388
+ CREATE TABLE "actuate_redirect_404_hits" (
389
+ "id" TEXT NOT NULL,
390
+ "path" TEXT NOT NULL,
391
+ "hits" INTEGER NOT NULL DEFAULT 1,
392
+ "referrer" TEXT,
393
+ "resolvedAt" TIMESTAMP(3),
394
+ "firstSeenAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
395
+ "lastSeenAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
396
+
397
+ CONSTRAINT "actuate_redirect_404_hits_pkey" PRIMARY KEY ("id")
398
+ );
399
+
400
+ -- CreateTable
401
+ CREATE TABLE "actuate_redirect_suggestions" (
402
+ "id" TEXT NOT NULL,
403
+ "fromPath" TEXT NOT NULL,
404
+ "toPath" TEXT NOT NULL,
405
+ "confidence" INTEGER NOT NULL DEFAULT 0,
406
+ "reason" TEXT,
407
+ "status" TEXT NOT NULL DEFAULT 'open',
408
+ "source" TEXT NOT NULL DEFAULT 'ai-404-recovery',
409
+ "metadata" JSONB,
410
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
411
+ "updatedAt" TIMESTAMP(3) NOT NULL,
412
+
413
+ CONSTRAINT "actuate_redirect_suggestions_pkey" PRIMARY KEY ("id")
414
+ );
415
+
416
+ -- CreateTable
417
+ CREATE TABLE "actuate_form_schema_versions" (
418
+ "id" TEXT NOT NULL,
419
+ "formId" TEXT NOT NULL,
420
+ "version" INTEGER NOT NULL,
421
+ "fields" JSONB NOT NULL,
422
+ "notes" TEXT,
423
+ "createdById" TEXT,
424
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
425
+
426
+ CONSTRAINT "actuate_form_schema_versions_pkey" PRIMARY KEY ("id")
427
+ );
428
+
263
429
  -- CreateTable
264
430
  CREATE TABLE "actuate_form_submissions" (
265
431
  "id" TEXT NOT NULL,
432
+ "entryNumber" INTEGER,
266
433
  "formId" TEXT NOT NULL,
434
+ "schemaVersionId" TEXT,
267
435
  "data" JSONB NOT NULL,
436
+ "normalizedData" JSONB,
268
437
  "attribution" JSONB,
438
+ "senderName" TEXT,
439
+ "senderEmail" TEXT,
440
+ "senderPhone" TEXT,
441
+ "preview" TEXT,
269
442
  "status" TEXT NOT NULL DEFAULT 'new',
443
+ "unread" BOOLEAN NOT NULL DEFAULT true,
444
+ "starred" BOOLEAN NOT NULL DEFAULT false,
445
+ "archived" BOOLEAN NOT NULL DEFAULT false,
446
+ "spamStatus" TEXT NOT NULL DEFAULT 'clean',
447
+ "ipAddressHash" TEXT,
448
+ "userAgent" TEXT,
449
+ "referrer" TEXT,
450
+ "pageUrl" TEXT,
451
+ "utmSource" TEXT,
452
+ "utmMedium" TEXT,
453
+ "utmCampaign" TEXT,
270
454
  "submittedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
455
+ "readAt" TIMESTAMP(3),
456
+ "archivedAt" TIMESTAMP(3),
271
457
  "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
458
+ "updatedAt" TIMESTAMP(3) NOT NULL,
272
459
 
273
460
  CONSTRAINT "actuate_form_submissions_pkey" PRIMARY KEY ("id")
274
461
  );
275
462
 
463
+ -- CreateTable
464
+ CREATE TABLE "actuate_form_submission_files" (
465
+ "id" TEXT NOT NULL,
466
+ "submissionId" TEXT NOT NULL,
467
+ "fieldKey" TEXT NOT NULL,
468
+ "mediaAssetId" TEXT,
469
+ "fileName" TEXT NOT NULL,
470
+ "mimeType" TEXT NOT NULL,
471
+ "sizeBytes" INTEGER NOT NULL,
472
+ "storageKey" TEXT NOT NULL,
473
+ "publicUrl" TEXT,
474
+ "secureDownloadUrl" TEXT,
475
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
476
+
477
+ CONSTRAINT "actuate_form_submission_files_pkey" PRIMARY KEY ("id")
478
+ );
479
+
480
+ -- CreateTable
481
+ CREATE TABLE "actuate_form_webhooks" (
482
+ "id" TEXT NOT NULL,
483
+ "formId" TEXT NOT NULL,
484
+ "url" TEXT NOT NULL,
485
+ "secret" TEXT NOT NULL,
486
+ "enabled" BOOLEAN NOT NULL DEFAULT true,
487
+ "events" JSONB NOT NULL,
488
+ "retryCount" INTEGER NOT NULL DEFAULT 0,
489
+ "lastDeliveryAt" TIMESTAMP(3),
490
+ "lastDeliveryStatus" TEXT,
491
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
492
+ "updatedAt" TIMESTAMP(3) NOT NULL,
493
+
494
+ CONSTRAINT "actuate_form_webhooks_pkey" PRIMARY KEY ("id")
495
+ );
496
+
276
497
  -- CreateTable
277
498
  CREATE TABLE "actuate_backup_records" (
278
499
  "id" TEXT NOT NULL,
@@ -286,6 +507,143 @@ CREATE TABLE "actuate_backup_records" (
286
507
  CONSTRAINT "actuate_backup_records_pkey" PRIMARY KEY ("id")
287
508
  );
288
509
 
510
+ -- CreateTable
511
+ CREATE TABLE "actuate_webhook_endpoints" (
512
+ "id" TEXT NOT NULL,
513
+ "url" TEXT NOT NULL,
514
+ "events" JSONB NOT NULL,
515
+ "secret" TEXT NOT NULL,
516
+ "active" BOOLEAN NOT NULL DEFAULT true,
517
+ "name" TEXT,
518
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
519
+ "updatedAt" TIMESTAMP(3) NOT NULL,
520
+
521
+ CONSTRAINT "actuate_webhook_endpoints_pkey" PRIMARY KEY ("id")
522
+ );
523
+
524
+ -- CreateTable
525
+ CREATE TABLE "actuate_webhook_deliveries" (
526
+ "id" TEXT NOT NULL,
527
+ "endpointId" TEXT NOT NULL,
528
+ "event" TEXT NOT NULL,
529
+ "payload" JSONB NOT NULL,
530
+ "status" TEXT NOT NULL DEFAULT 'pending',
531
+ "attempts" INTEGER NOT NULL DEFAULT 0,
532
+ "maxAttempts" INTEGER NOT NULL DEFAULT 3,
533
+ "lastAttemptAt" TIMESTAMP(3),
534
+ "nextRetryAt" TIMESTAMP(3),
535
+ "responseStatus" INTEGER,
536
+ "responseBody" TEXT,
537
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
538
+
539
+ CONSTRAINT "actuate_webhook_deliveries_pkey" PRIMARY KEY ("id")
540
+ );
541
+
542
+ -- CreateTable
543
+ CREATE TABLE "actuate_password_reset_tokens" (
544
+ "id" TEXT NOT NULL,
545
+ "userId" TEXT NOT NULL,
546
+ "tokenHash" TEXT NOT NULL,
547
+ "expiresAt" TIMESTAMP(3) NOT NULL,
548
+ "usedAt" TIMESTAMP(3),
549
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
550
+
551
+ CONSTRAINT "actuate_password_reset_tokens_pkey" PRIMARY KEY ("id")
552
+ );
553
+
554
+ -- CreateTable
555
+ CREATE TABLE "actuate_invites" (
556
+ "id" TEXT NOT NULL,
557
+ "email" TEXT NOT NULL,
558
+ "role" "UserRole" NOT NULL,
559
+ "status" "InviteStatus" NOT NULL DEFAULT 'PENDING',
560
+ "tokenHash" TEXT NOT NULL,
561
+ "message" TEXT,
562
+ "invitedByUserId" TEXT,
563
+ "acceptedUserId" TEXT,
564
+ "expiresAt" TIMESTAMP(3) NOT NULL,
565
+ "acceptedAt" TIMESTAMP(3),
566
+ "cancelledAt" TIMESTAMP(3),
567
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
568
+ "updatedAt" TIMESTAMP(3) NOT NULL,
569
+
570
+ CONSTRAINT "actuate_invites_pkey" PRIMARY KEY ("id")
571
+ );
572
+
573
+ -- CreateTable
574
+ CREATE TABLE "actuate_script_tags" (
575
+ "id" TEXT NOT NULL,
576
+ "name" TEXT NOT NULL,
577
+ "code" TEXT NOT NULL,
578
+ "placement" TEXT NOT NULL,
579
+ "scope" TEXT NOT NULL,
580
+ "targetPaths" TEXT[],
581
+ "priority" INTEGER NOT NULL DEFAULT 100,
582
+ "enabled" BOOLEAN NOT NULL DEFAULT true,
583
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
584
+ "updatedAt" TIMESTAMP(3) NOT NULL,
585
+
586
+ CONSTRAINT "actuate_script_tags_pkey" PRIMARY KEY ("id")
587
+ );
588
+
589
+ -- CreateTable
590
+ CREATE TABLE "actuate_page_templates" (
591
+ "id" TEXT NOT NULL,
592
+ "name" TEXT NOT NULL,
593
+ "description" TEXT,
594
+ "category" TEXT NOT NULL DEFAULT 'content',
595
+ "tree" JSONB NOT NULL,
596
+ "thumbnail" TEXT,
597
+ "builtIn" BOOLEAN NOT NULL DEFAULT false,
598
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
599
+ "updatedAt" TIMESTAMP(3) NOT NULL,
600
+
601
+ CONSTRAINT "actuate_page_templates_pkey" PRIMARY KEY ("id")
602
+ );
603
+
604
+ -- CreateTable
605
+ CREATE TABLE "actuate_saved_sections" (
606
+ "id" TEXT NOT NULL,
607
+ "name" TEXT NOT NULL,
608
+ "description" TEXT,
609
+ "category" TEXT NOT NULL DEFAULT 'content',
610
+ "tree" JSONB NOT NULL,
611
+ "thumbnail" TEXT,
612
+ "usageCount" INTEGER NOT NULL DEFAULT 0,
613
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
614
+ "updatedAt" TIMESTAMP(3) NOT NULL,
615
+
616
+ CONSTRAINT "actuate_saved_sections_pkey" PRIMARY KEY ("id")
617
+ );
618
+
619
+ -- CreateTable
620
+ CREATE TABLE "actuate_api_request_metrics" (
621
+ "id" TEXT NOT NULL,
622
+ "bucketStart" TIMESTAMP(3) NOT NULL,
623
+ "route" TEXT NOT NULL,
624
+ "statusBucket" TEXT NOT NULL,
625
+ "count" INTEGER NOT NULL DEFAULT 0,
626
+ "sumLatencyMs" DOUBLE PRECISION NOT NULL DEFAULT 0,
627
+ "maxLatencyMs" DOUBLE PRECISION NOT NULL DEFAULT 0,
628
+ "latencyHistogram" JSONB NOT NULL,
629
+ "updatedAt" TIMESTAMP(3) NOT NULL,
630
+
631
+ CONSTRAINT "actuate_api_request_metrics_pkey" PRIMARY KEY ("id")
632
+ );
633
+
634
+ -- CreateTable
635
+ CREATE TABLE "actuate_content_issues" (
636
+ "id" TEXT NOT NULL,
637
+ "documentId" TEXT NOT NULL,
638
+ "type" "ContentIssueType" NOT NULL,
639
+ "count" INTEGER NOT NULL DEFAULT 1,
640
+ "details" JSONB,
641
+ "firstSeenAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
642
+ "lastSeenAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
643
+
644
+ CONSTRAINT "actuate_content_issues_pkey" PRIMARY KEY ("id")
645
+ );
646
+
289
647
  -- CreateIndex
290
648
  CREATE UNIQUE INDEX "actuate_users_email_key" ON "actuate_users"("email");
291
649
 
@@ -295,6 +653,12 @@ CREATE UNIQUE INDEX "actuate_oauth_accounts_provider_providerAccountId_key" ON "
295
653
  -- CreateIndex
296
654
  CREATE UNIQUE INDEX "actuate_sessions_token_key" ON "actuate_sessions"("token");
297
655
 
656
+ -- CreateIndex
657
+ CREATE INDEX "actuate_sessions_userId_idx" ON "actuate_sessions"("userId");
658
+
659
+ -- CreateIndex
660
+ CREATE INDEX "actuate_sessions_expiresAt_idx" ON "actuate_sessions"("expiresAt");
661
+
298
662
  -- CreateIndex
299
663
  CREATE UNIQUE INDEX "actuate_api_keys_keyHash_key" ON "actuate_api_keys"("keyHash");
300
664
 
@@ -307,6 +671,12 @@ CREATE INDEX "actuate_audit_logs_userId_idx" ON "actuate_audit_logs"("userId");
307
671
  -- CreateIndex
308
672
  CREATE INDEX "actuate_audit_logs_timestamp_idx" ON "actuate_audit_logs"("timestamp");
309
673
 
674
+ -- CreateIndex
675
+ CREATE INDEX "actuate_folders_scope_idx" ON "actuate_folders"("scope");
676
+
677
+ -- CreateIndex
678
+ CREATE INDEX "actuate_folders_parentId_idx" ON "actuate_folders"("parentId");
679
+
310
680
  -- CreateIndex
311
681
  CREATE INDEX "actuate_documents_collection_idx" ON "actuate_documents"("collection");
312
682
 
@@ -319,24 +689,180 @@ CREATE INDEX "actuate_documents_deletedAt_idx" ON "actuate_documents"("deletedAt
319
689
  -- CreateIndex
320
690
  CREATE INDEX "actuate_documents_publishedAt_idx" ON "actuate_documents"("publishedAt");
321
691
 
692
+ -- CreateIndex
693
+ CREATE INDEX "actuate_documents_folderId_idx" ON "actuate_documents"("folderId");
694
+
695
+ -- CreateIndex
696
+ CREATE INDEX "actuate_documents_scheduledAt_idx" ON "actuate_documents"("scheduledAt");
697
+
698
+ -- CreateIndex
699
+ CREATE INDEX "actuate_documents_localeGroupId_idx" ON "actuate_documents"("localeGroupId");
700
+
701
+ -- CreateIndex
702
+ CREATE INDEX "actuate_documents_createdById_idx" ON "actuate_documents"("createdById");
703
+
704
+ -- CreateIndex
705
+ CREATE UNIQUE INDEX "actuate_documents_collection_slug_key" ON "actuate_documents"("collection", "slug");
706
+
707
+ -- CreateIndex
708
+ CREATE INDEX "actuate_versions_documentId_idx" ON "actuate_versions"("documentId");
709
+
322
710
  -- CreateIndex
323
711
  CREATE UNIQUE INDEX "actuate_media_storageKey_key" ON "actuate_media"("storageKey");
324
712
 
713
+ -- CreateIndex
714
+ CREATE INDEX "actuate_media_folderId_idx" ON "actuate_media"("folderId");
715
+
716
+ -- CreateIndex
717
+ CREATE INDEX "actuate_media_deletedAt_idx" ON "actuate_media"("deletedAt");
718
+
719
+ -- CreateIndex
720
+ CREATE INDEX "actuate_media_mimeType_idx" ON "actuate_media"("mimeType");
721
+
722
+ -- CreateIndex
723
+ CREATE INDEX "actuate_media_usages_documentId_idx" ON "actuate_media_usages"("documentId");
724
+
725
+ -- CreateIndex
726
+ CREATE UNIQUE INDEX "actuate_media_usages_mediaId_documentId_fieldName_key" ON "actuate_media_usages"("mediaId", "documentId", "fieldName");
727
+
325
728
  -- CreateIndex
326
729
  CREATE UNIQUE INDEX "actuate_sites_domain_key" ON "actuate_sites"("domain");
327
730
 
328
731
  -- CreateIndex
329
732
  CREATE UNIQUE INDEX "actuate_workflow_states_documentId_key" ON "actuate_workflow_states"("documentId");
330
733
 
734
+ -- CreateIndex
735
+ CREATE INDEX "actuate_redirects_enabled_idx" ON "actuate_redirects"("enabled");
736
+
737
+ -- CreateIndex
738
+ CREATE INDEX "actuate_redirects_lastHitAt_idx" ON "actuate_redirects"("lastHitAt");
739
+
331
740
  -- CreateIndex
332
741
  CREATE UNIQUE INDEX "actuate_redirects_source_key" ON "actuate_redirects"("source");
333
742
 
743
+ -- CreateIndex
744
+ CREATE INDEX "actuate_seo_audit_runs_status_idx" ON "actuate_seo_audit_runs"("status");
745
+
746
+ -- CreateIndex
747
+ CREATE INDEX "actuate_seo_audit_runs_startedAt_idx" ON "actuate_seo_audit_runs"("startedAt");
748
+
749
+ -- CreateIndex
750
+ CREATE INDEX "actuate_seo_issues_auditRunId_idx" ON "actuate_seo_issues"("auditRunId");
751
+
752
+ -- CreateIndex
753
+ CREATE INDEX "actuate_seo_issues_status_idx" ON "actuate_seo_issues"("status");
754
+
755
+ -- CreateIndex
756
+ CREATE INDEX "actuate_seo_issues_severity_idx" ON "actuate_seo_issues"("severity");
757
+
758
+ -- CreateIndex
759
+ CREATE INDEX "actuate_seo_issues_category_idx" ON "actuate_seo_issues"("category");
760
+
761
+ -- CreateIndex
762
+ CREATE INDEX "actuate_seo_issues_issueKey_idx" ON "actuate_seo_issues"("issueKey");
763
+
764
+ -- CreateIndex
765
+ CREATE INDEX "actuate_redirect_404_hits_lastSeenAt_idx" ON "actuate_redirect_404_hits"("lastSeenAt");
766
+
767
+ -- CreateIndex
768
+ CREATE UNIQUE INDEX "actuate_redirect_404_hits_path_key" ON "actuate_redirect_404_hits"("path");
769
+
770
+ -- CreateIndex
771
+ CREATE INDEX "actuate_redirect_suggestions_status_idx" ON "actuate_redirect_suggestions"("status");
772
+
773
+ -- CreateIndex
774
+ CREATE INDEX "actuate_redirect_suggestions_fromPath_idx" ON "actuate_redirect_suggestions"("fromPath");
775
+
776
+ -- CreateIndex
777
+ CREATE INDEX "actuate_form_schema_versions_formId_idx" ON "actuate_form_schema_versions"("formId");
778
+
779
+ -- CreateIndex
780
+ CREATE UNIQUE INDEX "actuate_form_schema_versions_formId_version_key" ON "actuate_form_schema_versions"("formId", "version");
781
+
334
782
  -- CreateIndex
335
783
  CREATE INDEX "actuate_form_submissions_formId_idx" ON "actuate_form_submissions"("formId");
336
784
 
337
785
  -- CreateIndex
338
786
  CREATE INDEX "actuate_form_submissions_status_idx" ON "actuate_form_submissions"("status");
339
787
 
788
+ -- CreateIndex
789
+ CREATE INDEX "actuate_form_submissions_unread_idx" ON "actuate_form_submissions"("unread");
790
+
791
+ -- CreateIndex
792
+ CREATE INDEX "actuate_form_submissions_starred_idx" ON "actuate_form_submissions"("starred");
793
+
794
+ -- CreateIndex
795
+ CREATE INDEX "actuate_form_submissions_archived_idx" ON "actuate_form_submissions"("archived");
796
+
797
+ -- CreateIndex
798
+ CREATE INDEX "actuate_form_submissions_spamStatus_idx" ON "actuate_form_submissions"("spamStatus");
799
+
800
+ -- CreateIndex
801
+ CREATE INDEX "actuate_form_submissions_submittedAt_idx" ON "actuate_form_submissions"("submittedAt");
802
+
803
+ -- CreateIndex
804
+ CREATE INDEX "actuate_form_submissions_senderEmail_idx" ON "actuate_form_submissions"("senderEmail");
805
+
806
+ -- CreateIndex
807
+ CREATE INDEX "actuate_form_submission_files_submissionId_idx" ON "actuate_form_submission_files"("submissionId");
808
+
809
+ -- CreateIndex
810
+ CREATE INDEX "actuate_form_webhooks_formId_idx" ON "actuate_form_webhooks"("formId");
811
+
812
+ -- CreateIndex
813
+ CREATE INDEX "actuate_webhook_deliveries_endpointId_idx" ON "actuate_webhook_deliveries"("endpointId");
814
+
815
+ -- CreateIndex
816
+ CREATE INDEX "actuate_webhook_deliveries_status_idx" ON "actuate_webhook_deliveries"("status");
817
+
818
+ -- CreateIndex
819
+ CREATE INDEX "actuate_webhook_deliveries_nextRetryAt_idx" ON "actuate_webhook_deliveries"("nextRetryAt");
820
+
821
+ -- CreateIndex
822
+ CREATE INDEX "actuate_password_reset_tokens_tokenHash_idx" ON "actuate_password_reset_tokens"("tokenHash");
823
+
824
+ -- CreateIndex
825
+ CREATE INDEX "actuate_password_reset_tokens_userId_idx" ON "actuate_password_reset_tokens"("userId");
826
+
827
+ -- CreateIndex
828
+ CREATE INDEX "actuate_invites_email_idx" ON "actuate_invites"("email");
829
+
830
+ -- CreateIndex
831
+ CREATE INDEX "actuate_invites_tokenHash_idx" ON "actuate_invites"("tokenHash");
832
+
833
+ -- CreateIndex
834
+ CREATE INDEX "actuate_invites_status_idx" ON "actuate_invites"("status");
835
+
836
+ -- CreateIndex
837
+ CREATE INDEX "actuate_script_tags_enabled_idx" ON "actuate_script_tags"("enabled");
838
+
839
+ -- CreateIndex
840
+ CREATE INDEX "actuate_script_tags_placement_idx" ON "actuate_script_tags"("placement");
841
+
842
+ -- CreateIndex
843
+ CREATE INDEX "actuate_page_templates_category_idx" ON "actuate_page_templates"("category");
844
+
845
+ -- CreateIndex
846
+ CREATE INDEX "actuate_page_templates_builtIn_idx" ON "actuate_page_templates"("builtIn");
847
+
848
+ -- CreateIndex
849
+ CREATE INDEX "actuate_saved_sections_category_idx" ON "actuate_saved_sections"("category");
850
+
851
+ -- CreateIndex
852
+ CREATE INDEX "actuate_api_request_metrics_bucketStart_idx" ON "actuate_api_request_metrics"("bucketStart");
853
+
854
+ -- CreateIndex
855
+ CREATE UNIQUE INDEX "actuate_api_request_metrics_bucketStart_route_statusBucket_key" ON "actuate_api_request_metrics"("bucketStart", "route", "statusBucket");
856
+
857
+ -- CreateIndex
858
+ CREATE INDEX "actuate_content_issues_type_idx" ON "actuate_content_issues"("type");
859
+
860
+ -- CreateIndex
861
+ CREATE INDEX "actuate_content_issues_documentId_idx" ON "actuate_content_issues"("documentId");
862
+
863
+ -- CreateIndex
864
+ CREATE UNIQUE INDEX "actuate_content_issues_documentId_type_key" ON "actuate_content_issues"("documentId", "type");
865
+
340
866
  -- AddForeignKey
341
867
  ALTER TABLE "actuate_oauth_accounts" ADD CONSTRAINT "actuate_oauth_accounts_userId_fkey" FOREIGN KEY ("userId") REFERENCES "actuate_users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
342
868
 
@@ -346,12 +872,18 @@ ALTER TABLE "actuate_sessions" ADD CONSTRAINT "actuate_sessions_userId_fkey" FOR
346
872
  -- AddForeignKey
347
873
  ALTER TABLE "actuate_api_keys" ADD CONSTRAINT "actuate_api_keys_userId_fkey" FOREIGN KEY ("userId") REFERENCES "actuate_users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
348
874
 
875
+ -- AddForeignKey
876
+ ALTER TABLE "actuate_folders" ADD CONSTRAINT "actuate_folders_parentId_fkey" FOREIGN KEY ("parentId") REFERENCES "actuate_folders"("id") ON DELETE CASCADE ON UPDATE CASCADE;
877
+
349
878
  -- AddForeignKey
350
879
  ALTER TABLE "actuate_documents" ADD CONSTRAINT "actuate_documents_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "actuate_users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
351
880
 
352
881
  -- AddForeignKey
353
882
  ALTER TABLE "actuate_documents" ADD CONSTRAINT "actuate_documents_updatedById_fkey" FOREIGN KEY ("updatedById") REFERENCES "actuate_users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
354
883
 
884
+ -- AddForeignKey
885
+ ALTER TABLE "actuate_documents" ADD CONSTRAINT "actuate_documents_folderId_fkey" FOREIGN KEY ("folderId") REFERENCES "actuate_folders"("id") ON DELETE SET NULL ON UPDATE CASCADE;
886
+
355
887
  -- AddForeignKey
356
888
  ALTER TABLE "actuate_versions" ADD CONSTRAINT "actuate_versions_documentId_fkey" FOREIGN KEY ("documentId") REFERENCES "actuate_documents"("id") ON DELETE CASCADE ON UPDATE CASCADE;
357
889
 
@@ -361,6 +893,9 @@ ALTER TABLE "actuate_versions" ADD CONSTRAINT "actuate_versions_changedById_fkey
361
893
  -- AddForeignKey
362
894
  ALTER TABLE "actuate_media" ADD CONSTRAINT "actuate_media_uploadedById_fkey" FOREIGN KEY ("uploadedById") REFERENCES "actuate_users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
363
895
 
896
+ -- AddForeignKey
897
+ ALTER TABLE "actuate_media" ADD CONSTRAINT "actuate_media_folderId_fkey" FOREIGN KEY ("folderId") REFERENCES "actuate_folders"("id") ON DELETE SET NULL ON UPDATE CASCADE;
898
+
364
899
  -- AddForeignKey
365
900
  ALTER TABLE "actuate_media_usages" ADD CONSTRAINT "actuate_media_usages_mediaId_fkey" FOREIGN KEY ("mediaId") REFERENCES "actuate_media"("id") ON DELETE CASCADE ON UPDATE CASCADE;
366
901
 
@@ -382,3 +917,25 @@ ALTER TABLE "actuate_content_templates" ADD CONSTRAINT "actuate_content_template
382
917
  -- AddForeignKey
383
918
  ALTER TABLE "actuate_workflow_states" ADD CONSTRAINT "actuate_workflow_states_assignedToId_fkey" FOREIGN KEY ("assignedToId") REFERENCES "actuate_users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
384
919
 
920
+ -- AddForeignKey
921
+ ALTER TABLE "actuate_seo_issues" ADD CONSTRAINT "actuate_seo_issues_auditRunId_fkey" FOREIGN KEY ("auditRunId") REFERENCES "actuate_seo_audit_runs"("id") ON DELETE SET NULL ON UPDATE CASCADE;
922
+
923
+ -- AddForeignKey
924
+ ALTER TABLE "actuate_form_submission_files" ADD CONSTRAINT "actuate_form_submission_files_submissionId_fkey" FOREIGN KEY ("submissionId") REFERENCES "actuate_form_submissions"("id") ON DELETE CASCADE ON UPDATE CASCADE;
925
+
926
+ -- AddForeignKey
927
+ ALTER TABLE "actuate_webhook_deliveries" ADD CONSTRAINT "actuate_webhook_deliveries_endpointId_fkey" FOREIGN KEY ("endpointId") REFERENCES "actuate_webhook_endpoints"("id") ON DELETE CASCADE ON UPDATE CASCADE;
928
+
929
+ -- AddForeignKey
930
+ ALTER TABLE "actuate_password_reset_tokens" ADD CONSTRAINT "actuate_password_reset_tokens_userId_fkey" FOREIGN KEY ("userId") REFERENCES "actuate_users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
931
+
932
+ -- AddForeignKey
933
+ ALTER TABLE "actuate_content_issues" ADD CONSTRAINT "actuate_content_issues_documentId_fkey" FOREIGN KEY ("documentId") REFERENCES "actuate_documents"("id") ON DELETE CASCADE ON UPDATE CASCADE;
934
+
935
+ -- Full-text search: GIN index on documents for fast ts_vector queries.
936
+ -- Raw index (not modeled in schema.prisma); consumed by src/search/index.ts.
937
+ -- Kept in the baseline so a fresh `migrate deploy` reproduces search acceleration.
938
+ CREATE INDEX IF NOT EXISTS "idx_actuate_documents_fts"
939
+ ON "actuate_documents"
940
+ USING GIN (to_tsvector('english', COALESCE("title", '') || ' ' || COALESCE("plainText", '')));
941
+