npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rivtor/erasure

v1.1.0

Published

GDPR Article 17 Right to be Forgotten with legal retention engine and dependency graph resolver

Downloads

21

Readme

@rivtor/erasure

Production-ready GDPR Article 17 Right to be Forgotten with legal retention engine

Features

  • Legal Retention Engine: Pre-configured retention rules for EU/UK/California jurisdictions
  • Dependency Graph Resolver: Intelligent cascading deletes across related tables
  • Anonymization Strategies: Hash, tokenize, nullify, randomize, and aggregate options
  • Processor Notification Queue: Automatic webhook notifications to Stripe, SendGrid, and more
  • Grace Period Management: 30-day grace period with cancellation support
  • Comprehensive Audit Trail: Complete logging of all erasure operations

Installation

npm install @rivtor/erasure
# or
yarn add @rivtor/erasure
# or
pnpm add @rivtor/erasure

Quick Start

1. Execute Immediate Erasure

import { executeEraseUser } from '@rivtor/erasure/server';

const result = await executeEraseUser('user-123', {
  retention_overrides: {
    invoices: {
      retain_until: '2035-01-01',
      reason: 'German tax law (10 years)',
      legal_basis: 'legal_obligation',
      jurisdiction: 'DE'
    }
  },
  anonymize_instead_of_delete: {
    analytics: {
      strategy: 'aggregate',
      fields: ['user_id', 'ip_address']
    }
  },
  notify_processors: true
});

console.log(result);
// {
//   success: true,
//   deletedTables: ['users', 'profiles', 'sessions'],
//   anonymizedTables: ['analytics_events'],
//   retainedTables: ['invoices'],
//   notifications: ['stripe', 'sendgrid']
// }

2. Schedule Deletion with Grace Period

import { scheduleDeletion } from '@rivtor/erasure/server';

// Schedule for 30 days from now
const deletionId = await scheduleDeletion('user-123', 'user', 30);

// User can cancel within grace period
await cancelScheduledDeletion(deletionId);

3. Process Scheduled Deletions

import { processScheduledDeletions } from '@rivtor/erasure/server';

// Call from cron job (e.g., every hour)
const processed = await processScheduledDeletions(10);
console.log(`Processed ${processed} deletions`);

4. Check Deletion Status

import { checkDeletionStatus } from '@rivtor/erasure/server';

const { status, tracker } = await checkDeletionStatus('user-123');
console.log(status);
// 'pending' | 'processing' | 'completed' | 'failed' | 'not_found'

API Reference

Server Functions

import {
  executeEraseUser,
  scheduleDeletion,
  cancelScheduledDeletion,
  processScheduledDeletions,
  checkDeletionStatus
} from '@rivtor/erasure/server';

// Execute immediate erasure
await executeEraseUser(
  userId: string,
  options?: {
    retention_overrides?: Record<string, RetentionOverride>;
    anonymize_instead_of_delete?: Record<string, AnonymizationConfig>;
    notify_processors?: boolean;
    external_apis?: ExternalApiConfig[];
  }
): Promise<ErasureResult>;

// Schedule deletion with grace period
await scheduleDeletion(
  userId: string,
  entityType: string,
  gracePeriodDays: number,
  options?: ErasureOptions
): Promise<string>; // Returns deletionId

// Cancel scheduled deletion
await cancelScheduledDeletion(deletionId: string): Promise<boolean>;

// Process scheduled deletions (for cron jobs)
await processScheduledDeletions(limit?: number): Promise<number>; // Returns count

// Check deletion status
await checkDeletionStatus(
  userId: string
): Promise<{
  status: 'pending' | 'processing' | 'completed' | 'failed' | 'not_found';
  tracker?: ErasureTracker;
}>;

Anonymization Strategies

type AnonymizationStrategy =
  | 'hash'      // One-way hash of the value
  | 'tokenize'  // Replace with random token
  | 'nullify'   // Set to NULL
  | 'randomize' // Replace with random realistic value
  | 'aggregate'; // Aggregate with other records

// Example usage
await executeEraseUser('user-123', {
  anonymize_instead_of_delete: {
    // Hash email for login records
    auth_logs: {
      strategy: 'hash',
      fields: ['email', 'ip_address']
    },
    // Nullify PII in analytics
    analytics_events: {
      strategy: 'nullify',
      fields: ['user_agent', 'referrer']
    },
    // Aggregate user interactions
    interactions: {
      strategy: 'aggregate',
      fields: ['user_id']
    }
  }
});

Retention Overrides

