# Customer Data Management (GDPR) This document covers procedures for handling customer data in compliance with GDPR and data protection regulations. --- ## Data Storage Overview Customer data is stored across multiple systems: | System | Data Stored | Retention | Notes | | ----------------------- | ----------------------------------------------------- | --------------------------- | ---------------------------- | | **Portal (PostgreSQL)** | User accounts, ID mappings, audit logs, notifications | Active account lifetime | Auth data only | | **WHMCS** | Billing, invoices, payment methods, addresses | Legal requirement (7 years) | System of record for billing | | **Salesforce** | CRM data, orders, cases, contacts | Business records | System of record for CRM | | **Redis** | Sessions, cache, rate limits | TTL-based (minutes to days) | Temporary data | ### Portal Database Tables with PII | Table | PII Fields | Purpose | | ---------------------------- | ------------------------------------ | -------------------- | | `users` | `email`, `passwordHash`, `mfaSecret` | Authentication | | `id_mappings` | Links to WHMCS/Salesforce IDs | Identity federation | | `audit_logs` | `ipAddress`, `userAgent`, `userId` | Security audit trail | | `residence_card_submissions` | Document images | ID verification | | `notifications` | User notifications | In-app messaging | | `sim_call_history_*` | Phone numbers, call details | Usage records | | `sim_sms_history` | Phone numbers, SMS details | Usage records | --- ## Data Subject Rights Under GDPR, customers have the following rights: | Right | Portal Support | Notes | | ---------------------- | ------------------ | ------------------------- | | Right of Access | Manual export | See Data Export section | | Right to Rectification | WHMCS self-service | Customer updates in WHMCS | | Right to Erasure | Manual process | See Data Deletion section | | Right to Portability | Manual export | See Data Export section | | Right to Object | Manual process | Opt-out of processing | --- ## Data Deletion Procedures ### Overview Complete customer data deletion requires coordination across all systems: 1. Portal database deletion 2. WHMCS account handling 3. Salesforce record handling 4. Redis cache clearing 5. Audit trail retention ### Pre-Deletion Checklist - [ ] Verify customer identity (authentication or CS verification) - [ ] Check for active subscriptions (must be cancelled first) - [ ] Check for unpaid invoices (must be settled first) - [ ] Check legal retention requirements (invoices, tax records) - [ ] Document the deletion request with timestamp ### Step 1: Portal Database Deletion ```sql -- 1. Get user information SELECT u.id, u.email, im.whmcs_client_id, im.sf_account_id FROM users u LEFT JOIN id_mappings im ON u.id = im.user_id WHERE u.email = 'customer@example.com'; -- 2. Delete notifications DELETE FROM notifications WHERE user_id = ''; -- 3. Delete residence card submissions DELETE FROM residence_card_submissions WHERE user_id = ''; -- 4. Delete SIM usage data (if applicable) -- Note: Check if SIM account is linked to this user first DELETE FROM sim_usage_daily WHERE account IN ( SELECT account FROM sim_voice_options WHERE account = '' ); DELETE FROM sim_call_history_domestic WHERE account = ''; DELETE FROM sim_call_history_international WHERE account = ''; DELETE FROM sim_sms_history WHERE account = ''; DELETE FROM sim_voice_options WHERE account = ''; -- 5. Delete ID mapping (cascades from user deletion) -- The id_mappings table has onDelete: Cascade -- 6. Delete user (cascades audit_logs user reference to NULL, deletes id_mapping) DELETE FROM users WHERE id = ''; ``` **Using the Mappings Service:** ```typescript // Delete mapping programmatically (clears cache too) await mappingsService.deleteMapping(userId); ``` ### Step 2: Audit Log Handling Audit logs may need to be retained for security compliance. Options: **Option A: Anonymize (Recommended)** ```sql -- Anonymize audit logs (keeps security trail, removes PII) UPDATE audit_logs SET user_id = NULL, ip_address = 'ANONYMIZED', user_agent = 'ANONYMIZED', details = jsonb_set( COALESCE(details, '{}'::jsonb), '{anonymized}', 'true'::jsonb ) WHERE user_id = ''; ``` **Option B: Delete (If Legally Permitted)** ```sql DELETE FROM audit_logs WHERE user_id = ''; ``` ### Step 3: Redis Cache Clearing ```bash # Clear user-specific cache keys redis-cli KEYS "user:*:*" | xargs redis-cli DEL redis-cli KEYS "session:*:*" | xargs redis-cli DEL redis-cli KEYS "mapping:*:*" | xargs redis-cli DEL # Clear refresh token families redis-cli KEYS "refresh:user:*" | xargs redis-cli DEL redis-cli KEYS "refresh:family:*" | xargs redis-cli DEL # May need filtering # Clear rate limit records redis-cli KEYS "auth-login:*" | xargs redis-cli DEL # Clears by IP, not user ``` ### Step 4: WHMCS Account Handling WHMCS does not support full account deletion. Options: **Option A: Close Account (Recommended)** 1. Cancel all active services 2. Set account status to "Closed" 3. Anonymize personal fields via WHMCS Admin 4. Document closure date **Option B: Anonymize via API** ```bash # Update client to anonymized data curl -X POST "$WHMCS_API_URL" \ -d "identifier=$WHMCS_API_IDENTIFIER" \ -d "secret=$WHMCS_API_SECRET" \ -d "action=UpdateClient" \ -d "clientid=" \ -d "firstname=Deleted" \ -d "lastname=User" \ -d "email=deleted_@deleted.local" \ -d "address1=Deleted" \ -d "city=Deleted" \ -d "state=Deleted" \ -d "postcode=000-0000" \ -d "phonenumber=000-0000-0000" \ -d "status=Closed" \ -d "responsetype=json" ``` ### Step 5: Salesforce Record Handling Salesforce records often have legal retention requirements: **For Personal Data:** 1. Work with Salesforce Admin 2. Consider anonymization vs deletion 3. Check integration impact (linked Orders, Cases) **Anonymization Approach:** - Update Account name to "Deleted Account - [ID]" - Clear personal fields (phone, address if not needed) - Keep transactional records with anonymized references --- ## Data Export Procedures ### Customer Data Export Request When a customer requests their data: #### 1. Portal Data Export ```sql -- Export user data SELECT u.id, u.email, u.email_verified, u.created_at, u.last_login_at, im.whmcs_client_id, im.sf_account_id FROM users u LEFT JOIN id_mappings im ON u.id = im.user_id WHERE u.email = 'customer@example.com'; -- Export audit log (security events) SELECT action, resource, success, created_at FROM audit_logs WHERE user_id = '' ORDER BY created_at DESC; -- Export notifications SELECT type, title, message, read, created_at FROM notifications WHERE user_id = '' ORDER BY created_at DESC; -- Export SIM usage history (if applicable) SELECT call_date, call_time, called_to, duration_sec, charge_yen FROM sim_call_history_domestic WHERE account = '' ORDER BY call_date DESC; ``` #### 2. WHMCS Data Export Request via WHMCS Admin: - Client Details - Invoices - Services/Subscriptions - Tickets/Support History - Transaction History #### 3. Salesforce Data Export Request via Salesforce Admin: - Account record - Contact record - Order history - Case history - Opportunities ### Export Format Provide data in machine-readable format: - JSON for structured data - CSV for tabular data - PDF for documents (invoices) --- ## PII Handling During Debugging ### Safe Logging Practices The BFF uses Pino with automatic PII redaction. Sensitive fields are sanitized: ```json { "email": "cust***@example.com", "password": "[REDACTED]", "token": "[REDACTED]", "authorization": "[REDACTED]" } ``` ### What NOT to Log - Full email addresses (use masked version) - Passwords or password hashes - JWT tokens - API keys or secrets - Credit card numbers - Full phone numbers - Full addresses - ID document contents ### Safe Debug Queries ```sql -- Use ID instead of email for lookups SELECT * FROM users WHERE id = ''; -- Mask PII in query results SELECT id, CONCAT(LEFT(email, 3), '***', SUBSTRING(email FROM POSITION('@' IN email))) as masked_email, created_at FROM users WHERE id = ''; ``` ### Production Debugging When investigating production issues: 1. **Use correlation IDs** - Search logs by request ID, not user email 2. **Access minimal data** - Only query what's needed 3. **Document access** - Note why you accessed customer data 4. **Use anonymized exports** - When sharing data for analysis --- ## Data Retention Policies ### Recommended Retention Periods | Data Type | Retention | Justification | | ------------------------ | ---------- | ---------------------- | | Active user accounts | Indefinite | Active service | | Closed accounts (portal) | 30 days | Grace period | | Audit logs | 2 years | Security compliance | | Session data (Redis) | 24 hours | Active sessions | | Rate limit data | 15 minutes | Operational | | Invoices | 7 years | Tax/legal requirement | | Support cases | 5 years | Service history | | Call/SMS history | 6 months | Billing reconciliation | ### Automated Cleanup ```sql -- Delete expired notifications (30 days after expiry) DELETE FROM notifications WHERE expires_at < NOW() - INTERVAL '30 days'; -- Anonymize old audit logs (over 2 years) UPDATE audit_logs SET ip_address = 'EXPIRED', user_agent = 'EXPIRED' WHERE created_at < NOW() - INTERVAL '2 years' AND ip_address != 'EXPIRED'; ``` --- ## Compliance Checklist ### Monthly Review - [ ] Review data access logs for unusual patterns - [ ] Verify automated cleanup jobs are running - [ ] Check for pending deletion requests - [ ] Review new data collection points ### Quarterly Review - [ ] Audit third-party data sharing - [ ] Review retention policies - [ ] Update data inventory if schema changed - [ ] Staff training on data handling ### Annual Review - [ ] Full data protection impact assessment - [ ] Policy review and updates - [ ] Vendor compliance verification - [ ] Documentation updates --- ## Emergency Data Breach Response If a data breach is suspected: 1. **Contain** - Isolate affected systems 2. **Assess** - Determine scope and data exposed 3. **Notify** - Inform DPO/legal within 24 hours 4. **Report** - GDPR requires notification within 72 hours 5. **Remediate** - Fix vulnerability and prevent recurrence 6. **Document** - Full incident report See [Incident Response](./incident-response.md) for general incident procedures. --- ## Related Documents - [Incident Response](./incident-response.md) - [Database Operations](./database-operations.md) - [Logging Guide](./logging.md) - [Security Monitoring](./security-monitoring.md) --- **Last Updated:** December 2025