Now I have read all 44 files. Let me compile the comprehensive audit report.

---

# COMPREHENSIVE SERVICES AUDIT REPORT
## `/home/ccuser/rateright-growth/src/services/`
### 44 Files Audited

---

## CRITICAL FINDINGS SUMMARY

Before diving into per-file details, here are the highest-severity issues across the entire codebase:

**SECURITY - CRITICAL:**
1. **deepgram.js line 47**: `getClientConfig()` exposes `DEEPGRAM_API_KEY` directly to the client. The comment on line 54 says "NEVER expose this to the client" but the function does exactly that.
2. **taskExecutor.js lines 141, 209, 256, 318**: SQL injection via `.ilike` with unsanitized user input from voice commands (e.g., `.or(\`first_name.ilike.%${name}%\`)`). The `name` variable comes from parsed voice transcripts.
3. **twilioMediaSetup.js line 21**: Logs ALL request headers including potentially sensitive auth headers with `JSON.stringify(request.headers)`.
4. **enrichment.js line 167**: API key stored as `api_key_encrypted` but comment says "In production, decrypt this" -- it is used raw, never decrypted.

**BUGS - CRITICAL:**
1. **promptManagement.js lines 167, 203**: Uses `db.raw()` which does NOT exist on the Supabase JS client. These calls silently fail due to `.catch(() => {})`, meaning usage counts and success/fail counts are never incremented.
2. **leaderboardService.js line 499**: `getTodaysCallCount()` does NOT filter by userId -- it counts ALL users' calls, making daily leaderboard call counts wrong.
3. **callAnalytics.js line 253**: `callerTotal` is initialized but never incremented -- dead variable. Line 275: `agentTotal++` increments for ALL questions regardless of speaker.
4. **weeklyIntelligence.js line 9**: `new OpenAI({ apiKey: process.env.OPENAI_API_KEY })` at module level without checking if the key exists. Will crash at import time if OpenAI package is installed but key is missing.
5. **enrichment.js line 81**: Uses `db.raw('credits_used_this_month + ?', [credits])` -- Supabase JS does NOT support `.raw()`. Credit consumption silently fails.

---

## PER-FILE AUDIT

---

### 1. `/home/ccuser/rateright-growth/src/services/challengesServiceV2.js` (367 lines)

**Exports:** `createChallenge`, `joinChallenge`, `getActiveChallenges`, `getChallengeDetails`, `updateChallengeScores`, `completeChallenge`, `cancelChallenge`, `processExpiredChallenges`

**Bug Risks:**
- **Line 293**: `.catch(() => {})` silently swallows XP award errors. If XP awards fail, participants never know.
- **Line 296**: Dynamic `require('./duelsService')` inside function body. This creates a hidden circular dependency risk.
- **Lines 194-235**: `updateChallengeScores` does sequential per-participant DB queries in a `for` loop. No batching, no parallelism. N+1 query problem.

**Error Handling:** Errors caught at top level but XP/celebration errors silently swallowed (line 293).

**Dead Code:** None found.

**Security:** No direct injection risks. Uses Supabase parameterized queries.

**External APIs:** OpenAI indirectly via duelsService.

**Database Tables:** `manager_challenges`, `user_xp`, `celebration_events`

---

### 2. `/home/ccuser/rateright-growth/src/services/aiCallScoring.js` (441 lines)

**Exports:** `scoreCall`, `getCallScore`, `getUserScores`, `getBestCalls`, `getCallsNeedingCoaching`, `getUserScoreStats`, `getScoreLeaderboard`

**Bug Risks:**
- **Line 137**: Truncates transcript at 8000 chars with `transcript.substring(0, 8000)`. Could miss critical context at end of long calls.
- Heuristic fallback scoring (lines 230-305) when OpenAI is unavailable uses simplistic keyword counting. Results may be misleading.

**Error Handling:** Good -- returns `{ error }` objects rather than throwing. Fallback scoring when AI unavailable.

**Dead Code:** None found.

**Security:** No issues. Uses parameterized Supabase queries.

**External APIs:** OpenAI GPT-4o for call scoring.

**Database Tables:** `call_quality_scores`, `communications`, `copilot_sessions`, `user_xp`

---

### 3. `/home/ccuser/rateright-growth/src/services/activationAI.js` (469 lines)

**Exports:** `analyzeBlockers`, `generateNudge`, `generateBulkNudges`, `suggestAction`, `analyzeStageDropoff`

**Bug Risks:**
- **Line 185**: `generateBulkNudges` processes leads sequentially in a for loop. No parallelism, no batching. Could be very slow for large lead sets.

**Error Handling:** Good -- returns fallback templates when AI fails.

**Dead Code:** None found.

**Security:** No issues. Pure AI prompt service, no DB queries.

**External APIs:** OpenAI GPT-4o-mini for nudge generation.

**Database Tables:** None directly (receives data as parameters).

---

### 4. `/home/ccuser/rateright-growth/src/services/challengesService.js` (429 lines)

**Exports:** `INDIVIDUAL_CHALLENGES`, `TEAM_CHALLENGES`, `generateDailyChallenges`, `generateTeamChallenge`, `updateChallengeProgress`, `getTodayChallenges`, `updateTeamChallengeProgress`

**Bug Risks:**
- **Lines 189-235**: Challenge matching based on title string matching (`title.includes('Make')`, `title.includes('Send')`, etc.). Extremely fragile -- renaming a challenge title breaks progress tracking silently.
- **Lines 260, 398**: Dynamic `require('./xpService')` inside function body inside loop iterations.
- **Lines 90-96, 145-155**: Handles duplicate key errors (23505) -- good practice for concurrent inserts.

**Error Handling:** Catches 23505 duplicate key errors properly. Other errors logged but not propagated.

**Dead Code:** None found.

**Security:** No injection risks.

**External APIs:** None.

