Skip to content

Commit 7ecd681

Browse files
committed
update: added posthog tracking on cron job process
1 parent f64a282 commit 7ecd681

File tree

5 files changed

+728
-0
lines changed

5 files changed

+728
-0
lines changed

src/app/api/cron-process-query/route.ts

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { z } from "zod";
77
import { countries } from "@/lib/countries";
88
import { updateCreditUsage } from "@/lib/creditUsage";
99
import { getAvailableModels, getConstraints } from "@/lib/constraints";
10+
import { posthogServer } from "@/lib/posthog-server";
1011

1112
const supabase = createClient(
1213
process.env.NEXT_PUBLIC_SUPABASE_URL!,
@@ -367,14 +368,28 @@ const StoredResultsSchema = z
367368
export 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

Comments
 (0)