@@ -7,21 +7,21 @@ import {
77import { setCachedGitHubStats } from '~/utils/stats-db.server'
88
99/**
10- * Netlify Background Function - Refresh org-level stats cache
10+ * Netlify Background + Scheduled Function - Refresh org-level stats cache
1111 *
12- * Background functions are identified by the `-background` suffix in the filename.
13- * They have a 15-minute timeout (vs 30 seconds for regular functions) and return
14- * a 202 response immediately while processing continues in the background.
12+ * This function combines both background and scheduled execution:
13+ * - Can be invoked via HTTP POST (returns 202 immediately, runs in background)
14+ * - Can be triggered on a schedule (runs automatically via cron)
15+ *
16+ * Background functions have a 15-minute timeout (vs 30 seconds for regular functions)
17+ * and return a 202 response immediately while processing continues in the background.
1518 *
1619 * This function refreshes pre-aggregated stats for the TanStack organization:
1720 * - GitHub: stars, contributors, dependents
1821 * - NPM: total downloads across all packages (including legacy packages)
1922 *
20- * Invocation:
21- * POST https://tanstack.com/.netlify/functions/refresh-stats-cache-background
22- * Authorization: Bearer YOUR_CRON_SECRET
23- *
24- * Can be triggered manually from the admin panel.
23+ * Scheduled: Runs automatically every 6 hours (configured via export config)
24+ * Only called by Netlify's scheduler - not publicly accessible
2525 * Timeout: 15 minutes
2626 * Concurrency: 8 packages at a time, 500ms delay between packages
2727 *
@@ -33,36 +33,7 @@ export const handler: Handler = async (
3333 event : HandlerEvent ,
3434 context : HandlerContext
3535) => {
36- console . log (
37- '[refresh-stats-cache-background] Starting background stats refresh...'
38- )
39-
40- // Check authentication
41- const cronSecret = process . env . CRON_SECRET
42- const authHeader = event . headers . authorization || event . headers . Authorization
43-
44- if ( ! cronSecret ) {
45- console . error ( '[refresh-stats-cache-background] CRON_SECRET not configured' )
46- return {
47- statusCode : 500 ,
48- body : JSON . stringify ( {
49- error : 'CRON_SECRET not configured' ,
50- } ) ,
51- }
52- }
53-
54- // Extract token from "Bearer TOKEN" format
55- const providedSecret = authHeader ?. replace ( / ^ B e a r e r \s + / i, '' )
56-
57- if ( providedSecret !== cronSecret ) {
58- console . error ( '[refresh-stats-cache-background] Invalid authentication' )
59- return {
60- statusCode : 401 ,
61- body : JSON . stringify ( {
62- error : 'Invalid authentication' ,
63- } ) ,
64- }
65- }
36+ console . log ( '[refresh-stats-cache-background] Starting stats refresh...' )
6637
6738 const startTime = Date . now ( )
6839
@@ -200,3 +171,13 @@ export const handler: Handler = async (
200171 }
201172 }
202173}
174+
175+ /**
176+ * Netlify function configuration
177+ * - type: 'experimental-background' enables background execution (15 min timeout, returns 202 immediately)
178+ * - schedule: Cron expression for scheduled execution (runs every 6 hours)
179+ */
180+ export const config = {
181+ type : 'experimental-background' as const ,
182+ schedule : '0 */6 * * *' , // Every 6 hours
183+ }
0 commit comments