@@ -7,6 +7,7 @@ import { z } from "zod";
77import { countries } from "@/lib/countries" ;
88import { updateCreditUsage } from "@/lib/creditUsage" ;
99import { getAvailableModels , getConstraints } from "@/lib/constraints" ;
10+ import { posthogServer } from "@/lib/posthog-server" ;
1011
1112const supabase = createClient (
1213 process . env . NEXT_PUBLIC_SUPABASE_URL ! ,
@@ -367,14 +368,28 @@ const StoredResultsSchema = z
367368export async function GET ( req : NextRequest ) {
368369 const authHeader = req . headers . get ( "authorization" ) ;
369370 if ( authHeader !== `Bearer ${ process . env . CRON_SECRET } ` ) {
371+ await posthogServer . capture ( 'cron-system' , 'cron_unauthorized_access' , {
372+ endpoint : '/api/cron-process-query' ,
373+ timestamp : new Date ( ) . toISOString ( ) ,
374+ } ) ;
370375 return new Response ( "Unauthorized" , {
371376 status : 401 ,
372377 } ) ;
373378 }
374379
380+ const cronStartTime = Date . now ( ) ;
381+
375382 try {
376383 const now = new Date ( ) . toISOString ( ) ;
377384
385+ // Track cron job start
386+ await posthogServer . capture ( 'cron-system' , 'cron_job_started' , {
387+ endpoint : '/api/cron-process-query' ,
388+ timestamp : now ,
389+ batch_size : BATCH_SIZE ,
390+ concurrency_limit : CONCURRENCY_LIMIT ,
391+ } ) ;
392+
378393 // Step 1: Get the total count of queries that need processing
379394 const { count, error : countError } = await supabase
380395 . from ( "scheduled_queries" )
@@ -384,6 +399,11 @@ export async function GET(req: NextRequest) {
384399
385400 if ( countError ) {
386401 console . error ( "Error getting query count:" , countError ) ;
402+ await posthogServer . captureError ( 'cron-system' , new Error ( `Failed to get query count: ${ countError . message } ` ) , {
403+ endpoint : '/api/cron-process-query' ,
404+ error_code : countError . code ,
405+ error_details : countError . details ,
406+ } ) ;
387407 return NextResponse . json (
388408 { error : "Failed to get query count" } ,
389409 { status : 500 }
@@ -392,6 +412,12 @@ export async function GET(req: NextRequest) {
392412
393413 console . log ( `Total queries to process: ${ count } ` ) ;
394414
415+ // Track query count metrics
416+ await posthogServer . capture ( 'cron-system' , 'cron_queries_counted' , {
417+ total_queries : count || 0 ,
418+ timestamp : now ,
419+ } ) ;
420+
395421 // Step 2: Fetch just the first batch
396422 const { data : queries , error } = await supabase
397423 . from ( "scheduled_queries" )
@@ -403,13 +429,25 @@ export async function GET(req: NextRequest) {
403429
404430 if ( error ) {
405431 console . error ( "Error fetching queries:" , error ) ;
432+ await posthogServer . captureError ( 'cron-system' , new Error ( `Failed to fetch queries: ${ error . message } ` ) , {
433+ endpoint : '/api/cron-process-query' ,
434+ error_code : error . code ,
435+ error_details : error . details ,
436+ } ) ;
406437 return NextResponse . json (
407438 { error : "Failed to fetch queries" } ,
408439 { status : 500 }
409440 ) ;
410441 }
411442
412443 console . log ( `Processing batch of ${ queries . length } queries` ) ;
444+
445+ // Track batch processing start
446+ await posthogServer . capture ( 'cron-system' , 'cron_batch_started' , {
447+ batch_size : queries . length ,
448+ total_remaining : count || 0 ,
449+ unique_users : [ ...new Set ( queries . map ( q => q . user_id ) ) ] . length ,
450+ } ) ;
413451
414452 // Step 3: Process queries with concurrency control
415453 const results = [ ] ;
@@ -502,6 +540,26 @@ export async function GET(req: NextRequest) {
502540 console . log ( ` ⚠️ Failed: ${ failed } ` ) ;
503541 console . log ( ` ❌ Errors: ${ errors } ` ) ;
504542
543+ const cronDuration = Date . now ( ) - cronStartTime ;
544+
545+ // Track comprehensive cron job completion
546+ await posthogServer . capture ( 'cron-system' , 'cron_job_completed' , {
547+ endpoint : '/api/cron-process-query' ,
548+ duration_ms : cronDuration ,
549+ total_queries : count || 0 ,
550+ processed_queries : queries . length ,
551+ remaining_queries : count ? count - queries . length : 0 ,
552+ successful_queries : successful ,
553+ paused_queries : paused ,
554+ failed_queries : failed ,
555+ error_queries : errors ,
556+ success_rate : queries . length > 0 ? ( successful / queries . length * 100 ) . toFixed ( 2 ) : 0 ,
557+ unique_users_processed : [ ...new Set ( queries . map ( q => q . user_id ) ) ] . length ,
558+ batch_size : BATCH_SIZE ,
559+ concurrency_limit : CONCURRENCY_LIMIT ,
560+ avg_processing_time_per_query : queries . length > 0 ? ( cronDuration / queries . length ) . toFixed ( 2 ) : 0 ,
561+ } ) ;
562+
505563 return NextResponse . json ( {
506564 message : `Processed ${ queries . length } queries` ,
507565 total : count ,
@@ -517,6 +575,15 @@ export async function GET(req: NextRequest) {
517575 } ) ;
518576 } catch ( error : any ) {
519577 console . error ( "Cron job error:" , error ) ;
578+ const cronDuration = Date . now ( ) - cronStartTime ;
579+
580+ // Track cron job failure
581+ await posthogServer . captureError ( 'cron-system' , error , {
582+ endpoint : '/api/cron-process-query' ,
583+ duration_ms : cronDuration ,
584+ failure_point : 'cron_job_execution' ,
585+ } ) ;
586+
520587 return NextResponse . json ( { error : error . message } , { status : 500 } ) ;
521588 }
522589}
@@ -528,13 +595,27 @@ async function processQueryDirectly(query: any) {
528595 // without making HTTP requests to your own API
529596
530597 const now = new Date ( ) . toISOString ( ) ;
598+ const queryStartTime = Date . now ( ) ;
531599
532600 try {
533601 console . log (
534602 `Processing query ID: ${ query . id } , Text: "${ query . query } ", Mode: ${
535603 query . mode || "Default"
536604 } `
537605 ) ;
606+
607+ // Track individual query processing start
608+ await posthogServer . capture ( query . user_id , 'cron_query_started' , {
609+ query_id : query . id ,
610+ query_text : query . query ,
611+ mode : query . mode || 'Default' ,
612+ frequency : query . frequency ,
613+ location : query . location ,
614+ selected_models : query . selected_models ,
615+ credits_per_run : query . credits_per_run ,
616+ include_google_search : query . include_google_search ,
617+ timestamp : now ,
618+ } ) ;
538619
539620 // Check if user has enough credits before processing
540621 console . log ( `💳 Checking credits for user ${ query . user_id } ...` ) ;
@@ -579,11 +660,30 @@ async function processQueryDirectly(query: any) {
579660 console . log ( ` - Max credits: ${ userConstraints . max_credits } ` ) ;
580661 console . log ( ` - Credits required: ${ creditsRequired } ` ) ;
581662 console . log ( ` - Remaining: ${ userConstraints . max_credits - currentUsage } ` ) ;
663+
664+ // Track credit check details
665+ await posthogServer . capture ( query . user_id , 'cron_credit_check' , {
666+ query_id : query . id ,
667+ current_usage : currentUsage ,
668+ max_credits : userConstraints . max_credits ,
669+ credits_required : creditsRequired ,
670+ remaining_credits : userConstraints . max_credits - currentUsage ,
671+ product_name : productName ,
672+ subscription_status : subscription . status ,
673+ } ) ;
582674
583675 // Check if user has enough credits
584676 if ( currentUsage + creditsRequired > userConstraints . max_credits ) {
585677 console . warn ( `⚠️ User ${ query . user_id } has insufficient credits. Pausing query ${ query . id } ` ) ;
586678
679+ // Track insufficient credits event
680+ await posthogServer . capture ( query . user_id , 'cron_query_paused_insufficient_credits' , {
681+ query_id : query . id ,
682+ current_usage : currentUsage ,
683+ max_credits : userConstraints . max_credits ,
684+ credits_required : creditsRequired ,
685+ } ) ;
686+
587687 // Pause the query instead of processing it
588688 const { error : pauseError } = await supabase
589689 . from ( 'scheduled_queries' )
@@ -615,6 +715,13 @@ async function processQueryDirectly(query: any) {
615715 if ( subscription . status !== 'active' ) {
616716 console . warn ( `⚠️ User ${ query . user_id } subscription is not active (${ subscription . status } ). Pausing query ${ query . id } ` ) ;
617717
718+ // Track inactive subscription event
719+ await posthogServer . capture ( query . user_id , 'cron_query_paused_inactive_subscription' , {
720+ query_id : query . id ,
721+ subscription_status : subscription . status ,
722+ product_name : productName ,
723+ } ) ;
724+
618725 // Pause the query
619726 const { error : pauseError } = await supabase
620727 . from ( 'scheduled_queries' )
@@ -1148,6 +1255,22 @@ async function processQueryDirectly(query: any) {
11481255 throw new Error ( `Failed to update query record: ${ updateError . message } ` ) ;
11491256 }
11501257
1258+ const queryDuration = Date . now ( ) - queryStartTime ;
1259+
1260+ // Track successful query completion
1261+ await posthogServer . capture ( query . user_id , 'cron_query_completed_successfully' , {
1262+ query_id : query . id ,
1263+ query_text : query . query ,
1264+ duration_ms : queryDuration ,
1265+ credits_used : query . credits_per_run || 1 ,
1266+ models_processed : selectedModels . length ,
1267+ next_scheduled : nextAnalysisDate . toISOString ( ) ,
1268+ successful_models : finalModelResultsForDB . filter ( r => r . status === 'fulfilled' ) . length ,
1269+ failed_models : finalModelResultsForDB . filter ( r => r . status === 'rejected' ) . length ,
1270+ include_google_search : query . include_google_search ,
1271+ mode : query . mode || 'Default' ,
1272+ } ) ;
1273+
11511274 return {
11521275 success : true ,
11531276 queryId : query . id ,
@@ -1157,6 +1280,17 @@ async function processQueryDirectly(query: any) {
11571280 } ;
11581281 } catch ( error : any ) {
11591282 console . error ( `Error in processQueryDirectly for query ${ query . id } :` , error ) ;
1283+ const queryDuration = Date . now ( ) - queryStartTime ;
1284+
1285+ // Track query processing error
1286+ await posthogServer . captureError ( query . user_id , error , {
1287+ query_id : query . id ,
1288+ query_text : query . query ,
1289+ duration_ms : queryDuration ,
1290+ failure_point : 'query_processing' ,
1291+ mode : query . mode || 'Default' ,
1292+ } ) ;
1293+
11601294 throw error ;
11611295 }
11621296}
0 commit comments