CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; CREATE TABLE IF NOT EXISTS users ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), email VARCHAR(255) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, role VARCHAR(50) DEFAULT 'free', is_email_verified BOOLEAN DEFAULT false, email_verification_token VARCHAR(255), created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS qr_codes ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), user_id UUID REFERENCES users(id) ON DELETE CASCADE, workspace_id UUID, -- If created inside a team workspace type VARCHAR(20) NOT NULL, -- 'static' or 'dynamic' data_type VARCHAR(50) NOT NULL, -- 'URL', 'Wi-Fi', etc. destination_url TEXT, routing_data JSONB, -- Stores specific data for vCard, App Store, etc. short_url_id VARCHAR(50) UNIQUE, -- Only for dynamic routing e.g. 'xyz123' design_data JSONB, -- Custom styling tags TEXT[] DEFAULT '{}', created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS folders ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), user_id UUID REFERENCES users(id) ON DELETE CASCADE, workspace_id UUID, name VARCHAR(255) NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS workspace_members ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), owner_id UUID REFERENCES users(id) ON DELETE CASCADE, member_email VARCHAR(255) NOT NULL, role VARCHAR(50) DEFAULT 'editor', created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, UNIQUE(owner_id, member_email) ); CREATE TABLE IF NOT EXISTS qr_scans ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), qr_code_id UUID REFERENCES qr_codes(id) ON DELETE CASCADE, ip_address VARCHAR(45), user_agent TEXT, os VARCHAR(50), device_type VARCHAR(50), browser VARCHAR(50), country VARCHAR(100), city VARCHAR(100), scanned_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP );