CREATE TABLE IF NOT EXISTS likes ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, thought_id UUID NOT NULL REFERENCES thoughts(id) ON DELETE CASCADE, ap_id TEXT UNIQUE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), UNIQUE (user_id, thought_id) ); CREATE TABLE IF NOT EXISTS boosts ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, thought_id UUID NOT NULL REFERENCES thoughts(id) ON DELETE CASCADE, ap_id TEXT UNIQUE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), UNIQUE (user_id, thought_id) ); CREATE TABLE IF NOT EXISTS blocks ( blocker_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, blocked_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), PRIMARY KEY (blocker_id, blocked_id) ); CREATE TABLE IF NOT EXISTS remote_actors ( url TEXT PRIMARY KEY, handle TEXT NOT NULL, display_name TEXT, inbox_url TEXT NOT NULL, shared_inbox_url TEXT, public_key TEXT NOT NULL, last_fetched_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE TABLE IF NOT EXISTS notifications ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, type TEXT NOT NULL, from_user_id UUID REFERENCES users(id) ON DELETE SET NULL, thought_id UUID REFERENCES thoughts(id) ON DELETE CASCADE, read BOOLEAN NOT NULL DEFAULT false, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_thoughts_user_id ON thoughts(user_id); CREATE INDEX IF NOT EXISTS idx_thoughts_created_at ON thoughts(created_at DESC); CREATE INDEX IF NOT EXISTS idx_follows_following_id ON follows(following_id); CREATE INDEX IF NOT EXISTS idx_notifications_user_id ON notifications(user_id, read);