-- Create comments table CREATE TABLE IF NOT EXISTS comments ( id BIGSERIAL PRIMARY KEY, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, target_type VARCHAR(30) NOT NULL, target_id VARCHAR(128) NOT NULL, user_id BIGINT NOT NULL, parent_id BIGINT, content TEXT NOT NULL, status VARCHAR(20) NOT NULL DEFAULT 'visible', spam_score REAL NOT NULL DEFAULT 0, spam_rules TEXT, is_edited BOOLEAN NOT NULL DEFAULT FALSE, edited_at TIMESTAMP WITH TIME ZONE, CONSTRAINT fk_comments_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, CONSTRAINT fk_comments_parent FOREIGN KEY (parent_id) REFERENCES comments(id) ON DELETE CASCADE ); CREATE INDEX idx_comments_target ON comments(target_type, target_id); CREATE INDEX idx_comments_user ON comments(user_id); CREATE INDEX idx_comments_parent ON comments(parent_id); CREATE INDEX idx_comments_status ON comments(status); CREATE INDEX idx_comments_created ON comments(created_at DESC); CREATE INDEX idx_comments_spam ON comments(spam_score DESC) WHERE spam_score > 0.5; -- Create comment bans table CREATE TABLE IF NOT EXISTS comment_bans ( id BIGSERIAL PRIMARY KEY, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, user_id BIGINT NOT NULL, reason TEXT, until TIMESTAMP WITH TIME ZONE, created_by_id BIGINT NOT NULL, CONSTRAINT fk_bans_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, CONSTRAINT fk_bans_creator FOREIGN KEY (created_by_id) REFERENCES users(id) ON DELETE CASCADE ); CREATE INDEX idx_comment_bans_user ON comment_bans(user_id); CREATE INDEX idx_comment_bans_until ON comment_bans(until); CREATE INDEX idx_comment_bans_creator ON comment_bans(created_by_id); -- Create unban requests table CREATE TABLE IF NOT EXISTS unban_requests ( id BIGSERIAL PRIMARY KEY, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, user_id BIGINT NOT NULL, message TEXT, status VARCHAR(20) NOT NULL DEFAULT 'pending', resolved_by_id BIGINT, resolved_at TIMESTAMP WITH TIME ZONE, CONSTRAINT fk_unban_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, CONSTRAINT fk_unban_resolver FOREIGN KEY (resolved_by_id) REFERENCES users(id) ON DELETE SET NULL ); CREATE INDEX idx_unban_user ON unban_requests(user_id); CREATE INDEX idx_unban_status ON unban_requests(status); CREATE INDEX idx_unban_created ON unban_requests(created_at DESC); -- Create comment reports table CREATE TABLE IF NOT EXISTS comment_reports ( id BIGSERIAL PRIMARY KEY, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, comment_id BIGINT NOT NULL, user_id BIGINT NOT NULL, reason VARCHAR(255), CONSTRAINT fk_reports_comment FOREIGN KEY (comment_id) REFERENCES comments(id) ON DELETE CASCADE, CONSTRAINT fk_reports_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, UNIQUE (comment_id, user_id) ); CREATE INDEX idx_comment_reports_comment ON comment_reports(comment_id); CREATE INDEX idx_comment_reports_user ON comment_reports(user_id); -- Create comment reactions table CREATE TABLE IF NOT EXISTS comment_reactions ( id BIGSERIAL PRIMARY KEY, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, comment_id BIGINT NOT NULL, user_id BIGINT NOT NULL, type VARCHAR(24) NOT NULL, CONSTRAINT fk_reactions_comment FOREIGN KEY (comment_id) REFERENCES comments(id) ON DELETE CASCADE, CONSTRAINT fk_reactions_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, UNIQUE (comment_id, user_id) ); CREATE INDEX idx_comment_reactions_comment ON comment_reactions(comment_id); CREATE INDEX idx_comment_reactions_user ON comment_reactions(user_id); CREATE INDEX idx_comment_reactions_type ON comment_reactions(type);