Add missing tables to Supabase and improve API logging for federation data
Creates SQL migration script for federation tables in Supabase and adds detailed logging to federation API endpoints in webServer.js. Replit-Commit-Author: Agent Replit-Commit-Session-Id: aed2e46d-25bb-4b73-81a1-bb9e8437c261 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: f067ae59-c14c-4c16-bbf9-bb3883920fcc Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3bdfff67-975a-46ad-9845-fbb6b4a4c4b5/aed2e46d-25bb-4b73-81a1-bb9e8437c261/BXwPVpJ Replit-Helium-Checkpoint-Created: true
This commit is contained in:
parent
280b62ced9
commit
6fb0e785f6
2 changed files with 144 additions and 4 deletions
128
aethex-bot/migrations/create_federation_tables.sql
Normal file
128
aethex-bot/migrations/create_federation_tables.sql
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
-- Federation Tables for AeThex Bot
|
||||
-- Run this in your Supabase SQL Editor
|
||||
|
||||
-- Federation Servers - Tracks servers that are part of the federation
|
||||
CREATE TABLE IF NOT EXISTS federation_servers (
|
||||
id SERIAL PRIMARY KEY,
|
||||
guild_id VARCHAR(32) UNIQUE NOT NULL,
|
||||
guild_name VARCHAR(255),
|
||||
guild_icon VARCHAR(255),
|
||||
owner_id VARCHAR(32),
|
||||
member_count INTEGER DEFAULT 0,
|
||||
status VARCHAR(32) DEFAULT 'pending', -- pending, approved, rejected, suspended
|
||||
tier VARCHAR(32) DEFAULT 'free', -- free, premium
|
||||
trust_level VARCHAR(32) DEFAULT 'bronze', -- bronze, silver, gold, platinum
|
||||
reputation_score INTEGER DEFAULT 0,
|
||||
subscription_id VARCHAR(255),
|
||||
subscription_status VARCHAR(32),
|
||||
invite_code VARCHAR(32),
|
||||
description TEXT,
|
||||
joined_federation_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Federation Bans - Shared ban list across federation servers
|
||||
CREATE TABLE IF NOT EXISTS federation_bans (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id VARCHAR(32) NOT NULL,
|
||||
username VARCHAR(255),
|
||||
reason TEXT,
|
||||
evidence TEXT,
|
||||
severity VARCHAR(32) DEFAULT 'low', -- low, medium, high, critical
|
||||
reported_by VARCHAR(32),
|
||||
reported_by_guild_id VARCHAR(32),
|
||||
active BOOLEAN DEFAULT true,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Federation Applications - Servers applying to join
|
||||
CREATE TABLE IF NOT EXISTS federation_applications (
|
||||
id SERIAL PRIMARY KEY,
|
||||
guild_id VARCHAR(32) UNIQUE NOT NULL,
|
||||
guild_name VARCHAR(255),
|
||||
guild_icon VARCHAR(255),
|
||||
owner_id VARCHAR(32),
|
||||
member_count INTEGER DEFAULT 0,
|
||||
reason TEXT,
|
||||
status VARCHAR(32) DEFAULT 'pending', -- pending, approved, rejected
|
||||
reviewed_by VARCHAR(32),
|
||||
reviewed_at TIMESTAMP WITH TIME ZONE,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Federation Mappings - Cross-server role mappings
|
||||
CREATE TABLE IF NOT EXISTS federation_mappings (
|
||||
id SERIAL PRIMARY KEY,
|
||||
role_id VARCHAR(32) UNIQUE NOT NULL,
|
||||
role_name VARCHAR(255),
|
||||
guild_id VARCHAR(32) NOT NULL,
|
||||
federation_role VARCHAR(64), -- The unified role name
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Federation Featured - Premium featured slots
|
||||
CREATE TABLE IF NOT EXISTS federation_featured (
|
||||
id SERIAL PRIMARY KEY,
|
||||
guild_id VARCHAR(32) UNIQUE NOT NULL,
|
||||
subscription_id VARCHAR(255),
|
||||
active BOOLEAN DEFAULT true,
|
||||
expires_at TIMESTAMP WITH TIME ZONE,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Federation Reputation - Tracks server reputation metrics
|
||||
CREATE TABLE IF NOT EXISTS federation_reputation (
|
||||
id SERIAL PRIMARY KEY,
|
||||
guild_id VARCHAR(32) NOT NULL,
|
||||
valid_reports INTEGER DEFAULT 0,
|
||||
false_positives INTEGER DEFAULT 0,
|
||||
total_reports INTEGER DEFAULT 0,
|
||||
last_updated TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
UNIQUE(guild_id)
|
||||
);
|
||||
|
||||
-- Create indexes for better query performance
|
||||
CREATE INDEX IF NOT EXISTS idx_federation_servers_status ON federation_servers(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_federation_servers_guild_id ON federation_servers(guild_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_federation_bans_user_id ON federation_bans(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_federation_bans_active ON federation_bans(active);
|
||||
CREATE INDEX IF NOT EXISTS idx_federation_applications_status ON federation_applications(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_federation_mappings_guild_id ON federation_mappings(guild_id);
|
||||
|
||||
-- Disable RLS for now (or configure appropriate policies)
|
||||
ALTER TABLE federation_servers ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE federation_bans ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE federation_applications ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE federation_mappings ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE federation_featured ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE federation_reputation ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- Allow service role full access (for the bot)
|
||||
CREATE POLICY "Service role has full access to federation_servers" ON federation_servers
|
||||
FOR ALL USING (true) WITH CHECK (true);
|
||||
|
||||
CREATE POLICY "Service role has full access to federation_bans" ON federation_bans
|
||||
FOR ALL USING (true) WITH CHECK (true);
|
||||
|
||||
CREATE POLICY "Service role has full access to federation_applications" ON federation_applications
|
||||
FOR ALL USING (true) WITH CHECK (true);
|
||||
|
||||
CREATE POLICY "Service role has full access to federation_mappings" ON federation_mappings
|
||||
FOR ALL USING (true) WITH CHECK (true);
|
||||
|
||||
CREATE POLICY "Service role has full access to federation_featured" ON federation_featured
|
||||
FOR ALL USING (true) WITH CHECK (true);
|
||||
|
||||
CREATE POLICY "Service role has full access to federation_reputation" ON federation_reputation
|
||||
FOR ALL USING (true) WITH CHECK (true);
|
||||
|
||||
-- Grant usage
|
||||
GRANT ALL ON federation_servers TO service_role;
|
||||
GRANT ALL ON federation_bans TO service_role;
|
||||
GRANT ALL ON federation_applications TO service_role;
|
||||
GRANT ALL ON federation_mappings TO service_role;
|
||||
GRANT ALL ON federation_featured TO service_role;
|
||||
GRANT ALL ON federation_reputation TO service_role;
|
||||
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO service_role;
|
||||
|
|
@ -1320,17 +1320,22 @@ function createWebServer(discordClient, supabase, options = {}) {
|
|||
|
||||
try {
|
||||
const [servers, bans, applications] = await Promise.all([
|
||||
supabase.from('federation_servers').select('id', { count: 'exact' }).eq('status', 'approved'),
|
||||
supabase.from('federation_bans').select('id', { count: 'exact' }).eq('active', true),
|
||||
supabase.from('federation_applications').select('id', { count: 'exact' }).eq('status', 'pending')
|
||||
supabase.from('federation_servers').select('id', { count: 'exact', head: true }).eq('status', 'approved'),
|
||||
supabase.from('federation_bans').select('id', { count: 'exact', head: true }).eq('active', true),
|
||||
supabase.from('federation_applications').select('id', { count: 'exact', head: true }).eq('status', 'pending')
|
||||
]);
|
||||
|
||||
console.log('[Federation Stats] servers:', servers);
|
||||
console.log('[Federation Stats] bans:', bans);
|
||||
console.log('[Federation Stats] applications:', applications);
|
||||
|
||||
res.json({
|
||||
totalServers: servers.count || 0,
|
||||
activeBans: bans.count || 0,
|
||||
pendingApplications: applications.count || 0
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('[Federation Stats] Error:', error);
|
||||
res.status(500).json({ error: 'Failed to fetch stats' });
|
||||
}
|
||||
});
|
||||
|
|
@ -1367,14 +1372,21 @@ function createWebServer(discordClient, supabase, options = {}) {
|
|||
}
|
||||
|
||||
try {
|
||||
const { data: servers } = await supabase
|
||||
const { data: servers, error } = await supabase
|
||||
.from('federation_servers')
|
||||
.select('*')
|
||||
.eq('status', 'approved')
|
||||
.order('member_count', { ascending: false });
|
||||
|
||||
console.log('[Federation Servers] Query result:', { servers, error });
|
||||
|
||||
if (error) {
|
||||
console.error('[Federation Servers] Supabase error:', error);
|
||||
}
|
||||
|
||||
res.json({ servers: servers || [] });
|
||||
} catch (error) {
|
||||
console.error('[Federation Servers] Error:', error);
|
||||
res.status(500).json({ error: 'Failed to fetch servers' });
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue