diff --git a/backend/services/gdpr.ts b/backend/services/gdpr.ts index eadd669..53fec37 100644 --- a/backend/services/gdpr.ts +++ b/backend/services/gdpr.ts @@ -13,19 +13,13 @@ export interface UserConsent { export const exportUserData = async (userId: string) => { console.log(`Exporting data for user: ${userId}`); - + // In a real scenario, this would query multiple tables/collections const userData = { profile: { id: userId, email: 'user@example.com', registeredAt: '2026-01-01' }, - subscriptions: [ - { id: 'sub_1', name: 'Netflix', amount: 15.99, status: 'active' } - ], - billingHistory: [ - { id: 'tx_1', date: '2026-04-20', amount: 15.99, status: 'completed' } - ], - consentLogs: [ - { type: 'analytics', status: 'granted', date: '2026-01-01' } - ], + subscriptions: [{ id: 'sub_1', name: 'Netflix', amount: 15.99, status: 'active' }], + billingHistory: [{ id: 'tx_1', date: '2026-04-20', amount: 15.99, status: 'completed' }], + consentLogs: [{ type: 'analytics', status: 'granted', date: '2026-01-01' }], }; return JSON.stringify(userData, null, 2); @@ -42,23 +36,13 @@ export const deleteUserData = async (userId: string, permanent: boolean = false) // Hard delete logic across all services // await SubscriptionModel.deleteMany({ userId }); // await ProfileModel.deleteOne({ userId }); - + return { success: true, message: 'User data permanently deleted' }; }; export const anonymizeUserData = async (userId: string) => { console.log(`Anonymizing data for user: ${userId}`); - // Replace sensitive identifiers with null/dummy values - const updates = { - email: `deleted-${Date.now()}@anonymized.invalid`, - name: 'Anonymized User', - address: null, - phone: null, - }; - - // await ProfileModel.updateOne({ userId }, updates); - return { success: true, message: 'User data has been anonymized' }; }; @@ -70,8 +54,8 @@ export const updateConsent = async (userId: string, preferences: Partial = { + debug: 0, + info: 1, + warn: 2, + error: 3, +}; + +// Change this via env later +const CURRENT_LEVEL: LogLevel = __DEV__ ? 'debug' : 'info'; + +// Correlation ID generator (simple version) +const generateId = () => { + return Math.random().toString(36).substring(2) + Date.now().toString(36); +}; + +export interface LogContext { + [key: string]: any; + correlationId?: string; +} + +function shouldLog(level: LogLevel) { + return LOG_LEVEL_PRIORITY[level] >= LOG_LEVEL_PRIORITY[CURRENT_LEVEL]; +} + +function formatLog(level: LogLevel, message: string, context?: LogContext) { + return { + level, + message, + timestamp: new Date().toISOString(), + ...context, + }; +} + +function sendToConsole(logEntry: any) { + console.log(JSON.stringify(logEntry, null, 2)); +} + +// future: plug Sentry / API here +async function sendToRemote(_logEntry: any) { + // Example: + // await fetch("https://your-api/logs", { method: "POST", body: JSON.stringify(logEntry) }); +} + +function log(level: LogLevel, message: string, context?: LogContext) { + if (!shouldLog(level)) return; + + const logEntry = formatLog(level, message, context); + + sendToConsole(logEntry); + + if (level === 'error') { + sendToRemote(logEntry); + } +} + +export const logger = { + debug: (msg: string, ctx?: LogContext) => log('debug', msg, ctx), + info: (msg: string, ctx?: LogContext) => log('info', msg, ctx), + warn: (msg: string, ctx?: LogContext) => log('warn', msg, ctx), + error: (msg: string, ctx?: LogContext) => log('error', msg, ctx), + + createCorrelationId: generateId, +}; diff --git a/backend/tests/load/stress-wrapper.js b/backend/tests/load/stress-wrapper.js index f966087..bd1ad44 100644 --- a/backend/tests/load/stress-wrapper.js +++ b/backend/tests/load/stress-wrapper.js @@ -1,6 +1,6 @@ /** * Backend Load Test Wrapper - * This script can be used to trigger k6 tests from a backend context or + * This script can be used to trigger k6 tests from a backend context or * to provide a wrapper for internal stress testing of specific modules. */ @@ -8,7 +8,7 @@ const { spawn } = require('child_process'); function runLoadTest(scenario = 'subscription') { console.log(`Starting load test for scenario: ${scenario}...`); - + const k6 = spawn('k6', ['run', '-e', `SCENARIO=${scenario}`, '../../load-tests/run.js']); k6.stdout.on('data', (data) => {