This commit is contained in:
dev 2026-10-31 08:34:19 +00:00
parent 2cd955f835
commit 952c755e1d

129
app.py
View File

@ -1026,6 +1026,7 @@ def sqlite_error(error):
app.logger.exception("Database error: %s", error) app.logger.exception("Database error: %s", error)
return jsonify({"error": "A database error occurred."}), 500 return jsonify({"error": "A database error occurred."}), 500
def init_db() -> None: def init_db() -> None:
UPLOAD_DIR.mkdir(parents=True, exist_ok=True) UPLOAD_DIR.mkdir(parents=True, exist_ok=True)
@ -1161,29 +1162,6 @@ def init_db() -> None:
""" """
) )
db.execute(
"""
CREATE TABLE IF NOT EXISTS direct_conversations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
member_pair_key TEXT UNIQUE NOT NULL,
created_at TEXT NOT NULL
)
"""
)
db.execute(
"""
CREATE TABLE IF NOT EXISTS direct_conversation_members (
direct_conversation_id INTEGER NOT NULL,
user_id INTEGER NOT NULL,
added_at TEXT NOT NULL,
PRIMARY KEY (direct_conversation_id, user_id),
FOREIGN KEY (direct_conversation_id) REFERENCES direct_conversations(id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
)
"""
)
db.execute( db.execute(
""" """
CREATE TABLE IF NOT EXISTS messages ( CREATE TABLE IF NOT EXISTS messages (
@ -1313,7 +1291,6 @@ def init_db() -> None:
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
team_id INTEGER NOT NULL, team_id INTEGER NOT NULL,
channel_id INTEGER, channel_id INTEGER,
parent_page_id INTEGER,
slug TEXT COLLATE NOCASE NOT NULL, slug TEXT COLLATE NOCASE NOT NULL,
title TEXT NOT NULL, title TEXT NOT NULL,
body TEXT NOT NULL DEFAULT '', body TEXT NOT NULL DEFAULT '',
@ -1327,7 +1304,6 @@ def init_db() -> None:
UNIQUE(team_id, slug), UNIQUE(team_id, slug),
FOREIGN KEY (team_id) REFERENCES teams(id) ON DELETE CASCADE, FOREIGN KEY (team_id) REFERENCES teams(id) ON DELETE CASCADE,
FOREIGN KEY (channel_id) REFERENCES channels(id) ON DELETE SET NULL, FOREIGN KEY (channel_id) REFERENCES channels(id) ON DELETE SET NULL,
FOREIGN KEY (parent_page_id) REFERENCES pages(id) ON DELETE SET NULL,
FOREIGN KEY (created_by_user_id) REFERENCES users(id) ON DELETE RESTRICT, FOREIGN KEY (created_by_user_id) REFERENCES users(id) ON DELETE RESTRICT,
FOREIGN KEY (updated_by_user_id) REFERENCES users(id) ON DELETE RESTRICT FOREIGN KEY (updated_by_user_id) REFERENCES users(id) ON DELETE RESTRICT
) )
@ -1344,11 +1320,8 @@ def init_db() -> None:
bio_mode TEXT NOT NULL DEFAULT 'txt', bio_mode TEXT NOT NULL DEFAULT 'txt',
website TEXT, website TEXT,
location TEXT, location TEXT,
status_message TEXT NOT NULL DEFAULT '',
banner_attachment_id INTEGER,
updated_at TEXT NOT NULL, updated_at TEXT NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
FOREIGN KEY (banner_attachment_id) REFERENCES attachments(id) ON DELETE SET NULL
) )
""" """
) )
@ -1361,11 +1334,6 @@ def init_db() -> None:
name_color TEXT, name_color TEXT,
custom_css TEXT NOT NULL DEFAULT '', custom_css TEXT NOT NULL DEFAULT '',
theme_mode TEXT NOT NULL DEFAULT 'dark', theme_mode TEXT NOT NULL DEFAULT 'dark',
presence_mode TEXT NOT NULL DEFAULT 'online',
profile_background_color TEXT,
profile_banner_color TEXT,
profile_visibility TEXT NOT NULL DEFAULT 'public',
last_active_visibility TEXT NOT NULL DEFAULT 'everyone',
updated_at TEXT NOT NULL, updated_at TEXT NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) )
@ -1429,31 +1397,6 @@ def init_db() -> None:
""" """
) )
db.execute(
"""
CREATE TABLE IF NOT EXISTS message_pins (
message_id INTEGER PRIMARY KEY,
pinned_by_user_id INTEGER NOT NULL,
pinned_at TEXT NOT NULL,
FOREIGN KEY (message_id) REFERENCES messages(id) ON DELETE CASCADE,
FOREIGN KEY (pinned_by_user_id) REFERENCES users(id) ON DELETE CASCADE
)
"""
)
db.execute(
"""
CREATE TABLE IF NOT EXISTS message_bookmarks (
message_id INTEGER NOT NULL,
user_id INTEGER NOT NULL,
created_at TEXT NOT NULL,
PRIMARY KEY (message_id, user_id),
FOREIGN KEY (message_id) REFERENCES messages(id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
)
"""
)
db.execute( db.execute(
""" """
CREATE TABLE IF NOT EXISTS presence_events ( CREATE TABLE IF NOT EXISTS presence_events (
@ -1468,6 +1411,29 @@ def init_db() -> None:
""" """
) )
db.execute(
"""
CREATE TABLE IF NOT EXISTS direct_conversations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
member_pair_key TEXT UNIQUE NOT NULL,
created_at TEXT NOT NULL
)
"""
)
db.execute(
"""
CREATE TABLE IF NOT EXISTS direct_conversation_members (
direct_conversation_id INTEGER NOT NULL,
user_id INTEGER NOT NULL,
added_at TEXT NOT NULL,
PRIMARY KEY (direct_conversation_id, user_id),
FOREIGN KEY (direct_conversation_id) REFERENCES direct_conversations(id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
)
"""
)
db.execute( db.execute(
""" """
CREATE TABLE IF NOT EXISTS call_sessions ( CREATE TABLE IF NOT EXISTS call_sessions (
@ -1565,22 +1531,6 @@ def init_db() -> None:
db.execute("ALTER TABLE presence_events ADD COLUMN direct_conversation_id INTEGER") db.execute("ALTER TABLE presence_events ADD COLUMN direct_conversation_id INTEGER")
if not column_exists(db, "user_profiles", "badge_text"): if not column_exists(db, "user_profiles", "badge_text"):
db.execute("ALTER TABLE user_profiles ADD COLUMN badge_text TEXT") db.execute("ALTER TABLE user_profiles ADD COLUMN badge_text TEXT")
if not column_exists(db, "user_profiles", "status_message"):
db.execute("ALTER TABLE user_profiles ADD COLUMN status_message TEXT NOT NULL DEFAULT ''")
if not column_exists(db, "user_profiles", "banner_attachment_id"):
db.execute("ALTER TABLE user_profiles ADD COLUMN banner_attachment_id INTEGER")
if not column_exists(db, "user_settings", "presence_mode"):
db.execute("ALTER TABLE user_settings ADD COLUMN presence_mode TEXT NOT NULL DEFAULT 'online'")
if not column_exists(db, "user_settings", "profile_background_color"):
db.execute("ALTER TABLE user_settings ADD COLUMN profile_background_color TEXT")
if not column_exists(db, "user_settings", "profile_banner_color"):
db.execute("ALTER TABLE user_settings ADD COLUMN profile_banner_color TEXT")
if not column_exists(db, "user_settings", "profile_visibility"):
db.execute("ALTER TABLE user_settings ADD COLUMN profile_visibility TEXT NOT NULL DEFAULT 'public'")
if not column_exists(db, "user_settings", "last_active_visibility"):
db.execute("ALTER TABLE user_settings ADD COLUMN last_active_visibility TEXT NOT NULL DEFAULT 'everyone'")
if not column_exists(db, "pages", "parent_page_id"):
db.execute("ALTER TABLE pages ADD COLUMN parent_page_id INTEGER")
db.execute("CREATE INDEX IF NOT EXISTS idx_messages_room_id_id ON messages(room_id, id)") db.execute("CREATE INDEX IF NOT EXISTS idx_messages_room_id_id ON messages(room_id, id)")
db.execute("CREATE INDEX IF NOT EXISTS idx_messages_channel_id_id ON messages(channel_id, id)") db.execute("CREATE INDEX IF NOT EXISTS idx_messages_channel_id_id ON messages(channel_id, id)")
@ -1592,7 +1542,6 @@ def init_db() -> None:
db.execute("CREATE INDEX IF NOT EXISTS idx_channels_team_id_slug ON channels(team_id, slug)") db.execute("CREATE INDEX IF NOT EXISTS idx_channels_team_id_slug ON channels(team_id, slug)")
db.execute("CREATE INDEX IF NOT EXISTS idx_channels_legacy_room_id ON channels(legacy_room_id)") db.execute("CREATE INDEX IF NOT EXISTS idx_channels_legacy_room_id ON channels(legacy_room_id)")
db.execute("CREATE INDEX IF NOT EXISTS idx_pages_team_updated_at ON pages(team_id, updated_at DESC)") db.execute("CREATE INDEX IF NOT EXISTS idx_pages_team_updated_at ON pages(team_id, updated_at DESC)")
db.execute("CREATE INDEX IF NOT EXISTS idx_pages_parent_page_id ON pages(parent_page_id)")
db.execute("CREATE INDEX IF NOT EXISTS idx_channel_typing_events_updated_at ON channel_typing_events(channel_id, updated_at)") db.execute("CREATE INDEX IF NOT EXISTS idx_channel_typing_events_updated_at ON channel_typing_events(channel_id, updated_at)")
db.execute("CREATE INDEX IF NOT EXISTS idx_dm_typing_events_updated_at ON dm_typing_events(direct_conversation_id, updated_at)") db.execute("CREATE INDEX IF NOT EXISTS idx_dm_typing_events_updated_at ON dm_typing_events(direct_conversation_id, updated_at)")
db.execute("CREATE INDEX IF NOT EXISTS idx_invites_token_hash ON room_invites(token_hash)") db.execute("CREATE INDEX IF NOT EXISTS idx_invites_token_hash ON room_invites(token_hash)")
@ -1603,7 +1552,6 @@ def init_db() -> None:
db.execute("CREATE INDEX IF NOT EXISTS idx_message_reactions_message ON message_reactions(message_id, emoji)") db.execute("CREATE INDEX IF NOT EXISTS idx_message_reactions_message ON message_reactions(message_id, emoji)")
db.execute("CREATE INDEX IF NOT EXISTS idx_message_receipts_user_seen ON message_receipts(user_id, seen_at)") db.execute("CREATE INDEX IF NOT EXISTS idx_message_receipts_user_seen ON message_receipts(user_id, seen_at)")
db.execute("CREATE INDEX IF NOT EXISTS idx_message_attachments_message_position ON message_attachments(message_id, position)") db.execute("CREATE INDEX IF NOT EXISTS idx_message_attachments_message_position ON message_attachments(message_id, position)")
db.execute("CREATE INDEX IF NOT EXISTS idx_message_bookmarks_user_created ON message_bookmarks(user_id, created_at DESC)")
db.execute("CREATE INDEX IF NOT EXISTS idx_presence_events_updated_at ON presence_events(updated_at)") db.execute("CREATE INDEX IF NOT EXISTS idx_presence_events_updated_at ON presence_events(updated_at)")
db.execute("CREATE INDEX IF NOT EXISTS idx_presence_events_dm_id ON presence_events(direct_conversation_id, updated_at)") db.execute("CREATE INDEX IF NOT EXISTS idx_presence_events_dm_id ON presence_events(direct_conversation_id, updated_at)")
db.execute("CREATE INDEX IF NOT EXISTS idx_direct_conversation_members_user ON direct_conversation_members(user_id, direct_conversation_id)") db.execute("CREATE INDEX IF NOT EXISTS idx_direct_conversation_members_user ON direct_conversation_members(user_id, direct_conversation_id)")
@ -1648,7 +1596,6 @@ def init_db() -> None:
END END
WHERE role IS NULL WHERE role IS NULL
OR role = '' OR role = ''
OR role NOT IN ('user', 'moderator', 'admin')
""" """
) )
@ -1661,7 +1608,6 @@ def init_db() -> None:
END END
WHERE status IS NULL WHERE status IS NULL
OR status = '' OR status = ''
OR status NOT IN ('active', 'disabled', 'restricted', 'blacklisted')
""" """
) )
@ -1776,8 +1722,6 @@ def init_db() -> None:
bio_mode, bio_mode,
website, website,
location, location,
status_message,
banner_attachment_id,
updated_at updated_at
) )
SELECT SELECT
@ -1788,8 +1732,6 @@ def init_db() -> None:
'txt', 'txt',
'', '',
'', '',
'',
NULL,
? ?
FROM users FROM users
""", """,
@ -1804,11 +1746,6 @@ def init_db() -> None:
name_color, name_color,
custom_css, custom_css,
theme_mode, theme_mode,
presence_mode,
profile_background_color,
profile_banner_color,
profile_visibility,
last_active_visibility,
updated_at updated_at
) )
SELECT SELECT
@ -1817,11 +1754,6 @@ def init_db() -> None:
NULL, NULL,
'', '',
'dark', 'dark',
'online',
NULL,
NULL,
'public',
'everyone',
? ?
FROM users FROM users
""", """,
@ -1914,10 +1846,8 @@ def bootstrap_admin() -> None:
bio_mode, bio_mode,
website, website,
location, location,
status_message,
banner_attachment_id,
updated_at updated_at
) VALUES (?, ?, '', '', 'txt', '', '', '', NULL, ?) ) VALUES (?, ?, '', '', 'txt', '', '', ?)
""", """,
(user_id, username, now_iso()), (user_id, username, now_iso()),
) )
@ -1930,13 +1860,8 @@ def bootstrap_admin() -> None:
name_color, name_color,
custom_css, custom_css,
theme_mode, theme_mode,
presence_mode,
profile_background_color,
profile_banner_color,
profile_visibility,
last_active_visibility,
updated_at updated_at
) VALUES (?, '#f7dce8', NULL, '', 'dark', 'online', NULL, NULL, 'public', 'everyone', ?) ) VALUES (?, '#f7dce8', NULL, '', 'dark', ?)
""", """,
(user_id, now_iso()), (user_id, now_iso()),
) )