46 KiB

Complete Schema Reference

This page provides a comprehensive listing of all 33 models across both Prisma and Drizzle ORMs.

Models Summary

Group Model Table Name Description ORM
Auth & Users User users User accounts with role-based access control Prisma
RefreshToken refresh_tokens JWT refresh token storage Prisma
Influence Campaign campaigns Advocacy campaigns with feature flags Prisma
Representative representatives Cached representative data from Represent API Prisma
CampaignEmail campaign_emails Email tracking and delivery logs Prisma
RepresentativeResponse representative_responses Response wall submissions with moderation Prisma
ResponseUpvote response_upvotes Upvote tracking with deduplication Prisma
CustomRecipient custom_recipients Custom email targets for campaigns Prisma
PostalCodeCache postal_code_cache Postal code geocoding cache Prisma
EmailLog email_logs Global email audit trail Prisma
EmailVerification email_verifications Email verification tokens Prisma
Call calls Phone call tracking Prisma
Map — Locations Location locations Building-level address data with geocoding Prisma
Address addresses Unit-level data with support levels Prisma
LocationHistory location_history Audit trail for location changes Prisma
Map — Shifts & Cuts Shift shifts Volunteer shifts with scheduling Prisma
ShiftSignup shift_signups Shift signup tracking Prisma
Cut cuts GeoJSON polygon overlays for map filtering Prisma
MapSettings map_settings Singleton for map configuration Prisma
Canvassing CanvassSession canvass_sessions Canvassing session lifecycle Prisma
CanvassVisit canvass_visits Visit recording with outcomes Prisma
TrackingSession tracking_sessions GPS tracking sessions Prisma
TrackPoint track_points GPS breadcrumb trail Prisma
Email Templates EmailTemplate email_templates Email template master records Prisma
EmailTemplateVariable email_template_variables Template variable definitions Prisma
EmailTemplateVersion email_template_versions Template version history Prisma
EmailTemplateTestLog email_template_test_logs Test email audit logs Prisma
Landing Pages LandingPage landing_pages GrapesJS editor output with MkDocs export Prisma
PageBlock page_blocks Reusable block library Prisma
Site Settings SiteSettings site_settings Global site configuration singleton Prisma
Media videos videos Video library with metadata Drizzle
compilations compilations Video compilation tracking Drizzle
jobs jobs Job queue with resource management Drizzle

Total: 33 models (30 Prisma + 3 Drizzle)


Auth & Users

User

Table: users Description: User accounts with role-based access control, temporary user support, and audit tracking.

Field Type Required Default Description
id String cuid() Primary key
email String Unique email address
password String bcrypt hashed password (12+ chars policy)
name String null User display name
phone String null Phone number
role UserRole USER Role: SUPER_ADMIN, INFLUENCE_ADMIN, MAP_ADMIN, USER, TEMP
status UserStatus ACTIVE Status: ACTIVE, INACTIVE, SUSPENDED, EXPIRED
permissions Json null Granular per-app permissions object
createdVia UserCreatedVia STANDARD Creation source: ADMIN, PUBLIC_SHIFT_SIGNUP, STANDARD
expiresAt DateTime null Expiration date for TEMP users
expireDays Int null Days until expiration for TEMP users
lastLoginAt DateTime null Last login timestamp
emailVerified Boolean false Email verification status
createdAt DateTime now() Creation timestamp
updatedAt DateTime Auto Last update timestamp

Indexes:

  • Unique: email

Relations (33 total):

  • refreshTokens → RefreshToken[]
  • campaignsCreated → Campaign[]
  • campaignEmails → CampaignEmail[]
  • responses → RepresentativeResponse[]
  • responseUpvotes → ResponseUpvote[]
  • shiftSignups → ShiftSignup[]
  • locationsCreated → Location[]
  • locationsUpdated → Location[]
  • addressesCreated → Address[]
  • addressesUpdated → Address[]
  • locationEdits → LocationHistory[]
  • cutsCreated → Cut[]
  • canvassVisits → CanvassVisit[]
  • canvassSessions → CanvassSession[]
  • trackingSessions → TrackingSession[]
  • templatesCreated → EmailTemplate[]
  • templatesUpdated → EmailTemplate[]
  • templateVersionsCreated → EmailTemplateVersion[]
  • templateTestsSent → EmailTemplateTestLog[]

