Skip to main content

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"
}
]
}