Skip to content

Database Tables & Migration Reference

Overview

All ODP tables use the odp_ prefix. User-defined collections use their own names without a prefix. This document covers all system tables created by the migration files.

Supported databases: PostgreSQL, MySQL/MySQL2, SQLite/better-sqlite3


Core Schema Tables

odp_collections

Metadata for all collections (both system and user-defined).

ColumnTypeNullableDefaultDescription
collectionstring(255) PKNoCollection name (= table name)
iconstring(30)YesAdmin UI icon
notetextYesDescription
colorstring(10)YesBrand color hex
display_templatestring(255)YesItem display template
hiddenbooleanNofalseHide from admin UI
singletonbooleanNofalseSingle-item collection
archive_fieldstring(64)YesField used for soft-delete
archive_valuestring(255)YesValue that marks item as archived
unarchive_valuestring(255)YesValue that marks item as active
archive_app_filterbooleanNotrueShow archive filter in app
sort_fieldstring(64)YesField used for manual sort
accountabilitystring(25)NoallAudit mode: all, activity, null
groupstring(255) FK → odp_collectionsYesParent collection group
collapsestring(25)NoopenGroup collapse state
preview_urlstring(255)YesPreview URL template
versioningbooleanNofalseEnable content versioning

odp_fields

Field metadata and display configuration.

ColumnTypeNullableDefaultDescription
idinteger PK (auto)No
collectionstring(255) FK → odp_collectionsNo
fieldstring(255)NoField name (column name)
specialtext (JSON)YesSpecial field types (uuid, json, csv, etc.)
interfacestring(255)YesAdmin UI interface component
optionstext (JSON)YesInterface options
displaystring(255)YesDisplay component
display_optionstext (JSON)YesDisplay options
readonlybooleanNofalseRead-only in admin
hiddenbooleanNofalseHidden in admin
sortintegerYesField order
widthstring(30)NofullDisplay width
translationstext (JSON)YesLabel translations
notetextYesHelp text
conditionstext (JSON)YesConditional display rules
requiredbooleanNofalseRequired field
groupinteger FK → odp_fieldsYesField group parent
validationtext (JSON)YesValidation rules
validation_messagestring(255)YesCustom validation message
searchablebooleanNotrueInclude in search

odp_relations

Relation metadata between collections (foreign key descriptions).

ColumnTypeNullableDefaultDescription
idinteger PK (auto)No
many_collectionstring(255)NoThe "many" side collection
many_fieldstring(255)NoFK field on many side
one_collectionstring(255)YesThe "one" side collection (M2O/O2M)
one_fieldstring(255)YesVirtual O2M field name
one_collection_fieldstring(255)YesM2A discriminator field
one_allowed_collectionstext (JSON)YesM2A allowed collection names
junction_fieldstring(255)YesM2M junction field
sort_fieldstring(255)YesSort field for O2M lists
one_deselect_actionstring(255)Nonullifynullify or delete

Auth & Identity

odp_roles

User roles for access control grouping.

ColumnTypeNullableDefaultDescription
idUUID PKNogen_random_uuid()
namestring(255)NoRole display name
iconstring(30)Nosupervised_user_circle
descriptiontextYes
parentUUID FK → odp_rolesYesParent role (role inheritance)
admin_accessbooleanNofalseAccess to admin dashboard
app_accessbooleanNofalseAccess to frontend app
tech_accessbooleanNofalseSuperadmin: bypass all permission checks
impersonate_accessbooleanNofalseCan start impersonation sessions

odp_policies

Access control policies with optional IP restriction and TFA enforcement.

ColumnTypeNullableDefaultDescription
idUUID PKNo
namestring(255)NoPolicy name
iconstring(30)Nobadge
descriptiontextYes
ip_accesstext (JSON)YesArray of allowed CIDR ranges
enforce_tfabooleanNofalseRequire TFA for users with this policy
admin_accessbooleanNofalseGrant admin access
app_accessbooleanNofalseGrant app access

odp_access

Junction table: links policies to roles or individual users.

ColumnTypeNullableDefaultDescription
idUUID PKNo
policyUUID FK → odp_policiesNo(CASCADE delete)
roleUUID FK → odp_rolesYes(CASCADE delete)
userUUID FK → odp_usersYes(CASCADE delete)
sortintegerYesDisplay/priority order

