Skip to content

Database Schema

This page documents the complete PostgreSQL database schema for Alita Robot.

  • Total Tables: 27
  • Database Type: PostgreSQL
  • ORM: GORM
  • Migration Tool: Custom SQL migration runner (alita/db/migrations.go)
  • Migrations: 27 files using YYYYMMDDHHMMSS_description.sql naming (e.g., 20250805200527_initial_migration.sql)

All tables use an auto-incremented id field as the primary key (internal identifier), while external identifiers like user_id and chat_id (Telegram IDs) are stored with unique constraints.

Benefits:

  • Decouples internal schema from external systems
  • Provides stability if external IDs change
  • Simplifies GORM operations with consistent integer primary keys
  • Better performance for joins and indexing

Chat membership is managed via the JSONB users column on the chats table (an Int64Array of user IDs). The ChatUser GORM model exists in code for type safety but the physical chat_users join table has been dropped by migration.

Stores admin settings per chat.

ColumnTypeNullableDefaultConstraints
idBIGINTNOauto-incrementPRIMARY KEY
chat_idBIGINTNOUNIQUE
anon_adminBOOLEANNOfalse
created_atTIMESTAMPYES
updated_atTIMESTAMPYES
  • idx_admin_settings_chat
  • chat_idchats(chat_id) ON DELETE CASCADE ON UPDATE CASCADE

Stores anti-flood configuration per chat.

ColumnTypeNullableDefaultConstraints
idBIGINTNOauto-incrementPRIMARY KEY
chat_idBIGINTNOUNIQUE
flood_limitBIGINTNO5CHECK (flood_limit >= 0)
actionTEXTNO'mute'CHECK (action IN ('mute','ban','kick','warn','tban','tmute'))
delete_antiflood_messageBOOLEANNOfalse
created_atTIMESTAMPYES
updated_atTIMESTAMPYES

Note: Previous mode and limit columns were dropped by migrations (20260420120000_consolidate_duplicate_fields.sql, 20250814100000_fix_antiflood_column_duplication.sql). Only flood_limit is used.

  • idx_antiflood_chat_flood_active (conditional: flood_limit > 0)
  • chat_idchats(chat_id) ON DELETE CASCADE ON UPDATE CASCADE

Stores blacklisted words and their actions per chat.

ColumnTypeNullableDefaultConstraints
idBIGINTNOauto-incrementPRIMARY KEY
chat_idBIGINTNO
wordTEXTNO
actionTEXTNO'warn'CHECK (action IN ('warn','mute','ban','kick','tban','tmute','delete','none'))
reasonTEXTYES
created_atTIMESTAMPYES
updated_atTIMESTAMPYES
  • idx_blacklist_chat_word (composite: chat_id, word)
  • chat_idchats(chat_id) ON DELETE CASCADE ON UPDATE CASCADE

Tracks active captcha verification attempts for users.

ColumnTypeNullableDefaultConstraints
idSERIALNOauto-incrementPRIMARY KEY
user_idBIGINTNO
chat_idBIGINTNO
answerVARCHAR(255)NO
attemptsINTEGERNO0
message_idBIGINTYES
refresh_countINTEGERNO0
expires_atTIMESTAMPNOCHECK (expires_at > created_at)
created_atTIMESTAMPNOCURRENT_TIMESTAMP
updated_atTIMESTAMPNOCURRENT_TIMESTAMP
  • idx_captcha_user_chat (composite: user_id, chat_id)
  • idx_captcha_attempts_chat_id
  • idx_captcha_expires_at (dropped by migration 20250808120328; may not exist)
  • user_idusers(user_id) ON DELETE CASCADE
  • chat_idchats(chat_id) ON DELETE CASCADE

Tracks users who failed captcha with mute action, for automatic un-mute scheduling.

ColumnTypeNullableDefaultConstraints
idBIGSERIALNOauto-incrementPRIMARY KEY
user_idBIGINTNO
chat_idBIGINTNO
unmute_atTIMESTAMPTZNO
created_atTIMESTAMPTZNONOW()
  • idx_captcha_muted_user_chat (composite: user_id, chat_id)
  • idx_captcha_unmute_at
  • user_idusers(user_id) ON DELETE CASCADE
  • chat_idchats(chat_id) ON DELETE CASCADE

Stores captcha configuration per chat.