**Database Tables:** `daily_challenges`, `team_challenges`, `user_xp`, `celebration_events`

---

### 5. `/home/ccuser/rateright-growth/src/services/badgesService.js` (353 lines)

**Exports:** `awardWeeklyBadges`, `getUserBadges`, `getCurrentWeekBadges`, `userHasBadge`, `getWeekStart`

**Bug Risks:**
- **Lines 28-71**: N+1 query pattern -- fires one query per user for call stats inside a loop.
- **Line 103**: "Consistent" badge logic only awards the FIRST qualifying user via `topCaller`, not all qualifying users. If multiple users qualify, only one gets the badge.
- **Line 254**: Dynamic `require('./slack')` inside function.

**Error Handling:** Errors logged, function continues processing other badges.

**Dead Code:** None found.

**Security:** No issues.

**External APIs:** Slack (via slack service).

**Database Tables:** `user_badges`, `communications`, `user_xp`

---

### 6. `/home/ccuser/rateright-growth/src/services/callListRanker.js` (558 lines)

**Exports:** `computeLeadPriority`, `rankLeadsForCallList`, `buildRankingContext`, `refreshLeadPriority`, `computeUrgencyScore`, `computeIntentScore`, `computeTimingScore`, `computePatternScore`, `computeBaseScore`

**Bug Risks:**
- 5-minute in-memory cache (line 15) works well for single-instance deployments but would cause inconsistency in multi-instance scenarios.

**Error Handling:** Good -- uses try/catch throughout with console.error logging.

**Dead Code:** None found.

**Security:** No issues.

**External APIs:** None.

**Database Tables:** `leads`, `callbacks`, `winning_patterns`, `conversion_patterns`

---

### 7. `/home/ccuser/rateright-growth/src/services/callAnalytics.js` (802 lines)

**Exports:** `analyzeCall`, `getCallAnalytics`, `getLeadCallAnalytics`, `getQualityTrends`, `getCoachingAlerts`, `reviewCoachingAlert`, `getQualityLeaderboard`

**Bug Risks:**
- **Line 253**: `callerTotal` is initialized to 0 but NEVER incremented anywhere. Dead variable.
- **Line 275**: `agentTotal++` increments for ALL questions, regardless of which speaker asked them. The code assumes all questions are from the agent, making the "questions asked by agent" metric incorrect.
```javascript
// Line 275
agentTotal++; // BUG: increments for ALL questions, not just agent questions
```

**Error Handling:** Adequate. Returns default values on error.

**Dead Code:** `callerTotal` variable (line 253) -- never used after initialization.

**Security:** No issues.

**External APIs:** None (pure analytics on local data).

**Database Tables:** `communications`, `coaching_alerts`, `call_quality_scores`

---

### 8. `/home/ccuser/rateright-growth/src/services/promptManagement.js` (373 lines)

**Exports:** `DEFAULT_PROMPTS`, `getActivePrompt`, `fillTemplate`, `recordPromptOutcome`, `getPromptPerformance`, `createPromptVersion`, `activatePromptVersion`, `getAllPromptStatus`

**Bug Risks:**
- **Line 167**: `db.raw('usage_count + 1')` -- Supabase JS client does NOT support `.raw()`. This silently fails because of `.catch(() => {})` on line 172. Usage counts are NEVER incremented.
```javascript
// Line 167
.update({ usage_count: db.raw('usage_count + 1') }) // BUG: .raw() doesn't exist on Supabase
```
- **Line 203**: Same issue: `db.raw(\`${updateField} + 1\`)` -- success/fail counts never increment.
- **Lines 309-321**: `activatePromptVersion` does deactivate-then-activate in two separate queries. Not atomic -- if the process crashes between them, all versions of that prompt type could be deactivated.

**Error Handling:** Errors silently swallowed with `.catch(() => {})` on lines 172 and 210. This masks the `.raw()` bug.

**Dead Code:** None found (but the usage tracking is effectively dead due to the bug).

**Security:** No injection risks.

**External APIs:** None.

**Database Tables:** `prompt_versions`

---

### 9. `/home/ccuser/rateright-growth/src/services/learning.js` (470 lines)

**Exports:** `captureConversionPattern`, `recordSuggestionFeedback`, `getEffectiveResponses`, `getSimilarWins`

**Bug Risks:** None significant. Uses `Promise.allSettled` correctly (line 27).

**Error Handling:** Good -- individual query failures don't crash the whole function.

**Dead Code:** None found.

**Security:** No issues.

**External APIs:** None.

**Database Tables:** `leads`, `communications`, `copilot_sessions`, `lead_notes`, `conversion_patterns`, `objection_responses`, `suggestion_feedback`

---

### 10. `/home/ccuser/rateright-growth/src/services/duelsService.js` (610 lines)

**Exports:** `DUEL_TYPES`, `calculateOdds`, `createDuel`, `acceptDuel`, `declineDuel`, `getUserDuels`, `getUserDuelHistory`, `updateDuelScores`, `completeDuel`, `createCelebrationEvent`, `getRecentCelebrations`, `processExpiredDuels`

**Bug Risks:**
- **Lines 493-530**: `updateDuelHistory` is a classic read-then-write race condition. It reads `duel_history` JSON array from the DB, pushes a new entry, and writes it back. Concurrent writes will lose data.
- **Lines 162-201**: `createDuel` checks for existing active duels then inserts -- TOCTOU (time-of-check-time-of-use) vulnerability. Two concurrent requests could both pass the check and create duplicate duels.

**Error Handling:** Good overall. Uses try/catch with error returns.

**Dead Code:**
- **Line 39**: `MAX_DAILY_LOSS_PERCENT` constant is defined but never referenced anywhere in the file.

**Security:** No injection risks.

**External APIs:** None.

**Database Tables:** `duels`, `user_xp`, `xp_history`, `celebration_events`

---

### 11. `/home/ccuser/rateright-growth/src/services/dealIntelligence.js` (602 lines)