RefreshToken

Table: refresh_tokens Description: JWT refresh token storage with expiration tracking.

Field Type Required Default Description
id String cuid() Primary key
token String JWT refresh token (unique)
userId String Foreign key to User
expiresAt DateTime Token expiration timestamp
createdAt DateTime now() Creation timestamp

Indexes:

  • Unique: token
  • Foreign key: userId

Relations:

  • user → User (onDelete: Cascade)

Influence

Campaign

Table: campaigns Description: Advocacy campaigns with 12 feature flags and government-level targeting.

Field Type Required Default Description
id String cuid() Primary key
slug String URL-friendly slug (unique)
title String Campaign title
description String null Campaign description (long text)
emailSubject String Default email subject line
emailBody String Default email body (long text)
callToAction String null Call-to-action text (long text)
coverPhoto String null Cover photo URL
status CampaignStatus DRAFT Status: DRAFT, ACTIVE, PAUSED, ARCHIVED
allowSmtpEmail Boolean true Allow SMTP email sending
allowMailtoLink Boolean true Allow mailto: links
collectUserInfo Boolean true Collect user information
showEmailCount Boolean true Show email sent count
showCallCount Boolean true Show call made count
allowEmailEditing Boolean false Allow users to edit email content
allowCustomRecipients Boolean false Allow custom email recipients
showResponseWall Boolean false Show public response wall
highlightCampaign Boolean false Highlight on campaign list page
targetGovernmentLevels GovernmentLevel[] [] Target levels: FEDERAL, PROVINCIAL, MUNICIPAL, SCHOOL_BOARD
createdByUserId String null Foreign key to User (creator)
createdByUserEmail String null Creator email (denormalized)
createdByUserName String null Creator name (denormalized)
createdAt DateTime now() Creation timestamp
updatedAt DateTime Auto Last update timestamp

Indexes:

  • Unique: slug

Relations:

  • createdByUser → User (onDelete: SetNull)
  • emails → CampaignEmail[]
  • responses → RepresentativeResponse[]
  • customRecipients → CustomRecipient[]
  • calls → Call[]

Representative

Table: representatives Description: Cached representative data from Represent API.

Field Type Required Default Description
id String cuid() Primary key
postalCode String Canadian postal code (indexed)
name String null Representative name
email String null Representative email
districtName String null Electoral district name
electedOffice String null Office title
partyName String null Political party
representativeSetName String null Representative set from Represent API
url String null Official website URL
photoUrl String null Photo URL
offices Json null Array of office contact info objects
cachedAt DateTime now() Cache timestamp

Indexes:

  • Non-unique: postalCode

Relations: None (standalone cache)

CampaignEmail

Table: campaign_emails Description: Email tracking and delivery logs for campaign emails.

Field Type Required Default Description
id String cuid() Primary key
campaignId String Foreign key to Campaign
campaignSlug String Denormalized campaign slug
userId String null Foreign key to User (sender)
userEmail String null Sender email
userName String null Sender name
userPostalCode String null Sender postal code
recipientEmail String Recipient email address
recipientName String null Recipient name
recipientTitle String null Recipient title
recipientLevel GovernmentLevel null Government level
emailMethod EmailMethod Method: SMTP, MAILTO
subject String Email subject line
message String Email message body (long text)
status CampaignEmailStatus SENT Status: QUEUED, SENT, FAILED, CLICKED, USER_INFO_CAPTURED
senderIp String null Sender IP address
sentAt DateTime now() Send timestamp

Indexes:

  • Foreign key: campaignId
  • Non-unique: campaignSlug

Relations:

  • campaign → Campaign (onDelete: Cascade)
  • user → User (onDelete: SetNull)

RepresentativeResponse

Table: representative_responses Description: Response wall submissions with moderation workflow.