odp_permissions

Row-level RBAC permissions on collections.

ColumnTypeNullableDefaultDescription
idinteger PK (auto)No
policyUUID FK → odp_policiesNo(CASCADE delete)
collectionstring(255)NoCollection name
actionstring(10)Nocreate, read, update, delete, share
fieldstext (JSON)YesAllowed fields (null = all)
permissionstext (JSON)YesRow filter conditions
validationtext (JSON)YesWrite validation rules
presetstext (JSON)YesDefault field values for creates

odp_users

User accounts.

ColumnTypeNullableDefaultDescription
idUUID PKNogen_random_uuid()
first_namestring(50)Yes
last_namestring(50)Yes
emailstring(255) UNIQUEYes
passwordstring(255)YesArgon2 hash
locationstring(255)Yes
titlestring(50)Yes
descriptiontextYes
tagstext (JSON)YesArray of tag strings
avatarUUID FK → odp_filesYes
languagestring(10)Noen-USPreferred language
tfa_secretstring(255)YesTOTP secret (if TFA enabled)
statusstring(16)Noactiveactive, suspended, archived
roleUUID FK → odp_rolesYes
tokenstring(255) UNIQUEYesStatic API token
last_accesstimestampYes
last_pagestring(255)YesLast visited admin page
email_notificationsbooleanNotrue
appearancestring(10)Noautoauto, light, dark
theme_lightstring(255)Yes
theme_darkstring(255)Yes
theme_light_overridestext (JSON)Yes
theme_dark_overridestext (JSON)Yes

odp_sessions

Active user sessions (refresh tokens).

ColumnTypeNullableDefaultDescription
tokenstring(64) PKNoSession/refresh token
userUUID FK → odp_usersYes(CASCADE delete)
expirestimestampNoSession expiry
ipstring(255)Yes
user_agenttextYes
shareUUID FK → odp_sharesYesFor share sessions
originstring(255)YesRequest origin
next_tokenstring(64)YesRolling session next token

odp_user_providers

Junction table: links users to SSO provider identities.

ColumnTypeNullableDefaultDescription
idUUID PKNo
user_idUUID FK → odp_usersNo(CASCADE delete)
providerstring(128)NoProvider name (e.g., google)
external_identifierstring(255)NoProvider's user ID
provider_emailstring(255)YesEmail from provider
auth_datatext (JSON)YesRaw provider auth data
created_attimestampYesnow()

Unique constraint: (provider, external_identifier)


odp_user_tokens

Sub-tokens (scoped API keys).

ColumnTypeNullableDefaultDescription
idUUID PKNo
user_idUUID FK → odp_usersNo(CASCADE delete)
namestring(255)NoHuman label
descriptiontextYes
token_hashstring(64) UNIQUENoSHA-256 hash of the token
token_prefixstring(8)NoAlways odp:
scopesjsonYes["read","create","update","delete"] subset
allowed_rolesjsonYesArray of role UUIDs
expires_attimestampYes
last_used_attimestampYes
revoked_attimestampYes
created_attimestampNonow()

odp_impersonation_sessions

Impersonation session records.

ColumnTypeNullableDefaultDescription
idUUID PKNo
admin_userUUID FK → odp_usersNoUser performing impersonation
target_userUUID FK → odp_usersNoUser being impersonated
tokenstring(64) UNIQUENoSession lookup token
expirestimestampNoJWT expiry
ipstring(255)Yes
user_agenttextYes
reasontextYesAudit reason
ended_attimestampYesNull if active
end_reasonstring(50)Yesmanual, expired, revoked
created_attimestampNonow()

odp_ephemeral_codes

Short-lived one-time codes (used for SAML callback flow).

ColumnTypeNullableDefaultDescription
codestring(64) PKNoRandom hex code
typestring(32)Nosaml
datajsonbNoStored payload
expires_attimestamp (TZ)No5-minute TTL
created_attimestamp (TZ)Nonow()

Files & Storage

odp_folders

Hierarchical file organization.

ColumnTypeNullableDefaultDescription
idUUID PKNo
namestring(255)NoFolder name
parentUUID FK → odp_foldersYesSelf-referential parent

odp_files

File records (metadata + storage reference).

