juicebox-data-handling

📁 jeremylongshore/claude-code-plugins-plus-skills 📅 11 days ago
9
总安装量
9
周安装量
#33130
全站排名
安装命令
npx skills add https://github.com/jeremylongshore/claude-code-plugins-plus-skills --skill juicebox-data-handling

Agent 安装分布

claude-code 8
mcpjam 7
mistral-vibe 7
junie 7
windsurf 7
zencoder 7

Skill 文档

Juicebox Data Handling

Overview

Implement compliant data handling practices for personal and candidate data from Juicebox.

Prerequisites

  • Understanding of applicable privacy regulations (GDPR, CCPA)
  • Data classification framework
  • Legal/compliance team sign-off

Data Classification

Category Examples Retention Access
Public Name, title, company 1 year All users
Contact Email, phone 90 days Recruiters only
Sensitive SSN, salary 30 days Admins only
Derived Scores, notes Permanent Internal only

Instructions

Step 1: Data Classification System

// lib/data-classifier.ts
export enum DataCategory {
  PUBLIC = 'public',
  CONTACT = 'contact',
  SENSITIVE = 'sensitive',
  DERIVED = 'derived'
}

export const fieldClassification: Record<string, DataCategory> = {
  // Public data
  name: DataCategory.PUBLIC,
  title: DataCategory.PUBLIC,
  company: DataCategory.PUBLIC,
  location: DataCategory.PUBLIC,
  linkedin_url: DataCategory.PUBLIC,

  // Contact data
  email: DataCategory.CONTACT,
  phone: DataCategory.CONTACT,
  personal_email: DataCategory.CONTACT,

  // Sensitive data
  salary: DataCategory.SENSITIVE,
  compensation: DataCategory.SENSITIVE,

  // Derived data
  fit_score: DataCategory.DERIVED,
  recruiter_notes: DataCategory.DERIVED
};

export function classifyData(data: Record<string, any>): Record<DataCategory, string[]> {
  const classified: Record<DataCategory, string[]> = {
    [DataCategory.PUBLIC]: [],
    [DataCategory.CONTACT]: [],
    [DataCategory.SENSITIVE]: [],
    [DataCategory.DERIVED]: []
  };

  for (const field of Object.keys(data)) {
    const category = fieldClassification[field] || DataCategory.DERIVED;
    classified[category].push(field);
  }

  return classified;
}

Step 2: PII Handling

// lib/pii-handler.ts
import crypto from 'crypto';

export class PIIHandler {
  // Mask sensitive fields for logging
  maskForLogging(profile: Profile): Record<string, any> {
    return {
      ...profile,
      email: this.maskEmail(profile.email),
      phone: this.maskPhone(profile.phone),
      personal_email: undefined // Remove entirely
    };
  }

  private maskEmail(email?: string): string | undefined {
    if (!email) return undefined;
    const [local, domain] = email.split('@');
    return `${local[0]}***@${domain}`;
  }

  private maskPhone(phone?: string): string | undefined {
    if (!phone) return undefined;
    return `***-***-${phone.slice(-4)}`;
  }

  // Encrypt sensitive data at rest
  encrypt(data: string, key: Buffer): string {
    const iv = crypto.randomBytes(16);
    const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
    let encrypted = cipher.update(data, 'utf8', 'base64');
    encrypted += cipher.final('base64');
    const tag = cipher.getAuthTag();
    return `${iv.toString('base64')}:${tag.toString('base64')}:${encrypted}`;
  }

  // Decrypt sensitive data
  decrypt(encrypted: string, key: Buffer): string {
    const [ivB64, tagB64, data] = encrypted.split(':');
    const iv = Buffer.from(ivB64, 'base64');
    const tag = Buffer.from(tagB64, 'base64');
    const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
    decipher.setAuthTag(tag);
    let decrypted = decipher.update(data, 'base64', 'utf8');
    decrypted += decipher.final('utf8');
    return decrypted;
  }
}

Step 3: Retention Policies

// lib/retention-policy.ts
export class RetentionPolicy {
  private policies: Record<DataCategory, number> = {
    [DataCategory.PUBLIC]: 365,      // 1 year
    [DataCategory.CONTACT]: 90,      // 90 days
    [DataCategory.SENSITIVE]: 30,    // 30 days
    [DataCategory.DERIVED]: -1       // No auto-delete
  };

  getRetentionDays(category: DataCategory): number {
    return this.policies[category];
  }