Field Type Required Default Description
id String cuid() Primary key
campaignId String Foreign key to Campaign
campaignSlug String Denormalized campaign slug
representativeName String Representative name
representativeTitle String null Representative title
representativeLevel GovernmentLevel Government level
representativeEmail String null Representative email
responseType ResponseType Type: EMAIL, LETTER, PHONE_CALL, MEETING, SOCIAL_MEDIA, OTHER
responseText String Response text (long text)
userComment String null User comment (long text)
screenshotUrl String null Screenshot URL
submittedByUserId String null Foreign key to User
submittedByName String null Submitter name
submittedByEmail String null Submitter email
isAnonymous Boolean false Anonymous submission flag
status ResponseStatus PENDING Status: PENDING, APPROVED, REJECTED
isVerified Boolean false Email verification status
verificationToken String null Verification token
verificationSentAt DateTime null Verification email timestamp
verifiedAt DateTime null Verification timestamp
verifiedBy String null Email address that verified
upvoteCount Int 0 Upvote count (denormalized)
submittedIp String null Submitter IP address
createdAt DateTime now() Creation timestamp
updatedAt DateTime Auto Last update timestamp

Indexes:

  • Foreign key: campaignId
  • Non-unique: campaignSlug

Relations:

  • campaign → Campaign (onDelete: Cascade)
  • submittedByUser → User (onDelete: SetNull)
  • upvotes → ResponseUpvote[]

ResponseUpvote

Table: response_upvotes Description: Upvote tracking with deduplication by user ID and IP address.

Field Type Required Default Description
id String cuid() Primary key
responseId String Foreign key to RepresentativeResponse
userId String null Foreign key to User
userEmail String null User email (for guest upvotes)
upvotedIp String null Upvoter IP address

Indexes:

  • Unique: [responseId, userId] (prevent duplicate upvotes from logged-in users)
  • Unique: [responseId, upvotedIp] (prevent duplicate upvotes from same IP)

Relations:

  • response → RepresentativeResponse (onDelete: Cascade)
  • user → User (onDelete: SetNull)

CustomRecipient

Table: custom_recipients Description: Custom email targets for campaigns (when allowCustomRecipients enabled).

Field Type Required Default Description
id String cuid() Primary key
campaignId String Foreign key to Campaign
campaignSlug String Denormalized campaign slug
recipientName String Recipient name
recipientEmail String Recipient email address
recipientTitle String null Recipient title
recipientOrganization String null Recipient organization
notes String null Admin notes (long text)
isActive Boolean true Active status
createdAt DateTime now() Creation timestamp
updatedAt DateTime Auto Last update timestamp

Indexes:

  • Foreign key: campaignId

Relations:

  • campaign → Campaign (onDelete: Cascade)

PostalCodeCache

Table: postal_code_cache Description: Postal code geocoding cache for centroid lookups.

Field Type Required Default Description
id String cuid() Primary key
postalCode String Canadian postal code (unique)
city String null City name
province String null Province code (e.g., "AB")
centroidLat Decimal(10,8) null Centroid latitude
centroidLng Decimal(11,8) null Centroid longitude
lastUpdated DateTime now() Last cache update

Indexes:

  • Unique: postalCode

Relations: None (standalone cache)

EmailLog

Table: email_logs Description: Global email audit trail (all email types).

Field Type Required Default Description
id String cuid() Primary key
recipientEmail String Recipient email address
senderName String Sender name
senderEmail String Sender email address
subject String null Email subject line
message String null Email message body (long text)
postalCode String null Sender postal code
status String "sent" Status: sent, failed, previewed
senderIp String null Sender IP address
sentAt DateTime now() Send timestamp

Indexes: None

Relations: None (audit log only)

EmailVerification

Table: email_verifications Description: Email verification tokens for response wall submissions.

Field Type Required Default Description
id String cuid() Primary key
token String Verification token (unique)
email String Email address to verify
tempCampaignData String null Temporary campaign data JSON (long text)
createdAt DateTime now() Creation timestamp
expiresAt DateTime Token expiration timestamp
used Boolean false Token used flag

Indexes:

  • Unique: token

Relations: None (standalone)

Call

Table: calls Description: Phone call tracking for advocacy campaigns.

Field Type Required Default Description
id String cuid() Primary key
representativeName String Representative name
representativeTitle String null Representative title
phoneNumber String Phone number called
officeType String null Office type (constituency, legislative, etc.)
callerName String null Caller name
callerEmail String null Caller email
postalCode String null Caller postal code
campaignId String null Foreign key to Campaign
campaignSlug String null Denormalized campaign slug
callerIp String null Caller IP address
calledAt DateTime now() Call timestamp