ColumnTypeNullableDefaultDescription
idUUID PKNo
storagestring(255)NolocalStorage driver name
filename_diskstring(255)YesInternal filename (UUID-based)
filename_downloadstring(255)YesOriginal filename for downloads
titlestring(255)YesDisplay title
typestring(255)YesMIME type
folderUUID FK → odp_foldersYes
uploaded_byUUID FK → odp_usersYes
created_ontimestampYesnow()
modified_byUUID FK → odp_usersYes
modified_ontimestampYesnow()
charsetstring(50)YesCharacter encoding
filesizebigintYesFile size in bytes
widthintegerYesImage width
heightintegerYesImage height
durationintegerYesMedia duration (seconds)
embedstring(200)YesEmbed provider
descriptiontextYes
locationstring(200)YesGeographic location
tagstext (JSON)YesTag array
metadatatext (JSON)YesEXIF/XMP metadata
focal_point_xintegerYes
focal_point_yintegerYes
tus_idstring(255)YesTUS upload ID
tus_datatext (JSON)YesTUS upload metadata

Content

odp_versions

Content version snapshots.

ColumnTypeNullableDefaultDescription
idUUID PKNo
keystring(64)NoHuman-readable slug
namestring(255)YesDisplay name
collectionstring(255) FK → odp_collectionsNo
itemstring(255)NoItem primary key
hashstring(255)YesContent hash
date_createdtimestampYesnow()
date_updatedtimestampYes
user_createdUUID FK → odp_usersYes
user_updatedUUID FK → odp_usersYes
deltatext (JSON)YesChanged fields

odp_activity

Audit log of all system actions.

ColumnTypeNullableDefaultDescription
idinteger PK (auto)No
actionstring(45)NoAction type
userUUID FK → odp_usersYesActing user
timestamptimestampYesnow()
ipstring(50)Yes
user_agenttextYes
collectionstring(255)YesAffected collection
itemstring(255)YesAffected item PK
originstring(255)YesRequest origin
impersonated_byUUIDYesReal admin when impersonating

odp_revisions

Point-in-time data snapshots linked to activity records.

ColumnTypeNullableDefaultDescription
idinteger PK (auto)No
activityinteger FK → odp_activityYes(CASCADE delete)
collectionstring(255)No
itemstring(255)No
datatext (JSON)YesFull item snapshot after change
deltatext (JSON)YesOnly changed fields
parentinteger FK → odp_revisionsYesParent revision
versionUUID FK → odp_versionsYesLinked version

odp_comments

Item comments.

ColumnTypeNullableDefaultDescription
idUUID PKNo
collectionstring(255)No
itemstring(255)No
commenttextNoMarkdown comment text
date_createdtimestampYesnow()
date_updatedtimestampYes
user_createdUUID FK → odp_usersYes
user_updatedUUID FK → odp_usersYes

System Config

odp_settings

Global project settings (singleton — always row id=1).

ColumnTypeNullableDefaultDescription
idinteger PKNoAlways 1
project_namestring(255)NoCMS
project_urlstring(255)Yes
project_colorstring(10)YesHex color
project_logoUUID FK → odp_filesYes
public_foregroundUUID FK → odp_filesYes
public_backgroundUUID FK → odp_filesYes
public_notetextYesLogin page note
auth_login_attemptsintegerYes25Max failed attempts before lockout
auth_password_policystring(100)YesPassword policy descriptor
storage_asset_transformstring(30)Noallall, none, presets
storage_asset_presetstext (JSON)YesNamed transform presets
custom_csstextYesCSS injected into admin
storage_default_folderUUID FK → odp_foldersYes
report_error_urlstring(255)Yes
report_bug_urlstring(255)Yes
report_feature_urlstring(255)Yes
public_registrationbooleanNofalse
public_registration_verify_emailbooleanNotrue
public_registration_roleUUID FK → odp_rolesYes
public_registration_email_filtertext (JSON)YesAllowed email domains
public_roleUUID FK → odp_rolesYesRole for unauthenticated access

odp_presets

Saved collection view configurations.

ColumnTypeNullableDefaultDescription
idinteger PK (auto)No
bookmarkstring(255)YesSaved bookmark name
userUUID FK → odp_usersYesPer-user preset (CASCADE delete)
roleUUID FK → odp_rolesYesPer-role preset (CASCADE delete)
collectionstring(255)Yes
searchstring(255)YesSaved search
layoutstring(100)Yestabular
layout_querytext (JSON)Yes
layout_optionstext (JSON)Yes
refresh_intervalintegerYesAuto-refresh seconds
filtertext (JSON)YesFilter rules
iconstring(30)Nobookmark
colorstring(10)Yes