interface RetentionOverride {
  retain_until: string;      // ISO date string
  reason: string;            // Legal reason for retention
  legal_basis: string;       // 'legal_obligation' | 'contract' | 'legitimate_interest'
  jurisdiction: string;      // Country code (DE, UK, CA, etc.)
}

// Pre-configured retention rules for common jurisdictions
await executeEraseUser('user-123', {
  retention_overrides: {
    // German tax law (10 years)
    invoices: {
      retain_until: '2035-01-01',
      reason: 'German tax law (10 years)',
      legal_basis: 'legal_obligation',
      jurisdiction: 'DE'
    },
    // UK financial records (7 years)
    transactions: {
      retain_until: '2032-01-01',
      reason: 'UK financial regulations',
      legal_basis: 'legal_obligation',
      jurisdiction: 'UK'
    }
  }
});

Processor Notifications

interface ExternalApiConfig {
  name: string;
  url: string;
  method: 'POST' | 'DELETE';
  headers?: Record<string, string>;
  body_template?: string;
  retry_count?: number;
}

await executeEraseUser('user-123', {
  external_apis: [
    {
      name: 'stripe',
      url: 'https://api.stripe.com/v1/customers/{{user_id}}',
      method: 'DELETE',
      headers: {
        'Authorization': `Bearer ${process.env.STRIPE_API_KEY}`
      },
      retry_count: 3
    },
    {
      name: 'sendgrid',
      url: 'https://api.sendgrid.com/v3/marketing/contacts',
      method: 'DELETE',
      headers: {
        'Authorization': `Bearer ${process.env.SENDGRID_API_KEY}`
      }
    }
  ]
});

Database Schema

-- Scheduled deletions with grace period
CREATE TABLE scheduled_deletions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL,
    entity_type TEXT NOT NULL,
    scheduled_for TIMESTAMPTZ NOT NULL,
    status TEXT NOT NULL DEFAULT 'pending',
    created_at TIMESTAMPTZ DEFAULT NOW(),
    cancelled_at TIMESTAMPTZ,
    completed_at TIMESTAMPTZ,
    error TEXT,
    options JSONB
);

-- Comprehensive erasure audit logs
CREATE TABLE erasure_audit_logs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL,
    entity_type TEXT NOT NULL,
    status TEXT NOT NULL,
    started_at TIMESTAMPTZ NOT NULL,
    completed_at TIMESTAMPTZ,
    deleted_tables TEXT[] NOT NULL DEFAULT '{}',
    anonymized_tables TEXT[] NOT NULL DEFAULT '{}',
    retained_tables TEXT[] NOT NULL DEFAULT '{}',
    retention_overrides JSONB,
    external_api_calls JSONB,
    errors JSONB,
    requested_by TEXT,
    ip_address TEXT
);

-- Indexes for efficient queries
CREATE INDEX idx_scheduled_deletions_user ON scheduled_deletions(user_id);
CREATE INDEX idx_scheduled_deletions_status ON scheduled_deletions(status);
CREATE INDEX idx_scheduled_deletions_scheduled_for ON scheduled_deletions(scheduled_for);
CREATE INDEX idx_erasure_audit_logs_user ON erasure_audit_logs(user_id);
CREATE INDEX idx_erasure_audit_logs_status ON erasure_audit_logs(status);

Configuration

import { configureErasure } from '@rivtor/erasure/server';

configureErasure({
  // Default grace period in days
  defaultGracePeriodDays: 30,

  // Default retention rules by jurisdiction
  defaultRetention: {
    EU: {
      invoices: { years: 10 },
      tax_records: { years: 10 },
      contracts: { years: 5 }
    },
    UK: {
      financial_records: { years: 7 },
      invoices: { years: 6 }
    },
    US: {
      tax_records: { years: 7 },
      employment_records: { years: 7 }
    }
  },

  // Default anonymization strategy
  defaultAnonymization: {
    strategy: 'hash',
    fields: ['email', 'name', 'phone']
  },

  // External API retry settings
  retryConfig: {
    maxRetries: 3,
    backoffMs: 1000,
    timeoutMs: 30000
  }
});

Best Practices

  1. Always Use Grace Periods: Give users time to change their mind
  2. Document Retention: Keep clear records of why data is retained
  3. Test Anonymization: Verify anonymization strategies before production
  4. Monitor External APIs: Track processor notification success rates
  5. Regular Audit Reviews: Review erasure audit logs periodically

Legal Compliance

This package helps comply with:

  • GDPR Article 17: Right to erasure (right to be forgotten)
  • CCPA: Right to delete
  • UK GDPR: Data deletion requirements
  • Various Tax Laws: Legal retention obligations

License

MIT


Made with ❤️ by Rivtor