Skip to main content

Database Schema

Open ACE supports both SQLite (single-machine) and PostgreSQL (production). The schema contains 44 tables + 1 materialized view (full list in schema-postgres.sql; docs below cover the most commonly referenced tables).

Reference: schema/schema-postgres.sql

User & Authentication

users

Core user table with role-based access control.

ColumnTypeNotes
idinteger PKAuto-increment
usernamevarcharUNIQUE, NOT NULL
password_hashvarcharbcrypt (12 rounds)
emailvarchar
is_adminbooleanDEFAULT false
is_activebooleanDEFAULT true
rolevarcharCHECK IN ('admin','manager','user')
daily_token_quotainteger
monthly_token_quotainteger
daily_request_quotainteger
monthly_request_quotainteger
tenant_idintegerFK → tenants(id) ON DELETE SET NULL
must_change_passwordbooleanDEFAULT false
system_accounttextOS username for multi-user mode
deleted_attimestampSoft delete
avatar_urlvarchar(500)Avatar URL

Indexes: idx_users_active, idx_users_deleted, idx_users_email, idx_users_role, idx_users_tenant

sessions

Authentication sessions with token-based access.

ColumnTypeNotes
idinteger PK
tokenvarcharUNIQUE, NOT NULL
user_idintegerFK → users(id) ON DELETE CASCADE
created_attimestamp
expires_attimestampNOT NULL
is_activebooleanDEFAULT true

Indexes: idx_sessions_active, idx_sessions_expires, idx_sessions_token, idx_sessions_user_id

web_user_auth_sessions

Web UI authentication sessions.

ColumnTypeNotes
idinteger PK
user_idintegerFK → users(id)
session_tokentextUNIQUE
created_attimestamp
expires_attimestamp

user_tool_accounts

Maps system accounts to platform users for different AI tools.

ColumnTypeNotes
idinteger PK
user_idintegerFK → users(id) ON DELETE CASCADE
tool_accountvarchar(255)UNIQUE
tool_typevarchar(50)
descriptionvarchar(255)

user_daily_stats

Pre-aggregated daily usage per user for optimized queries.

ColumnTypeNotes
idinteger PK
user_idintegerFK → users(id) ON DELETE CASCADE
datedate
requestsintegerDEFAULT 0
tokensintegerDEFAULT 0
input_tokensintegerDEFAULT 0
output_tokensintegerDEFAULT 0
cache_tokensintegerDEFAULT 0

Unique: (user_id, date)

Messages & Sessions

daily_messages

Core message table — the primary data store for all AI interactions.

ColumnTypeNotes
idinteger PK
datevarcharNOT NULL
tool_namevarcharNOT NULL
host_namevarcharDEFAULT 'localhost'
message_idvarcharNOT NULL
parent_idvarchar
rolevarcharNOT NULL (user/assistant/system)
contenttext
full_entrytext
tokens_usedintegerDEFAULT 0
input_tokensintegerDEFAULT 0
output_tokensintegerDEFAULT 0
modelvarchar
timestamptimestamp
sender_idvarchar
sender_namevarchar
message_sourcevarchar
conversation_idvarchar
agent_session_idvarchar
user_idinteger
project_pathtext

Unique: (date, tool_name, message_id, host_name). 18 indexes covering query patterns.

agent_sessions

AI agent session tracking.

ColumnTypeNotes
idinteger PK
session_idtextUNIQUE
session_typetextDEFAULT 'chat'
titletext
tool_nametextNOT NULL
host_nametextDEFAULT 'localhost'
user_idinteger
statustextDEFAULT 'active'
total_tokensintegerDEFAULT 0
total_input_tokensintegerDEFAULT 0
total_output_tokensintegerDEFAULT 0
message_countintegerDEFAULT 0
modeltext
project_idinteger
project_pathvarchar(500)
contexttextSession context
settingstextSession settings
tagstextTags
created_attimestampCreation time
updated_attimestampUpdate time
completed_attimestampCompletion time
expires_attimestampExpiry time
request_countintegerDEFAULT 0, request count
workspace_typetextDEFAULT 'local', workspace type
remote_machine_idtextAssociated remote machine ID
paused_attimestampPause time

session_messages

Messages within an agent session.

