diff --git a/app.py b/app.py index 8f35a90..5fa2ee1 100644 --- a/app.py +++ b/app.py @@ -1026,7 +1026,6 @@ def sqlite_error(error): app.logger.exception("Database error: %s", error) return jsonify({"error": "A database error occurred."}), 500 - def init_db() -> None: UPLOAD_DIR.mkdir(parents=True, exist_ok=True) @@ -1162,6 +1161,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( """ CREATE TABLE IF NOT EXISTS messages ( @@ -1291,6 +1313,7 @@ def init_db() -> None: id INTEGER PRIMARY KEY AUTOINCREMENT, team_id INTEGER NOT NULL, channel_id INTEGER, + parent_page_id INTEGER, slug TEXT COLLATE NOCASE NOT NULL, title TEXT NOT NULL, body TEXT NOT NULL DEFAULT '', @@ -1304,6 +1327,7 @@ def init_db() -> None: UNIQUE(team_id, slug), FOREIGN KEY (team_id) REFERENCES teams(id) ON DELETE CASCADE, 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 (updated_by_user_id) REFERENCES users(id) ON DELETE RESTRICT ) @@ -1320,8 +1344,11 @@ def init_db() -> None: bio_mode TEXT NOT NULL DEFAULT 'txt', website TEXT, location TEXT, + status_message TEXT NOT NULL DEFAULT '', + banner_attachment_id INTEGER, 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 ) """ ) @@ -1334,6 +1361,11 @@ def init_db() -> None: name_color TEXT, custom_css TEXT NOT NULL DEFAULT '', 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, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ) @@ -1399,13 +1431,24 @@ def init_db() -> None: db.execute( """ - CREATE TABLE IF NOT EXISTS presence_events ( - user_id INTEGER PRIMARY KEY, - updated_at REAL NOT NULL, - view_name TEXT, - room_id INTEGER, - channel_id INTEGER, - direct_conversation_id INTEGER, + 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 ) """ @@ -1413,22 +1456,13 @@ 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, + CREATE TABLE IF NOT EXISTS presence_events ( + user_id INTEGER PRIMARY KEY, + updated_at REAL NOT NULL, + view_name TEXT, + room_id INTEGER, + channel_id INTEGER, + direct_conversation_id INTEGER, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ) """ @@ -1531,6 +1565,22 @@ def init_db() -> None: db.execute("ALTER TABLE presence_events ADD COLUMN direct_conversation_id INTEGER") if not column_exists(db, "user_profiles", "badge_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_channel_id_id ON messages(channel_id, id)") @@ -1542,6 +1592,7 @@ 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_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_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_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)") @@ -1552,6 +1603,7 @@ 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_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_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_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)") @@ -1596,6 +1648,7 @@ def init_db() -> None: END WHERE role IS NULL OR role = '' + OR role NOT IN ('user', 'moderator', 'admin') """ ) @@ -1608,6 +1661,7 @@ def init_db() -> None: END WHERE status IS NULL OR status = '' + OR status NOT IN ('active', 'disabled', 'restricted', 'blacklisted') """ ) @@ -1722,6 +1776,8 @@ def init_db() -> None: bio_mode, website, location, + status_message, + banner_attachment_id, updated_at ) SELECT @@ -1732,6 +1788,8 @@ def init_db() -> None: 'txt', '', '', + '', + NULL, ? FROM users """, @@ -1746,6 +1804,11 @@ def init_db() -> None: name_color, custom_css, theme_mode, + presence_mode, + profile_background_color, + profile_banner_color, + profile_visibility, + last_active_visibility, updated_at ) SELECT @@ -1754,6 +1817,11 @@ def init_db() -> None: NULL, '', 'dark', + 'online', + NULL, + NULL, + 'public', + 'everyone', ? FROM users """,