Indexes:

  • Foreign key: campaignId

Relations:

  • campaign → Campaign (onDelete: SetNull)

Map — Locations

Location

Table: locations Description: Building-level address data with geocoding and NAR integration.

Field Type Required Default Description
id String cuid() Primary key
latitude Decimal(10,8) Latitude coordinate (required)
longitude Decimal(11,8) Longitude coordinate (required)
address String Base street address (no unit number)
postalCode String null Canadian postal code
province String null Province code (e.g., "AB")
federalDistrict String null Federal electoral district name
buildingUse Int null NAR BU_USE: 1=Residential, 2=Partial, 3=Non-Residential, 4=Unknown
locGuid String null NAR LOC_GUID (unique)
buildingType BuildingType SINGLE_FAMILY Type: SINGLE_FAMILY, MULTI_UNIT, MIXED_USE, COMMERCIAL
totalUnits Int 1 Total units in building
buildingNotes String null Access codes, manager contact (long text)
geocodeConfidence Int null Geocoding confidence (0-100)
geocodeProvider GeocodeProvider null Provider: GOOGLE, MAPBOX, NOMINATIM, PHOTON, LOCATIONIQ, ARCGIS, UNKNOWN
createdByUserId String null Foreign key to User (creator)
updatedByUserId String null Foreign key to User (last updater)
createdAt DateTime now() Creation timestamp
updatedAt DateTime Auto Last update timestamp

Indexes:

  • Unique: locGuid
  • Composite: [latitude, longitude] (spatial queries)
  • Non-unique: postalCode

Relations:

  • createdByUser → User (onDelete: SetNull)
  • updatedByUser → User (onDelete: SetNull)
  • addresses → Address[]
  • history → LocationHistory[]

Address

Table: addresses Description: Unit-level data with support levels and canvassing information.

Field Type Required Default Description
id String cuid() Primary key
locationId String Foreign key to Location
unitNumber String null Unit/apartment number
addrGuid String null NAR ADDR_GUID (unique)
firstName String null Occupant first name
lastName String null Occupant last name
email String null Occupant email
phone String null Occupant phone
supportLevel SupportLevel null Support level: 1, 2, 3, 4
sign Boolean false Sign requested flag
signSize String null Sign size
notes String null Canvassing notes (long text)
createdByUserId String null Foreign key to User (creator)
updatedByUserId String null Foreign key to User (last updater)
createdAt DateTime now() Creation timestamp
updatedAt DateTime Auto Last update timestamp

Indexes:

  • Unique: addrGuid
  • Foreign key: locationId
  • Composite: [locationId, unitNumber] (unit lookups)

Relations:

  • location → Location (onDelete: Cascade)
  • createdByUser → User (onDelete: SetNull)
  • updatedByUser → User (onDelete: SetNull)
  • canvassVisits → CanvassVisit[]

LocationHistory

Table: location_history Description: Audit trail for location changes with action types.

Field Type Required Default Description
id String cuid() Primary key
locationId String Foreign key to Location
userId String null Foreign key to User
action LocationHistoryAction Action: CREATED, UPDATED, GEOCODED, BULK_GEOCODED, MOVED_ON_MAP, IMPORTED_CSV, IMPORTED_NAR
field String null Field name that changed
oldValue String null Old value (long text)
newValue String null New value (long text)
metadata Json null Provider, confidence, etc.
createdAt DateTime now() Timestamp

Indexes:

  • Foreign key: locationId
  • Foreign key: userId
  • Non-unique: createdAt (temporal queries)

Relations:

  • location → Location (onDelete: Cascade)
  • user → User (onDelete: SetNull)

Map — Shifts & Cuts

Shift

Table: shifts Description: Volunteer shifts with scheduling and capacity tracking.

Field Type Required Default Description
id String cuid() Primary key
title String Shift title
description String null Shift description (long text)
date DateTime Shift date (date only, no time)
startTime String Start time (HH:MM format)
endTime String End time (HH:MM format)
location String null Shift location description
maxVolunteers Int Maximum volunteer capacity
currentVolunteers Int 0 Current signup count
status ShiftStatus OPEN Status: OPEN, FULL, CANCELLED
isPublic Boolean false Public signup allowed
cutId String null Foreign key to Cut
createdBy String null Creator user ID (string, not FK)
createdAt DateTime now() Creation timestamp
updatedAt DateTime Auto Last update timestamp

