From 5538e4765074af62c2e656184e30341a1d8d4c71 Mon Sep 17 00:00:00 2001 From: Bretton May Date: Thu, 4 Dec 2025 23:32:54 -0800 Subject: [PATCH] feat(db): add migration for comment deletion metadata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add migration 021 that: - Creates deletion_reason enum type (author, moderator) - Adds deletion_reason and deleted_by columns to comments table - Backfills existing deleted comments as author-deleted - Removes deleted_at IS NULL filter from thread indexes to preserve structure - Adds indexes for deletion_reason and deleted_by for moderation queries 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../021_add_comment_deletion_metadata.sql | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 internal/db/migrations/021_add_comment_deletion_metadata.sql diff --git a/internal/db/migrations/021_add_comment_deletion_metadata.sql b/internal/db/migrations/021_add_comment_deletion_metadata.sql new file mode 100644 index 0000000..65c0735 --- /dev/null +++ b/internal/db/migrations/021_add_comment_deletion_metadata.sql @@ -0,0 +1,66 @@ +-- +goose Up +-- Add deletion reason tracking to preserve thread structure while respecting privacy +-- When comments are deleted, we blank content but keep the record for threading + +-- Create enum type for deletion reasons +CREATE TYPE deletion_reason AS ENUM ('author', 'moderator'); + +-- Add new columns to comments table +ALTER TABLE comments ADD COLUMN deletion_reason deletion_reason; +ALTER TABLE comments ADD COLUMN deleted_by TEXT; + +-- Add comments for new columns +COMMENT ON COLUMN comments.deletion_reason IS 'Reason for deletion: author (user deleted), moderator (community mod removed)'; +COMMENT ON COLUMN comments.deleted_by IS 'DID of the actor who performed the deletion'; + +-- Backfill existing deleted comments as author-deleted +-- This handles existing soft-deleted comments gracefully +UPDATE comments +SET deletion_reason = 'author', + deleted_by = commenter_did +WHERE deleted_at IS NOT NULL AND deletion_reason IS NULL; + +-- Modify existing indexes to NOT filter deleted_at IS NULL +-- This allows deleted comments to appear in thread queries for structure preservation +-- Note: We drop and recreate to change the partial index condition + +-- Drop old partial indexes that exclude deleted comments +DROP INDEX IF EXISTS idx_comments_root; +DROP INDEX IF EXISTS idx_comments_parent; +DROP INDEX IF EXISTS idx_comments_parent_score; +DROP INDEX IF EXISTS idx_comments_uri_active; + +-- Recreate indexes without the deleted_at filter (include all comments for threading) +CREATE INDEX idx_comments_root ON comments(root_uri, created_at DESC); +CREATE INDEX idx_comments_parent ON comments(parent_uri, created_at DESC); +CREATE INDEX idx_comments_parent_score ON comments(parent_uri, score DESC, created_at DESC); +CREATE INDEX idx_comments_uri_lookup ON comments(uri); + +-- Add index for querying by deletion_reason (for moderation dashboard) +CREATE INDEX idx_comments_deleted_reason ON comments(deletion_reason, deleted_at DESC) +WHERE deleted_at IS NOT NULL; + +-- Add index for querying by deleted_by (for moderation audit/filtering) +CREATE INDEX idx_comments_deleted_by ON comments(deleted_by, deleted_at DESC) +WHERE deleted_at IS NOT NULL; + +-- +goose Down +-- Remove deletion metadata columns and restore original indexes + +DROP INDEX IF EXISTS idx_comments_deleted_by; +DROP INDEX IF EXISTS idx_comments_deleted_reason; +DROP INDEX IF EXISTS idx_comments_uri_lookup; +DROP INDEX IF EXISTS idx_comments_parent_score; +DROP INDEX IF EXISTS idx_comments_parent; +DROP INDEX IF EXISTS idx_comments_root; + +-- Restore original partial indexes (excluding deleted comments) +CREATE INDEX idx_comments_root ON comments(root_uri, created_at DESC) WHERE deleted_at IS NULL; +CREATE INDEX idx_comments_parent ON comments(parent_uri, created_at DESC) WHERE deleted_at IS NULL; +CREATE INDEX idx_comments_parent_score ON comments(parent_uri, score DESC, created_at DESC) WHERE deleted_at IS NULL; +CREATE INDEX idx_comments_uri_active ON comments(uri) WHERE deleted_at IS NULL; + +ALTER TABLE comments DROP COLUMN IF EXISTS deleted_by; +ALTER TABLE comments DROP COLUMN IF EXISTS deletion_reason; + +DROP TYPE IF EXISTS deletion_reason; -- 2.51.2