**Exports:** `recordStageTransition`, `recordDealOutcome`, `analyzeObjectionImpact`, `findWinningResponses`, `getDealVelocity`, `predictStall`, `getLossReasons`, `getLossReasonOptions`, `getDealsAtRisk`

**Bug Risks:**
- **Line 158**: `updateObjectionOutcomes` updates ALL `objection_responses` matching the objection type, not just responses used for this specific lead. This inflates effectiveness scores for popular objection types.
- **Line 566**: N+1 query in `getDealsAtRisk` -- calls `predictStall()` per lead (up to 50 leads), each of which does its own DB queries.

**Error Handling:** Adequate. Returns empty arrays on error.

**Dead Code:** None found.

**Security:** No issues.

**External APIs:** None.

**Database Tables:** `stage_transitions`, `deal_outcomes`, `objection_responses`, `leads`, `communications`

---

### 12. `/home/ccuser/rateright-growth/src/services/selfImprovement.js` (434 lines)

**Exports:** `getThresholds`, `saveThresholds`, `analyzeSuggestionPerformance`, `analyzeFrictionAccuracy`, `autoAdjustThresholds`, `learnFromSuccess`, `generateSelfImprovementReport`, `DEFAULT_THRESHOLDS`

**Bug Risks:** None significant. Well-structured with proper bounds checking on threshold adjustments.

**Error Handling:** Good. Falls back to `DEFAULT_THRESHOLDS` when DB unavailable.

**Dead Code:** None found.

**Security:** No issues.

**External APIs:** Slack (for threshold change notifications).

**Database Tables:** `system_settings`, `intelligence_suggestions`, `detected_friction`, `intelligence_adjustments`

---

### 13. `/home/ccuser/rateright-growth/src/services/platformSync.js` (550 lines)

**Exports:** `platformRequest`, `fetchPlatformUsers`, `fetchPlatformStats`, `fetchPlatformJobs`, `fetchPlatformContracts`, `syncPlatformUser`, `syncAllPlatformUsers`, `checkPlatformConnection`, `findExistingLead`, `getLeadType`, `getUserJobs`, `getUserContracts`

**Bug Risks:**
- **Line 461**: `syncAllPlatformUsers` processes users sequentially in a for loop. No batching, no parallelism. Could take a very long time for large user bases.

**Error Handling:** Good -- individual user sync failures don't stop the batch.

**Dead Code:** None found.

**Security:** API key passed via `X-API-Key` header (line 30). Key comes from env var `RATERIGHT_API_KEY`.

**External APIs:** RateRight Admin API with 30s timeout.

**Database Tables:** `leads`, `platform_activity`

---

### 14. `/home/ccuser/rateright-growth/src/services/perplexity.js` (713 lines)

**Exports:** `searchCompany`, `searchPerson`, `searchDecisionMaker`, `searchInterestNews`, `getCachedCompanyIntel`, `getCachedLeadIntel`, `normalizeCompanyName`, `autoResearchFromTranscript`

**Bug Risks:** None significant.

**Error Handling:** Good -- returns null/empty on failure, logs errors.

**Dead Code:** None found.

**Security/Privacy:**
- `searchPerson` scrapes personal information (family status, hobbies, social profiles). While this is a business feature, it collects sensitive personal data via web search.

**External APIs:** Perplexity AI (sonar model) with 45s timeout.

**Database Tables:** `company_intel`, `lead_intel` (30-day cache).

---

### 15. `/home/ccuser/rateright-growth/src/services/repPerformance.js` (587 lines)

**Exports:** `generateWeeklyRepReport`, `aggregateRepWeeklyStats`, `analyzeRepPerformance`, `scoreCall`, `saveCallScore`, `saveWeeklySnapshot`, `getAllReps`, `formatDuration`, `formatHour`

**Bug Risks:** None significant.

**Error Handling:** Good. Returns structured error objects.

**Dead Code:** None found.

**Security:** No issues.

**External APIs:** OpenAI for performance analysis.

**Database Tables:** `user_xp`, `communications`, `leads`, `call_quality_scores`, `rep_weekly_snapshots`

---

### 16. `/home/ccuser/rateright-growth/src/services/compliance.js` (578 lines)

**Exports:** `getGuidelines`, `clearGuidelinesCache`, `checkCompliance`, `autoFixMessage`, `validateScript`, `batchValidate`, `addToReviewQueue`, `checkToneWithAI`

**Bug Risks:**
- **Line 535**: `checkToneWithAI` lazy-loads `ai.js` to avoid circular dependency. This works but is fragile.

**Error Handling:** Good. 2-hour cache with proper invalidation.

**Dead Code:** None found.

**Security:** No issues.

**External APIs:** OpenAI (via ai.js) for tone checking.

**Database Tables:** `brand_guidelines`, `compliance_review_queue`

---

### 17. `/home/ccuser/rateright-growth/src/services/openai.js` (70 lines)

**Exports:** `generateChatCompletion`, `isConfigured`

**Bug Risks:** None. Clean, minimal wrapper.

**Error Handling:** Good. Checks for API key before making calls.

**Dead Code:** None.

**Security:** No issues. API key used server-side only.

**External APIs:** OpenAI.

**Database Tables:** None.

---

### 18. `/home/ccuser/rateright-growth/src/services/criticalAlerts.js` (536 lines)

**Exports:** `processEventForAlerts`, `checkRageClicks`, `checkErrorSpike`, `checkAbandonmentSpike`, `checkApiFailures`, `checkSmsDeliveryFailures`, `checkSlowApiResponses`, `runFullAlertCheck`, `sendCriticalAlert`, `THRESHOLDS`

**Bug Risks:**
- **Line 34**: `setInterval` at module level (60-second cleanup interval). This:
  - Runs even in test environments
  - Prevents clean process shutdown (no `clearInterval` exported or called)
  - Could cause memory leaks in long-running processes if the module is loaded/unloaded multiple times.