  async enforceRetention(): Promise<RetentionReport> {
    const report: RetentionReport = {
      processed: 0,
      deleted: 0,
      errors: []
    };

    for (const [category, days] of Object.entries(this.policies)) {
      if (days < 0) continue; // Skip no-delete categories

      const cutoff = new Date();
      cutoff.setDate(cutoff.getDate() - days);

      const result = await this.deleteExpiredData(category as DataCategory, cutoff);
      report.processed += result.processed;
      report.deleted += result.deleted;
    }

    return report;
  }

  private async deleteExpiredData(
    category: DataCategory,
    cutoff: Date
  ): Promise<{ processed: number; deleted: number }> {
    // Implementation depends on data storage
    return db.$transaction(async (tx) => {
      const expired = await tx.profileData.findMany({
        where: {
          category,
          createdAt: { lt: cutoff }
        }
      });

      await tx.profileData.deleteMany({
        where: {
          id: { in: expired.map(e => e.id) }
        }
      });

      return {
        processed: expired.length,
        deleted: expired.length
      };
    });
  }
}

// Run retention daily
cron.schedule('0 2 * * *', async () => {
  const policy = new RetentionPolicy();
  const report = await policy.enforceRetention();
  logger.info('Retention policy enforced', report);
});

Step 4: Data Subject Rights

// services/data-rights.ts
export class DataRightsService {
  // Right to access
  async handleAccessRequest(subjectEmail: string): Promise<DataExport> {
    // Find all data for subject
    const profiles = await db.profiles.findMany({
      where: { email: subjectEmail }
    });

    // Include access logs
    const accessLogs = await db.accessLogs.findMany({
      where: { profileEmail: subjectEmail }
    });

    return {
      profiles,
      accessLogs,
      exportedAt: new Date(),
      format: 'json'
    };
  }

  // Right to erasure (GDPR Article 17)
  async handleDeletionRequest(
    subjectEmail: string,
    requestId: string
  ): Promise<DeletionReport> {
    const report: DeletionReport = {
      requestId,
      subjectEmail,
      deletedRecords: 0,
      status: 'completed',
      completedAt: new Date()
    };

    await db.$transaction(async (tx) => {
      // Delete profile data
      const deleted = await tx.profiles.deleteMany({
        where: { email: subjectEmail }
      });
      report.deletedRecords += deleted.count;

      // Delete from cache
      await cache.deleteByPattern(`*${subjectEmail}*`);

      // Log deletion for compliance
      await tx.deletionLogs.create({
        data: {
          requestId,
          subjectEmail,
          deletedCount: report.deletedRecords,
          completedAt: new Date()
        }
      });
    });

    // Notify downstream systems
    await this.notifyDeletion(subjectEmail, requestId);

    return report;
  }

  // Right to rectification
  async handleRectificationRequest(
    subjectEmail: string,
    corrections: Record<string, any>
  ): Promise<void> {
    await db.profiles.updateMany({
      where: { email: subjectEmail },
      data: corrections
    });

    // Log for audit
    await db.auditLogs.create({
      data: {
        type: 'rectification',
        subjectEmail,
        changes: corrections
      }
    });
  }
}

Step 5: Access Logging

// middleware/access-logging.ts
export function logDataAccess(req: Request, res: Response, next: NextFunction) {
  const originalJson = res.json.bind(res);

  res.json = (data: any) => {
    // Log access to profile data
    if (data?.profiles || data?.profile) {
      const profiles = data.profiles || [data.profile];
      const profileIds = profiles.map((p: any) => p.id);

      db.accessLogs.create({
        data: {
          userId: req.user?.id,
          profileIds,
          operation: req.method,
          path: req.path,
          timestamp: new Date(),
          ip: req.ip,
          userAgent: req.get('user-agent')
        }
      }).catch(console.error);
    }

    return originalJson(data);
  };

  next();
}

Compliance Checklist

## Data Handling Compliance

### GDPR Requirements
- [ ] Lawful basis for processing documented
- [ ] Privacy policy updated
- [ ] Data subject rights implemented
- [ ] Data breach notification process
- [ ] DPA with Juicebox executed

### CCPA Requirements
- [ ] "Do Not Sell" option implemented
- [ ] Consumer rights portal
- [ ] Opt-out mechanisms
- [ ] Annual training completed

### Security
- [ ] Encryption at rest
- [ ] Encryption in transit
- [ ] Access logging
- [ ] Regular audits

Output

  • Data classification system
  • PII handling utilities
  • Retention policy enforcement
  • Data subject rights handlers

Resources

Next Steps

After data handling, see juicebox-enterprise-rbac for access controls.