odp_translations

Custom string translations.

ColumnTypeNullableDefaultDescription
idUUID PKNo
languagestring(10)NoLanguage code (e.g., en-US)
keystring(255)NoTranslation key
valuetextNoTranslated string

odp_extensions

Registered extensions.

ColumnTypeNullableDefaultDescription
idUUID PKNo
enabledbooleanNotrueWhether extension is loaded
folderstring(255)NoDirectory name under EXTENSIONS_PATH
sourcestring(255)Nolocal, registry, or module
bundleUUID FK → odp_extensionsYesParent bundle

odp_extension_settings

Key-value settings store for extensions and system features.

ColumnTypeNullableDefaultDescription
idinteger PK (auto)No
extension_keystringNoNamespace (e.g., system_auth_provider)
namestringNoSetting name within namespace
valuetext/JSONYesConfiguration value

Migration 053 added an index on extension_key for fast lookups.


Notifications

odp_notifications

In-app notifications sent to users.

ColumnTypeNullableDefaultDescription
idinteger PK (auto)No
timestamptimestampYesnow()
statusstring(25)Noinboxinbox or archived
recipientUUID FK → odp_usersNo(CASCADE delete)
senderUUID FK → odp_usersYes
subjectstring(255)No
messagetextYes
collectionstring(255)YesRelated collection
itemstring(255)YesRelated item PK

Sharing

odp_shares

Public/password-protected content shares.

ColumnTypeNullableDefaultDescription
idUUID PKNo
namestring(255)YesDisplay name
collectionstring(255)No
itemstring(255)No
roleUUID FK → odp_rolesYesRole applied to share sessions
passwordstring(255)YesHashed password
user_createdUUID FK → odp_usersYes
date_createdtimestampYesnow()
date_starttimestampYesShare validity start
date_endtimestampYesShare validity end
times_usedintegerNo0Usage counter
max_usesintegerYesMaximum uses limit

App Permissions

odp_app_permissions

Feature-level permission grants.

ColumnTypeNullableDefaultDescription
idUUID PKNo
policyUUID FK → odp_policiesNo(CASCADE delete)
moduletextNoModule ID (e.g., mcp, workflow)
actiontextNoAction ID or *
collection_scopetextNo__global__Collection name or __global__
created_attimestampNonow()
created_byUUID FK → odp_usersYes

Unique constraint: (policy, module, action, collection_scope)


odp_app_access_logs

App permission access audit log.

ColumnTypeNullableDefaultDescription
idUUID PKNo
user_idtextYes
initiated_bytextYesReal actor (differs from user_id during impersonation)
moduletextNo
actiontextNo
collection_scopetextYes
resulttextNopass or fail
policy_idtextYesMatched policy (on pass)
fail_reasontextYesReason for denial (on fail)
iptextYes
user_agenttextYes
created_attimestampNonow()

Workflow

odp_workflows

Workflow definitions.

ColumnTypeNullableDefaultDescription
idstring PKNoUUID
namestringNo
descriptiontextYes
collectionstringYesTarget collection
statusstringNodraftdraft, active, archived
trigger_eventstringNomanualitems.create, items.update, manual
trigger_filterjsonYesRow filter for auto-trigger
optionsjsonYes
created_bystringYes
created_attimestampYesnow()
updated_attimestampYesnow()

odp_workflow_steps

Individual steps in a workflow.

ColumnTypeNullableDefaultDescription
idstring PKNoUUID
workflow_idstring FK → odp_workflowsNo(CASCADE delete)
keystringNoUnique key within workflow
namestringNoDisplay name
typestringNoapprovalstart, approval, condition, action, notification, end
assign_typestringYesrole, user, field, creator, auto
assign_valuestringYesAssignment value
approval_modestringYesanyany, all, majority, count
approval_countintegerYesRequired approvals for count mode
timeout_minutesintegerYesStep timeout
timeout_actionstringYesescalate, auto_approve, auto_reject, notify
escalate_tostringYesEscalation target
action_typestringYesFor action steps
action_configjsonYesAction configuration
position_x, position_yfloatYes0Visual position
sort_orderintegerYes0
optionsjsonYes