```javascript
// Line 34
setInterval(() => { /* cleanup stale entries */ }, 60 * 1000);
```
- Duplicate cleanup logic: `shouldSendAlert` (line 62) AND the setInterval both clean stale entries from `recentAlerts`.

**Error Handling:** Good. Individual alert checks wrapped in try/catch.

**Dead Code:** The duplicate cleanup in the setInterval is redundant with the cleanup in `shouldSendAlert`.

**Security:** No issues.

**External APIs:** Slack (via slack service).

**Database Tables:** `usage_events`, `intelligence_alerts`

---

### 19. `/home/ccuser/rateright-growth/src/services/leaderboardService.js` (531 lines)

**Exports:** `RECORD_TYPES`, `WEEKLY_BADGES`, `STREAK_TIERS`, `getLeaderboard`, `checkOvertake`, `checkRecord`, `getHallOfFame`, `createPulseEvent`, `getTeamPulse`, `updateStreakTier`, `saveLeaderboardSnapshot`, `getTodaysCallCount`, `formatRecordName`

**Bug Risks:**
- **Line 499**: `getTodaysCallCount()` does NOT filter by userId. It counts ALL users' calls for today:
```javascript
// Line 499-509
async function getTodaysCallCount() {
  const { count } = await db
    .from('communications')
    .select('*', { count: 'exact', head: true })
    .eq('type', 'call_outbound')
    .gte('created_at', todayStr);
  return count || 0;
  // BUG: No .eq('user_id', userId) filter!
}
```

**Error Handling:** Good overall.

**Dead Code:** None found.

**Security:** No issues.

**External APIs:** None.

**Database Tables:** `user_xp`, `communications`, `leaderboard_records`, `team_pulse`, `leaderboard_snapshots`

---

### 20. `/home/ccuser/rateright-growth/src/services/deepgram.js` (86 lines)

**Exports:** `isConfigured`, `getClientConfig`, `getApiKey`, `getAuthenticatedWSUrl`

**Bug Risks:** None structurally.

**Error Handling:** Good -- returns `{ configured: false, error: ... }` when key missing.

**Dead Code:** None.

**Security - CRITICAL:**
- **Line 47**: `getClientConfig()` returns `DEEPGRAM_API_KEY` to the client:
```javascript
// Line 47
return {
  configured: true,
  apiKey: process.env.DEEPGRAM_API_KEY, // SECURITY: Exposes API key to client!
};
```
- **Line 54** comment: "NEVER expose this to the client" -- but `getClientConfig()` does exactly that. `getApiKey()` (line 61) has the warning comment, but both functions expose the same key.

**External APIs:** Deepgram (configuration only).

**Database Tables:** None.

---

### 21. `/home/ccuser/rateright-growth/src/services/scoring.js` (278 lines)

**Exports:** `calculateLeadScore`, `updateLeadScore`, `recalculateAllScores`, `getScoreTier`, `SCORE_RULES`

**Bug Risks:**
- **Line 246**: `recalculateAllScores` processes leads sequentially. Could be very slow for large datasets.

**Error Handling:** Good. Returns structured results.

**Dead Code:** None.

**Security:** No issues.

**External APIs:** None.

**Database Tables:** `leads`, `communications`, `platform_activity`

---

### 22. `/home/ccuser/rateright-growth/src/services/pushNotifications.js` (306 lines)

**Exports:** `sendPushNotification`, `broadcastPush`, `isQuietHours`, `notifyHighIntentSms`, `notifyNewSignup`, `notifyCallbackDue`, `notifyConversion`

**Bug Risks:** None significant. Properly handles expired subscriptions (410/404).

**Error Handling:** Good -- handles expired push subscriptions by deleting stale records.

**Dead Code:** None.

**Security:** VAPID configuration at module level uses env vars properly.

**External APIs:** Web Push API.

**Database Tables:** `push_subscriptions`

---

### 23. `/home/ccuser/rateright-growth/src/services/weeklyIntelligence.js` (506 lines)

**Exports:** `runWeeklyAnalysis`, `getLatestReport`, `getPageStats`, `getFlowStats`, `getErrorStats`, `getAIQualityStats`

**Bug Risks:**
- **Line 9**: `const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY })` -- Creates client at module load without checking if API key exists. Unlike other files that guard with `if (process.env.OPENAI_API_KEY)`, this will crash at module import time if the OpenAI package is installed but the key is missing.
- **Line 71**: `getWeekStart()` mutates the `now` Date object via `now.setDate(diff)`. This is a side-effect bug -- if the caller reuses the Date, it will have been mutated.

**Error Handling:** Adequate. Returns empty result sets on error.

**Dead Code:** None.

**Security:** No issues.

**External APIs:** OpenAI GPT-4o.

**Database Tables:** `usage_events`, `suggestion_feedback`, `weekly_excellence_reports`, `intelligence_suggestions`, `detected_friction`

---

### 24. `/home/ccuser/rateright-growth/src/services/twilioMedia.js` (365 lines)

**Exports:** `handleTwilioMediaStream`, `subscribeToTranscripts`, `activeStreams`

**Bug Risks:**
- **Line 16**: `activeStreams` Map entries may not be cleaned up if WebSocket disconnects abnormally without a 'stop' event. The `ws.on('close')` handler (line 148) does attempt cleanup, but if `callSid` was never set (e.g., connection closed before 'start' event), the stream is leaked.
- **Line 116**: `mixAndSendAudio` is called on every 'media' event, which creates CPU overhead even when only one track has data.

**Error Handling:** Good -- try/catch around message processing.

**Dead Code:** None.

**Security:** Deepgram API key used server-side only (in WebSocket auth header).

**External APIs:** Deepgram (real-time transcription via WebSocket).

**Database Tables:** `copilot_sessions` (for saving transcripts).

---

