Read the file /tmp/claude-1000/-home-ccuser-rateright-growth/tasks/a0359b8.output (it may be very large, read it in chunks). This is a routes audit of a Growth Engine codebase.

Extract and compile into a structured report:
1. EVERY endpoint found with method + path + purpose (complete list)
2. ALL security issues found (auth bypasses, missing validation, etc.)
3. ALL dead code found
4. ALL error handling issues
5. Twilio/VAPI webhook validation issues
6. Which routes have auth middleware and which don't

Format the output as a clean structured report I can paste into a markdown file. Be thorough - don't miss any endpoints.


I'll start by reading the file to understand its size and content.


<tool_use_error>File content (714.7KB) exceeds maximum allowed size (256KB). Please use offset and limit parameters to read specific portions of the file, or use the GrepTool to search for specific content.</tool_use_error>

Error: File content (714.7KB) exceeds maximum allowed size (256KB). Please use offset and limit parameters to read specific portions of the file, or use the GrepTool to search for specific content.


Large file. Let me read it in chunks.


Error: File content (681.3KB) exceeds maximum allowed size (256KB). Please use offset and limit parameters to read specific portions of the file, or use the GrepTool to search for specific content.


Bash

Count total lines in the file


<tool_use_error>Sibling tool call errored</tool_use_error>


Count total lines in the file


104 /tmp/claude-1000/-home-ccuser-rateright-growth/tasks/a0359b8.output


Only 104 lines but 714KB -- likely very long lines. Let me use a different approach.


Check file size in bytes


731859 /tmp/claude-1000/-home-ccuser-rateright-growth/tasks/a0359b8.output


head -c 30000 /tmp/claude-1000/-home-ccuser-rateright-growth/tasks/a0359b8.output

Read first 30KB of the audit file