Indexes:

  • Foreign key: cutId

Relations:

  • cut → Cut (onDelete: SetNull)
  • signups → ShiftSignup[]
  • canvassVisits → CanvassVisit[]
  • canvassSessions → CanvassSession[]

ShiftSignup

Table: shift_signups Description: Shift signup tracking with source attribution.

Field Type Required Default Description
id String cuid() Primary key
shiftId String Foreign key to Shift
shiftTitle String null Denormalized shift title
userId String null Foreign key to User
userEmail String User email (for guest signups)
userName String null User name
userPhone String null User phone
signupDate DateTime now() Signup timestamp
status SignupStatus CONFIRMED Status: CONFIRMED, CANCELLED
signupSource SignupSource AUTHENTICATED Source: AUTHENTICATED, PUBLIC, ADMIN

Indexes:

  • Unique: [shiftId, userEmail] (prevent duplicate signups)
  • Foreign key: shiftId

Relations:

  • shift → Shift (onDelete: Cascade)
  • user → User (onDelete: SetNull)

Cut

Table: cuts Description: GeoJSON polygon overlays for map filtering and canvassing.

Field Type Required Default Description
id String cuid() Primary key
name String Cut name
description String null Cut description (long text)
color String "#3388ff" Polygon fill color (hex)
opacity Decimal(3,2) 0.3 Polygon opacity (0.00-1.00)
category CutCategory null Category: CUSTOM, WARD, NEIGHBORHOOD, DISTRICT
isPublic Boolean false Public visibility flag
isOfficial Boolean false Official boundary flag
geojson String GeoJSON polygon data (long text)
bounds String null Bounding box JSON (long text)
showLocations Boolean true Show locations on map
exportEnabled Boolean true Export enabled flag
assignedTo String null Assigned user ID (string, not FK)
filterSettings Json null Filter configuration object
lastCanvassed DateTime null Last canvass timestamp
completionPercentage Int 0 Canvass completion percentage
createdByUserId String null Foreign key to User (creator)
createdAt DateTime now() Creation timestamp
updatedAt DateTime Auto Last update timestamp

Indexes: None

Relations:

  • createdByUser → User (onDelete: SetNull)
  • shifts → Shift[]
  • canvassSessions → CanvassSession[]

MapSettings

Table: map_settings Description: Singleton for map center/zoom and walk sheet configuration.

Field Type Required Default Description
id String cuid() Primary key (always "default")
latitude Decimal(10,8) null Map center latitude
longitude Decimal(11,8) null Map center longitude
zoom Int null Default map zoom level
walkSheetTitle String null Walk sheet header title
walkSheetSubtitle String null Walk sheet header subtitle
walkSheetFooter String null Walk sheet footer text (long text)
qrCode1Url String null QR code 1 URL
qrCode1Label String null QR code 1 label
qrCode2Url String null QR code 2 URL
qrCode2Label String null QR code 2 label
qrCode3Url String null QR code 3 URL
qrCode3Label String null QR code 3 label
createdBy String null Creator user ID (string, not FK)
createdAt DateTime now() Creation timestamp
updatedAt DateTime Auto Last update timestamp

Indexes: None

Relations: None (singleton)


Canvassing

CanvassSession

Table: canvass_sessions Description: Canvassing session lifecycle with status tracking.

Field Type Required Default Description
id String cuid() Primary key
userId String Foreign key to User
cutId String Foreign key to Cut
shiftId String null Foreign key to Shift
status CanvassSessionStatus ACTIVE Status: ACTIVE, COMPLETED, ABANDONED
startedAt DateTime now() Session start timestamp
endedAt DateTime null Session end timestamp
startLatitude Decimal(10,8) null Starting latitude
startLongitude Decimal(11,8) null Starting longitude

Indexes:

  • Foreign key: userId
  • Foreign key: cutId
  • Foreign key: shiftId

Relations:

  • user → User (onDelete: Cascade)
  • cut → Cut (onDelete: Cascade)
  • shift → Shift (onDelete: SetNull)
  • visits → CanvassVisit[]
  • trackingSession → TrackingSession (one-to-one)