### 25. `/home/ccuser/rateright-growth/src/services/twilioMediaSetup.js` (34 lines)

**Exports:** `setupTwilioMediaStreams`

**Bug Risks:** None.

**Error Handling:** Minimal but adequate for a setup file.

**Dead Code:** None.

**Security:**
- **Line 21**: Logs ALL request headers:
```javascript
console.log('[TwilioMedia] Headers:', JSON.stringify(request.headers, null, 2));
```
This could log sensitive authentication headers to stdout/log files.

**External APIs:** None directly.

**Database Tables:** None.

---

### 26. `/home/ccuser/rateright-growth/src/services/templates.js` (97 lines)

**Exports:** `getTemplate`, `getAllTemplates`, `renderTemplate`, `buildLeadVariables`

**Bug Risks:** None. Clean, simple service.

**Error Handling:** Good. Returns null/empty on failure.

**Dead Code:** None.

**Security:**
- **Line 69**: Removes unmatched template variables: `rendered.replace(/\{\{\s*\w+\s*\}\}/g, '')`. This is good -- prevents leaking variable names to users.

**External APIs:** None.

**Database Tables:** `sms_templates`

---

### 27. `/home/ccuser/rateright-growth/src/services/slack.js` (1143 lines)

**Exports:** `sendSlackMessage`, `sendInboundAlert`, `sendInboundCallAlert`, `sendMissedCallAlert`, `sendVoicemailAlert`, `sendCallbackReminder`, `sendDailySummary`, `sendConversionAlert`, `sendWeeklyReport`, `sendBugReport`, `sendContractorReferralAlert`, `sendWebsiteSignupAlert`, `sendDevQueueItem`, `sendDevQueueReady`, `isConfigured`

**Bug Risks:**
- Rate limiting at 1 message/second (line 9). If many events fire simultaneously, messages queue up and delays compound.

**Error Handling:** Good. Returns success/failure status. Handles rate limiting.

**Dead Code:** None found (large file but all functions appear used).

**Security:** Uses `SLACK_WEBHOOK_URL` from env vars. No secret exposure.

**External APIs:** Slack Incoming Webhooks.

**Database Tables:** None directly (receives data as parameters).

---

### 28. `/home/ccuser/rateright-growth/src/services/xpService.js` (210 lines)

**Exports:** `XP_AWARDS`, `LEVEL_NAMES`, `calculateLevel`, `awardXP`, `awardXPForCall`, `awardXPForSMS`

**Bug Risks:**
- **Lines 65-118**: Classic read-then-update race condition on `user_xp` table. `awardXP` reads current XP, adds award amount, writes back. Concurrent XP awards will lose data:
```javascript
// Line 65-80 (simplified)
const { data: existing } = await db.from('user_xp').select('total_xp, ...').eq('user_id', userId);
const newTotal = (existing.total_xp || 0) + amount;
await db.from('user_xp').update({ total_xp: newTotal }).eq('user_id', userId);
// BUG: If two awards happen concurrently, one is lost
```

**Error Handling:** Good. Returns structured results with success flag.

**Dead Code:** None.

**Security:** No issues.

**External APIs:** None.

**Database Tables:** `user_xp`, `xp_history`

---

### 29. `/home/ccuser/rateright-growth/src/services/wisdom.js` (489 lines)

**Exports:** `getWisdom`, `rateWisdom`, `analyzeContext`, `determineTrigger`

**Bug Risks:**
- **Line 395**: Calls `saveWisdomToDb` but there's also a `saveWisdom` function (line 312) that does similar work. Potential confusion, though both are called in different paths.
- In-memory `wisdomCache` Map (line 19) grows unbounded. No maximum size or eviction policy beyond TTL checks.

**Error Handling:** Good. Multiple fallback paths (AI -> curated DB -> hardcoded fallback).

**Dead Code:**
- **Lines 312-325**: `saveWisdom` function is defined but never called (replaced by `saveWisdomToDb` on line 395). Dead code.

**Security:** No issues.

**External APIs:** OpenAI GPT-4o-mini.

**Database Tables:** `wisdom`, `wisdom_shown`

---

### 30. `/home/ccuser/rateright-growth/src/services/stageDiagnosis.js` (433 lines)

**Exports:** `diagnose`, `detectPattern`, `getStageProgress`, `getStageContext`, `getStagesForType`, `getLikelyBlocker`, `getRecommendedAction`, `generateSMSTemplate`, `WORKER_STAGES`, `CONTRACTOR_STAGES`, `STAGE_LABELS`, `STAGE_BLOCKERS`, `STAGE_ACTIONS`

**Bug Risks:** None significant. Well-structured service with clear pattern detection logic.

**Error Handling:** Good. Returns fallback scripts when AI fails.

**Dead Code:** None.

**Security:** No issues.

**External APIs:** OpenAI (via openai.js wrapper) for script generation.

**Database Tables:** None directly.

---

### 31. `/home/ccuser/rateright-growth/src/services/stageCalculator.js` (433 lines)

**Exports:** `calculateWorkerStage`, `calculateContractorStage`, `calculateHealthScore`, `getStageIndex`, `hasStageProgressed`, `getStagesForType`, `getStageLabel`, `logStageTransition`, `handleSequenceAutoEnrollment`, `calculateDaysInStage`, `isStuck`, `diagnoseStuckReason`, `WORKER_STAGES`, `CONTRACTOR_STAGES`, `STAGE_LABELS`

**Bug Risks:**
- **Lines 227-353**: `handleSequenceAutoEnrollment` makes 5-6 sequential DB queries. Not a bug per se, but slow under load.
- **Line 299**: `.or(\`status.eq.active,enrolled_at.gte.${thirtyDaysAgo.toISOString()}\`)` -- Supabase `.or()` with template literals. While the Date ISO string is safe, this pattern is fragile if user-controlled data were ever passed.

**Error Handling:** Good. Individual failures logged but don't stop processing.