odp_workflow_transitions

Transitions between workflow steps.

ColumnTypeNullableDefaultDescription
idstring PKNoUUID
workflow_idstring FK → odp_workflowsNo(CASCADE delete)
from_step_idstring FK → odp_workflow_stepsNo(CASCADE delete)
to_step_idstring FK → odp_workflow_stepsNo(CASCADE delete)
triggerstringNoapproveapprove, reject, timeout, condition, always
conditionjsonYesFilter condition for condition trigger
sort_orderintegerYes0
labelstringYesDisplay label

odp_workflow_instances

Active/completed workflow runs.

ColumnTypeNullableDefaultDescription
idstring PKNoUUID
workflow_idstring FK → odp_workflowsNo(RESTRICT delete)
collectionstringNoCollection of the item
item_idstringNoItem primary key
statusstringNorunningrunning, completed, rejected, cancelled, error
current_step_idstring FK → odp_workflow_stepsYes(SET NULL)
started_bystringYes
started_attimestampYesnow()
completed_attimestampYes
optionsjsonYes

odp_workflow_instance_steps

Per-step state within a running workflow instance.

ColumnTypeNullableDefaultDescription
idstring PKNo
instance_idstring FK → odp_workflow_instancesNo(CASCADE delete)
step_idstring FK → odp_workflow_stepsNo(RESTRICT)
statusstringNopendingpending, active, approved, rejected, skipped, timed_out
assigned_usersjsonYesArray of user IDs
approvalsjsonYesArray of approval records
activated_attimestampYes
completed_attimestampYes
timeout_attimestampYes
resultstringYes

odp_workflow_actions

Workflow audit log.

ColumnTypeNullableDefaultDescription
idstring PKNo
instance_idstring FK → odp_workflow_instancesNo(CASCADE delete)
step_idstring FK → odp_workflow_stepsYes(SET NULL)
user_idstringYes
actionstringNostart, approve, reject, delegate, comment, escalate, cancel, auto_approve, timeout
commenttextYes
datajsonYesAdditional action data
created_attimestampYesnow()

odp_workflow_instance_step_users

Junction: users assigned to a workflow instance step.

ColumnTypeDescription
(created by migration 040)Additional junction for step user assignments

Notify System

odp_notify_settings (singleton)

Notification system settings.

odp_notify_templates

Email/notification template definitions.

odp_notify_template_contents

Template content for each channel (email, in-app).

odp_notify_logs

Notification send log (read-only).

odp_notify_layouts

Email layout templates (wraps template content).


Migration History

MigrationDescription
001Create odp_collections
002Create odp_fields
003Create odp_relations
004Create odp_roles
005Create odp_policies
006Create odp_folders
007Create odp_files
008Create odp_users
009Create odp_access
010Create odp_permissions
011Create odp_sessions
012Create odp_activity
013Create odp_revisions
014Create odp_versions
015Create odp_comments
016Create odp_settings
017Create odp_presets
018Create odp_extensions
019Create odp_notifications
020Create odp_translations
021Create odp_shares
022Create odp_migrations
023Create indexes
024Seed default roles/policies
025Add roles shortname/weight
026Add password policy to settings
027Add module bar to settings
028Create notify system tables
029Seed default notification templates
030Add email transport settings
031Add tech_access to odp_roles
032Add session device/token fields
033Add MCP settings
034Create odp_user_providers (replaces legacy provider columns on odp_users)
035Add provider_email to odp_user_providers
036Add collection translations
037Create workflow tables (odp_workflows, steps, transitions, instances, instance_steps, actions)
038Add workflow notify templates
039Create odp_ephemeral_codes
040Create odp_workflow_instance_step_users junction
041Add extra MCP settings fields
042Add impersonate_access to odp_roles
043Create odp_impersonation_sessions
044Add impersonated_by to odp_activity
045Add type and group_name to odp_fields
046Create odp_app_permissions + odp_app_access_logs
047Seed default app permissions
048Create odp_notify_layouts
049Create odp_user_tokens
050Add theme settings to odp_settings
051Create odp_extension_settings
052Create Public role + add public_role to odp_settings
053Add extension_key index to odp_extension_settings
054Add sort to collections
055Add is_system flag to odp_notify_templates

ODP Internal API Documentation