CanvassVisit

Table: canvass_visits Description: Visit recording with outcome tracking.

Field Type Required Default Description
id String cuid() Primary key
addressId String Foreign key to Address
userId String Foreign key to User
shiftId String null Foreign key to Shift
sessionId String null Foreign key to CanvassSession
outcome VisitOutcome Outcome: NOT_HOME, REFUSED, MOVED, ALREADY_VOTED, SPOKE_WITH, LEFT_LITERATURE, COME_BACK_LATER
supportLevel SupportLevel null Support level: 1, 2, 3, 4
signRequested Boolean false Sign requested flag
signSize String null Sign size
notes String null Visit notes (long text)
durationSeconds Int null Visit duration in seconds
visitedAt DateTime now() Visit timestamp

Indexes:

  • Foreign key: addressId
  • Foreign key: userId
  • Foreign key: shiftId
  • Foreign key: sessionId
  • Non-unique: visitedAt (temporal queries)

Relations:

  • address → Address (onDelete: Cascade)
  • user → User (onDelete: Cascade)
  • shift → Shift (onDelete: SetNull)
  • session → CanvassSession (onDelete: SetNull)

TrackingSession

Table: tracking_sessions Description: GPS tracking sessions with distance calculation.

Field Type Required Default Description
id String cuid() Primary key
userId String Foreign key to User
canvassSessionId String null Foreign key to CanvassSession (unique, one-to-one)
startedAt DateTime now() Tracking start timestamp
endedAt DateTime null Tracking end timestamp
isActive Boolean true Active tracking flag
totalPoints Int 0 Total GPS points recorded
totalDistanceM Float 0 Total distance in meters
lastLatitude Decimal(10,8) null Last recorded latitude
lastLongitude Decimal(11,8) null Last recorded longitude
lastRecordedAt DateTime null Last GPS point timestamp

Indexes:

  • Unique: canvassSessionId
  • Foreign key: userId
  • Non-unique: isActive
  • Composite: [isActive, lastRecordedAt] (cleanup queries)

Relations:

  • user → User (onDelete: Cascade)
  • canvassSession → CanvassSession (onDelete: SetNull)
  • trackPoints → TrackPoint[]

TrackPoint

Table: track_points Description: GPS breadcrumb trail with event types.

Field Type Required Default Description
id String cuid() Primary key
trackingSessionId String Foreign key to TrackingSession
latitude Decimal(10,8) GPS latitude
longitude Decimal(11,8) GPS longitude
accuracy Float null GPS accuracy in meters
recordedAt DateTime now() GPS point timestamp
eventType TrackPointEvent null Event: LOCATION_ADDED, VISIT_RECORDED, SESSION_STARTED, SESSION_ENDED

Indexes:

  • Composite: [trackingSessionId, recordedAt] (temporal queries)
  • Non-unique: recordedAt

Relations:

  • trackingSession → TrackingSession (onDelete: Cascade)

Email Templates

EmailTemplate

Table: email_templates Description: Email template master records with category organization.

Field Type Required Default Description
id String cuid() Primary key
key String Template key (unique, e.g., "campaign-email")
name String Display name
description String null Template description (long text)
category EmailTemplateCategory Category: INFLUENCE, MAP, SYSTEM
subjectLine String Subject line with {{VAR}} support
htmlContent String HTML template (long text)
textContent String Plain text template (long text)
isSystem Boolean false System template (prevent deletion)
isActive Boolean true Active status
createdByUserId String Foreign key to User (creator)
updatedByUserId String null Foreign key to User (last updater)
createdAt DateTime now() Creation timestamp
updatedAt DateTime Auto Last update timestamp

Indexes:

  • Unique: key
  • Non-unique: category
  • Non-unique: isActive

Relations:

  • createdBy → User
  • updatedBy → User
  • variables → EmailTemplateVariable[]
  • versions → EmailTemplateVersion[]
  • testLogs → EmailTemplateTestLog[]

EmailTemplateVariable

Table: email_template_variables Description: Template variable definitions with validation.

