Debugging Guide
Common debugging techniques for the CRM platform.
Logging
Log Levels
this.logger.error('Critical failure', error.stack);
this.logger.warn('Unusual condition');
this.logger.log('Normal operation');
this.logger.debug('Detailed info');
this.logger.verbose('Very detailed info');
Structured Logging
this.logger.log('Processing event', {
eventId: event.id,
eventType: event.type,
customerId: profile?.id,
});
Enable Debug Logging
# Enable all debug logs
LOG_LEVEL=debug npx nx serve crm-backend
# Enable BullMQ debug logs
DEBUG=bullmq:* npx nx serve crm-backend
API Debugging
Request/Response Logging
// Add to main.ts for dev
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
console.log('Body:', req.body);
next();
});
curl Examples
# Get customer
curl -X GET 'http://localhost:3000/api/v1/customers/123' \
-H 'Authorization: Bearer TOKEN'
# Create customer
curl -X POST 'http://localhost:3000/api/v1/customers' \
-H 'Authorization: Bearer TOKEN' \
-H 'Content-Type: application/json' \
-d '{"tenantId":"t1","email":"test@example.com"}'
Database Debugging
Prisma Query Logging
// In module setup
const prisma = new PrismaClient({
log: ['query', 'info', 'warn', 'error'],
});
Direct SQL Queries
# Connect to database
kubectl exec -it deploy/crm-backend -n crm -- \
psql $CRM_DATABASE_URL
# Or locally
psql postgresql://postgres:postgres@localhost:5432/crm
Useful Queries
-- Recent activities
SELECT * FROM "Activity" ORDER BY created_at DESC LIMIT 10;
-- Find customer by email
SELECT * FROM "CustomerProfile" WHERE email = 'test@example.com';
-- Check segment membership
SELECT cp.* FROM "CustomerProfile" cp
JOIN "CustomerSegmentMembership" csm ON cp.id = csm.customer_id
WHERE csm.segment_id = 'SEGMENT_ID';
Event/Queue Debugging
View Queue Status
# Connect to Redis
redis-cli
# List queues
KEYS bull:*
# View queue length
LLEN bull:crm-events:wait
View Failed Jobs
# Get failed jobs
redis-cli LRANGE bull:crm-events:failed 0 -1
Debug Event Processing
@Processor('crm-events')
export class CrmEventProcessor {
@OnQueueFailed()
onFailed(job: Job, error: Error) {
console.error('Job failed:', {
jobId: job.id,
data: job.data,
error: error.message,
});
}
}
Memory Debugging
Heap Snapshot
# Start with inspector
node --inspect dist/main.js
# Connect Chrome DevTools
chrome://inspect
Memory Profiling
// Add to suspect code
const before = process.memoryUsage();
// ... operation ...
const after = process.memoryUsage();
console.log('Memory delta:', {
heapUsed: after.heapUsed - before.heapUsed,
external: after.external - before.external,
});
Performance Debugging
Timing Operations
const start = performance.now();
await this.expensiveOperation();
const duration = performance.now() - start;
this.logger.log(`Operation took ${duration}ms`);
Slow Query Detection
// Enable slow query logging in Prisma
const prisma = new PrismaClient({
log: [
{ level: 'query', emit: 'event' },
],
});
prisma.$on('query', (e) => {
if (e.duration > 100) {
console.warn('Slow query:', e.query, `${e.duration}ms`);
}
});
Common Issues
Identity Resolution Failing
// Log identity resolution
this.logger.debug('Resolving identity', {
authUserId: event.identity.authUserId,
email: event.identity.email,
phone: event.identity.phoneNumber,
});
Segment Not Updating
-- Check segment refresh status
SELECT id, name, last_refreshed_at, is_refreshing, refresh_error
FROM "CustomerSegment"
WHERE id = 'SEGMENT_ID';
-- Force refresh
UPDATE "CustomerSegment"
SET last_refreshed_at = NULL
WHERE id = 'SEGMENT_ID';
Journey Not Triggering
-- Check journey status
SELECT status, trigger_type, trigger_conditions
FROM "Journey"
WHERE id = 'JOURNEY_ID';
-- Check enrollments
SELECT * FROM "JourneyEnrollment"
WHERE journey_id = 'JOURNEY_ID'
ORDER BY created_at DESC LIMIT 10;
VS Code Debugging
Launch Configuration
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug CRM Backend",
"type": "node",
"request": "launch",
"runtimeExecutable": "pnpm",
"runtimeArgs": ["nx", "serve", "crm-backend"],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal",
"skipFiles": ["<node_internals>/**"]
},
{
"name": "Debug Current Test File",
"type": "node",
"request": "launch",
"runtimeExecutable": "pnpm",
"runtimeArgs": ["vitest", "run", "${relativeFile}"],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal"
}
]
}