Skip to main content
User profiles in Mirage are fully customizable spaces where users showcase their identity, track their stats, manage connections, and display their content.

Profile Components

Every Mirage profile includes essential information and social metrics.

Basic Information

  • Username (unique identifier)
  • Avatar image (custom or default)
  • Bio/Description (up to 500 words)
  • Account creation date

Profile Stats

  • Followers count
  • Following count
  • Total posts published
  • Total upvotes received
  • Total downvotes received

Visual Customization

  • Custom CSS styling
  • Background image
  • Avatar URL customization

Social Content

  • All user’s posts displayed chronologically
  • Post voting metrics
  • Reply threads

Viewing Profiles

Access any user’s public profile to see their information and content.
app/routes/users.py:78-113
@users_bp.route('/api/user/<username>',methods=['GET'])
def get_user(username):
    conn = get_db_connection()
    c = conn.cursor()
    
    # Get basic user info
    c.execute('SELECT * FROM users WHERE username=?', (username,))
    row = c.fetchone()
    
    if not row:
        return jsonify({'error':'user not found'}),404
    
    # Get profile stats from user_profile table
    c.execute('SELECT followers, following, posts, upvotes, downvotes FROM user_profile WHERE username=?', (username,))
    profile_stats = c.fetchone()
    
    user_data = {
        'username': row[1],
        'avatar_url': row[3],
        'description': row[4],
        'created_at': row[7],
        'custom_css': row[8],
        'background_image': row[9],
        'stats': {
            'followers': profile_stats[0] if profile_stats else 0,
            'following': profile_stats[1] if profile_stats else 0,
            'posts': profile_stats[2] if profile_stats else 0,
            'upvotes': profile_stats[3] if profile_stats else 0,
            'downvotes': profile_stats[4] if profile_stats else 0
        }
    }

    return jsonify(user_data),200
Profile viewing is public and doesn’t require authentication. Anyone can view any user’s profile information.

Editing Your Profile

Customize your profile settings to reflect your personality and style.
You can update the following profile settings:
  • Email: Change your account email address
  • Avatar URL: Update your profile picture
  • Description: Edit your bio (max 500 words)
  • Password: Change your account password (securely hashed)
  • Custom CSS: Add personal styling to your profile
  • Background Image: Set a custom background
Email Uniqueness: Each email can only be associated with one account. Attempting to use an existing email will result in an error.

Profile Statistics

Mirage automatically tracks and displays comprehensive user statistics.

Stats Tracking

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)
)
Automatically updated when users follow/unfollow:
app/routes/users.py:148-156
# When someone follows you
c.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,))
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,))
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,))

Following System

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
3

Feed Integration

Their posts now appear in your For You Page

Unfollow

app/routes/users.py:159-192
@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.

Viewing Connections

See who follows a user and who they follow.
app/routes/users.py:221-244
@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()]

Profile Customization

Make your profile unique with custom styling and backgrounds.

Custom CSS

Add your own CSS to personalize your profile’s appearance:
custom_css = """
.profile-header {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 10px;
}
"""
CSS is stored in the database and applied when users view your profile.

Background Images

Set a custom background image URL to personalize your profile:
background_image = "https://example.com/my-background.jpg"

User Posts

View all posts created by a specific user on their profile.
app/routes/posts.py:43-63
@posts_bp.route('/api/get_posts/<username>',methods=['GET'])
def get_posts(username):
    c.execute('''SELECT id, username, content, created_at, upvotes, downvotes 
                 FROM posts 
                 WHERE username=? 
                 ORDER BY created_at DESC''',(username,))
    rows = c.fetchall()
    
    posts = []
    for row in rows:
        post_data = {
            'id': row[0],
            'username': row[1],
            'content': row[2],
            'created_at': row[3],
            'upvotes': row[4],
            'downvotes': row[5]
        }
        posts.append(post_data)
    
    return jsonify({'posts': posts}), 200
Posts are displayed in reverse chronological order (newest first) on user profiles.

Profile Initialization

New user profiles are automatically created with default stats during registration.
app/routes/auth.py:44-48
# Initialize all stats to 0
c.execute('''
INSERT INTO user_profile (username, followers, following, posts, upvotes, downvotes)
VALUES (?, 0, 0, 0, 0, 0)
''', (username,))
1

User Registration

When a new account is created, a corresponding profile entry is initialized
2

Default Values

All counters start at 0 (followers, following, posts, votes)
3

Auto-Increment

Stats automatically update as the user interacts with the platform

Database Schema

app/db.py:77-88
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
)

Profile Features Summary

Public Visibility

All profiles are publicly viewable without authentication

Real-Time Stats

Statistics update instantly as users interact with content

Full Customization

Custom CSS and backgrounds for personal expression

Social Graph

View followers and following to understand user networks

Content History

All user posts accessible from their profile

Secure Updates

Only the profile owner can edit their settings

API Endpoints

Get Profile

View user profile

Update Settings

Edit profile settings

Follow User

Follow a user

Unfollow User

Unfollow a user

Get Followers

View followers list

Get Following

View following list
Profile editing requires authentication, but viewing profiles is public and accessible to all users.

Build docs developers (and LLMs) love