ColumnTypeNotes
idinteger PK
session_idtextFK → agent_sessions(session_id)
roletextNOT NULL
contenttext
tokens_usedintegerDEFAULT 0
modeltext
timestamptimestamp
metadatatext

Statistics

daily_stats

Aggregated daily statistics per tool/host/sender.

ColumnTypeNotes
datevarchar(10)NOT NULL
tool_namevarchar(50)NOT NULL
host_namevarchar(100)DEFAULT 'localhost'
sender_namevarchar(100)
total_tokensbigintNOT NULL
total_input_tokensbigintNOT NULL
total_output_tokensbigintNOT NULL
message_countintegerNOT NULL
project_idinteger
project_pathvarchar(500)

Unique: (date, tool_name, host_name, sender_name)

hourly_stats

Hourly breakdown of usage.

ColumnTypeNotes
datevarchar(10)NOT NULL
hourintegerNOT NULL
tool_namevarchar(50)NOT NULL
host_namevarchar(100)DEFAULT 'localhost'
total_tokensbigintNOT NULL
total_input_tokensbigintNOT NULL
total_output_tokensbigintNOT NULL
message_countintegerNOT NULL

Unique: (date, hour, tool_name, host_name)

daily_usage

Daily usage with cache token tracking.

ColumnTypeNotes
idinteger PK
datedateNOT NULL
tool_namevarcharNOT NULL
host_namevarcharDEFAULT 'localhost'
tokens_usedintegerDEFAULT 0
input_tokensintegerDEFAULT 0
output_tokensintegerDEFAULT 0
cache_tokensintegerDEFAULT 0
request_countintegerDEFAULT 0
models_usedtext

Unique: (date, tool_name, host_name)

usage_summary

Overall summary per tool/host for dashboard.

ColumnTypeNotes
tool_namevarchar(50)NOT NULL
host_namevarchar(100)
days_countintegerNOT NULL
total_tokensbigintNOT NULL
avg_tokensbigintNOT NULL
total_requestsintegerNOT NULL
total_input_tokensbigintNOT NULL
total_output_tokensbigintNOT NULL
first_datevarchar(10)
last_datevarchar(10)

Unique: (tool_name, host_name)

session_stats (Materialized View)

Aggregated from daily_messages where agent_session_id IS NOT NULL. Provides session-level token counts, message counts, and timestamp ranges.

Multi-Tenant

tenants

ColumnTypeNotes
idinteger PK
nametextNOT NULL
slugtextUNIQUE
statustextCHECK IN ('active','suspended','trial','inactive')
plantextCHECK IN ('free','standard','premium','enterprise')
contact_emailtext
user_countintegerDEFAULT 0
total_tokens_usedintegerDEFAULT 0
deleted_attimestampSoft delete

tenant_settings (1:1 with tenants)

ColumnTypeNotes
tenant_idintegerUNIQUE FK → tenants(id) ON DELETE CASCADE
content_filter_enabledbooleanDEFAULT true
audit_log_enabledbooleanDEFAULT true
audit_log_retention_daysintegerDEFAULT 90
data_retention_daysintegerDEFAULT 365
sso_enabledbooleanDEFAULT false

tenant_quotas (1:1 with tenants)

ColumnTypeNotes
tenant_idintegerUNIQUE FK → tenants(id) ON DELETE CASCADE
daily_token_limitintegerDEFAULT 1,000,000
monthly_token_limitintegerDEFAULT 30,000,000
max_usersintegerDEFAULT 100
max_sessions_per_userintegerDEFAULT 5

tenant_usage

ColumnTypeNotes
idinteger PK
tenant_idintegerFK → tenants(id) ON DELETE CASCADE
datedateNOT NULL
tokens_usedintegerDEFAULT 0
requests_madeintegerDEFAULT 0
active_usersintegerDEFAULT 0

Unique: (tenant_id, date)

SSO

sso_providers

ColumnTypeNotes
idinteger PK
nametextUNIQUE
provider_typetextNOT NULL (oauth2/oidc)
configtextNOT NULL (JSON)
tenant_idintegerFK → tenants(id)
is_activebooleanDEFAULT true

sso_identities

ColumnTypeNotes
idinteger PK
user_idintegerFK → users(id)
provider_nametextNOT NULL
provider_user_idtextNOT NULL

