fix(cron): run LoTW sync in-process instead of self-fetching localhost#225
Merged
Conversation
The unified sync cron invoked /api/lotw/upload and /api/lotw/download by fetching NEXTAUTH_URL || http://localhost:3000 — in serverless deployments nothing listens on localhost, so every LoTW leg failed with ECONNREFUSED 127.0.0.1:3000. Extract the upload/download logic into src/lib/lotw-sync.ts (performLotwUpload / performLotwDownload) and call it directly from both the cron and the API routes. The routes keep byte-identical response shapes and status codes; the cron no longer depends on NEXTAUTH_URL. With the self-fetch gone, the X-Cron-Job request mode on the LoTW routes has no remaining callers, so it is removed — they now always require a user token, and cron work is scoped by the station's own user_id inside the lib. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
There was a problem hiding this comment.
Pull request overview
Refactors the LoTW sync implementation so the unified cron (/api/cron/sync) runs LoTW upload/download logic in-process rather than self-fetching the app over HTTP (via NEXTAUTH_URL/localhost), which fails in serverless deployments and doubles invocations.
Changes:
- Extracts LoTW upload/download logic into a shared library (
performLotwUpload/performLotwDownload) returning{ status, body }for direct route/cron consumption. - Updates LoTW upload/download API routes to become thin, user-token-only wrappers around the shared library.
- Updates the unified cron to call the shared library directly (removing the internal HTTP fetch helper).
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/lib/lotw-sync.ts |
New shared in-process LoTW upload/download implementation used by both cron and user routes. |
src/app/api/lotw/upload/route.ts |
Removes cron-mode logic; delegates POST handling to performLotwUpload after verifyToken. |
src/app/api/lotw/download/route.ts |
Removes cron-mode logic; delegates POST handling to performLotwDownload after verifyToken. |
src/app/api/cron/sync/route.ts |
Removes self-fetch (NEXTAUTH_URL/localhost) pattern; invokes LoTW sync library functions directly. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The unified sync cron (
/api/cron/sync) invoked the LoTW upload/download API routes by fetchingNEXTAUTH_URL || http://localhost:3000. In serverless deployments nothing listens on localhost inside the function, so every LoTW leg failed:Even with
NEXTAUTH_URLset, the self-fetch pattern doubles invocations and depends on the deployment's public URL being reachable from inside the cron function.Fix
src/lib/lotw-sync.ts— the full upload/download logic extracted from the two API routes intoperformLotwUpload()/performLotwDownload(). Each takesstationIdplus an optionalrequesterUserId: when present (user-facing API path) the station must belong to that user; when omitted (cron path) the station's ownuser_idscopes logging and contacts. Returns{ status, body }so routes pass results straight toNextResponse.json— response shapes and status codes are unchanged./api/cron/sync—callLotwRoute()(the self-fetch) is deleted; the LoTW legs call the lib in-process. No moreNEXTAUTH_URLdependency./api/lotw/upload+/api/lotw/download— now thin wrappers:verifyToken, validatestation_id, delegate. TheX-Cron-Jobcron mode is removed entirely since its only caller now runs in-process; the routes always require a user token.GETlog-listing handlers unchanged.The download lib carries over the recent sync-overhaul improvements verbatim (incremental fetch via
lotw_last_qsl_rcvd_date, per-row confirmation apply isolation, singleqsl_lotw_dateassignment).Verification
npm run typecheck,npm run lint,npm run buildall pass./api/cron/syncreturns 401 with no/wrong Bearer token;/api/lotw/uploadand/api/lotw/downloadreturn 401 with a spoofedX-Cron-Job: trueheader.🤖 Generated with Claude Code