Customizable user profiles with stats, posts, and social connections in Mirage
User profiles in Mirage are fully customizable spaces where users showcase their identity, track their stats, manage connections, and display their content.
CREATE TABLE IF NOT EXISTS user_profile ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT UNIQUE NOT NULL, followers INTEGER DEFAULT 0, following INTEGER DEFAULT 0, posts INTEGER DEFAULT 0, upvotes INTEGER DEFAULT 0, downvotes INTEGER DEFAULT 0, FOREIGN KEY(username) REFERENCES users(username))
Followers & Following
Automatically updated when users follow/unfollow:
app/routes/users.py:148-156
# When someone follows youc.execute('INSERT INTO following (follower, following) VALUES (?, ?)', (username, target_username))c.execute('UPDATE user_profile SET following = following + 1 WHERE username=?', (username,))c.execute('UPDATE user_profile SET followers = followers + 1 WHERE username=?', (target_username,))
Post Count
Incremented whenever you create a post or reply:
app/routes/posts.py:33-35
c.execute('INSERT INTO posts (username,content) VALUES (?,?)', (username,content))c.execute('UPDATE user_profile SET posts = posts + 1 WHERE username=?', (username,))
Vote Counts
Updated when your posts receive upvotes or downvotes:
app/routes/posts.py:128-133
if vote_type == 'up': c.execute('UPDATE posts SET upvotes = upvotes + 1 WHERE id=?', (post_id,)) c.execute('UPDATE user_profile SET upvotes = upvotes + 1 WHERE username=?', (post_author,))
Build your network by following other Mirage users.
1
Follow a User
Visit their profile and click the follow button
app/routes/users.py:116-157
@users_bp.route('/api/follow', methods=['POST'])def follow_user(): # Verify target user exists c.execute('SELECT username FROM users WHERE username=?', (target_username,)) if not c.fetchone(): return jsonify({'error': 'user not found'}), 404 # Check if already following c.execute('SELECT * FROM following WHERE follower=? AND following=?', (username, target_username)) if c.fetchone(): return jsonify({'error': 'already following'}), 400 # Create follow relationship c.execute('INSERT INTO following (follower, following) VALUES (?, ?)', (username, target_username))
2
Automatic Stats Update
Your following count increases, their follower count increases
@users_bp.route('/api/unfollow', methods=['POST'])def unfollow_user(): # Remove follow relationship c.execute('DELETE FROM following WHERE follower=? AND following=?', (username, target_username)) if c.rowcount == 0: return jsonify({'error': 'not following this user'}), 400 # Update follower counts (decrement) c.execute('UPDATE user_profile SET following = following - 1 WHERE username=?', (username,)) c.execute('UPDATE user_profile SET followers = followers - 1 WHERE username=?', (target_username,))
You can only unfollow users you’re currently following. The system validates the relationship exists before removing it.
@users_bp.route('/api/get_followers/<username>', methods=['GET'])def get_followers(username): # Get followers with their avatars c.execute(''' SELECT u.username, u.avatar_url FROM following f JOIN users u ON f.follower = u.username WHERE f.following = ? ORDER BY f.created_at DESC ''', (username,)) followers = [{'username': row[0], 'avatar_url': row[1] or 'default.png'} for row in c.fetchall()]
app/routes/users.py:246-269
@users_bp.route('/api/get_following/<username>', methods=['GET'])def get_following(username): # Get following with their avatars c.execute(''' SELECT u.username, u.avatar_url FROM following f JOIN users u ON f.following = u.username WHERE f.follower = ? ORDER BY f.created_at DESC ''', (username,)) following = [{'username': row[0], 'avatar_url': row[1] or 'default.png'} for row in c.fetchall()]
app/routes/users.py:194-218
@users_bp.route('/api/check_follow', methods=['GET'])def check_follow(): # Check if following specific user c.execute('SELECT * FROM following WHERE follower=? AND following=?', (username, target_username)) is_following = bool(c.fetchone()) return jsonify({'is_following': is_following}), 200
CREATE TABLE IF NOT EXISTS users( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT UNIQUE NOT NULL, email TEXT UNIQUE NOT NULL, avatar_url TEXT, description TEXT, password TEXT NOT NULL, token TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, custom_css TEXT, background_image TEXT)
app/db.py:113-122
CREATE TABLE IF NOT EXISTS user_profile ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT UNIQUE NOT NULL, followers INTEGER DEFAULT 0, following INTEGER DEFAULT 0, posts INTEGER DEFAULT 0, upvotes INTEGER DEFAULT 0, downvotes INTEGER DEFAULT 0, FOREIGN KEY(username) REFERENCES users(username))
app/db.py:142-150
CREATE TABLE IF NOT EXISTS following ( id INTEGER PRIMARY KEY AUTOINCREMENT, follower TEXT NOT NULL, following TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY(follower) REFERENCES users(username), FOREIGN KEY(following) REFERENCES users(username), UNIQUE(follower, following))