Unique: (provider_name, provider_user_id)

sso_sessions

ColumnTypeNotes
idinteger PK
session_tokentextUNIQUE
user_idintegerFK → users(id)
provider_nametextNOT NULL
access_tokentext
refresh_tokentext
expires_attimestamp

Governance & Compliance

audit_logs

ColumnTypeNotes
idinteger PK
timestamptimestampDEFAULT CURRENT_TIMESTAMP
user_idinteger
usernametext
actiontextNOT NULL
severitytextDEFAULT 'info'
resource_typetext
resource_idtext
detailstext
ip_addresstext
successbooleanDEFAULT true

Indexes: idx_audit_timestamp, idx_audit_user_id, idx_audit_action, idx_audit_severity

content_filter_rules

ColumnTypeNotes
idinteger PK
patterntextNOT NULL
typetextDEFAULT 'keyword'
severitytextDEFAULT 'medium'
actiontextDEFAULT 'warn'
is_enabledbooleanDEFAULT true

security_settings

Key-value store for security configuration.

ColumnTypeNotes
idinteger PK
setting_keyvarchar(100)UNIQUE
setting_valuetext
descriptiontext

anomaly_status

Anomaly status tracking.

ColumnTypeNotes
idinteger PKAuto-increment
anomaly_typevarcharAnomaly type
affected_users_hashvarcharAffected users hash
statusvarcharProcessing status
processed_byintegerProcessor ID
processed_attimestampProcessing time
created_attimestampCreation time

insights_reports

AI-generated usage insight reports.

ColumnTypeNotes
idinteger PKAuto-increment
user_idintegerUser ID
start_datevarcharStart date
end_datevarcharEnd date
overall_scoreintegerOverall score
overall_assessmenttextOverall assessment
strengthstextStrengths (JSON)
areas_for_improvementtextAreas for improvement (JSON)
suggestionstextSuggestions (JSON)
usage_summarytextUsage summary (JSON)
modelvarcharModel used
raw_responsetextRaw AI response
created_attimestampCreation time

Security & Permissions

login_attempts

Failed login attempt tracking for account lockout.

ColumnTypeNotes
usernamevarcharNOT NULL, lookup key
attempt_countintegerDEFAULT 0
locked_untiltimestampLock expiry time

user_permissions

User-level permission overrides.

ColumnTypeNotes
idinteger PKAuto-increment
user_idintegerNOT NULL
permissiontextNOT NULL
granted_byintegerGrantor
granted_attimestampDEFAULT CURRENT_TIMESTAMP

Indexes: idx_user_permissions_user, idx_user_permissions_permission

role_permissions

Role permission templates.

ColumnTypeNotes
idinteger PKAuto-increment
roletextNOT NULL
permissiontextNOT NULL

Indexes: idx_role_permissions_role, idx_role_permissions_permission

Alerts & Quotas

alerts

ColumnTypeNotes
idinteger PK
alert_idtextUNIQUE
alert_typetextNOT NULL
severitytextNOT NULL
titletextNOT NULL
messagetext
user_idinteger
readbooleanDEFAULT false

quota_usage

ColumnTypeNotes
idinteger PK
user_idintegerFK → users(id) ON DELETE CASCADE
datedateNOT NULL
periodtextDEFAULT 'daily'
tokens_usedintegerDEFAULT 0
requests_usedintegerDEFAULT 0

Unique: (user_id, date, period)

quota_alerts

ColumnTypeNotes
idinteger PK
user_idintegerFK → users(id) ON DELETE CASCADE
alert_typetextNOT NULL
quota_typetextNOT NULL
thresholdrealNOT NULL
current_usageintegerNOT NULL
quota_limitintegerNOT NULL
percentagerealNOT NULL
acknowledgedbooleanDEFAULT false

notification_preferences

ColumnTypeNotes
user_idintegerPK
email_enabledbooleanDEFAULT true
push_enabledbooleanDEFAULT true
min_severitytextDEFAULT 'warning'

Workspace & Projects

projects

ColumnTypeNotes
idinteger PK
pathvarchar(500)UNIQUE
namevarchar(200)
descriptiontext
created_byinteger
is_activebooleanDEFAULT true
is_sharedbooleanDEFAULT false

user_projects