ColumnTypeNullableDefaultConstraints
idSERIALNOauto-incrementPRIMARY KEY
chat_idBIGINTNOUNIQUE
enabledBOOLEANNOFALSE
captcha_modeVARCHAR(10)NO'math'CHECK (captcha_mode IN ('math','text'))
timeoutINTEGERNO2CHECK (timeout BETWEEN 1 AND 10)
failure_actionVARCHAR(10)NO'kick'CHECK (failure_action IN ('kick','ban','mute'))
max_attemptsINTEGERNO3CHECK (max_attempts BETWEEN 1 AND 10)
created_atTIMESTAMPNOCURRENT_TIMESTAMP
updated_atTIMESTAMPNOCURRENT_TIMESTAMP
  • uk_captcha_settings_chat_id (UNIQUE)
  • chat_idchats(chat_id) ON DELETE CASCADE

Stores channel metadata and linked channel relationships.

ColumnTypeNullableDefaultConstraints
idBIGINTNOauto-incrementPRIMARY KEY
chat_idBIGINTNOUNIQUE
channel_idBIGINTYES
channel_nameTEXTYES
usernameTEXTYES
created_atTIMESTAMPYES
updated_atTIMESTAMPYES
  • idx_channels_chat_update
  • idx_channels_username

Note: All foreign key constraints on this table have been dropped by migrations (20260117104821_fix_invalid_channels_fk_constraint.sql, 20260117120000_drop_channels_chat_fk.sql). The chat_id column stores the channel’s own Telegram ID for identification.


Junction table for many-to-many relationship between chats and users.

Note: The physical chat_users table has been dropped by migration (20250814100001_drop_unused_chat_users_table.sql). Chat membership is now managed exclusively via the JSONB users column on the chats table. The ChatUser GORM model exists in code for type safety only.

ColumnTypeNullableDefaultConstraints
chat_idBIGINTNOPRIMARY KEY (composite)
user_idBIGINTNOPRIMARY KEY (composite)

Main table storing chat/group information.

ColumnTypeNullableDefaultConstraints
idBIGINTNOauto-incrementPRIMARY KEY
chat_idBIGINTNOUNIQUE
chat_nameTEXTYES
languageTEXTYES
usersJSONBYES
is_inactiveBOOLEANNOfalse
last_activityTIMESTAMPYES
created_atTIMESTAMPYES
updated_atTIMESTAMPYES
  • idx_chats_chat_id_active
  • idx_chats_covering
  • idx_chats_users_gin
  • idx_chats_inactive
  • idx_chats_last_activity
  • idx_chats_activity_status

User-to-chat connection state.

ColumnTypeNullableDefaultConstraints
idBIGINTNOauto-incrementPRIMARY KEY
user_idBIGINTNOUNIQUE (composite: user_id, chat_id)
chat_idBIGINTNOUNIQUE (composite: user_id, chat_id)
connectedBOOLEANNOfalse
created_atTIMESTAMPYES
updated_atTIMESTAMPYES
  • idx_connection_user_id
  • idx_connection_chat_id
  • user_idusers(user_id) ON DELETE CASCADE ON UPDATE CASCADE
  • chat_idchats(chat_id) ON DELETE CASCADE ON UPDATE CASCADE

Chat-level connection configuration.

ColumnTypeNullableDefaultConstraints
idBIGINTNOauto-incrementPRIMARY KEY
chat_idBIGINTNOUNIQUE
enabledBOOLEANNOtrue
allow_connectBOOLEANNOtrue
created_atTIMESTAMPYES
updated_atTIMESTAMPYES

Note: The enabled column was dropped by migration 20251231131415 as duplicate of allow_connect. It remains defined in the GORM model but may not exist in the physical database schema.

  • chat_idchats(chat_id) ON DELETE CASCADE ON UPDATE CASCADE

Bot developers and sudo users.

ColumnTypeNullableDefaultConstraints
idBIGINTNOauto-incrementPRIMARY KEY
user_idBIGINTNOUNIQUE
is_devBOOLEANNOfalse
devBOOLEANNOfalse
sudoBOOLEANNOfalse
created_atTIMESTAMPYES
updated_atTIMESTAMPYES

Note: The dev column was dropped by migration 20260420120000 (consolidated into is_dev). It remains defined in the GORM model for backward compatibility but may not exist in the physical database schema.

  • user_idusers(user_id) ON DELETE CASCADE ON UPDATE CASCADE

Per-command disable state for chats.