**Dead Code:** None.

**Security:** No injection risks (ISO date strings are safe).

**External APIs:** None.

**Database Tables:** `leads`, `stage_transitions`, `sequence_enrollments`, `sequences`, `sequence_steps`

---

### 32. `/home/ccuser/rateright-growth/src/services/twimlWithStream.js` (70 lines)

**Exports:** `generateTwiMLWithStream`

**Bug Risks:**
- **Line 27**: Uses `req.headers.host` to construct WebSocket URL. If behind a proxy without proper `X-Forwarded-Host` handling, this could produce incorrect URLs.

**Error Handling:** Minimal -- no try/catch. If Twilio SDK throws, the error propagates unhandled.

**Dead Code:** None.

**Security:** No direct issues. Request parameters used in TwiML generation are not user-injectable in a dangerous way.

**External APIs:** Twilio (TwiML generation).

**Database Tables:** None.

---

### 33. `/home/ccuser/rateright-growth/src/services/qualityAudit.js` (1134 lines)

**Exports:** `runFullAudit`, `runAPITests`, `runExternalServiceTests`, `runCriticalTests`, `runBusinessMetricTests`, `runSyntheticJourneyTests`, `runFrontendTests`, `formatSlackReport`, `formatTextReport`, `AUDIT_CATEGORIES`, `SEVERITY_MAP`

