diff --git a/aethex-bot/migrations/simple_migration.sql b/aethex-bot/migrations/simple_migration.sql new file mode 100644 index 0000000..302f3f0 --- /dev/null +++ b/aethex-bot/migrations/simple_migration.sql @@ -0,0 +1,209 @@ +-- Simple Migration - Only creates tables if they don't exist +-- Run this in Supabase SQL Editor + +-- Core user tables +CREATE TABLE IF NOT EXISTS user_profiles ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + username VARCHAR(255), + xp INTEGER DEFAULT 0, + prestige_level INTEGER DEFAULT 0, + total_xp_earned INTEGER DEFAULT 0, + daily_streak INTEGER DEFAULT 0, + last_daily TIMESTAMP WITH TIME ZONE, + title VARCHAR(255), + bio TEXT, + avatar_url VARCHAR(512), + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() +); + +CREATE TABLE IF NOT EXISTS discord_links ( + id SERIAL PRIMARY KEY, + discord_id VARCHAR(32) UNIQUE NOT NULL, + user_id UUID, + username VARCHAR(255), + linked_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() +); + +CREATE TABLE IF NOT EXISTS discord_verifications ( + id SERIAL PRIMARY KEY, + discord_id VARCHAR(32) UNIQUE NOT NULL, + verification_code VARCHAR(32) NOT NULL, + expires_at TIMESTAMP WITH TIME ZONE NOT NULL, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() +); + +CREATE TABLE IF NOT EXISTS server_config ( + id SERIAL PRIMARY KEY, + guild_id VARCHAR(32) UNIQUE NOT NULL, + prefix VARCHAR(10) DEFAULT '!', + verified_role_id VARCHAR(32), + welcome_channel_id VARCHAR(32), + welcome_message TEXT, + goodbye_channel_id VARCHAR(32), + goodbye_message TEXT, + log_channel_id VARCHAR(32), + mod_log_channel_id VARCHAR(32), + starboard_channel_id VARCHAR(32), + starboard_threshold INTEGER DEFAULT 3, + level_up_channel_id VARCHAR(32), + level_up_message TEXT, + xp_mode VARCHAR(32) DEFAULT 'standalone', + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() +); + +CREATE TABLE IF NOT EXISTS xp_config ( + id SERIAL PRIMARY KEY, + guild_id VARCHAR(32) UNIQUE NOT NULL, + xp_per_message INTEGER DEFAULT 15, + xp_cooldown INTEGER DEFAULT 60, + voice_xp_per_minute INTEGER DEFAULT 5, + reaction_xp INTEGER DEFAULT 5, + difficulty VARCHAR(32) DEFAULT 'normal', + bonus_channels JSONB DEFAULT '[]', + role_multipliers JSONB DEFAULT '{}', + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() +); + +CREATE TABLE IF NOT EXISTS guild_user_xp ( + id SERIAL PRIMARY KEY, + guild_id VARCHAR(32) NOT NULL, + user_id VARCHAR(32) NOT NULL, + xp INTEGER DEFAULT 0, + level INTEGER DEFAULT 0, + prestige INTEGER DEFAULT 0, + messages INTEGER DEFAULT 0, + voice_minutes INTEGER DEFAULT 0, + last_xp_at TIMESTAMP WITH TIME ZONE, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + UNIQUE(guild_id, user_id) +); + +CREATE TABLE IF NOT EXISTS user_stats ( + id SERIAL PRIMARY KEY, + user_id UUID, + guild_id VARCHAR(32) NOT NULL, + messages_sent INTEGER DEFAULT 0, + reactions_given INTEGER DEFAULT 0, + reactions_received INTEGER DEFAULT 0, + voice_minutes INTEGER DEFAULT 0, + commands_used INTEGER DEFAULT 0, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() +); + +CREATE TABLE IF NOT EXISTS level_roles ( + id SERIAL PRIMARY KEY, + guild_id VARCHAR(32) NOT NULL, + level INTEGER NOT NULL, + role_id VARCHAR(32) NOT NULL, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + UNIQUE(guild_id, level) +); + +CREATE TABLE IF NOT EXISTS achievements ( + id SERIAL PRIMARY KEY, + guild_id VARCHAR(32) NOT NULL, + name VARCHAR(255) NOT NULL, + description TEXT, + icon VARCHAR(64), + trigger_type VARCHAR(32) NOT NULL, + trigger_value INTEGER NOT NULL, + xp_reward INTEGER DEFAULT 0, + role_reward_id VARCHAR(32), + hidden BOOLEAN DEFAULT false, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() +); + +CREATE TABLE IF NOT EXISTS quests ( + id SERIAL PRIMARY KEY, + guild_id VARCHAR(32) NOT NULL, + name VARCHAR(255) NOT NULL, + description TEXT, + quest_type VARCHAR(32) DEFAULT 'daily', + trigger_type VARCHAR(32) NOT NULL, + target_value INTEGER NOT NULL, + xp_reward INTEGER DEFAULT 100, + active BOOLEAN DEFAULT true, + starts_at TIMESTAMP WITH TIME ZONE, + expires_at TIMESTAMP WITH TIME ZONE, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() +); + +CREATE TABLE IF NOT EXISTS shop_items ( + id SERIAL PRIMARY KEY, + guild_id VARCHAR(32) NOT NULL, + name VARCHAR(255) NOT NULL, + description TEXT, + price INTEGER NOT NULL, + item_type VARCHAR(32) NOT NULL, + item_data JSONB DEFAULT '{}', + stock INTEGER, + enabled BOOLEAN DEFAULT true, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() +); + +CREATE TABLE IF NOT EXISTS warnings ( + id SERIAL PRIMARY KEY, + guild_id VARCHAR(32) NOT NULL, + user_id VARCHAR(32) NOT NULL, + moderator_id VARCHAR(32) NOT NULL, + reason TEXT, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() +); + +CREATE TABLE IF NOT EXISTS mod_actions ( + id SERIAL PRIMARY KEY, + guild_id VARCHAR(32) NOT NULL, + user_id VARCHAR(32) NOT NULL, + moderator_id VARCHAR(32) NOT NULL, + action VARCHAR(32) NOT NULL, + reason TEXT, + duration INTEGER, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() +); + +CREATE TABLE IF NOT EXISTS command_cooldowns ( + id SERIAL PRIMARY KEY, + guild_id VARCHAR(32) NOT NULL, + user_id VARCHAR(32) NOT NULL, + command VARCHAR(64) NOT NULL, + expires_at TIMESTAMP WITH TIME ZONE NOT NULL, + UNIQUE(guild_id, user_id, command) +); + +CREATE TABLE IF NOT EXISTS command_logs ( + id SERIAL PRIMARY KEY, + guild_id VARCHAR(32) NOT NULL, + user_id VARCHAR(32) NOT NULL, + command VARCHAR(64) NOT NULL, + options JSONB, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() +); + +-- Enable RLS with permissive policies +DO $$ +DECLARE + t text; + tables text[] := ARRAY[ + 'user_profiles', 'discord_links', 'discord_verifications', 'server_config', + 'xp_config', 'guild_user_xp', 'user_stats', 'level_roles', 'achievements', + 'quests', 'shop_items', 'warnings', 'mod_actions', 'command_cooldowns', 'command_logs' + ]; +BEGIN + FOREACH t IN ARRAY tables + LOOP + BEGIN + EXECUTE format('ALTER TABLE %I ENABLE ROW LEVEL SECURITY', t); + EXECUTE format('DROP POLICY IF EXISTS "Allow all" ON %I', t); + EXECUTE format('CREATE POLICY "Allow all" ON %I FOR ALL USING (true) WITH CHECK (true)', t); + EXCEPTION WHEN OTHERS THEN + NULL; + END; + END LOOP; +END $$; + +GRANT ALL ON ALL TABLES IN SCHEMA public TO service_role; +GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO service_role;