ColumnTypeNullableDefaultConstraints
idBIGINTNOauto-incrementPRIMARY KEY
chat_idBIGINTNOUNIQUE (composite: chat_id, command)
commandTEXTNOUNIQUE (composite: chat_id, command)
disabledBOOLEANNOtrue
delete_commandsBOOLEANNOfalse
created_atTIMESTAMPYES
updated_atTIMESTAMPYES
  • chat_idchats(chat_id) ON DELETE CASCADE ON UPDATE CASCADE

Chat-level disable configuration for command deletion behavior.

ColumnTypeNullableDefaultConstraints
idBIGINTNOauto-incrementPRIMARY KEY
chat_idBIGINTNOUNIQUE
delete_commandsBOOLEANNOfalse
created_atTIMESTAMPYES
updated_atTIMESTAMPYES

Custom keyword filters per chat.

ColumnTypeNullableDefaultConstraints
idBIGINTNOauto-incrementPRIMARY KEY
chat_idBIGINTNOUNIQUE (composite: chat_id, keyword)
keywordTEXTNOUNIQUE (composite: chat_id, keyword)
filter_replyTEXTYES
msgtypeBIGINTYES
fileidTEXTYES
nonotifBOOLEANNOfalse
filter_buttonsJSONBYES
created_atTIMESTAMPYES
updated_atTIMESTAMPYES
  • idx_filters_chat_keyword (composite: chat_id, keyword)
  • chat_idchats(chat_id) ON DELETE CASCADE ON UPDATE CASCADE

Welcome and goodbye message settings per chat.

ColumnTypeNullableDefaultConstraints
idBIGINTNOauto-incrementPRIMARY KEY
chat_idBIGINTNOUNIQUE
clean_service_settingsBOOLEANNOfalse
welcome_clean_oldBOOLEANNOfalse
welcome_last_msg_idBIGINTYES
welcome_enabledBOOLEANNOtrue
welcome_textTEXTYES
welcome_file_idTEXTYES
welcome_typeBIGINTNO1
welcome_btnsJSONBYES
goodbye_clean_oldBOOLEANNOfalse
goodbye_last_msg_idBIGINTYES
goodbye_enabledBOOLEANNOtrue
goodbye_textTEXTYES
goodbye_file_idTEXTYES
goodbye_typeBIGINTNO1
goodbye_btnsJSONBYES
auto_approveBOOLEANNOfalse
created_atTIMESTAMPYES
updated_atTIMESTAMPYES
  • idx_greetings_chat_enabled
  • chat_idchats(chat_id) ON DELETE CASCADE ON UPDATE CASCADE

Locked permissions per chat.

ColumnTypeNullableDefaultConstraints
idBIGINTNOauto-incrementPRIMARY KEY
chat_idBIGINTNOUNIQUE (composite: chat_id, lock_type)
lock_typeTEXTNOUNIQUE (composite: chat_id, lock_type)
lockedBOOLEANNOfalse
created_atTIMESTAMPYES
updated_atTIMESTAMPYES
  • idx_locks_chat_lock_lookup
  • idx_locks_covering
  • chat_idchats(chat_id) ON DELETE CASCADE ON UPDATE CASCADE

Saved notes/tags per chat.

ColumnTypeNullableDefaultConstraints
idBIGINTNOauto-incrementPRIMARY KEY
chat_idBIGINTNOUNIQUE (composite: chat_id, note_name)
note_nameTEXTNOUNIQUE (composite: chat_id, note_name)
note_contentTEXTYES
file_idTEXTYES
msg_typeBIGINTYES
buttonsJSONBYES
admin_onlyBOOLEANNOfalse
private_onlyBOOLEANNOfalse
group_onlyBOOLEANNOfalse
web_previewBOOLEANNOtrue
is_protectedBOOLEANNOfalse
no_notifBOOLEANNOfalse
created_atTIMESTAMPYES
updated_atTIMESTAMPYES
  • idx_notes_chat_name (composite: chat_id, note_name)
  • chat_idchats(chat_id) ON DELETE CASCADE ON UPDATE CASCADE

Note settings per chat.

ColumnTypeNullableDefaultConstraints
idBIGINTNOauto-incrementPRIMARY KEY
chat_idBIGINTNOUNIQUE
privateBOOLEANNOfalse
created_atTIMESTAMPYES
updated_atTIMESTAMPYES
  • chat_idchats(chat_id) ON DELETE CASCADE ON UPDATE CASCADE

Pinned message settings per chat.