**Bug Risks:**
- **Lines 62-71**: Audit tests run sequentially (each category `await`'d). Could be parallelized for faster audit runs.
- **Line 305**: `require('./deepgram')` called inside test function. If deepgram module has side effects, this could cause issues in test environments.

**Error Handling:** Excellent. Each test is wrapped in `runTest` which catches all errors and reports them as test failures.

**Dead Code:** None.

**Security:** No issues. Tests read data but don't modify anything critical.

**External APIs:** Tests connectivity to Twilio, OpenAI, Deepgram, Supabase Realtime, and Slack.

**Database Tables:** Reads from many tables: `leads`, `communications`, `user_xp`, `sequences`, `callbacks`, `copilot_sessions`, `ai_insights`, `conversion_patterns`, `objection_responses`, `lead_intel`, `winning_patterns`, `sms_templates`, `web_vitals`, `frontend_errors`, `speed_to_lead`, `lead_dossier`, `playbook_messages`, `sequence_enrollments`, `duels`, `manager_challenges`, `webhook_endpoints`

---

### 34. `/home/ccuser/rateright-growth/src/services/ai.js` (2306 lines)

**Exports:** `generateIntelBrief`, `generatePostCallSummary`, `draftMessage`, `transcribeAudio`, `parseVoiceCommand`, `getObjectionResponse`, `calculateConversionProbability`, `generateWeeklyInsights`, `cleanupNotes`, `findSimilarWins`, `extractTranscriptIntel`, `extractPersonalIntelFromConversations`, `saveExtractedIntel`, `extractAndSaveCallIntel`, `parseContactFromSMS`, `generateReEngagedInsight`, `extractLeadCorrections`, `recommendScriptForLead`, `extractQuickIntel`, `extractInboundIntel`, `findSimilarLeads`, `generatePersonalizedBatch`

**Bug Risks:**
- **Lines 2167-2192**: `findSimilarLeads` fires N+1 queries. For each candidate lead, it queries `communications` to check last message direction. With `limit * 2` candidates (default 10), that's 10 separate DB queries.
- **Line 1264**: Transcript content is truncated to first 2000 chars per session (`s.transcript.substring(0, 2000)`). Could miss important intel in longer call transcripts.
- **Line 1286**: Entire conversation text further truncated to 8000 chars for AI processing.

**Error Handling:** Good throughout. Every AI function checks `if (!openai)` and returns error objects.

**Dead Code:** None found (despite the file being very large, all functions are exported and appear referenced).

**Security:**
- The `parseVoiceCommand` function handles user voice input, but the downstream functions that use the parsed data (in taskExecutor.js) have SQL injection risks via `.ilike` (see taskExecutor entry).

**External APIs:** OpenAI (GPT-4o, GPT-4o-mini, Whisper).

**Database Tables:** `leads`, `communications`, `copilot_sessions`, `lead_notes`, `lead_intel`, `company_intel`, `scripts`

---

### 35. `/home/ccuser/rateright-growth/src/services/notifications.js` (95 lines)

**Exports:** `notifyTaskComplete`

**Bug Risks:**
- **Line 9**: Falls back to `TWILIO_PHONE_NUMBER` if `MICHAEL_PHONE` is not set. This would send notification SMS FROM the Twilio number TO the same Twilio number, which would fail or loop.

**Error Handling:** Good. Catches and logs errors.

**Dead Code:**
- **Lines 86-91**: `notifyViaCall` function is defined but only called as a fallback for SMS. The TODO comment indicates this is incomplete.

**Security:** No issues.

**External APIs:** Twilio (via twilio service) for SMS.

**Database Tables:** `vapi_tasks`

---

### 36. `/home/ccuser/rateright-growth/src/services/taskExecutor.js` (461 lines)

**Exports:** `executeTask`

**Bug Risks:** None structurally. Well-organized switch/case pattern.

**Error Handling:** Good. Updates task status on both success and failure.

**Dead Code:** None.

**Security - HIGH:**
- **Lines 141, 209, 256, 318**: User-provided `name` from parsed voice commands is interpolated directly into Supabase `.or()` queries:
```javascript
// Line 141
.or(`first_name.ilike.%${name}%,last_name.ilike.%${name}%`)
```
While Supabase's PostgREST does escape values to some degree, this pattern is unsafe. A crafted `name` value could potentially manipulate the query logic. The `name` comes from `task.task_params` which originates from voice transcript parsing -- user-controlled input.

**External APIs:** Twilio (via twilio service).

**Database Tables:** `vapi_tasks`, `leads`, `callbacks`, `communications`, `dev_queue`

---

### 37. `/home/ccuser/rateright-growth/src/services/taskParser.js` (207 lines)

**Exports:** `parseTaskFromTranscript`

**Bug Risks:**
- **Line 7**: `const { extractJson } = require('../services/ai')` -- imports a function `extractJson` that does NOT exist in `ai.js`'s exports. This will be `undefined` at runtime, and the `aiParseTask` fallback (line 177: `const parsed = extractJson(response)`) will throw a TypeError.

**Error Handling:** Catches AI parse errors and falls back to custom task type.

**Dead Code:** None.

**Security:** Voice transcript input is passed to regex patterns. No injection risk in the regex itself.

**External APIs:** OpenAI (via direct SDK instantiation in `aiParseTask`).

**Database Tables:** None directly.

---

### 38. `/home/ccuser/rateright-growth/src/services/exportService.js` (259 lines)

**Exports:** `exportLeadsToCSV`, `exportLeadsToJSON`, `exportCommunicationsToCSV`, `exportAnalyticsToCSV`

**Bug Risks:**
- **Line 55**: Hard limit of 10,000 rows via `.limit(10000)`. No pagination support for larger datasets. Users may not realize exports are truncated.
- CSV escaping (lines 70-74) handles commas, quotes, and newlines but does not handle the "CSV injection" attack vector where values starting with `=`, `+`, `-`, or `@` could be interpreted as formulas by spreadsheet software.

**Error Handling:** Throws errors directly. Caller must handle.

**Dead Code:** None.

**Security:**
- CSV injection risk: Lead data (names, companies) could contain formula-like strings that would execute in Excel/Google Sheets when opened.

**External APIs:** None.

**Database Tables:** `leads`, `communications`, `conversions`

---

### 39. `/home/ccuser/rateright-growth/src/services/webhookDelivery.js` (287 lines)

**Exports:** `WEBHOOK_EVENTS`, `deliverWebhook`, `fireWebhooks`, `processPendingRetries`, `signPayload`

**Bug Risks:**
- **Line 170**: `attemptNum` is calculated as `delivery.attempts + 1` but the actual `attempts` field was already incremented to this value on line 105. This means the retry comparison on line 172 (`attemptNum < retryConfig.max_attempts`) is off by one -- it will retry one fewer time than configured.

**Error Handling:** Good. Proper retry logic with exponential backoff.

**Dead Code:** None.

**Security:** Proper HMAC-SHA256 signature verification for webhook payloads. Good security practice.

**External APIs:** Customer-configured webhook endpoints.

**Database Tables:** `webhook_endpoints`, `webhook_deliveries`

---

### 40. `/home/ccuser/rateright-growth/src/services/enrichment.js` (424 lines)

**Exports:** `getConfig`, `updateConfig`, `hasCredits`, `getCachedEnrichment`, `enrichLead`, `enrichLeadsBulk`, `getUsageStats`, `SOURCES`

**Bug Risks:**
- **Line 81**: `db.raw('credits_used_this_month + ?', [credits])` -- Supabase JS does NOT support `.raw()`. Credit consumption silently fails, meaning credits are never deducted and the monthly limit is never enforced.
```javascript
// Line 81
.update({
  credits_used_this_month: db.raw('credits_used_this_month + ?', [credits]), // BUG: .raw() doesn't exist
  updated_at: new Date().toISOString()
})
```
- **Lines 357-374**: `enrichLeadsBulk` processes leads sequentially. No parallelism.

**Error Handling:** Adequate but the `.raw()` bug means errors are silently produced.

**Dead Code:** None.

**Security:**
- **Line 167**: Comment says "In production, decrypt this" for `api_key_encrypted`, but the code uses it raw:
```javascript
const apiKey = config.api_key_encrypted; // In production, decrypt this
```
The API key is stored in the database but never decrypted before use, meaning either the encryption is not implemented, or the API calls will fail with an encrypted key.

**External APIs:** Apollo.io for lead enrichment.

**Database Tables:** `enrichment_config`, `enrichment_cache`, `enrichment_usage`, `leads`

---

### 41. `/home/ccuser/rateright-growth/src/services/jobLocking.js` (205 lines)

**Exports:** `acquireJobLock`, `releaseJobLock`, `runJobWithLock`, `isJobRunning`, `cleanupExpiredLocks`

**Bug Risks:**
- **Line 59**: Recursive call to `acquireJobLock` when cleaning up expired locks. If the DB has issues, this could cause infinite recursion (no recursion depth guard).
- Lock acquisition (lines 23-33) relies on Supabase unique constraint to prevent duplicates. This is correct but depends on the `job_locks` table having a proper unique constraint on `job_name`.

**Error Handling:** Good. Lock is always released on failure (line 128).

**Dead Code:** None.

**Security:** No issues.

**External APIs:** None.

**Database Tables:** `job_locks`

---

### 42. `/home/ccuser/rateright-growth/src/services/twilio.js` (178 lines)

**Exports:** `sendSMS`, `sendBatchSMS`, `validateWebhookSignature`, `isConfigured`, `generateVoiceToken`, `isVoiceConfigured`

**Bug Risks:**
- **Line 137**: `sendBatchSMS` uses a 100ms delay between messages. This is a fixed delay, not adaptive to Twilio's actual rate limits. Could still hit rate limits for large batches.

**Error Handling:** Good. Returns structured `{ success, error }` objects.

**Dead Code:** None.

**Security:** Proper webhook signature validation via `twilio.validateRequest`. API keys stay server-side.

**External APIs:** Twilio (SMS, Voice tokens).

**Database Tables:** None directly.

---

### 43. `/home/ccuser/rateright-growth/src/services/cache.js` (210 lines)

**Exports:** `cacheService` (singleton instance of `CacheService`)

**Bug Risks:**
- **Lines 11, 39**: `init()` is called in constructor but is `async`. The constructor returns before `init()` completes. Any immediate cache operations after `require('./cache')` may fail because Redis isn't connected yet.
- **Line 111**: `delPattern` uses `this.redisClient.keys(pattern)` which is an O(N) operation in Redis. In production with many keys, this will be slow and block the Redis event loop.
- **Lines 179-190**: Cache middleware overrides `res.json`. This monkey-patching approach can break if other middleware also overrides `res.json`, and doesn't handle errors in the original `json` call.

**Error Handling:** Good -- swallows errors and returns null/undefined gracefully. Falls back to in-memory cache when Redis unavailable.

**Dead Code:** None.

**Security:** No issues. Redis password from env vars.

**External APIs:** Redis.

**Database Tables:** None.

---

### 44. `/home/ccuser/rateright-growth/src/services/twimlWithStream.js` (70 lines)

Already covered above as item #32.

---

## CROSS-CUTTING ISSUES

### 1. `db.raw()` Usage (Supabase Incompatibility)
Three files use `db.raw()` which does not exist on the Supabase JS client:
- **promptManagement.js** lines 167, 203 -- usage/success counts never increment
- **enrichment.js** line 81 -- credit consumption never works

These are silent failures because errors are swallowed.

### 2. Read-Then-Write Race Conditions
Multiple files have non-atomic read-update patterns on shared data:
- **xpService.js** (lines 65-118) -- XP awards can be lost
- **duelsService.js** (lines 493-530) -- duel history entries can be lost
- **promptManagement.js** (lines 309-321) -- prompt activation is non-atomic

All of these need either atomic increments (Supabase RPC functions) or optimistic concurrency control.

### 3. Sequential Processing in Loops (N+1 Queries)
Multiple files process items sequentially that could be batched or parallelized:
- **platformSync.js** `syncAllPlatformUsers` -- sequential per-user sync
- **activationAI.js** `generateBulkNudges` -- sequential per-lead
- **scoring.js** `recalculateAllScores` -- sequential per-lead
- **enrichment.js** `enrichLeadsBulk` -- sequential per-lead
- **badgesService.js** `awardWeeklyBadges` -- N+1 queries per user
- **dealIntelligence.js** `getDealsAtRisk` -- N+1 queries per lead
- **ai.js** `findSimilarLeads` -- N+1 queries per candidate

### 4. In-Memory State Without Cleanup
Several files maintain in-memory Maps/caches without bounded size:
- **wisdom.js** `wisdomCache` -- no max size
- **callListRanker.js** -- 5-min cache, no max size
- **criticalAlerts.js** `recentAlerts` -- cleaned by timer, but timer never stops
- **twilioMedia.js** `activeStreams` -- leaked entries on abnormal disconnect

### 5. Dynamic `require()` Inside Functions
Multiple files use `require()` inside function bodies to avoid circular dependencies:
- **challengesServiceV2.js** line 296
- **challengesService.js** lines 260, 398
- **badgesService.js** line 254
- **compliance.js** line 535

This works but makes dependency analysis difficult and can cause subtle initialization order bugs.

### 6. Module-Level Side Effects
- **criticalAlerts.js** line 34: `setInterval` that runs forever
- **cache.js** lines 11, 208: Constructor calls async `init()`, creating Redis connections at module load
- **weeklyIntelligence.js** line 9: Creates OpenAI client at module load without key check

---

## DATABASE TABLES ACCESSED (COMPLETE LIST)

Across all 44 files, the following tables are queried:

`leads`, `communications`, `user_xp`, `xp_history`, `callbacks`, `sequences`, `sequence_enrollments`, `sequence_steps`, `sms_templates`, `daily_challenges`, `team_challenges`, `manager_challenges`, `duels`, `celebration_events`, `user_badges`, `leaderboard_records`, `leaderboard_snapshots`, `team_pulse`, `call_quality_scores`, `rep_weekly_snapshots`, `copilot_sessions`, `lead_notes`, `conversion_patterns`, `objection_responses`, `suggestion_feedback`, `stage_transitions`, `deal_outcomes`, `winning_patterns`, `company_intel`, `lead_intel`, `lead_dossier`, `platform_activity`, `ai_insights`, `brand_guidelines`, `compliance_review_queue`, `prompt_versions`, `system_settings`, `intelligence_suggestions`, `detected_friction`, `intelligence_adjustments`, `weekly_excellence_reports`, `usage_events`, `wisdom`, `wisdom_shown`, `push_subscriptions`, `vapi_tasks`, `dev_queue`, `enrichment_config`, `enrichment_cache`, `enrichment_usage`, `webhook_endpoints`, `webhook_deliveries`, `job_locks`, `web_vitals`, `frontend_errors`, `speed_to_lead`, `playbook_messages`, `scripts`, `conversions`

**Total: ~60 distinct tables.**

---

## EXTERNAL API DEPENDENCIES

1. **OpenAI** (GPT-4o, GPT-4o-mini, Whisper) -- used by: ai.js, activationAI.js, aiCallScoring.js, weeklyIntelligence.js, wisdom.js, stageDiagnosis.js, repPerformance.js, compliance.js, taskParser.js, selfImprovement.js
2. **Twilio** (SMS, Voice, Media Streams) -- used by: twilio.js, twimlWithStream.js, twilioMedia.js, twilioMediaSetup.js, notifications.js, taskExecutor.js
3. **Deepgram** (Real-time transcription) -- used by: deepgram.js, twilioMedia.js
4. **Perplexity AI** (Web research) -- used by: perplexity.js
5. **Apollo.io** (Lead enrichment) -- used by: enrichment.js
6. **Slack** (Webhooks) -- used by: slack.js, criticalAlerts.js, selfImprovement.js
7. **RateRight Admin API** (Platform sync) -- used by: platformSync.js
8. **Redis** (Caching) -- used by: cache.js
9. **Web Push** (Push notifications) -- used by: pushNotifications.js