Field Type Required Default Description
id String cuid() Primary key
templateId String Foreign key to EmailTemplate
key String Variable key (e.g., "USER_NAME")
label String Variable label (e.g., "User Name")
description String null Variable description (long text)
isRequired Boolean true Required flag
isConditional Boolean false Conditional variable (used in {{#if}})
sampleValue String null Sample value for testing (long text)
sortOrder Int 0 Display order

Indexes:

  • Unique: [templateId, key] (unique variable keys per template)
  • Foreign key: templateId

Relations:

  • template → EmailTemplate (onDelete: Cascade)

EmailTemplateVersion

Table: email_template_versions Description: Template version history with auto-increment version numbers.

Field Type Required Default Description
id String cuid() Primary key
templateId String Foreign key to EmailTemplate
versionNumber Int Auto-increment version number per template
subjectLine String Subject line snapshot
htmlContent String HTML content snapshot (long text)
textContent String Plain text snapshot (long text)
changeNotes String null Version notes (long text)
createdByUserId String Foreign key to User
createdAt DateTime now() Version timestamp

Indexes:

  • Unique: [templateId, versionNumber] (sequential version numbers)
  • Composite: [templateId, createdAt(sort: Desc)] (recent versions)

Relations:

  • template → EmailTemplate (onDelete: Cascade)
  • createdBy → User

EmailTemplateTestLog

Table: email_template_test_logs Description: Test email audit logs.

Field Type Required Default Description
id String cuid() Primary key
templateId String Foreign key to EmailTemplate
recipientEmail String Test recipient email
testData Json Sample variable values JSON
success Boolean Test success flag
errorMessage String null Error message (long text)
messageId String null Nodemailer message ID
sentByUserId String Foreign key to User
sentAt DateTime now() Send timestamp

Indexes:

  • Composite: [templateId, sentAt(sort: Desc)] (recent tests)

Relations:

  • template → EmailTemplate (onDelete: Cascade)
  • sentBy → User

Landing Pages

LandingPage

Table: landing_pages Description: GrapesJS editor output with MkDocs export support.

Field Type Required Default Description
id String cuid() Primary key
slug String URL slug (unique)
title String Page title
description String null Page description (long text)
blocks Json GrapesJS editor JSON
htmlOutput String null Rendered HTML (long text)
cssOutput String null Rendered CSS (long text)
editorMode EditorMode VISUAL Editor mode: VISUAL, CODE
mkdocsPath String null Path in mkdocs/overrides/
mkdocsStubPath String null Path to .md stub in mkdocs/docs/
mkdocsExportMode MkdocsExportMode THEMED Export mode: THEMED, STANDALONE
mkdocsHideNav Boolean true Hide navigation in MkDocs
mkdocsHideToc Boolean true Hide table of contents in MkDocs
mkdocsSkipExport Boolean false Skip MkDocs export flag
published Boolean false Published status
seoTitle String null SEO title override
seoDescription String null SEO description (long text)
seoImage String null SEO image URL
createdAt DateTime now() Creation timestamp
updatedAt DateTime Auto Last update timestamp

Indexes:

  • Unique: slug

Relations: None

PageBlock

Table: page_blocks Description: Reusable block library for GrapesJS editor.

Field Type Required Default Description
id String cuid() Primary key
type String Block type (hero, text, image, cta, features, testimonials, form)
label String Block label
schema Json Block configuration schema JSON
defaults Json Default values JSON
thumbnail String null Thumbnail URL
category String null Block category
sortOrder Int 0 Display order
createdAt DateTime now() Creation timestamp
updatedAt DateTime Auto Last update timestamp

Indexes: None

Relations: None


Site Settings

SiteSettings

Table: site_settings Description: Global site configuration singleton for branding, theme, SMTP, and feature toggles.

Field Type Required Default Description
id String cuid() Primary key (always "default")
organizationName String "Changemaker Lite" Organization name
organizationShortName String "CML" Short name/acronym
organizationLogoUrl String null Logo URL
organizationFaviconUrl String null Favicon URL
adminColorPrimary String "#9d4edd" Admin primary color (hex)
adminColorBgBase String "#1a1025" Admin background color (hex)
publicColorPrimary String "#3498db" Public primary color (hex)
publicColorBgBase String "#0d1b2a" Public background color (hex)
publicColorBgContainer String "#1b2838" Public container color (hex)
publicHeaderGradient String "linear-gradient(135deg, #005a9c 0%, #007acc 100%)" Public header gradient (CSS)
footerText String "Powered by Changemaker Lite" Footer text
loginSubtitle String "Admin" Login page subtitle
emailFromName String "Changemaker Lite" Email from name
smtpHost String "" SMTP host (empty = use env)
smtpPort Int 0 SMTP port (0 = use env)
smtpUser String "" SMTP username (empty = use env)
smtpPass String "" SMTP password (empty = use env)
smtpFromAddress String "" SMTP from address (empty = use env)
smtpActiveProvider String "mailhog" Active provider: "mailhog", "production"
emailTestMode Boolean true Email test mode flag
testEmailRecipient String "" Test email recipient
enableInfluence Boolean true Enable Influence module
enableMap Boolean true Enable Map module
enableNewsletter Boolean true Enable Newsletter module
enableLandingPages Boolean true Enable Landing Pages module
createdAt DateTime now() Creation timestamp
updatedAt DateTime Auto Last update timestamp

Indexes: None

Relations: None (singleton)


Media (Drizzle ORM)

videos

Table: videos Description: Video library with metadata extraction and engagement tracking.

Field Type Required Default Description
id serial Auto Primary key (auto-increment)
path text File path (unique)
filename text File name
producer text null Producer name
creator text null Creator name
title text null Video title
durationSeconds integer null Duration in seconds (FFprobe)
quality text null Quality string (e.g., "1080p")
orientation text null Orientation: portrait, landscape, square
hasAudio boolean true Audio track present flag
fileSize bigint null File size in bytes
fileHash text null MD5 hash
width integer null Video width (FFprobe)
height integer null Video height (FFprobe)
lastValidated timestamp null Last validation timestamp
isValid boolean true Valid file flag
thumbnailPath text null Thumbnail file path
createdAt timestamp now() Creation timestamp
tags jsonb null Array of tag strings
directoryType text null Directory type: studios, gifs, private, inbox, curated, playback, compilations, videos, highlights
publicViewCount integer null Public view count (historical)
publicUpvoteCount integer null Public upvote count (historical)
publicCommentCount integer null Public comment count (historical)
publicCompletionCount integer null Public completion count (historical)
publicTotalWatchTime integer null Public total watch time (historical)
movedFromPublicAt timestamp null Timestamp when moved from public media
originalFilename text null Original filename before standardization
originalPath text null Original path before standardization
standardizedAt timestamp null Standardization timestamp

Indexes:

  • Unique: path
  • Non-unique: orientation
  • Non-unique: producer
  • Non-unique: isValid
  • Non-unique: directoryType
  • Composite: [durationSeconds, fileSize, width, height] (fingerprint)
  • Composite: [directoryType, isValid, orientation] (common filtering)

Relations: None (standalone)

compilations

Table: compilations Description: Video compilation tracking.

Field Type Required Default Description
id serial Auto Primary key (auto-increment)
filename text Compilation filename
path text null Compilation file path
durationSeconds integer null Total duration in seconds
videoIds jsonb null Array of video IDs included
settings jsonb null Compilation settings object
createdAt timestamp now() Creation timestamp

Indexes: None

Relations: None (video IDs stored as JSON array)

jobs

Table: jobs Description: Job queue with resource category management.

Field Type Required Default Description
id serial Auto Primary key (auto-increment)
type text Job type (compilation, scan, organize, etc.)
status text "pending" Status: pending, queued, running, completed, failed, cancelled
progress integer 0 Progress percentage (0-100)
log text null Job log output
params jsonb null Job parameters object
startedAt timestamp null Job start timestamp
completedAt timestamp null Job completion timestamp
createdAt timestamp now() Creation timestamp
resourceCategory text "cpu" Resource category: gpu_ai, gpu_encode, cpu
vramRequired integer 0 VRAM required in MB
queuePosition integer null Queue position
waitingReason text null Reason for waiting
priority integer 5 Job priority (lower = higher priority)
pipelineId integer null Pipeline ID (for pipeline jobs)
pipelineStepId integer null Pipeline step ID

Indexes:

  • Composite: [status, priority, createdAt] (queue processing)
  • Composite: [resourceCategory, status] (resource filtering)
  • Non-unique: pipelineId

Relations: None (pipeline relations are external)