{"parentUuid":null,"isSidechain":true,"userType":"external","cwd":"/home/ccuser/rateright-growth","sessionId":"6138a2b4-4fed-4a8e-841b-ea0e29be8b8c","version":"2.1.34","gitBranch":"main","agentId":"a0359b8","slug":"lovely-tumbling-taco","type":"user","message":{"role":"user","content":"Read EVERY file in /home/ccuser/rateright-growth/src/routes/ and provide a detailed audit. For each file report:\n1. What endpoints it exposes (method, path, purpose)\n2. Auth checks — does it use any middleware for authentication? Are there unprotected routes?\n3. Input validation — are request params/body validated? Any injection risks?\n4. Error handling — are errors caught? Are internal details leaked?\n5. Dead code — unused routes, commented-out code, stale functions\n6. Security issues — API key exposure, SQL injection, any dangerous patterns\n7. Twilio/VAPI webhook validation — if applicable\n\nThe files to read are:\n- calls.js, aiAlerts.js, activation.js, dossier.js, dealIntelligence.js, battlegroundV2.js\n- frontendTracking.js, achievements.js, battleground.js, bugReport.js, dev.js, coaching.js\n- callScoring.js, analytics.js, ai.js, callAnalytics.js, prompts.js, sms.js\n- objections.js, notion.js, voicemail.js, health.js, users.js, notifications.js\n- scripts.js, intelligence.js, xp.js, manager.js, sync.js, jobs.js\n- voice.js, voice.js.patch, callList.js, sequences.js, vapi.js, tags.js, playbook.js\n- team.js, competitors.js, export.js, import.js, outboundWebhooks.js, enrichment.js\n- leads.js, dashboard.js, webhooks.js\n\nBe thorough and brutal. Report EVERYTHING. Include specific line numbers and code snippets for issues found."},"uuid":"27ee1006-5a56-41ce-8daf-124034de20df","timestamp":"2026-02-07T05:51:11.100Z"}
{"parentUuid":"27ee1006-5a56-41ce-8daf-124034de20df","isSidechain":true,"userType":"external","cwd":"/home/ccuser/rateright-growth","sessionId":"6138a2b4-4fed-4a8e-841b-ea0e29be8b8c","version":"2.1.34","gitBranch":"main","agentId":"a0359b8","slug":"lovely-tumbling-taco","message":{"model":"claude-opus-4-6","id":"msg_01DEitu5SPWm6RBgrAdP44ur","type":"message","role":"assistant","content":[{"type":"text","text":"\n\nI'll conduct a thorough audit of every file in the routes directory. Let me start by reading all the files systematically."}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":3157,"cache_read_input_tokens":10406,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":3157},"output_tokens":2,"service_tier":"standard","inference_geo":"not_available"}},"requestId":"req_011CXtBmHAHkjRuUDAqGzShc","type":"assistant","uuid":"f3bcc35f-2a8e-4b50-abf3-6822562fc264","timestamp":"2026-02-07T05:51:13.654Z"}
{"parentUuid":"f3bcc35f-2a8e-4b50-abf3-6822562fc264","isSidechain":true,"userType":"external","cwd":"/home/ccuser/rateright-growth","sessionId":"6138a2b4-4fed-4a8e-841b-ea0e29be8b8c","version":"2.1.34","gitBranch":"main","agentId":"a0359b8","slug":"lovely-tumbling-taco","message":{"model":"claude-opus-4-6","id":"msg_01DEitu5SPWm6RBgrAdP44ur","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_012iMWvxe7LUo7n7S8peLnWb","name":"TodoWrite","input":{"todos":[{"content":"Read and audit all route files in /home/ccuser/rateright-growth/src/routes/","status":"in_progress","activeForm":"Reading and auditing all route files"},{"content":"Compile detailed findings for each file","status":"pending","activeForm":"Compiling detailed findings"},{"content":"Produce final audit report","status":"pending","activeForm":"Producing final audit report"}]},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":3157,"cache_read_input_tokens":10406,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":3157},"output_tokens":2,"service_tier":"standard","inference_geo":"not_available"}},"requestId":"req_011CXtBmHAHkjRuUDAqGzShc","type":"assistant","uuid":"0de3883f-d448-4a33-97ae-70a7b7acb39d","timestamp":"2026-02-07T05:51:15.157Z"}
{"parentUuid":"0de3883f-d448-4a33-97ae-70a7b7acb39d","isSidechain":true,"userType":"external","cwd":"/home/ccuser/rateright-growth","sessionId":"6138a2b4-4fed-4a8e-841b-ea0e29be8b8c","version":"2.1.34","gitBranch":"main","agentId":"a0359b8","slug":"lovely-tumbling-taco","type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_012iMWvxe7LUo7n7S8peLnWb","type":"tool_result","content":"Todos have been modified successfully. Ensure that you continue to use the todo list to track your progress. Please proceed with the current tasks if applicable"}]},"uuid":"e2fe3b9c-8653-4cc6-879d-638834cbafe4","timestamp":"2026-02-07T05:51:15.160Z","sourceToolAssistantUUID":"0de3883f-d448-4a33-97ae-70a7b7acb39d"}
{"parentUuid":"e2fe3b9c-8653-4cc6-879d-638834cbafe4","isSidechain":true,"userType":"external","cwd":"/home/ccuser/rateright-growth","sessionId":"6138a2b4-4fed-4a8e-841b-ea0e29be8b8c","version":"2.1.34","gitBranch":"main","agentId":"a0359b8","slug":"lovely-tumbling-taco","message":{"model":"claude-opus-4-6","id":"msg_01TFk3xXqdDA6aw1W5TF8My6","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01VZZS7ia89UfpbTznvNoCTR","name":"Glob","input":{"pattern":"src/routes/*.js","path":"/home/ccuser/rateright-growth"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":233,"cache_read_input_tokens":13563,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":233},"output_tokens":26,"service_tier":"standard","inference_geo":"not_available"}},"requestId":"req_011CXtBmaWpZnzafRf5sjLDR","type":"assistant","uuid":"d34fafb9-8003-4dca-9e3c-dbd130dbb04f","timestamp":"2026-02-07T05:51:17.516Z"}
{"parentUuid":"d34fafb9-8003-4dca-9e3c-dbd130dbb04f","isSidechain":true,"userType":"external","cwd":"/home/ccuser/rateright-growth","sessionId":"6138a2b4-4fed-4a8e-841b-ea0e29be8b8c","version":"2.1.34","gitBranch":"main","agentId":"a0359b8","slug":"lovely-tumbling-taco","type":"progress","data":{"type":"hook_progress","hookEvent":"PostToolUse","hookName":"PostToolUse:Glob","command":"callback"},"parentToolUseID":"toolu_01VZZS7ia89UfpbTznvNoCTR","toolUseID":"toolu_01VZZS7ia89UfpbTznvNoCTR","timestamp":"2026-02-07T05:51:17.806Z","uuid":"22cccd3c-61e0-4974-9660-2f18295c35eb"}
{"parentUuid":"d34fafb9-8003-4dca-9e3c-dbd130dbb04f","isSidechain":true,"userType":"external","cwd":"/home/ccuser/rateright-growth","sessionId":"6138a2b4-4fed-4a8e-841b-ea0e29be8b8c","version":"2.1.34","gitBranch":"main","agentId":"a0359b8","slug":"lovely-tumbling-taco","type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01VZZS7ia89UfpbTznvNoCTR","type":"tool_result","content":"/home/ccuser/rateright-growth/src/routes/calls.js\n/home/ccuser/rateright-growth/src/routes/aiAlerts.js\n/home/ccuser/rateright-growth/src/routes/activation.js\n/home/ccuser/rateright-growth/src/routes/dossier.js\n/home/ccuser/rateright-growth/src/routes/dealIntelligence.js\n/home/ccuser/rateright-growth/src/routes/battlegroundV2.js\n/home/ccuser/rateright-growth/src/routes/frontendTracking.js\n/home/ccuser/rateright-growth/src/routes/achievements.js\n/home/ccuser/rateright-growth/src/routes/battleground.js\n/home/ccuser/rateright-growth/src/routes/bugReport.js\n/home/ccuser/rateright-growth/src/routes/dev.js\n/home/ccuser/rateright-growth/src/routes/coaching.js\n/home/ccuser/rateright-growth/src/routes/callScoring.js\n/home/ccuser/rateright-growth/src/routes/analytics.js\n/home/ccuser/rateright-growth/src/routes/ai.js\n/home/ccuser/rateright-growth/src/routes/callAnalytics.js\n/home/ccuser/rateright-growth/src/routes/prompts.js\n/home/ccuser/rateright-growth/src/routes/sms.js\n/home/ccuser/rateright-growth/src/routes/objections.js\n/home/ccuser/rateright-growth/src/routes/notion.js\n/home/ccuser/rateright-growth/src/routes/voicemail.js\n/home/ccuser/rateright-growth/src/routes/health.js\n/home/ccuser/rateright-growth/src/routes/users.js\n/home/ccuser/rateright-growth/src/routes/notifications.js\n/home/ccuser/rateright-growth/src/routes/scripts.js\n/home/ccuser/rateright-growth/src/routes/intelligence.js\n/home/ccuser/rateright-growth/src/routes/xp.js\n/home/ccuser/rateright-growth/src/routes/manager.js\n/home/ccuser/rateright-growth/src/routes/sync.js\n/home/ccuser/rateright-growth/src/routes/jobs.js\n/home/ccuser/rateright-growth/src/routes/callList.js\n/home/ccuser/rateright-growth/src/routes/voice.js\n/home/ccuser/rateright-growth/src/routes/sequences.js\n/home/ccuser/rateright-growth/src/routes/vapi.js\n/home/ccuser/rateright-growth/src/routes/tags.js\n/home/ccuser/rateright-growth/src/routes/playbook.js\n/home/ccuser/rateright-growth/src/routes/team.js\n/home/ccuser/rateright-growth/src/routes/competitors.js\n/home/ccuser/rateright-growth/src/routes/export.js\n/home/ccuser/rateright-growth/src/routes/import.js\n/home/ccuser/rateright-growth/src/routes/outboundWebhooks.js\n/home/ccuser/rateright-growth/src/routes/enrichment.js\n/home/ccuser/rateright-growth/src/routes/leads.js\n/home/ccuser/rateright-growth/src/routes/dashboard.js\n/home/ccuser/rateright-growth/src/routes/webhooks.js"}]},"uuid":"13503b78-d718-4a46-82fd-a065ef5a281c","timestamp":"2026-02-07T05:51:17.806Z","sourceToolAssistantUUID":"d34fafb9-8003-4dca-9e3c-dbd130dbb04f"}
{"parentUuid":"13503b78-d718-4a46-82fd-a065ef5a281c","isSidechain":true,"userType":"external","cwd":"/home/ccuser/rateright-growth","sessionId":"6138a2b4-4fed-4a8e-841b-ea0e29be8b8c","version":"2.1.34","gitBranch":"main","agentId":"a0359b8","slug":"lovely-tumbling-taco","message":{"model":"claude-opus-4-6","id":"msg_01TFk3xXqdDA6aw1W5TF8My6","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_018KWNARM4Z4DVaeegJqZvUg","name":"Glob","input":{"pattern":"src/routes/*.patch","path":"/home/ccuser/rateright-growth"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":233,"cache_read_input_tokens":13563,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":233},"output_tokens":26,"service_tier":"standard","inference_geo":"not_available"}},"requestId":"req_011CXtBmaWpZnzafRf5sjLDR","type":"assistant","uuid":"5e55d326-6d5e-4961-81a1-618f6abd3c9a","timestamp":"2026-02-07T05:51:18.013Z"}
{"parentUuid":"5e55d326-6d5e-4961-81a1-618f6abd3c9a","isSidechain":true,"userType":"external","cwd":"/home/ccuser/rateright-growth","sessionId":"6138a2b4-4fed-4a8e-841b-ea0e29be8b8c","version":"2.1.34","gitBranch":"main","agentId":"a0359b8","slug":"lovely-tumbling-taco","type":"progress","data":{"type":"hook_progress","hookEvent":"PostToolUse","hookName":"PostToolUse:Glob","command":"callback"},"parentToolUseID":"toolu_018KWNARM4Z4DVaeegJqZvUg","toolUseID":"toolu_018KWNARM4Z4DVaeegJqZvUg","timestamp":"2026-02-07T05:51:18.315Z","uuid":"02b99357-2787-4a2c-ba13-13ec9801093b"}
{"parentUuid":"5e55d326-6d5e-4961-81a1-618f6abd3c9a","isSidechain":true,"userType":"external","cwd":"/home/ccuser/rateright-growth","sessionId":"6138a2b4-4fed-4a8e-841b-ea0e29be8b8c","version":"2.1.34","gitBranch":"main","agentId":"a0359b8","slug":"lovely-tumbling-taco","type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_018KWNARM4Z4DVaeegJqZvUg","type":"tool_result","content":"/home/ccuser/rateright-growth/src/routes/voice.js.patch"}]},"uuid":"238dfabe-d21b-4dbd-8063-4bb393fff3b5","timestamp":"2026-02-07T05:51:18.315Z","sourceToolAssistantUUID":"5e55d326-6d5e-4961-81a1-618f6abd3c9a"}
{"parentUuid":"238dfabe-d21b-4dbd-8063-4bb393fff3b5","isSidechain":true,"userType":"external","cwd":"/home/ccuser/rateright-growth","sessionId":"6138a2b4-4fed-4a8e-841b-ea0e29be8b8c","version":"2.1.34","gitBranch":"main","agentId":"a0359b8","slug":"lovely-tumbling-taco","message":{"model":"claude-opus-4-6","id":"msg_012zFiqGqKWV45PQptdXdHd9","type":"message","role":"assistant","content":[{"type":"text","text":"Let me read all the files in parallel batches. Starting with the first batch."}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":1165,"cache_read_input_tokens":13796,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":1165},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"}},"requestId":"req_011CXtBmoyCUMzm27r2AGAEX","type":"assistant","uuid":"670b2a53-10d0-41df-8003-0a04db363479","timestamp":"2026-02-07T05:51:20.840Z"}
{"parentUuid":"670b2a53-10d0-41df-8003-0a04db363479","isSidechain":true,"userType":"external","cwd":"/home/ccuser/rateright-growth","sessionId":"6138a2b4-4fed-4a8e-841b-ea0e29be8b8c","version":"2.1.34","gitBranch":"main","agentId":"a0359b8","slug":"lovely-tumbling-taco","message":{"model":"claude-opus-4-6","id":"msg_012zFiqGqKWV45PQptdXdHd9","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01DY3owJxe2ZMPeakUsAwGv8","name":"Read","input":{"file_path":"/home/ccuser/rateright-growth/src/routes/calls.js"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":1,"cache_creation_input_tokens":1165,"cache_read_input_tokens":13796,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":1165},"output_tokens":1,"service_tier":"standard","inference_geo":"not_available"}},"requestId":"req_011CXtBmoyCUMzm27r2AGAEX","type":"assistant","uuid":"b705690e-6176-4027-b114-c5760c6b18b2","timestamp":"2026-02-07T05:51:21.183Z"}
{"parentUuid":"b705690e-6176-4027-b114-c5760c6b18b2","isSidechain":true,"userType":"external","cwd":"/home/ccuser/rateright-growth","sessionId":"6138a2b4-4fed-4a8e-841b-ea0e29be8b8c","version":"2.1.34","gitBranch":"main","agentId":"a0359b8","slug":"lovely-tumbling-taco","type":"progress","data":{"type":"hook_progress","hookEvent":"PostToolUse","hookName":"PostToolUse:Read","command":"callback"},"parentToolUseID":"toolu_01DY3owJxe2ZMPeakUsAwGv8","toolUseID":"toolu_01DY3owJxe2ZMPeakUsAwGv8","timestamp":"2026-02-07T05:51:21.189Z","uuid":"1a4c6522-464d-4f39-961a-afdfe26f8e52"}
{"parentUuid":"b705690e-6176-4027-b114-c5760c6b18b2","isSidechain":true,"userType":"external","cwd":"/home/ccuser/rateright-growth","sessionId":"6138a2b4-4fed-4a8e-841b-ea0e29be8b8c","version":"2.1.34","gitBranch":"main","agentId":"a0359b8","slug":"lovely-tumbling-taco","type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01DY3owJxe2ZMPeakUsAwGv8","type":"tool_result","content":"     1→/**\n     2→ * Call Logging API routes\n     3→ */\n     4→\n     5→const express = require('express');\n     6→const router = express.Router();\n     7→const { supabase, supabaseAdmin } = require('../config/database');\n     8→const perplexityService = require('../services/perplexity');\n     9→const { awardXPForCall } = require('../services/xpService');\n    10→const { checkRecord, RECORD_TYPES, createPulseEvent, getTodaysCallCount } = require('../services/leaderboardService');\n    11→const { updateChallengeProgress, updateTeamChallengeProgress } = require('../services/challengesService');\n    12→const { scoreCall, saveCallScore } = require('../services/repPerformance');\n    13→\n    14→/**\n    15→ * POST /api/calls/log\n    16→ * Log a call outcome\n    17→ */\n    18→router.post('/log', async (req, res) => {\n    19→  try {\n    20→    if (!supabase) {\n    21→      return res.status(503).json({ error: 'Database not configured' });\n    22→    }\n    23→\n    24→    const {\n    25→      leadId,\n    26→      outcome,\n    27→      durationSeconds,\n    28→      notes,\n    29→      objections = [],\n    30→      followUpAt,\n    31→      handledBy,\n    32→      // Auto-transcription fields\n    33→      transcript,\n    34→      aiSummary,\n    35→      // Twilio CallSid for linking recording transcript\n    36→      callSid,\n    37→    } = req.body;\n    38→\n    39→    if (!leadId) {\n    40→      return res.status(400).json({ error: 'leadId is required' });\n    41→    }\n    42→\n    43→    if (!outcome) {\n    44→      return res.status(400).json({ error: 'outcome is required' });\n    45→    }\n    46→\n    47→    // Valid outcomes\n    48→    const validOutcomes = [\n    49→      'connected', 'voicemail', 'no_answer', 'busy', 'wrong_number',\n    50→      'callback_scheduled', 'not_interested', 'interested', 'converted'\n    51→    ];\n    52→\n    53→    if (!validOutcomes.includes(outcome)) {\n    54→      return res.status(400).json({ error: `Invalid outcome. Must be one of: ${validOutcomes.join(', ')}` });\n    55→    }\n    56→\n    57→    // Get lead (specific columns only for performance)\n    58→    const { data: lead, error: leadError } = await supabase\n    59→      .from('leads')\n    60→      .select('id, assigned_to, phone, score, status, first_name, last_name, company')\n    61→      .eq('id', leadId)\n    62→      .single();\n    63→\n    64→    if (leadError || !lead) {\n    65→      return res.status(404).json({ error: 'Lead not found' });\n    66→    }\n    67→\n    68→    // Get the authenticated user ID for handled_by (prefer auth, fallback to passed value)\n    69→    const callHandledBy = req.user?.id || handledBy || null;\n    70→\n    71→    // Auto-assign lead if unassigned\n    72→    if (!lead.assigned_to && callHandledBy) {\n    73→      await supabase\n    74→        .from('leads')\n    75→        .update({\n    76→          assigned_to: callHandledBy,\n    77→          assigned_at: new Date().toISOString()\n    78→        })\n    79→        .eq('id', leadId);\n    80→      console.log(`Lead auto-assigned: ${leadId} to ${callHandledBy}`);\n    81→    }\n    82→\n    83→    // Log communication with transcript and AI summary\n    84→    const { data: comm, error: commError } = await supabase\n    85→      .from('communications')\n    86→      .insert({\n    87→        lead_id: leadId,\n    88→        type: 'call_outbound',\n    89→        direction: 'outbound',\n    90→        phone: lead.phone,\n    91→        content: notes || null,\n    92→        handled_by: callHandledBy, // Top-level for easy querying by rep performance\n    93→        user_id: callHandledBy, // User who made the call (for assignment tracking)\n    94→        // Denormalized columns for fast filtering (also kept in metadata for backwards compat)\n    95→        outcome,\n    96→        call_duration_seconds: durationSeconds || 0,\n    97→        metadata: {\n    98→          outcome,\n    99→          duration_seconds: durationSeconds || 0,\n   100→          objections,\n   101→          handled_by: callHandledBy,\n   102→          // Auto-transcription data\n   103→          transcript: transcript || null,\n   104→          ai_summary: aiSummary || null,\n   105→          auto_transcribed: !!transcript,\n   106→          // CallSid for linking recording transcript later\n   107→          call_sid: callSid || null,\n   108→        }\n   109→      })\n   110→      .select()\n   111→      .single();\n   112→\n   113→    if (commError) {\n   114→      console.error('Call log error:', commError.message);\n   115→      return res.status(500).json({ error: 'Failed to log call' });\n   116→    }\n   117→\n   118→    // Check for orphaned transcript from recording webhook (transcription runs before call is logged)\n   119→    if (callSid && !transcript) {\n   120→      try {\n   121→        const { data: orphan } = await supabase\n   122→          .from('copilot_sessions')\n   123→          .select('id, transcript, recording_url, duration_seconds')\n   124→          .eq('metadata->>call_sid', callSid)\n   125→          .eq('metadata->>orphaned', 'true')\n   126→          .single();\n   127→\n   128→        if (orphan && orphan.transcript) {\n   129→          console.log(`[Calls] Found orphaned transcript for CallSid ${callSid}, attaching...`);\n   130→          \n   131→          // Update the communication we just created\n   132→          const { error: attachError } = await supabase\n   133→            .from('communications')\n   134→            .update({\n   135→              metadata: {\n   136→                ...comm.metadata,\n   137→                transcript: orphan.transcript,\n   138→                recording_url: orphan.recording_url,\n   139→                recording_duration: orphan.duration_seconds,\n   140→                auto_transcribed: true,\n   141→                attached_from_orphan: true\n   142→              }\n   143→            })\n   144→            .eq('id', comm.id);\n   145→\n   146→          if (!attachError) {\n   147→            // Delete the orphan record\n   148→            await supabase.from('copilot_sessions').delete().eq('id', orphan.id);\n   149→            console.log(`[Calls] Transcript attached and orphan cleaned up`);\n   150→            \n   151→            // Update the comm object so XP/scoring can use the transcript\n   152→            comm.metadata = {\n   153→              ...comm.metadata,\n   154→              transcript: orphan.transcript,\n   155→              recording_url: orphan.recording_url,\n   156→              auto_transcribed: true\n   157→            };\n   158→          } else {\n   159→            console.error('[Calls] Failed to attach orphaned transcript:', attachError.message);\n   160→          }\n   161→        }\n   162→      } catch (orphanErr) {\n   163→        console.warn('[Calls] Orphan transcript check failed:', orphanErr.message);\n   164→      }\n   165→    }\n   166→\n   167→    // Update lead status based on outcome\n   168→    const leadUpdates = {\n   169→      last_contact_at: new Date().toISOString(),\n   170→      last_contact_type: 'call_outbound'\n   171→    };\n   172→\n   173→    if (outcome === 'converted') {\n   174→      leadUpdates.status = 'converted';\n   175→    } else if (outcome === 'not_interested') {\n   176→      leadUpdates.status = 'closed_lost';\n   177→    } else if (outcome === 'interested') {\n   178→      leadUpdates.status = 'engaged';\n   179→    }\n   180→\n   181→    // Apply AI-recommended score adjustment\n   182→    if (aiSummary?.score_adjustment) {\n   183→      const newScore = Math.max(0, Math.min(100, (lead.score || 50) + aiSummary.score_adjustment));\n   184→      leadUpdates.score = newScore;\n   185→    }\n   186→\n   187→    // Apply AI-recommended status if not already set\n   188→    if (!leadUpdates.status && aiSummary?.status_recommendation) {\n   189→      leadUpdates.status = aiSummary.status_recommendation;\n   190→    }\n   191→\n   192→    await supabase\n   193→      .from('leads')\n   194→      .update(leadUpdates)\n   195→      .eq('id', leadId);\n   196→\n   197→    // Create follow-up callback if scheduled\n   198→    let callbackId = null;\n   199→    if (followUpAt) {\n   200→      const { data: callback, error: cbError } = await supabase\n   201→        .from('callbacks')\n   202→        .insert({\n   203→          lead_id: leadId,\n   204→          phone: lead.phone,\n   205→          reason: `Follow-up from ${outcome} call`,\n   206→          priority: outcome === 'interested' ? 'high' : 'medium',\n   207→          status: 'pending',\n   208→          source_type: 'call_outbound',\n   209→          source_id: comm.id,\n   210→          scheduled_at: followUpAt,\n   211→          handled_by: handledBy\n   212→        })\n   213→        .select('id')\n   214→        .single();\n   215→\n   216→      if (!cbError && callback) {\n   217→        callbackId = callback.id;\n   218→      }\n   219→    }\n   220→\n   221→    // Mark any existing pending callbacks as completed\n   222→    let completeQuery = supabase\n   223→      .from('callbacks')\n   224→      .update({\n   225→        status: 'completed',\n   226→        completed_at: new Date().toISOString(),\n   227→        handled_by: handledBy\n   228→      })\n   229→      .eq('lead_id', leadId)\n   230→      .eq('status', 'pending');\n   231→\n   232→    // Only exclude new callback if one was created (fixes race condition)\n   233→    if (callbackId) {\n   234→      completeQuery = completeQuery.neq('id', callbackId);\n   235→    }\n   236→\n   237→    const { error: completeError } = await completeQuery;\n   238→    if (completeError) {\n   239→      console.warn('Failed to complete pending callbacks:', completeError.message);\n   240→    }\n   241→\n   242→    // Award XP for the call (fire and forget)\n   243→    // Use authenticated user ID from auth middleware\n   244→    const userId = req.user?.id || handledBy || 'default-user';\n   245→    let xpResult = null;\n   246→    try {\n   247→      xpResult = await awardXPForCall(userId, outcome, leadId);\n   248→      if (xpResult.success) {\n   249→        console.log(`XP awarded for call: +${xpResult.totalAwarded} XP (${outcome})`);\n   250→      }\n   251→    } catch (xpError) {\n   252→      console.warn('Failed to award XP:', xpError.message);\n   253→    }\n   254→\n   255→    // Add note if provided (or if auto-transcribed)\n   256→    if (notes || transcript) {\n   257→      const noteContent = transcript\n   258→        ? `[Auto-Transcribed Call - ${outcome}]\\n\\n${notes || aiSummary?.summary || transcript.substring(0, 500)}`\n   259→        : `Call (${outcome}): ${notes}`;\n   260→\n   261→      await supabase\n   262→        .from('lead_notes')\n   263→        .insert({\n   264→          lead_id: leadId,\n   265→          content: noteContent,\n   266→          created_by: handledBy || (transcript ? 'auto-transcribe' : 'system')\n   267→        });\n   268→    }\n   269→\n   270→    console.log(`Call logged: ${leadId} - ${outcome}${transcript ? ' (auto-transcribed)' : ''}`);\n   271→\n   272→    // Trigger background auto-research if we have a transcript\n   273→    // Fire and forget - don't block the response\n   274→    if (transcript && transcript.length >= 50) {\n   275→      setImmediate(() => {\n   276→        perplexityService.autoResearchFromTranscript(leadId, transcript)\n   277→          .then(result => {\n   278→            if (result.success) {\n   279→              console.log(`[AutoResearch] Background research completed for lead ${leadId}`);\n   280→            }\n   281→          })\n   282→          .catch(err => {\n   283→            console.error(`[AutoResearch] Background research failed for lead ${leadId}:`, err.message);\n   284→          });\n   285→      });\n   286→\n   287→      // AI call scoring (fire and forget)\n   288→      setImmediate(async () => {\n   289→        try {\n   290→          const callScore = await scoreCall(comm, transcript);\n   291→          if (callScore) {\n   292→            await saveCallScore(\n   293→              comm.id,\n   294→              leadId,\n   295→              userId,\n   296→              callScore,\n   297→              outcome,\n   298→              durationSeconds || 0\n   299→            );\n   300→            console.log(`[CallScore] Scored call ${comm.id}: ${callScore.overall_score}/10`);\n   301→          }\n   302→        } catch (err) {\n   303→          console.error(`[CallScore] Failed to score call:`, err.message);\n   304→        }\n   305→      });\n   306→    }\n   307→\n   308→    // Update lead dossier with call summary (fire and forget)\n   309→    setImmediate(async () => {\n   310→      try {\n   311→        // Get current dossier or create new one\n   312→        let { data: dossier } = await supabase\n   313→          .from('lead_dossier')\n   314→          .select('call_summaries, current_status')\n   315→          .eq('lead_id', leadId)\n   316→          .single();\n   317→\n   318→        const currentSummaries = dossier?.call_summaries || [];\n   319→\n   320→        // Extract key points from AI summary if available\n   321→        const keyPoints = [];\n   322→        if (aiSummary?.summary) keyPoints.push(aiSummary.summary);\n   323→        if (aiSummary?.next_step) keyPoints.push(`Next: ${aiSummary.next_step}`);\n   324→        if (aiSummary?.coaching_note) keyPoints.push(`Coaching: ${aiSummary.coaching_note}`);\n   325→\n   326→        const newSummary = {\n   327→          date: new Date().toISOString(),\n   328→          duration: durationSeconds || 0,\n   329→          outcome,\n   330→          key_points: keyPoints,\n   331→          next_steps: aiSummary?.next_step || null,\n   332→          mood: aiSummary?.sentiment || null,\n   333→          notes: notes?.substring(0, 500) || null,\n   334→        };\n   335→\n   336→        // Update current status\n   337→        const newStatus = {\n   338→          stage: leadUpdates.status || lead.status,\n   339→          temperature: outcome === 'interested' ? 'hot' : outcome === 'converted' ? 'closed' : 'warm',\n   340→          last_contact: new Date().toISOString(),\n   341→          next_action: aiSummary?.next_step || (followUpAt ? 'Follow up scheduled' : null),\n   342→          follow_up_date: followUpAt || null,\n   343→        };\n   344→\n   345→        await (supabaseAdmin || supabase)\n   346→          .from('lead_dossier')\n   347→          .upsert({\n   348→            lead_id: leadId,\n   349→            call_summaries: [...currentSummaries, newSummary],\n   350→            current_status: newStatus,\n   351→          }, {\n   352→            onConflict: 'lead_id'\n   353→


This is a conversation log in JSON format, not a direct audit report. Each line is a JSON message from the agent session. Let me extract just the final audit report from the end of the file.


tail -c 100000 /tmp/claude-1000/-home-ccuser-rateright-growth/tasks/a0359b8.output

Read the last 100KB of the file which likely contains the final report


<persisted-output>
Output too large (93.4KB). Full output saved to: /home/ccuser/.claude/projects/-home-ccuser-rateright-growth/6138a2b4-4fed-4a8e-841b-ea0e29be8b8c/tool-results/toolu_01Tz9jZRW4vtNkshMPGDwe2A.txt

Preview (first 2KB):
 (events.length > MAX_BATCH_SIZE) {\n   103→      return res.status(400).json({\n   104→        success: false,\n   105→        error: `Maximum ${MAX_BATCH_SIZE} events per batch`,\n   106→        received: events.length\n   107→      });\n   108→    }\n   109→\n   110→    // Get user_id from auth header if available\n   111→    const authHeader = req.headers.authorization;\n   112→    let user_id = null;\n   113→    if (authHeader) {\n   114→      const token = authHeader.replace('Bearer ', '');\n   115→      const { data: { user } } = await supabase.auth.getUser(token);\n   116→      user_id = user?.id;\n   117→    }\n   118→\n   119→    // Prepare events with user_id\n   120→    const eventsWithUser = events.map(event => ({\n   121→      ...event,\n   122→      user_id: event.user_id || user_id\n   123→    }));\n   124→\n   125→    // Insert all events\n   126→    const { data, error } = await db\n   127→      .from('usage_events')\n   128→      .insert(eventsWithUser);\n   129→\n   130→    if (error) {\n   131→      console.error('Failed to track batch events:', error.message);\n   132→      return res.json({ success: true, tracked: 0 });\n   133→    }\n   134→\n   135→    res.json({ success: true, tracked: events.length });\n   136→  } catch (error) {\n   137→    console.error('Track batch error:', error);\n   138→    res.json({ success: true, tracked: 0 });\n   139→  }\n   140→});\n   141→\n   142→/**\n   143→ * GET /api/intelligence/suggestions\n   144→ * Get improvement suggestions\n   145→ */\n   146→router.get('/suggestions', async (req, res) => {\n   147→  try {\n   148→    const { status, type, limit = 20 } = req.query;\n   149→\n   150→    let query = db\n   151→      .from('intelligence_suggestions')\n   152→      .select('*')\n   153→      .order('priority_score', { ascending: false })\n   154→      .limit(parseInt(limit));\n   155→\n   156→    if (status) {\n   157→      query = query.eq('status', status);\n   158→    }\n   159→\n   160→    if (type)
...
</persisted-output>


Let me find the final report text by searching for the assistant's final summary message.


python3 -c "
import json, sys

# Read the entire file
with open('/tmp/claude-1000/-home-ccuser-rateright-growth/tasks/a0359b8.output', 'r') as f:
    lines = f.readlines()

# Find the last assistant message with significant text content
for line in reversed(lines):
    try:
        msg = json.loads(line.strip())
        if msg.get('type') == 'assistant' and msg.get('message', {}).get('role') == 'assistant':
            content = msg['message'].get('content', [])
            for block in content:
                if block.get('type') == 'text' and len(block.get('text', '')) > 1000:
                    print(block['text'][:200])
                    print('...')
                    print(f'TOTAL LENGTH: {len(block[\"text\"])}')
                    sys.exit(0)
    except:
        continue
print('No large text block found')
"

Find the final audit report text in the JSON conversation log


No large text block found


python3 -c "
import json, sys

with open('/tmp/claude-1000/-home-ccuser-rateright-growth/tasks/a0359b8.output', 'r') as f:
    lines = f.readlines()

# Check message types and find text blocks
for i, line in enumerate(lines):
    try:
        msg = json.loads(line.strip())
        mtype = msg.get('type')
        role = msg.get('message', {}).get('role', '')
        content = msg.get('message', {}).get('content', [])
        if isinstance(content, list):
            for block in content:
                if block.get('type') == 'text' and len(block.get('text', '')) > 100:
                    print(f'Line {i}: type={mtype} role={role} text_len={len(block[\"text\"])} preview={block[\"text\"][:100]}')
    except:
        continue
" 2>&1 | tail -30

Find all text blocks in the conversation log


Line 1: type=assistant role=assistant text_len=124 preview=

I'll conduct a thorough audit of every file in the routes directory. Let me start by reading all t


The audit didn't produce a final report -- it seems the agent was still reading files. Let me look at the tool results to extract the actual file contents and audit findings.


python3 -c "
import json, sys

with open('/tmp/claude-1000/-home-ccuser-rateright-growth/tasks/a0359b8.output', 'r') as f:
    lines = f.readlines()

print(f'Total lines: {len(lines)}')
for i, line in enumerate(lines):
    try:
        msg = json.loads(line.strip())
        mtype = msg.get('type')
        role = msg.get('message', {}).get('role', '')
        content = msg.get('message', {}).get('content', [])

        # Check tool_use calls
        if isinstance(content, list):
            for block in content:
                if block.get('type') == 'tool_use':
                    tool = block.get('name', '')
                    inp = block.get('input', {})
                    if tool == 'Read':
                        print(f'Line {i}: Read file={inp.get(\"file_path\",\"?\")}')
                    elif tool == 'TodoWrite':
                        for t in inp.get('todos', []):
                            print(f'  TODO: [{t[\"status\"]}] {t[\"content\"]}')
                    elif tool in ('Glob', 'Grep'):
                        print(f'Line {i}: {tool} pattern={inp.get(\"pattern\",\"\")}')
                    else:
                        print(f'Line {i}: {tool}')
    except:
        continue
" 2>&1

Map out all tool calls in the conversation to understand progress


Total lines: 104
  TODO: [in_progress] Read and audit all route files in /home/ccuser/rateright-growth/src/routes/
  TODO: [pending] Compile detailed findings for each file
  TODO: [pending] Produce final audit report
Line 4: Glob pattern=src/routes/*.js
Line 7: Glob pattern=src/routes/*.patch
Line 11: Read file=/home/ccuser/rateright-growth/src/routes/calls.js
Line 14: Read file=/home/ccuser/rateright-growth/src/routes/aiAlerts.js
Line 17: Read file=/home/ccuser/rateright-growth/src/routes/activation.js
Line 20: Read file=/home/ccuser/rateright-growth/src/routes/dossier.js
Line 23: Read file=/home/ccuser/rateright-growth/src/routes/dealIntelligence.js
Line 26: Read file=/home/ccuser/rateright-growth/src/routes/battlegroundV2.js
Line 29: Read file=/home/ccuser/rateright-growth/src/routes/frontendTracking.js
Line 32: Read file=/home/ccuser/rateright-growth/src/routes/achievements.js
Line 35: Read file=/home/ccuser/rateright-growth/src/routes/battleground.js
Line 38: Read file=/home/ccuser/rateright-growth/src/routes/bugReport.js
Line 42: Read file=/home/ccuser/rateright-growth/src/routes/dev.js
Line 45: Read file=/home/ccuser/rateright-growth/src/routes/coaching.js
Line 48: Read file=/home/ccuser/rateright-growth/src/routes/callScoring.js
Line 51: Read file=/home/ccuser/rateright-growth/src/routes/analytics.js
Line 54: Read file=/home/ccuser/rateright-growth/src/routes/ai.js
Line 55: Read file=/home/ccuser/rateright-growth/src/routes/callAnalytics.js
Line 60: Read file=/home/ccuser/rateright-growth/src/routes/prompts.js
Line 63: Read file=/home/ccuser/rateright-growth/src/routes/sms.js
Line 66: Read file=/home/ccuser/rateright-growth/src/routes/objections.js
Line 69: Read file=/home/ccuser/rateright-growth/src/routes/notion.js
Line 73: Read file=/home/ccuser/rateright-growth/src/routes/voicemail.js
Line 76: Read file=/home/ccuser/rateright-growth/src/routes/health.js
Line 79: Read file=/home/ccuser/rateright-growth/src/routes/users.js
Line 82: Read file=/home/ccuser/rateright-growth/src/routes/notifications.js
Line 85: Read file=/home/ccuser/rateright-growth/src/routes/scripts.js
Line 88: Read file=/home/ccuser/rateright-growth/src/routes/intelligence.js
Line 91: Read file=/home/ccuser/rateright-growth/src/routes/xp.js
Line 94: Read file=/home/ccuser/rateright-growth/src/routes/manager.js
Line 97: Read file=/home/ccuser/rateright-growth/src/routes/sync.js
Line 100: Read file=/home/ccuser/rateright-growth/src/routes/jobs.js


The audit agent only read 33 of the 46 files before it stopped (no final report produced). The conversation data contains the raw file contents returned from each Read. I need to do the audit myself by reading the actual route files directly. Let me be thorough.


TodoWrite

Read all 46 route files from src/routes/

Extract all endpoints (method, path, purpose)

Identify security issues, auth gaps, dead code, error handling issues

Identifying security issues and code quality problems

Compile structured markdown report


Todos have been modified successfully. Ensure that you continue to use the todo list to track your progress. Please proceed with the current tasks if applicable


Let me read all the route files. I'll start by getting a quick view of each file to understand its structure.


Bash

List all route files


total 896
drwxr-xr-x 2 ccuser ccuser  4096 Feb  2 16:30 .
drwxr-xr-x 8 ccuser ccuser  4096 Feb  2 16:30 ..
-rw-r--r-- 1 ccuser ccuser 13192 Jan 30 19:24 achievements.js
-rw-r--r-- 1 ccuser ccuser 48269 Jan 30 19:24 activation.js
-rw-r--r-- 1 ccuser ccuser 62480 Jan 30 19:24 ai.js
-rw-r--r-- 1 ccuser ccuser 11044 Jan 30 19:24 aiAlerts.js
-rw-r--r-- 1 ccuser ccuser 19147 Jan 30 19:24 analytics.js
-rw-r--r-- 1 ccuser ccuser  8731 Jan 30 19:24 battleground.js
-rw-r--r-- 1 ccuser ccuser  9165 Jan 30 19:24 battlegroundV2.js
-rw-r--r-- 1 ccuser ccuser  2614 Jan 30 19:24 bugReport.js
-rw-r--r-- 1 ccuser ccuser  4236 Jan 30 19:24 callAnalytics.js
-rw-r--r-- 1 ccuser ccuser 11286 Jan 30 23:31 callList.js
-rw-r--r-- 1 ccuser ccuser  4421 Jan 30 19:24 callScoring.js
-rw-r--r-- 1 ccuser ccuser 22004 Jan 30 19:24 calls.js
-rw-r--r-- 1 ccuser ccuser 13395 Jan 30 19:24 coaching.js
-rw-r--r-- 1 ccuser ccuser 11690 Feb  2 16:24 competitors.js
-rw-r--r-- 1 ccuser ccuser 71390 Feb  7 05:45 dashboard.js
-rw-r--r-- 1 ccuser ccuser  6875 Jan 30 19:24 dealIntelligence.js
-rw-r--r-- 1 ccuser ccuser  7186 Jan 30 19:24 dev.js
-rw-r--r-- 1 ccuser ccuser  7651 Jan 30 19:24 dossier.js
-rw-r--r-- 1 ccuser ccuser  7420 Feb  2 16:30 enrichment.js
-rw-r--r-- 1 ccuser ccuser  7612 Feb  2 16:25 export.js
-rw-r--r-- 1 ccuser ccuser  4097 Jan 30 19:24 frontendTracking.js
-rw-r--r-- 1 ccuser ccuser  1053 Jan 30 19:24 health.js
-rw-r--r-- 1 ccuser ccuser  9834 Feb  2 16:26 import.js
-rw-r--r-- 1 ccuser ccuser 17395 Jan 30 19:24 intelligence.js
-rw-r--r-- 1 ccuser ccuser 10448 Jan 30 19:24 jobs.js
-rw-r--r-- 1 ccuser ccuser 37891 Feb  5 22:11 leads.js
-rw-r--r-- 1 ccuser ccuser 27289 Jan 30 19:24 manager.js
-rw-r--r-- 1 ccuser ccuser  6266 Jan 30 19:24 notifications.js
-rw-r--r-- 1 ccuser ccuser 20894 Jan 30 19:24 notion.js
-rw-r--r-- 1 ccuser ccuser  5318 Jan 30 19:24 objections.js
-rw-r--r-- 1 ccuser ccuser 10537 Feb  2 16:27 outboundWebhooks.js
-rw-r--r-- 1 ccuser ccuser 32757 Feb  2 16:21 playbook.js
-rw-r--r-- 1 ccuser ccuser 27520 Jan 30 19:24 prompts.js
-rw-r--r-- 1 ccuser ccuser 31802 Jan 30 19:24 scripts.js
-rw-r--r-- 1 ccuser ccuser 22540 Jan 30 23:41 sequences.js
-rw-r--r-- 1 ccuser ccuser 58100 Jan 30 19:24 sms.js
-rw-r--r-- 1 ccuser ccuser  4672 Jan 30 19:24 sync.js
-rw-r--r-- 1 ccuser ccuser  9873 Feb  2 16:19 tags.js
-rw-r--r-- 1 ccuser ccuser 20041 Feb  2 16:22 team.js
-rw-r--r-- 1 ccuser ccuser  5934 Jan 30 19:24 users.js
-rw-rw-r-- 1 ccuser ccuser  5754 Jan 31 23:46 vapi.js
-rw-r--r-- 1 ccuser ccuser 36096 Jan 30 23:31 voice.js
-rw-r--r-- 1 ccuser ccuser  4334 Jan 30 19:24 voice.js.patch
-rw-r--r-- 1 ccuser ccuser  9628 Jan 30 19:24 voicemail.js
-rw-r--r-- 1 ccuser ccuser 29960 Feb  7 14:56 webhooks.js
-rw-r--r-- 1 ccuser ccuser  9996 Jan 30 19:24 xp.js


Now let me extract the essential audit data from every file. I'll use a comprehensive grep approach first to find all route definitions and auth middleware usage.


grep -n "router\.\(get\|post\|put\|patch\|delete\|use\|all\)" src/routes/*.js | head -300

Find all route definitions across all files


src/routes/achievements.js:207:router.get('/', async (req, res) => {
src/routes/achievements.js:244:router.get('/user', async (req, res) => {
src/routes/achievements.js:299:router.post('/check', async (req, res) => {
src/routes/activation.js:36:router.get('/leads-at-stage', async (req, res) => {
src/routes/activation.js:119:router.get('/funnel', async (req, res) => {
src/routes/activation.js:165:router.get('/stuck', async (req, res) => {
src/routes/activation.js:285:router.get('/revenue-at-risk', async (req, res) => {
src/routes/activation.js:367:router.get('/metrics', async (req, res) => {
src/routes/activation.js:402:router.get('/stage-transitions', async (req, res) => {
src/routes/activation.js:465:router.post('/bulk-nudge', async (req, res) => {
src/routes/activation.js:639:router.post('/add-to-call-list', async (req, res) => {
src/routes/activation.js:716:router.get('/analyze', async (req, res) => {
src/routes/activation.js:761:router.post('/nudge', async (req, res) => {
src/routes/activation.js:820:router.get('/action-script', async (req, res) => {
src/routes/activation.js:847:router.get('/dropoff-analysis', async (req, res) => {
src/routes/activation.js:906:router.get('/journey/:leadId', async (req, res) => {
src/routes/activation.js:1081:router.get('/diagnose/:leadId', async (req, res) => {
src/routes/activation.js:1135:router.get('/similar-wins/:leadId', async (req, res) => {
src/routes/activation.js:1378:router.get('/nudge-templates', async (req, res) => {
src/routes/activation.js:1432:router.post('/nudge-templates', async (req, res) => {
src/routes/activation.js:1472:router.patch('/nudge-templates/:id', async (req, res) => {
src/routes/activation.js:1503:router.delete('/nudge-templates/:id', async (req, res) => {
src/routes/ai.js:28:router.get('/status', (req, res) => {
src/routes/ai.js:42:router.get('/intel-brief/:leadId', async (req, res) => {
src/routes/ai.js:139:router.post('/post-call-summary', async (req, res) => {
src/routes/ai.js:248:router.post('/draft-message', expensiveAiLimiter, async (req, res) => {
src/routes/ai.js:326:router.post('/draft-similar', async (req, res) => {
src/routes/ai.js:384:router.post('/transcribe', expensiveAiLimiter, upload.single('audio'), async (req, res) => {
src/routes/ai.js:415:router.post('/extract-lead-corrections', async (req, res) => {
src/routes/ai.js:452:router.post('/voice-command', async (req, res) => {
src/routes/ai.js:738:router.post('/explain-message', async (req, res) => {
src/routes/ai.js:814:router.post('/objection-response', async (req, res) => {
src/routes/ai.js:894:router.get('/conversion-probability/:leadId', async (req, res) => {
src/routes/ai.js:959:router.post('/weekly-insights', strictLimiter, async (req, res) => {
src/routes/ai.js:1035:router.post('/cleanup-notes', async (req, res) => {
src/routes/ai.js:1073:router.get('/insights', async (req, res) => {
src/routes/ai.js:1099:router.get('/deepgram-credentials', (req, res) => {
src/routes/ai.js:1122:router.post('/copilot-session', async (req, res) => {
src/routes/ai.js:1266:router.post('/suggestion-feedback', async (req, res) => {
src/routes/ai.js:1311:router.get('/effective-responses/:objectionType', async (req, res) => {
src/routes/ai.js:1333:router.get('/similar-wins/:leadId', async (req, res) => {
src/routes/ai.js:1366:router.get('/live-intel/:leadId', async (req, res) => {
src/routes/ai.js:1560:router.get('/company-research/:companyName', expensiveAiLimiter, async (req, res) => {
src/routes/ai.js:1596:router.get('/person-research/:leadId', expensiveAiLimiter, async (req, res) => {
src/routes/ai.js:1631:router.post('/update-intel', async (req, res) => {
src/routes/ai.js:1730:router.post('/extract-contractor', async (req, res) => {
src/routes/ai.js:1857:router.post('/parse-intel-voice', async (req, res) => {
src/routes/aiAlerts.js:25:router.get('/', async (req, res) => {
src/routes/aiAlerts.js:74:router.post('/', async (req, res) => {
src/routes/aiAlerts.js:116:router.patch('/:id/read', async (req, res) => {
src/routes/aiAlerts.js:140:router.patch('/:id/dismiss', async (req, res) => {
src/routes/aiAlerts.js:164:router.post('/read-all', async (req, res) => {
src/routes/aiAlerts.js:187:router.post('/generate', async (req, res) => {
src/routes/analytics.js:13:router.get('/trends', async (req, res) => {
src/routes/analytics.js:118:router.get('/patterns', async (req, res) => {
src/routes/analytics.js:151:router.get('/funnel', async (req, res) => {
src/routes/analytics.js:216:router.get('/best-times', async (req, res) => {
src/routes/analytics.js:316:router.get('/sources', async (req, res) => {
src/routes/analytics.js:380:router.post('/patterns', async (req, res) => {
src/routes/analytics.js:515:router.post('/vitals', async (req, res) => {
src/routes/analytics.js:555:router.post('/error', async (req, res) => {
src/routes/analytics.js:598:router.get('/vitals/summary', async (req, res) => {
src/routes/battleground.js:16:router.get('/leaderboard', async (req, res) => {
src/routes/battleground.js:28:router.get('/leaderboard/:userId', async (req, res) => {
src/routes/battleground.js:67:router.post('/leaderboard/snapshot', async (req, res) => {
src/routes/battleground.js:88:router.get('/hall-of-fame', async (req, res) => {
src/routes/battleground.js:99:router.post('/hall-of-fame/check', async (req, res) => {
src/routes/battleground.js:120:router.get('/challenges', async (req, res) => {
src/routes/battleground.js:132:router.post('/challenges/progress', async (req, res) => {
src/routes/battleground.js:159:router.post('/challenges/generate', async (req, res) => {
src/routes/battleground.js:178:router.get('/pulse', async (req, res) => {
src/routes/battleground.js:190:router.post('/pulse', async (req, res) => {
src/routes/battleground.js:221:router.get('/badges/:userId', async (req, res) => {
src/routes/battleground.js:232:router.get('/badges', async (req, res) => {
src/routes/battleground.js:243:router.post('/badges/award-weekly', async (req, res) => {
src/routes/battleground.js:258:router.post('/streak/update', async (req, res) => {
src/routes/battlegroundV2.js:18:router.get('/duels/types', (req, res) => {
src/routes/battlegroundV2.js:29:router.post('/duels/challenge', async (req, res) => {
src/routes/battlegroundV2.js:63:router.post('/duels/:id/accept', async (req, res) => {
src/routes/battlegroundV2.js:82:router.post('/duels/:id/decline', async (req, res) => {
src/routes/battlegroundV2.js:101:router.get('/duels/active', async (req, res) => {
src/routes/battlegroundV2.js:120:router.get('/duels/history', async (req, res) => {
src/routes/battlegroundV2.js:140:router.get('/duels/:id/scores', async (req, res) => {
src/routes/battlegroundV2.js:157:router.get('/duels/odds', async (req, res) => {
src/routes/battlegroundV2.js:194:router.get('/challenges/config', (req, res) => {
src/routes/battlegroundV2.js:206:router.post('/challenges', async (req, res) => {
src/routes/battlegroundV2.js:229:router.get('/challenges', async (req, res) => {
src/routes/battlegroundV2.js:243:router.get('/challenges/:id', async (req, res) => {
src/routes/battlegroundV2.js:257:router.post('/challenges/:id/join', async (req, res) => {
src/routes/battlegroundV2.js:276:router.delete('/challenges/:id', async (req, res) => {
src/routes/battlegroundV2.js:299:router.get('/celebrations', async (req, res) => {
src/routes/battlegroundV2.js:314:router.get('/team', async (req, res) => {
src/routes/bugReport.js:15:router.post('/', async (req, res) => {
src/routes/callAnalytics.js:14:router.post('/analyze', async (req, res) => {
src/routes/callAnalytics.js:46:router.get('/:communicationId', async (req, res) => {
src/routes/callAnalytics.js:66:router.get('/lead/:leadId', async (req, res) => {
src/routes/callAnalytics.js:82:router.get('/trends', async (req, res) => {
src/routes/callAnalytics.js:106:router.get('/leaderboard', async (req, res) => {
src/routes/callAnalytics.js:122:router.get('/coaching/alerts', async (req, res) => {
src/routes/callAnalytics.js:142:router.post('/coaching/alerts/:id/review', async (req, res) => {
src/routes/callList.js:23:router.get('/', async (req, res) => {
src/routes/callList.js:156:router.get('/stats', async (req, res) => {
src/routes/callList.js:281:router.get('/activity', async (req, res) => {
src/routes/callScoring.js:14:router.post('/score', async (req, res) => {
src/routes/callScoring.js:60:router.get('/:communicationId', async (req, res) => {
src/routes/callScoring.js:80:router.get('/user/:userId', async (req, res) => {
src/routes/callScoring.js:102:router.get('/user/:userId/stats', async (req, res) => {
src/routes/callScoring.js:133:router.get('/best', async (req, res) => {
src/routes/callScoring.js:152:router.get('/needs-coaching', async (req, res) => {
src/routes/callScoring.js:171:router.get('/leaderboard', async (req, res) => {
src/routes/calls.js:18:router.post('/log', async (req, res) => {
src/routes/calls.js:521:router.get('/outcomes', (req, res) => {
src/routes/calls.js:541:router.get('/history/:leadId', async (req, res) => {
src/routes/calls.js:584:router.get('/recording/:communicationId', async (req, res) => {
src/routes/coaching.js:57:router.get('/scores', async (req, res) => {
src/routes/coaching.js:113:router.post('/score', async (req, res) => {
src/routes/coaching.js:203:router.get('/tips', async (req, res) => {
src/routes/coaching.js:275:router.get('/weekly', async (req, res) => {
src/routes/coaching.js:421:router.get('/patterns', async (req, res) => {
src/routes/competitors.js:27:router.get('/', async (req, res) => {
src/routes/competitors.js:64:router.get('/:id', async (req, res) => {
src/routes/competitors.js:112:router.post('/', async (req, res) => {
src/routes/competitors.js:155:router.put('/:id', async (req, res) => {
src/routes/competitors.js:216:router.delete('/:id', async (req, res) => {
src/routes/competitors.js:242:router.get('/:id/mentions', async (req, res) => {
src/routes/competitors.js:293:router.post('/mentions', async (req, res) => {
src/routes/competitors.js:348:router.get('/stats/overview', async (req, res) => {
src/routes/dashboard.js:94:router.get('/stats', async (req, res) => {
src/routes/dashboard.js:525:router.get('/wisdom', async (req, res) => {
src/routes/dashboard.js:709:router.post('/wisdom/rate', async (req, res) => {
src/routes/dashboard.js:741:router.get('/strategy', async (req, res) => {
src/routes/dashboard.js:1299:router.get('/slipping', async (req, res) => {
src/routes/dashboard.js:1391:router.get('/priority-action', async (req, res) => {
src/routes/dashboard.js:1662:router.get('/all', async (req, res) => {
src/routes/dealIntelligence.js:14:router.get('/intelligence/objections', async (req, res) => {
src/routes/dealIntelligence.js:33:router.get('/intelligence/responses/:objectionType', async (req, res) => {
src/routes/dealIntelligence.js:53:router.get('/intelligence/velocity', async (req, res) => {
src/routes/dealIntelligence.js:77:router.get('/intelligence/stall/:leadId', async (req, res) => {
src/routes/dealIntelligence.js:97:router.get('/intelligence/at-risk', async (req, res) => {
src/routes/dealIntelligence.js:117:router.get('/outcomes', async (req, res) => {
src/routes/dealIntelligence.js:141:router.post('/outcomes', async (req, res) => {
src/routes/dealIntelligence.js:189:router.get('/outcomes/reasons', async (req, res) => {
src/routes/dealIntelligence.js:209:router.get('/outcomes/reason-options', async (req, res) => {
src/routes/dealIntelligence.js:228:router.post('/stages', async (req, res) => {
src/routes/dev.js:15:router.post('/bug', async (req, res) => {
src/routes/dev.js:91:router.post('/feature', async (req, res) => {
src/routes/dev.js:155:router.get('/queue', async (req, res) => {
src/routes/dev.js:202:router.patch('/queue/:id/status', async (req, res) => {
src/routes/dev.js:254:router.get('/queue/:id', async (req, res) => {
src/routes/dossier.js:14:router.get('/:leadId', async (req, res) => {
src/routes/dossier.js:70:router.patch('/:leadId', async (req, res) => {
src/routes/dossier.js:125:router.post('/:leadId/add-fact', async (req, res) => {
src/routes/dossier.js:180:router.post('/:leadId/add-call-summary', async (req, res) => {
src/routes/dossier.js:234:router.post('/:leadId/add-objection', async (req, res) => {
src/routes/enrichment.js:26:router.get('/usage', async (req, res) => {
src/routes/enrichment.js:47:router.get('/config', async (req, res) => {
src/routes/enrichment.js:74:router.put('/config', async (req, res) => {
src/routes/enrichment.js:154:router.get('/:leadId', async (req, res) => {
src/routes/enrichment.js:184:router.post('/:leadId', async (req, res) => {
src/routes/enrichment.js:222:router.post('/bulk', async (req, res) => {
src/routes/enrichment.js:266:router.get('/sources', async (req, res) => {
src/routes/export.js:30:router.post('/leads', async (req, res) => {
src/routes/export.js:107:router.post('/communications', async (req, res) => {
src/routes/export.js:172:router.post('/analytics', async (req, res) => {
src/routes/export.js:239:router.get('/:id', async (req, res) => {
src/routes/export.js:273:router.get('/', async (req, res) => {
src/routes/frontendTracking.js:17:router.post('/vitals', async (req, res) => {
src/routes/frontendTracking.js:56:router.post('/error', async (req, res) => {
src/routes/frontendTracking.js:96:router.get('/vitals/summary', async (req, res) => {
src/routes/health.js:9:router.get('/', async (req, res) => {
src/routes/health.js:37:router.get('/ping', (req, res) => {
src/routes/import.js:128:router.post('/leads', async (req, res) => {
src/routes/import.js:276:router.get('/:id', async (req, res) => {
src/routes/import.js:305:router.get('/:id/errors', async (req, res) => {
src/routes/import.js:341:router.get('/', async (req, res) => {
src/routes/intelligence.js:19:router.post('/track', async (req, res) => {
src/routes/intelligence.js:89:router.post('/track-batch', async (req, res) => {
src/routes/intelligence.js:146:router.get('/suggestions', async (req, res) => {
src/routes/intelligence.js:179:router.patch('/suggestions/:id/status', async (req, res) => {
src/routes/intelligence.js:232:router.post('/suggestions/:id/measure-impact', async (req, res) => {
src/routes/intelligence.js:264:router.get('/friction', async (req, res) => {
src/routes/intelligence.js:300:router.get('/weekly-report', async (req, res) => {
src/routes/intelligence.js:332:router.get('/metrics', async (req, res) => {
src/routes/intelligence.js:373:router.get('/page-stats', async (req, res) => {
src/routes/intelligence.js:451:router.get('/dashboard', async (req, res) => {
src/routes/jobs.js:53:router.post('/:jobName', async (req, res) => {
src/routes/jobs.js:70:router.get('/', (req, res) => {
src/routes/jobs.js:100:router.get('/audit-history', async (req, res) => {
src/routes/jobs.js:151:router.get('/audit-latest', async (req, res) => {
src/routes/jobs.js:181:router.get('/rep-performance', async (req, res) => {
src/routes/jobs.js:237:router.get('/call-scores/:userId', async (req, res) => {
src/routes/leads.js:28:router.get('/', cacheService.cacheMiddleware(60), async (req, res) => {
src/routes/leads.js:180:router.get('/search', async (req, res) => {
src/routes/leads.js:225:router.get('/assignments', async (req, res) => {
src/routes/leads.js:283:router.get('/:id', async (req, res) => {
src/routes/leads.js:354:router.post('/', async (req, res) => {
src/routes/leads.js:463:router.patch('/:id', async (req, res) => {
src/routes/leads.js:571:router.post('/import-sheet', importLimiter, async (req, res) => {
src/routes/leads.js:817:router.post('/:id/archive', async (req, res) => {
src/routes/leads.js:880:router.post('/:id/claim', async (req, res) => {
src/routes/leads.js:951:router.post('/:id/release', async (req, res) => {
src/routes/leads.js:1016:router.post('/:id/notes', async (req, res) => {
src/routes/leads.js:1079:router.get('/:id/notes', async (req, res) => {
src/routes/leads.js:1117:router.patch('/:id/intel', async (req, res) => {
src/routes/leads.js:1214:router.get('/:id/intel', async (req, res) => {
src/routes/leads.js:1257:router.delete('/:id', deleteLimiter, async (req, res) => {
src/routes/manager.js:58:router.get('/dashboard', async (req, res) => {
src/routes/manager.js:307:router.get('/rep/:userId', async (req, res) => {
src/routes/manager.js:435:router.get('/analytics', async (req, res) => {
src/routes/notifications.js:19:router.get('/vapid-public-key', (req, res) => {
src/routes/notifications.js:33:router.post('/subscribe', requireAuth, async (req, res) => {
src/routes/notifications.js:77:router.delete('/unsubscribe', requireAuth, async (req, res) => {
src/routes/notifications.js:105:router.get('/preferences', requireAuth, async (req, res) => {
src/routes/notifications.js:144:router.put('/preferences', requireAuth, async (req, res) => {
src/routes/notifications.js:178:router.post('/test', requireAuth, async (req, res) => {
src/routes/notifications.js:201:router.get('/status', requireAuth, async (req, res) => {
src/routes/notion.js:90:router.get('/snapshot', async (req, res) => {
src/routes/notion.js:245:router.get('/weekly-summary', async (req, res) => {
src/routes/notion.js:330:router.get('/knowledge-export', async (req, res) => {
src/routes/notion.js:396:router.post('/sync-business-state', async (req, res) => {
src/routes/notion.js:529:router.post('/sync-weekly-metrics', async (req, res) => {
src/routes/notion.js:639:router.get('/status', async (req, res) => {
src/routes/objections.js:19:router.get('/', async (req, res) => {
src/routes/objections.js:58:router.post('/', async (req, res) => {
src/routes/objections.js:102:router.put('/:id', async (req, res) => {
src/routes/objections.js:165:router.delete('/:id', async (req, res) => {
src/routes/outboundWebhooks.js:32:router.get('/events', (req, res) => {
src/routes/outboundWebhooks.js:62:router.get('/endpoints', async (req, res) => {
src/routes/outboundWebhooks.js:96:router.post('/endpoints', async (req, res) => {
src/routes/outboundWebhooks.js:158:router.put('/endpoints/:id', async (req, res) => {
src/routes/outboundWebhooks.js:235:router.delete('/endpoints/:id', async (req, res) => {
src/routes/outboundWebhooks.js:261:router.post('/endpoints/:id/test', async (req, res) => {
src/routes/outboundWebhooks.js:297:router.get('/endpoints/:id/deliveries', async (req, res) => {
src/routes/outboundWebhooks.js:341:router.post('/deliveries/:id/retry', async (req, res) => {
src/routes/playbook.js:29:router.get('/today', async (req, res) => {
src/routes/playbook.js:136:router.post('/send', async (req, res) => {
src/routes/playbook.js:284:router.get('/bulk-preview', async (req, res) => {
src/routes/playbook.js:401:router.post('/bulk-send', async (req, res) => {
src/routes/playbook.js:749:router.get('/sections', async (req, res) => {
src/routes/playbook.js:801:router.get('/sections/:category', async (req, res) => {
src/routes/playbook.js:841:router.post('/sections', async (req, res) => {
src/routes/playbook.js:891:router.put('/sections/:id', async (req, res) => {
src/routes/playbook.js:948:router.delete('/sections/:id', async (req, res) => {
src/routes/playbook.js:975:router.post('/sections/:id/record-use', async (req, res) => {
src/routes/playbook.js:1029:router.get('/recommend/:leadId', async (req, res) => {
src/routes/prompts.js:19:router.get('/', async (req, res) => {
src/routes/prompts.js:71:router.get('/:id', async (req, res) => {
src/routes/prompts.js:107:router.post('/', async (req, res) => {
src/routes/prompts.js:167:router.put('/:id', async (req, res) => {
src/routes/prompts.js:200:router.delete('/:id', async (req, res) => {
src/routes/prompts.js:234:router.post('/generate', async (req, res) => {
src/routes/prompts.js:328:router.post('/:id/preview', async (req, res) => {
src/routes/prompts.js:416:router.post('/:id/send', async (req, res) => {
src/routes/prompts.js:536:router.post('/:id/bulk-send', async (req, res) => {
src/routes/prompts.js:720:router.post('/recipients', async (req, res) => {
src/routes/prompts.js:823:router.get('/history', async (req, res) => {
src/routes/prompts.js:852:router.get('/stats', async (req, res) => {
src/routes/scripts.js:15:router.get('/guidelines', async (req, res) => {
src/routes/scripts.js:43:router.put('/guidelines', async (req, res) => {
src/routes/scripts.js:129:router.get('/guidelines/history', async (req, res) => {
src/routes/scripts.js:161:router.post('/compliance/check', async (req, res) => {
src/routes/scripts.js:184:router.post('/compliance/auto-fix', async (req, res) => {
src/routes/scripts.js:207:router.post('/compliance/validate/:id', async (req, res) => {
src/routes/scripts.js:227:router.post('/compliance/batch-validate', async (req, res) => {
src/routes/scripts.js:254:router.get('/compliance/queue', async (req, res) => {
src/routes/scripts.js:285:router.get('/compliance/stats', async (req, res) => {
src/routes/scripts.js:334:router.post('/compliance/queue/:id/approve', async (req, res) => {
src/routes/scripts.js:369:router.post('/compliance/queue/:id/reject', async (req, res) => {
src/routes/scripts.js:406:router.post('/compliance/queue/:id/edit', async (req, res) => {
src/routes/scripts.js:449:router.get('/', async (req, res) => {
src/routes/scripts.js:491:router.get('/:id', async (req, res) => {
src/routes/scripts.js:557:router.post('/', async (req, res) => {
src/routes/scripts.js:629:router.patch('/:id', async (req, res) => {
src/routes/scripts.js:659:router.delete('/:id', async (req, res) => {
src/routes/scripts.js:678:router.post('/:id/use', async (req, res) => {
src/routes/scripts.js:707:router.patch('/sessions/:sessionId', async (req, res) => {
src/routes/scripts.js:751:router.get('/for-lead/:leadId', async (req, res) => {
src/routes/scripts.js:803:router.get('/ai-recommend/:leadId', async (req, res) => {
src/routes/scripts.js:891:router.get('/analytics/overview', async (req, res) => {
src/routes/scripts.js:1004:router.get('/objections/list', async (req, res) => {
src/routes/scripts.js:1033:router.get('/objections/:id', async (req, res) => {
src/routes/scripts.js:1053:router.post('/objections', async (req, res) => {
src/routes/scripts.js:1082:router.post('/objections/:id/response', async (req, res) => {
src/routes/sequences.js:14:router.get('/', async (req, res) => {
src/routes/sequences.js:74:router.get('/check-enrollments', async (req, res) => {
src/routes/sequences.js:113:router.get('/:id', async (req, res) => {
src/routes/sequences.js:149:router.post('/:id/enroll', async (req, res) => {
src/routes/sequences.js:263:router.post('/:id/unenroll', async (req, res) => {
src/routes/sequences.js:300:router.get('/enrollments/active', async (req, res) => {
src/routes/sequences.js:344:router.get('/enrollments/lead/:leadId', async (req, res) => {
src/routes/sequences.js:385:router.post('/enrollments/:id/pause', async (req, res) => {
src/routes/sequences.js:417:router.post('/enrollments/:id/resume', async (req, res) => {
src/routes/sequences.js:464:router.post('/enrollments/:id/skip', async (req, res) => {
src/routes/sequences.js:527:router.post('/enrollments/:id/send-now', async (req, res) => {
src/routes/sequences.js:553:router.post('/lead/:leadId/opt-out', async (req, res) => {
src/routes/sequences.js:597:router.get('/lead/:leadId/opt-out', async (req, res) => {
src/routes/sequences.js:625:router.post('/:id/bulk-enroll', async (req, res) => {
src/routes/sms.js:19:router.get('/templates', async (req, res) => {
src/routes/sms.js:52:router.get('/templates/:id', async (req, res) => {
src/routes/sms.js:77:router.post('/templates', async (req, res) => {


grep -n "router\.\(get\|post\|put\|patch\|delete\|use\|all\)" /home/ccuser/rateright-growth/src/routes/*.js | grep -v "^Binary" | tail -200

Get remaining route definitions


/home/ccuser/rateright-growth/src/routes/import.js:128:router.post('/leads', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/import.js:276:router.get('/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/import.js:305:router.get('/:id/errors', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/import.js:341:router.get('/', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/intelligence.js:19:router.post('/track', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/intelligence.js:89:router.post('/track-batch', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/intelligence.js:146:router.get('/suggestions', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/intelligence.js:179:router.patch('/suggestions/:id/status', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/intelligence.js:232:router.post('/suggestions/:id/measure-impact', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/intelligence.js:264:router.get('/friction', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/intelligence.js:300:router.get('/weekly-report', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/intelligence.js:332:router.get('/metrics', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/intelligence.js:373:router.get('/page-stats', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/intelligence.js:451:router.get('/dashboard', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/jobs.js:53:router.post('/:jobName', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/jobs.js:70:router.get('/', (req, res) => {
/home/ccuser/rateright-growth/src/routes/jobs.js:100:router.get('/audit-history', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/jobs.js:151:router.get('/audit-latest', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/jobs.js:181:router.get('/rep-performance', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/jobs.js:237:router.get('/call-scores/:userId', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/leads.js:28:router.get('/', cacheService.cacheMiddleware(60), async (req, res) => {
/home/ccuser/rateright-growth/src/routes/leads.js:180:router.get('/search', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/leads.js:225:router.get('/assignments', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/leads.js:283:router.get('/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/leads.js:354:router.post('/', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/leads.js:463:router.patch('/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/leads.js:571:router.post('/import-sheet', importLimiter, async (req, res) => {
/home/ccuser/rateright-growth/src/routes/leads.js:817:router.post('/:id/archive', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/leads.js:880:router.post('/:id/claim', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/leads.js:951:router.post('/:id/release', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/leads.js:1016:router.post('/:id/notes', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/leads.js:1079:router.get('/:id/notes', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/leads.js:1117:router.patch('/:id/intel', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/leads.js:1214:router.get('/:id/intel', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/leads.js:1257:router.delete('/:id', deleteLimiter, async (req, res) => {
/home/ccuser/rateright-growth/src/routes/manager.js:58:router.get('/dashboard', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/manager.js:307:router.get('/rep/:userId', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/manager.js:435:router.get('/analytics', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/notifications.js:19:router.get('/vapid-public-key', (req, res) => {
/home/ccuser/rateright-growth/src/routes/notifications.js:33:router.post('/subscribe', requireAuth, async (req, res) => {
/home/ccuser/rateright-growth/src/routes/notifications.js:77:router.delete('/unsubscribe', requireAuth, async (req, res) => {
/home/ccuser/rateright-growth/src/routes/notifications.js:105:router.get('/preferences', requireAuth, async (req, res) => {
/home/ccuser/rateright-growth/src/routes/notifications.js:144:router.put('/preferences', requireAuth, async (req, res) => {
/home/ccuser/rateright-growth/src/routes/notifications.js:178:router.post('/test', requireAuth, async (req, res) => {
/home/ccuser/rateright-growth/src/routes/notifications.js:201:router.get('/status', requireAuth, async (req, res) => {
/home/ccuser/rateright-growth/src/routes/notion.js:90:router.get('/snapshot', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/notion.js:245:router.get('/weekly-summary', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/notion.js:330:router.get('/knowledge-export', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/notion.js:396:router.post('/sync-business-state', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/notion.js:529:router.post('/sync-weekly-metrics', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/notion.js:639:router.get('/status', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/objections.js:19:router.get('/', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/objections.js:58:router.post('/', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/objections.js:102:router.put('/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/objections.js:165:router.delete('/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/outboundWebhooks.js:32:router.get('/events', (req, res) => {
/home/ccuser/rateright-growth/src/routes/outboundWebhooks.js:62:router.get('/endpoints', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/outboundWebhooks.js:96:router.post('/endpoints', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/outboundWebhooks.js:158:router.put('/endpoints/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/outboundWebhooks.js:235:router.delete('/endpoints/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/outboundWebhooks.js:261:router.post('/endpoints/:id/test', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/outboundWebhooks.js:297:router.get('/endpoints/:id/deliveries', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/outboundWebhooks.js:341:router.post('/deliveries/:id/retry', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/playbook.js:29:router.get('/today', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/playbook.js:136:router.post('/send', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/playbook.js:284:router.get('/bulk-preview', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/playbook.js:401:router.post('/bulk-send', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/playbook.js:749:router.get('/sections', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/playbook.js:801:router.get('/sections/:category', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/playbook.js:841:router.post('/sections', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/playbook.js:891:router.put('/sections/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/playbook.js:948:router.delete('/sections/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/playbook.js:975:router.post('/sections/:id/record-use', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/playbook.js:1029:router.get('/recommend/:leadId', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/prompts.js:19:router.get('/', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/prompts.js:71:router.get('/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/prompts.js:107:router.post('/', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/prompts.js:167:router.put('/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/prompts.js:200:router.delete('/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/prompts.js:234:router.post('/generate', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/prompts.js:328:router.post('/:id/preview', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/prompts.js:416:router.post('/:id/send', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/prompts.js:536:router.post('/:id/bulk-send', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/prompts.js:720:router.post('/recipients', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/prompts.js:823:router.get('/history', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/prompts.js:852:router.get('/stats', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:15:router.get('/guidelines', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:43:router.put('/guidelines', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:129:router.get('/guidelines/history', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:161:router.post('/compliance/check', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:184:router.post('/compliance/auto-fix', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:207:router.post('/compliance/validate/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:227:router.post('/compliance/batch-validate', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:254:router.get('/compliance/queue', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:285:router.get('/compliance/stats', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:334:router.post('/compliance/queue/:id/approve', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:369:router.post('/compliance/queue/:id/reject', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:406:router.post('/compliance/queue/:id/edit', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:449:router.get('/', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:491:router.get('/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:557:router.post('/', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:629:router.patch('/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:659:router.delete('/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:678:router.post('/:id/use', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:707:router.patch('/sessions/:sessionId', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:751:router.get('/for-lead/:leadId', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:803:router.get('/ai-recommend/:leadId', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:891:router.get('/analytics/overview', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:1004:router.get('/objections/list', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:1033:router.get('/objections/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:1053:router.post('/objections', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/scripts.js:1082:router.post('/objections/:id/response', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sequences.js:14:router.get('/', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sequences.js:74:router.get('/check-enrollments', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sequences.js:113:router.get('/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sequences.js:149:router.post('/:id/enroll', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sequences.js:263:router.post('/:id/unenroll', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sequences.js:300:router.get('/enrollments/active', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sequences.js:344:router.get('/enrollments/lead/:leadId', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sequences.js:385:router.post('/enrollments/:id/pause', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sequences.js:417:router.post('/enrollments/:id/resume', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sequences.js:464:router.post('/enrollments/:id/skip', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sequences.js:527:router.post('/enrollments/:id/send-now', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sequences.js:553:router.post('/lead/:leadId/opt-out', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sequences.js:597:router.get('/lead/:leadId/opt-out', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sequences.js:625:router.post('/:id/bulk-enroll', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sms.js:19:router.get('/templates', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sms.js:52:router.get('/templates/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sms.js:77:router.post('/templates', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sms.js:127:router.put('/templates/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sms.js:177:router.delete('/templates/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sms.js:202:router.post('/templates/:id/use', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sms.js:228:router.post('/send', smsLimiter, async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sms.js:470:router.post('/send-batch', smsLimiter, async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sms.js:600:router.get('/scheduled', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sms.js:644:router.delete('/scheduled/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sms.js:687:router.post('/batch', smsBatchLimiter, async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sms.js:820:router.post('/request-contact', smsLimiter, async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sms.js:914:router.get('/conversations', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sms.js:1063:router.get('/conversation/:leadId', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sms.js:1125:router.patch('/conversation/:leadId/read', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sms.js:1162:router.patch('/conversation/:leadId/handle', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sms.js:1220:router.get('/conversations/prioritized', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sms.js:1422:router.post('/ai-suggest', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sms.js:1589:router.get('/stats', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sms.js:1735:router.post('/preview', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sms.js:1782:router.post('/flag/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sms.js:1837:router.get('/response-times', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sync.js:19:router.get('/platform/status', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sync.js:33:router.get('/platform/stats', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sync.js:48:router.post('/platform', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sync.js:79:router.post('/platform/recent', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/sync.js:112:router.get('/platform/debug', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/tags.js:34:router.get('/trades', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/tags.js:60:router.post('/trades', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/tags.js:103:router.put('/trades/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/tags.js:155:router.delete('/trades/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/tags.js:181:router.get('/trades/:id/leads', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/tags.js:235:router.post('/leads/:leadId/tags', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/tags.js:313:router.delete('/leads/:leadId/tags/:tagId', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/tags.js:344:router.get('/leads/:leadId/tags', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/team.js:53:router.get('/performance', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/team.js:210:router.get('/members', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/team.js:239:router.get('/:userId/stats', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/team.js:361:router.get('/roles', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/team.js:381:router.get('/roles/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/team.js:418:router.post('/roles', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/team.js:461:router.put('/roles/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/team.js:516:router.delete('/roles/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/team.js:557:router.put('/members/:userId/role', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/team.js:633:router.get('/permissions', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/team.js:682:router.get('/permissions/check', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/users.js:17:router.get('/', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/users.js:46:router.get('/me', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/users.js:93:router.post('/sync', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/users.js:161:router.get('/check/:email', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/users.js:200:router.get('/map', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/vapi.js:18:router.post('/webhook', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/vapi.js:129:router.get('/status', (req, res) => {
/home/ccuser/rateright-growth/src/routes/vapi.js:143:router.get('/tasks', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/vapi.js:176:router.post('/tasks/:id/retry', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/voice.js:27:router.get('/token', (req, res) => {
/home/ccuser/rateright-growth/src/routes/voice.js:834:router.get('/lookup-caller', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/voice.js:895:router.get('/status', (req, res) => {
/home/ccuser/rateright-growth/src/routes/voicemail.js:32:router.get('/recordings', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/voicemail.js:63:router.post('/recordings', upload.single('audio'), async (req, res) => {
/home/ccuser/rateright-growth/src/routes/voicemail.js:141:router.delete('/recordings/:id', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/voicemail.js:191:router.patch('/recordings/:id/default', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/voicemail.js:230:router.post('/drop', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/voicemail.js:306:router.get('/drops/stats', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/webhooks.js:29:router.post('/twilio/inbound', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/webhooks.js:440:router.get('/twilio/inbound', (req, res) => {
/home/ccuser/rateright-growth/src/routes/webhooks.js:456:router.get('/twilio/test-lookup', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/webhooks.js:519:router.post('/twilio/status', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/webhooks.js:579:router.post('/website-signup', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/webhooks.js:869:router.get('/website-signup', (req, res) => {
/home/ccuser/rateright-growth/src/routes/xp.js:51:router.get('/user', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/xp.js:118:router.post('/award', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/xp.js:276:router.get('/history', async (req, res) => {
/home/ccuser/rateright-growth/src/routes/xp.js:324:router.get('/leaderboard', async (req, res) => {


Now let me check how routes are mounted, and also find auth middleware patterns.


grep -n "app.use.*routes\|app.use.*require.*routes\|require.*routes" /home/ccuser/rateright-growth/src/server.js /home/ccuser/rateright-growth/src/app.js /home/ccuser/rateright-growth/src/index.js 2>/dev/null | head -80

Find how routes are mounted in the main app


/home/ccuser/rateright-growth/src/index.js:24:const healthRoutes = require('./routes/health');
/home/ccuser/rateright-growth/src/index.js:25:const webhookRoutes = require('./routes/webhooks');
/home/ccuser/rateright-growth/src/index.js:26:const leadRoutes = require('./routes/leads');
/home/ccuser/rateright-growth/src/index.js:27:const smsRoutes = require('./routes/sms');
/home/ccuser/rateright-growth/src/index.js:28:const callRoutes = require('./routes/calls');
/home/ccuser/rateright-growth/src/index.js:29:const callListRoutes = require('./routes/callList');
/home/ccuser/rateright-growth/src/index.js:30:const jobRoutes = require('./routes/jobs');
/home/ccuser/rateright-growth/src/index.js:33:  aiRoutes = require('./routes/ai');
/home/ccuser/rateright-growth/src/index.js:39:const voiceRoutes = require('./routes/voice');
/home/ccuser/rateright-growth/src/index.js:40:const bugReportRoutes = require('./routes/bugReport');
/home/ccuser/rateright-growth/src/index.js:41:const dashboardRoutes = require('./routes/dashboard');
/home/ccuser/rateright-growth/src/index.js:42:const syncRoutes = require('./routes/sync');
/home/ccuser/rateright-growth/src/index.js:43:const activationRoutes = require('./routes/activation');
/home/ccuser/rateright-growth/src/index.js:44:const scriptsRoutes = require('./routes/scripts');
/home/ccuser/rateright-growth/src/index.js:45:const achievementsRoutes = require('./routes/achievements');
/home/ccuser/rateright-growth/src/index.js:46:const xpRoutes = require('./routes/xp');
/home/ccuser/rateright-growth/src/index.js:47:const coachingRoutes = require('./routes/coaching');
/home/ccuser/rateright-growth/src/index.js:48:const analyticsRoutes = require('./routes/analytics');
/home/ccuser/rateright-growth/src/index.js:49:const aiAlertsRoutes = require('./routes/aiAlerts');
/home/ccuser/rateright-growth/src/index.js:50:const promptsRoutes = require('./routes/prompts');
/home/ccuser/rateright-growth/src/index.js:51:const battlegroundRoutes = require('./routes/battleground');
/home/ccuser/rateright-growth/src/index.js:52:const battlegroundV2Routes = require('./routes/battlegroundV2');
/home/ccuser/rateright-growth/src/index.js:53:const dossierRoutes = require('./routes/dossier');
/home/ccuser/rateright-growth/src/index.js:54:const managerRoutes = require('./routes/manager');
/home/ccuser/rateright-growth/src/index.js:55:const playbookRoutes = require('./routes/playbook');
/home/ccuser/rateright-growth/src/index.js:56:const voicemailRoutes = require('./routes/voicemail');
/home/ccuser/rateright-growth/src/index.js:57:const devRoutes = require('./routes/dev');
/home/ccuser/rateright-growth/src/index.js:58:const sequencesRoutes = require('./routes/sequences');
/home/ccuser/rateright-growth/src/index.js:59:const intelligenceRoutes = require('./routes/intelligence');
/home/ccuser/rateright-growth/src/index.js:60:const frontendTrackingRoutes = require('./routes/frontendTracking');
/home/ccuser/rateright-growth/src/index.js:61:const usersRoutes = require('./routes/users');
/home/ccuser/rateright-growth/src/index.js:62:const dealIntelligenceRoutes = require('./routes/dealIntelligence');
/home/ccuser/rateright-growth/src/index.js:63:// const notificationsRoutes = require('./routes/notifications'); // Temporarily disabled
/home/ccuser/rateright-growth/src/index.js:64:const callAnalyticsRoutes = require('./routes/callAnalytics');
/home/ccuser/rateright-growth/src/index.js:65:const callScoringRoutes = require('./routes/callScoring');
/home/ccuser/rateright-growth/src/index.js:66:const teamRoutes = require('./routes/team');
/home/ccuser/rateright-growth/src/index.js:67:const notionRoutes = require('./routes/notion');
/home/ccuser/rateright-growth/src/index.js:68:const objectionsRoutes = require('./routes/objections');
/home/ccuser/rateright-growth/src/index.js:69:const tagsRoutes = require('./routes/tags');
/home/ccuser/rateright-growth/src/index.js:70:const competitorsRoutes = require('./routes/competitors');
/home/ccuser/rateright-growth/src/index.js:71:const importRoutes = require('./routes/import');
/home/ccuser/rateright-growth/src/index.js:72:const exportRoutes = require('./routes/export');
/home/ccuser/rateright-growth/src/index.js:73:const outboundWebhooksRoutes = require('./routes/outboundWebhooks');
/home/ccuser/rateright-growth/src/index.js:74:const enrichmentRoutes = require('./routes/enrichment');
/home/ccuser/rateright-growth/src/index.js:215:const { voiceWebhooks } = require('./routes/voice');
/home/ccuser/rateright-growth/src/index.js:219:const vapiRoutes = require('./routes/vapi');
/home/ccuser/rateright-growth/src/index.js:223:const { internalJobTrigger } = require('./routes/jobs');
/home/ccuser/rateright-growth/src/index.js:227:const { internalLeadsRouter } = require('./routes/leads');
/home/ccuser/rateright-growth/src/index.js:233:app.use('/api/sms', requireApiKeyOrAuth(requireAuth), smsRoutes); // Rate limiting applied per-endpoint in routes
/home/ccuser/rateright-growth/src/index.js:238:app.use('/api/voice', requireAuth, voiceRoutes); // Protected voice routes (token)