fix: add pagination cursor and totalCount to cyber threats response#237
fix: add pagination cursor and totalCount to cyber threats response#237haosenwang1018 wants to merge 3 commits into
Conversation
The previous 0.5° rounding (~50km radius) merged distinct events in dense urban areas (e.g. Manhattan vs Brooklyn protests on the same day). Reducing to 0.1° (~10km) preserves neighborhood-level granularity while still deduplicating true duplicates. Fixes koala73#204 Signed-off-by: haosenwang1018 <[email protected]>
Replace Math.random() with a djb2 hash seeded by the threat ID, so the same threat always appears at the same coordinates. This prevents 'jumping' markers on the map when the same data is re-fetched. Fixes koala73#203 Signed-off-by: haosenwang1018 <[email protected]>
The handler previously returned pagination: undefined, making it impossible for clients to paginate. Now parses cursor as an offset, returns totalCount of filtered results, and nextCursor for the next page (empty string when no more results). Fixes koala73#202 Signed-off-by: haosenwang1018 <[email protected]>
|
@haosenwang1018 is attempting to deploy a commit to the Elie Team on Vercel. A member of the Team first needs to authorize it. |
|
Thanks again @haosenwang1018 much appreciated! Pls see below, the core pagination is on point - but it introduces a few other issues that you should handle PR Review: fix: add pagination cursor and totalCount to cyber threats responsePR #237 by haosenwang1018 | 3 commits | +30/-11 across 3 files SummaryThe PR addresses the
Issues Found1. Removing Redis caching is a significant performance regression (High)The PR removes the entire Redis caching layer ( The caching was likely removed because the old cache key didn't account for pagination offsets. The correct fix is to cache the full sorted/filtered result set (keyed by filters only, pre-pagination) and apply const cacheKey = `${REDIS_CACHE_KEY}:${req.timeRange?.start || 0}:${req.type || ''}:...`;
const cached = await getCachedJson(cacheKey) as CyberThreat[] | null;
if (cached?.length) {
const paged = cached.slice(offset, offset + pageSize);
return { threats: paged, pagination: { totalCount: cached.length, nextCursor: ... } };
}
// ... fetch, process, cache full result set, then paginate ...2. Negative cursor offset not guarded (Medium) —
|
|
CI failures. Closing per policy. |
Fixes 5 findings raised by the multi-agent review of PR #3247: - #234 P2: Drop dead `deps.log` shim from `deduplicateStories` — caller now owns the log line so the param rotted (no test used it post-#3247). Removed from JSDoc + signature logic. - #236 P3: Add defensive warn when `winningIdx === undefined` during sidecar `embeddingByHash` population. Shouldn't fire with the current `materializeCluster` contract, but catches a future refactor where a synthesised rep would silently skip topic grouping. - #237 P3: Skip `groupTopicsPostDedup` when `cfg.mode === 'jaccard'` — the kill-switch path returns an empty `embeddingByHash`, and running the secondary pass on it would log a noisy "missing embedding" warn every tick. Gate the call site; passthrough primary order. - #240a P3: Remove dead `top ?? []` fallback after `!Array.isArray(top)` already handled the falsy case. Replaced with an explicit Array check for the rare "falsy but also not-array" input (defence-in-depth). - #240b P3: Delete two redundant test blocks — the `titleHashHex tiebreak` 2-rep fixture (permutation-invariance at 15-rep scale already covers this invariant) and the `caller log-line format (regex splice)` describe block (the regex lives in seed-digest-notifications.mjs, not brief-dedup; the full-flow envelope-cleanliness test exercises the caller end-to-end). Deferred to follow-up: #235 (structured logParts vs regex splice), #238 (plumb cfg to avoid double env-read), #239 (repo-wide env .trim pattern). Tests: 5910 pass (was 5913; -3 redundant tests removed). typecheck, typecheck:api, biome all clean.
Problem
listCyberThreatsreturnspagination: undefined. Clients cannot implement 'next page' semantics — there's no cursor or total count to know if more results exist.Fix
req.pagination.cursoras an offset into the sorted/filtered resultstotalCount(total filtered results before paging)nextCursor(offset for next page, empty string when exhausted)slice(0, pageSize)before filtering — now applied after all filtersRef: PR #106 re-review (NEW-7)
Fixes #202