feat(web): expose last cache refresh time as header on rest endpoints - #474
Merged
Merged
Conversation
Cron handler records refresh timestamp in redis (rest:refresh:<job>) after a successful run. REST routes read it and return x-last-refresh, exposed via CORS.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
murderteeth
approved these changes
Sep 14, 2026
murderteeth
left a comment
Contributor
There was a problem hiding this comment.
Summary
Cron handler records a completion timestamp in redis after each successful run, and the five REST routes surface it as an x-last-refresh header with a matching Access-Control-Expose-Headers entry. Helper, handler, and timeseries route are covered by new specs; lint and the cron/rest vitest suites pass.
Verdict
APPROVE
How This Was Reviewed
Reviewed with the review-pr-workflow skill —
5 review lenses, each finding independently verified by claude. 1 candidate finding was refuted and dropped.
3 tasks
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.
Summary
REST cache consumers had no way to tell how stale a response was. The cron handler now writes the completion timestamp to redis (
rest:refresh:<job>, key derived from the cron path slug) after a successful run, and the REST routes return it asx-last-refresh(ISO 8601). Redis is needed because the crons and the routes run in separate serverless invocations.Header is added to
Access-Control-Expose-Headersso browsers can read it — the routes serveAccess-Control-Allow-Origin: *, which otherwise hides custom headers.Job → route mapping:
refresh-cache/rest/list/vaults,/rest/list/vaults/[chainId],/rest/snapshot/[chainId]/[address]reports-refresh/rest/reports/[chainId]/[address]timeseries-refresh/rest/timeseries/[segment]/[chainId]/[address]How to review
Start at
packages/web/app/api/rest/cache.ts(the three new helpers) andpackages/web/app/api/cron/handler.ts(where the write happens). The five route files are the same change repeated: the redis read for the header joins the existingPromise.all, so no extra round trip is serialized.Two things worth checking:
job()resolves, so a failed run leaves the previous value in place.Test plan
npx vitest run app/api/cron app/api/rest— 41 passed at first land. Added (not re-run in the review-fix loop):cache.spec.tscoverssetLastRefreshkey+ISO (and default Date) pluslastRefreshHeadershit / miss / throw;handler.spec.tscovers write on success, no write when the job throws, no write on an empty path slug, and 200 when the write throws; timeseriesroute.spec.tsasserts the route emitsx-last-refreshfor jobtimeseries-refresh.CRON_SECRETbearer, thencurl -ione of the REST routes and confirmx-last-refreshmatches.Risk / impact
Low. Additive response header, no change to any payload. No migrations, no auth changes.
Known limits:
s-maxage=900, so a cached hit serves the header captured at render time, not the current value.*-refresh-historicalcrons write their own keys, but no route reads them yet.x-last-refresh. List/snapshot/reports fetch the timestamp then drop it on 404; timeseries unknown-segment 404s before the redis read.Rollback is a revert; nothing depends on the redis key existing.