ColumnTypeNullableDefaultConstraints
idBIGINTNOauto-incrementPRIMARY KEY
chat_idBIGINTNOUNIQUE
msg_idBIGINTYES
clean_linkedBOOLEANNOfalse
anti_channel_pinBOOLEANNOfalse
created_atTIMESTAMPYES
updated_atTIMESTAMPYES
  • idx_pins_chat
  • chat_idchats(chat_id) ON DELETE CASCADE ON UPDATE CASCADE

Report settings per chat.

ColumnTypeNullableDefaultConstraints
idBIGINTNOauto-incrementPRIMARY KEY
chat_idBIGINTNOUNIQUE
enabledBOOLEANNOtrue
statusBOOLEANNOtrue
blocked_listJSONBYES
created_atTIMESTAMPYES
updated_atTIMESTAMPYES
  • chat_idchats(chat_id) ON DELETE CASCADE ON UPDATE CASCADE

Report settings per user.

ColumnTypeNullableDefaultConstraints
idBIGINTNOauto-incrementPRIMARY KEY
user_idBIGINTNOUNIQUE
enabledBOOLEANNOtrue
statusBOOLEANNOtrue
created_atTIMESTAMPYES
updated_atTIMESTAMPYES
  • user_idusers(user_id) ON DELETE CASCADE ON UPDATE CASCADE

Chat rules text.

ColumnTypeNullableDefaultConstraints
idBIGINTNOauto-incrementPRIMARY KEY
chat_idBIGINTNOUNIQUE
rulesTEXTYES
rules_btnTEXTYES
privateBOOLEANNOfalse
created_atTIMESTAMPYES
updated_atTIMESTAMPYES
  • chat_idchats(chat_id) ON DELETE CASCADE ON UPDATE CASCADE

Stores messages sent by users before completing captcha verification.

ColumnTypeNullableDefaultConstraints
idBIGSERIALNOauto-incrementPRIMARY KEY
user_idBIGINTNO
chat_idBIGINTNO
message_typeINTEGERNO1
contentTEXTYES
file_idTEXTYES
captionTEXTYES
attempt_idBIGINTNO
created_atTIMESTAMPTZNONOW()
  • idx_stored_user_chat (composite: user_id, chat_id)
  • idx_stored_attempt
  • attempt_idcaptcha_attempts(id) ON DELETE CASCADE

Main table storing user information.

ColumnTypeNullableDefaultConstraints
idBIGINTNOauto-incrementPRIMARY KEY
user_idBIGINTNOUNIQUE
usernameTEXTYESINDEXED
nameTEXTYES
languageTEXTNO'en'
last_activityTIMESTAMPYES
created_atTIMESTAMPYES
updated_atTIMESTAMPYES
  • idx_users_user_id_active
  • idx_users_covering
  • idx_users_last_activity

Warning system settings per chat.

ColumnTypeNullableDefaultConstraints
idBIGINTNOauto-incrementPRIMARY KEY
chat_idBIGINTNOUNIQUE
warn_limitBIGINTNO3CHECK (warn_limit > 0)
warn_modeTEXTYESCHECK (warn_mode IS NULL OR warn_mode = '' OR warn_mode IN ('ban','kick','mute','tban','tmute'))
created_atTIMESTAMPYES
updated_atTIMESTAMPYES
  • chat_idchats(chat_id) ON DELETE CASCADE ON UPDATE CASCADE

User warnings per chat.

ColumnTypeNullableDefaultConstraints
idBIGINTNOauto-incrementPRIMARY KEY
user_idBIGINTNOUNIQUE (composite: user_id, chat_id)
chat_idBIGINTNOUNIQUE (composite: user_id, chat_id)
num_warnsBIGINTNO0CHECK (num_warns >= 0)
warnsJSONBYES
created_atTIMESTAMPYES
updated_atTIMESTAMPYES
  • idx_warns_users_user_id
  • idx_warns_users_chat_id
  • idx_warns_users_composite
  • user_idusers(user_id) ON DELETE CASCADE ON UPDATE CASCADE
  • chat_idchats(chat_id) ON DELETE CASCADE ON UPDATE CASCADE
  • Users: Telegram users who interact with the bot
  • Chats: Telegram groups/channels managed by the bot
  • Chat Users: Managed via JSONB users array on the chats table (not a physical join table)
  • User ↔ Chat: Many-to-many through JSONB users field on chats
  • Chat → Settings: One-to-one (module-specific settings like warns_settings, antiflood_settings, pins)
  • Chat → Content: One-to-many (filters, notes, blacklists)
  • User → Chat Warnings: One-to-many through warns_users
  • Chat → Captcha: One-to-one (captcha_settings) with one-to-many attempts (captcha_attempts)