-- Sozial Platform Database Schema -- SQLite -- Users table CREATE TABLE IF NOT EXISTS users ( id TEXT PRIMARY KEY, email TEXT UNIQUE NOT NULL, password_hash TEXT NOT NULL, username TEXT UNIQUE NOT NULL, display_name TEXT, bio TEXT, avatar_url TEXT, photos TEXT, -- JSON array gender TEXT, interested_in TEXT, -- JSON array age INTEGER, location TEXT, -- JSON object {city, lat, lng} interests TEXT, -- JSON array is_online INTEGER DEFAULT 0, last_seen INTEGER, settings TEXT, -- JSON object created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL ); -- Profiles table (extended profile data) CREATE TABLE IF NOT EXISTS profiles ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL UNIQUE, first_name TEXT, last_name TEXT, birthday TEXT, city TEXT, country TEXT, latitude REAL, longitude REAL, height_cm INTEGER, body_type TEXT, education TEXT, occupation TEXT, relationship_status TEXT, looking_for TEXT, about_me TEXT, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ); -- Posts table CREATE TABLE IF NOT EXISTS posts ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, type TEXT NOT NULL DEFAULT 'text', -- text|image|checkin content TEXT, media_urls TEXT, -- JSON array location TEXT, -- JSON object {name, lat, lng} likes_count INTEGER DEFAULT 0, comments_count INTEGER DEFAULT 0, shares_count INTEGER DEFAULT 0, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ); -- Post likes table CREATE TABLE IF NOT EXISTS post_likes ( id TEXT PRIMARY KEY, post_id TEXT NOT NULL, user_id TEXT NOT NULL, created_at INTEGER NOT NULL, FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, UNIQUE(post_id, user_id) ); -- Post comments table CREATE TABLE IF NOT EXISTS post_comments ( id TEXT PRIMARY KEY, post_id TEXT NOT NULL, user_id TEXT NOT NULL, parent_id TEXT, content TEXT NOT NULL, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL, FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, FOREIGN KEY (parent_id) REFERENCES post_comments(id) ON DELETE CASCADE ); -- Relationships table (follows and friends) CREATE TABLE IF NOT EXISTS relationships ( id TEXT PRIMARY KEY, follower_id TEXT NOT NULL, following_id TEXT NOT NULL, type TEXT NOT NULL DEFAULT 'follow', -- follow|friend status TEXT DEFAULT 'active', -- active|blocked|pending created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL, FOREIGN KEY (follower_id) REFERENCES users(id) ON DELETE CASCADE, FOREIGN KEY (following_id) REFERENCES users(id) ON DELETE CASCADE, UNIQUE(follower_id, following_id) ); -- Swipes table (for discovery feature) CREATE TABLE IF NOT EXISTS swipes ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, target_user_id TEXT NOT NULL, direction TEXT NOT NULL, -- like|pass|super_like created_at INTEGER NOT NULL, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, FOREIGN KEY (target_user_id) REFERENCES users(id) ON DELETE CASCADE, UNIQUE(user_id, target_user_id) ); -- Matches table CREATE TABLE IF NOT EXISTS matches ( id TEXT PRIMARY KEY, user1_id TEXT NOT NULL, user2_id TEXT NOT NULL, created_at INTEGER NOT NULL, FOREIGN KEY (user1_id) REFERENCES users(id) ON DELETE CASCADE, FOREIGN KEY (user2_id) REFERENCES users(id) ON DELETE CASCADE, UNIQUE(user1_id, user2_id) ); -- Chats (conversations) table CREATE TABLE IF NOT EXISTS chats ( id TEXT PRIMARY KEY, type TEXT NOT NULL DEFAULT 'direct', -- direct|group name TEXT, avatar_url TEXT, created_by TEXT, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL, FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL ); -- Chat participants table CREATE TABLE IF NOT EXISTS chat_participants ( id TEXT PRIMARY KEY, chat_id TEXT NOT NULL, user_id TEXT NOT NULL, joined_at INTEGER NOT NULL, last_read_at INTEGER, is_admin INTEGER DEFAULT 0, FOREIGN KEY (chat_id) REFERENCES chats(id) ON DELETE CASCADE, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, UNIQUE(chat_id, user_id) ); -- Chat messages table CREATE TABLE IF NOT EXISTS chat_messages ( id TEXT PRIMARY KEY, chat_id TEXT NOT NULL, sender_id TEXT NOT NULL, content TEXT NOT NULL, type TEXT DEFAULT 'text', -- text|image|system media_url TEXT, read_at INTEGER, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL, FOREIGN KEY (chat_id) REFERENCES chats(id) ON DELETE CASCADE, FOREIGN KEY (sender_id) REFERENCES users(id) ON DELETE CASCADE ); -- Events table CREATE TABLE IF NOT EXISTS events ( id TEXT PRIMARY KEY, creator_id TEXT NOT NULL, title TEXT NOT NULL, description TEXT, event_type TEXT DEFAULT 'meetup', -- meetup|party|date|other location_name TEXT, location_address TEXT, latitude REAL, longitude REAL, start_date INTEGER, end_date INTEGER, max_participants INTEGER, is_public INTEGER DEFAULT 1, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL, FOREIGN KEY (creator_id) REFERENCES users(id) ON DELETE CASCADE ); -- Event participants table CREATE TABLE IF NOT EXISTS event_participants ( id TEXT PRIMARY KEY, event_id TEXT NOT NULL, user_id TEXT NOT NULL, status TEXT DEFAULT 'going', -- going|maybe|not_going created_at INTEGER NOT NULL, FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, UNIQUE(event_id, user_id) ); -- Notifications table CREATE TABLE IF NOT EXISTS notifications ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, type TEXT NOT NULL, -- friend_request|friend_accepted|post_liked|post_commented|message|match|system title TEXT NOT NULL, body TEXT, data TEXT, -- JSON object with additional data is_read INTEGER DEFAULT 0, created_at INTEGER NOT NULL, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ); -- Media uploads table CREATE TABLE IF NOT EXISTS media ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, filename TEXT NOT NULL, original_name TEXT, mime_type TEXT, size INTEGER, url TEXT NOT NULL, created_at INTEGER NOT NULL, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ); -- Refresh tokens table for JWT CREATE TABLE IF NOT EXISTS refresh_tokens ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, token_hash TEXT NOT NULL, expires_at INTEGER NOT NULL, created_at INTEGER NOT NULL, revoked_at INTEGER, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ); -- Indexes for better performance CREATE INDEX IF NOT EXISTS idx_users_email ON users(email); CREATE INDEX IF NOT EXISTS idx_users_username ON users(username); CREATE INDEX IF NOT EXISTS idx_posts_user_id ON posts(user_id); CREATE INDEX IF NOT EXISTS idx_posts_created_at ON posts(created_at); CREATE INDEX IF NOT EXISTS idx_relationships_follower ON relationships(follower_id); CREATE INDEX IF NOT EXISTS idx_relationships_following ON relationships(following_id); CREATE INDEX IF NOT EXISTS idx_chat_messages_chat_id ON chat_messages(chat_id); CREATE INDEX IF NOT EXISTS idx_chat_messages_created_at ON chat_messages(created_at); CREATE INDEX IF NOT EXISTS idx_notifications_user_id ON notifications(user_id); CREATE INDEX IF NOT EXISTS idx_notifications_created_at ON notifications(created_at); CREATE INDEX IF NOT EXISTS idx_swipes_user_id ON swipes(user_id); CREATE INDEX IF NOT EXISTS idx_matches_user1 ON matches(user1_id); CREATE INDEX IF NOT EXISTS idx_matches_user2 ON matches(user2_id);