ColumnTypeNotes
idinteger PK
user_idintegerNOT NULL
project_idintegerNOT NULL
total_sessionsintegerDEFAULT 0
total_tokensbigintDEFAULT 0
total_requestsintegerDEFAULT 0

Unique: (user_id, project_id)

prompt_templates

ColumnTypeNotes
idinteger PK
nametextNOT NULL
categorytextDEFAULT 'general'
contenttextNOT NULL
variablestext
tagstext
author_idinteger
is_publicbooleanDEFAULT false
is_featuredbooleanDEFAULT false
use_countintegerDEFAULT 0

Remote Workspace

remote_machines

Remote workspace machine registry.

ColumnTypeNotes
idinteger PKAuto-increment
machine_idtextMachine unique identifier
machine_nametextMachine name
hostnametextHostname
os_typetextOS type
os_versiontextOS version
ip_addresstextIP address
statustextStatus
agent_versiontextAgent version
capabilitiestextCapabilities (JSON)
cli_pathtextCLI path
work_dirtextWorking directory
tenant_idintegerTenant ID
created_byintegerCreator ID
created_attimestampCreation time
updated_attimestampUpdate time
last_heartbeattimestampLast heartbeat time

machine_assignments

User-to-remote-machine assignment relationships.

ColumnTypeNotes
idinteger PKAuto-increment
machine_idtextMachine ID
user_idintegerUser ID
permissiontextPermission level
granted_byintegerGrantor ID
granted_attimestampGrant time

api_key_store

Encrypted API key storage.

ColumnTypeNotes
idinteger PKAuto-increment
tenant_idintegerTenant ID
providertextAI service provider
key_nametextKey name
encrypted_keytextEncrypted key
key_hashtextKey hash
base_urltextAPI base URL
is_activebooleanDEFAULT true
created_byintegerCreator ID
created_attimestampCreation time
updated_attimestampUpdate time
cli_toolstextCLI tools configuration
cli_settingstextCLI settings

Collaboration

teams

ColumnTypeNotes
idinteger PK
team_idtextUNIQUE
nametextNOT NULL
descriptiontext
owner_idinteger

team_members

ColumnTypeNotes
idinteger PK
team_idtextNOT NULL
user_idintegerNOT NULL
roletextDEFAULT 'member'

Unique: (team_id, user_id)

shared_sessions

ColumnTypeNotes
idinteger PK
share_idtextUNIQUE
session_idtextNOT NULL
shared_byinteger
permissiontextDEFAULT 'view'
expires_attimestamp

knowledge_base

ColumnTypeNotes
idinteger PK
entry_idtextUNIQUE
team_idtext
titletextNOT NULL
contenttext
categorytextDEFAULT 'general'
is_publishedbooleanDEFAULT false

annotations

ColumnTypeNotes
idinteger PK
annotation_idtextUNIQUE
session_idtextNOT NULL
message_idtext
user_idinteger
contenttext
annotation_typetextDEFAULT 'comment'

Sync

sync_events

ColumnTypeNotes
idinteger PK
event_idtextUNIQUE
event_typetextNOT NULL
sourcetext
session_idtext
user_idinteger
tool_nametext
datatext

retention_history

ColumnTypeNotes
idinteger PK
timestamptimestampDEFAULT CURRENT_TIMESTAMP
report_datatextNOT NULL

Foreign Key Summary

Child TableColumnParent TableOn Delete
userstenant_idtenantsSET NULL
sessionsuser_idusersCASCADE
web_user_auth_sessionsuser_idusers
user_tool_accountsuser_idusersCASCADE
user_daily_statsuser_idusersCASCADE
session_messagessession_idagent_sessions
quota_usageuser_idusersCASCADE
quota_alertsuser_idusersCASCADE
sso_identitiesuser_idusers
sso_sessionsuser_idusers
sso_providerstenant_idtenants
tenant_quotastenant_idtenantsCASCADE
tenant_settingstenant_idtenantsCASCADE
tenant_usagetenant_idtenantsCASCADE
anomaly_statusprocessed_byusers
insights_reportsuser_idusers

Cross-Database Compatibility

See DATABASE-CONVENTIONS.md for naming conventions. The adapt_sql() function in app/repositories/database.py handles placeholder conversion (?%s) automatically.