feat(feeds): add ?since= filter for incremental feed polling#2179
Conversation
Add an optional `?since=<ISO-8601>` lower bound to the content feeds: return only items at or after that instant (e.g. ?since=2026-06-01 or ?since=2026-06-01T00:00:00Z). It composes with the existing ?tag= filter, so an agent can poll a focused, incremental slice instead of re-diffing the whole window each time. - Items are filtered by their existing `timestamp`; an unparseable timestamp is dropped so it never leaks past an explicit `since`. - A malformed `since` is a 400 via the shared feed error envelope, matching the strict param validation elsewhere in the API. - Absent `since` is a no-op (the whole feed) — fully backward-compatible. Worker-computed in src/feeds.mjs; no schema/contract/artifact change. Covered by unit tests for filterSince (bound, inclusivity, bad timestamps) and handler tests for the future/past cases, ?tag= composition, and the 400. Closes JSONbored#2178
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2179 +/- ##
=======================================
Coverage 93.25% 93.26%
=======================================
Files 51 51
Lines 8076 8087 +11
Branches 2962 2966 +4
=======================================
+ Hits 7531 7542 +11
Misses 92 92
Partials 453 453
🚀 New features to boost your workflow:
|
|
Tip 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 ✅ Gittensory review — safe to merge
✅ Approved — safe to merge Review summary
Nits — 5 non-blocking
Review context
Contributor next steps
Signal definitions
Review detailsGenerated from public PR metadata and the diff. Advisory only; deterministic signals remain authoritative. Adds an optional `?since=<ISO-8601>` lower-bound filter to all three feed endpoints by parsing the param once before any artifact I/O (the correct early-rejection pattern), applying it as a composable post-filter after `filterByTag` and before `sortAndCap`, and exporting `filterSince` through `__test`. The implementation is correct: the inclusive `>=` comparison, the NaN-drop for unparseable item timestamps, the null no-op, and the 400 on a malformed param all behave exactly as documented. No contract artifact regeneration is needed since feeds aren't part of the typed OpenAPI envelope — the scoping call is sound. Nits (4)
🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.
|
Summary
Adds an optional
?since=<ISO-8601>lower bound to the content feeds (/api/v1/feeds/registry,/incidents,/subnets/{netuid}), alongside the existing?tag=filter. It returns only items at or after that instant, so a consumer can poll a focused, incremental slice instead of re-fetching and re-diffing the whole window each time.Closes #2178
Behavior
?since=2026-06-20or?since=2026-06-20T00:00:00Z→ only items withtimestamp >= since.?tag=— e.g.?tag=incident&since=<last_seen>.timestamp; an item whose timestamp can't be parsed is dropped (never leaks past an explicitsince).sinceis a 400 (via the shared feed error envelope), matching the strict param validation used elsewhere in the API.sinceis a no-op (the whole feed) — fully backward-compatible.Scope
src/feeds.mjs— Worker-computed at request time; no schema/contract/artifact change (feeds aren't part of the typed OpenAPI envelope), so nothing to regenerate.filterByTaghelper and thefail(...)error path.Tests (
tests/feeds.test.mjs)filterSinceunit tests: null no-op, at/after the bound, inclusivity of the exact bound, dropping unparseable timestamps.since→ empty-but-valid 200 feed; a pastsincekeeps items and composes with?tag=; a malformedsince→ 400.eslintandprettier --checkclean on both files. Full localvitestrun shows no new failures (only pre-existing Windows-only env issues that pass on Linux CI).