58 lines
2.2 KiB
Plaintext
58 lines
2.2 KiB
Plaintext
Task: todo 19a — notification-gate peek + read-only HTTP API
|
|
Date: 2026-09-01
|
|
|
|
Files created/modified:
|
|
- crates/news-server/src/gate.rs (refactored: shared decide(), new peek(), tests)
|
|
- crates/news-server/src/api/mod.rs (register config + stories modules)
|
|
- crates/news-server/src/api/config.rs (new GET /api/config endpoint + tests)
|
|
- crates/news-server/src/api/stories.rs (new GET /api/stories endpoint)
|
|
- crates/news-server/src/api/stories/tests.rs (new tests)
|
|
- crates/news-server/src/main.rs (wire /api/config and /api/stories routers)
|
|
|
|
Verification commands
|
|
---------------------
|
|
|
|
1. Formatting
|
|
$ cargo fmt --all --check
|
|
Result: clean
|
|
|
|
2. Clippy
|
|
$ cargo clippy --workspace --all-targets -- -D warnings
|
|
Result: clean
|
|
|
|
3. Workspace tests
|
|
$ cargo test --workspace
|
|
Result: passed (83 tests total)
|
|
- news-cli: 2 passed
|
|
- news-core: 18 passed
|
|
- news-ingest: 4 passed
|
|
- news-server: 41 passed (up from 33 in task 18)
|
|
- news-store: 22 passed
|
|
|
|
4. Build
|
|
$ cargo build --workspace --bins
|
|
Result: finished successfully
|
|
|
|
Implementation notes
|
|
--------------------
|
|
- NotificationGate::peek is side-effect-free: clones the token bucket, refills
|
|
in memory only, calls the shared decide() logic, and never writes
|
|
notification_log or decrements budget.tokens.
|
|
- Shared decision logic lives in a private decide() method used by both
|
|
evaluate_with_mode and peek, guaranteeing identical Notify/Digest/Suppress
|
|
outcomes.
|
|
- GET /api/stories queries story_clusters joined to raw_items for the canonical
|
|
item, recomputes relevance (RelevanceScorer) and importance
|
|
(ImportanceScorer) per request, derives percentile ranks from
|
|
percentile_stats over a 7-day window, calls gate.peek, and returns a JSON
|
|
array of story rows with decision/reason/last_notification_lane.
|
|
- GET /api/config returns the current in-memory NewsConfig as JSON.
|
|
- Both endpoints are read-only: no notification_log rows are written and the
|
|
gate token budget is unchanged after a request.
|
|
|
|
Known divergences from plan wording
|
|
-----------------------------------
|
|
- Percentile ranks are computed with a direct SQL query on percentile_stats
|
|
rather than through PercentileTracker, because PercentileTracker exposes no
|
|
rank API and news-store is frozen for this task.
|