-- Migration: Create users table -- Core user table for authentication and profile CREATE TABLE IF NOT EXISTS users ( id BIGSERIAL PRIMARY KEY, username VARCHAR(30) NOT NULL, slug VARCHAR(255), email VARCHAR(255) NOT NULL, password_hash VARCHAR(255), token_version INTEGER NOT NULL DEFAULT 0, first_name VARCHAR(100), last_name VARCHAR(100), avatar TEXT, bio TEXT, location VARCHAR(100), birthdate TIMESTAMP WITH TIME ZONE, gender VARCHAR(20), username_changed_at TIMESTAMP WITH TIME ZONE, role VARCHAR(50) NOT NULL DEFAULT 'user', is_active BOOLEAN DEFAULT TRUE, is_verified BOOLEAN DEFAULT FALSE, is_admin BOOLEAN DEFAULT FALSE, is_public BOOLEAN DEFAULT TRUE, last_login_at TIMESTAMP WITH TIME ZONE, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, deleted_at TIMESTAMP WITH TIME ZONE ); -- Unique indexes with soft delete support CREATE UNIQUE INDEX IF NOT EXISTS idx_users_email ON users(email) WHERE deleted_at IS NULL; CREATE UNIQUE INDEX IF NOT EXISTS idx_users_username ON users(username) WHERE deleted_at IS NULL; CREATE UNIQUE INDEX IF NOT EXISTS idx_users_slug ON users(slug) WHERE deleted_at IS NULL; -- Performance indexes CREATE INDEX IF NOT EXISTS idx_users_deleted_at ON users(deleted_at); CREATE INDEX IF NOT EXISTS idx_users_created_at ON users(created_at DESC); CREATE INDEX IF NOT EXISTS idx_users_is_active ON users(is_active) WHERE deleted_at IS NULL; -- Comments COMMENT ON TABLE users IS 'Core user accounts for authentication and profiles'; COMMENT ON COLUMN users.token_version IS 'Version number for JWT token invalidation'; COMMENT ON COLUMN users.slug IS 'URL-friendly unique identifier for user profile';