Initial commit -- did OMO do a good job?
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
Task 16 — daily digest (news-server/src/notify/digest.rs)
|
||||
==========================================================
|
||||
|
||||
What was built
|
||||
--------------
|
||||
- NEW crates/news-server/src/notify/digest.rs
|
||||
- pub async fn build_and_send_digest(pool, scorer, ntfy, config, now)
|
||||
- Due-time gate: today's 07:00 in now.timezone(); before that -> Ok(()) debug log.
|
||||
- Idempotency gate: SELECT COUNT(*) FROM notification_log WHERE lane = 'digest' AND created_at >= ?1 (today's 07:00 UTC RFC3339).
|
||||
- Queries story_clusters created in the last 24h joined to canonical raw_items.
|
||||
- Scores canonical items, skips blocklisted (NEG_INFINITY) and opinion pieces when notify_opinions = false.
|
||||
- Band check: score in [p75, p90) of the trailing-7-day relevance distribution via PercentileTracker.
|
||||
- Sends one ntfy request via NtfyPublisher::publish_digest with Title, Priority: 2, Markdown: yes, Tags: newspaper, bullet-list body.
|
||||
- Records one notification_log row with Uuid::nil(), lane='digest', source_count_at_notify=<story count>, dry_run=0.
|
||||
- No token-bucket interaction.
|
||||
- MODIFIED crates/news-server/src/notify/ntfy.rs
|
||||
- Added NotifyError::{Store, Sql, Server} #[from] variants.
|
||||
- Added pub async fn publish_digest(title, body_markdown).
|
||||
- Factored retry-once logic into private send_with_retry(Fn() -> RequestBuilder) so publish() behavior/tests are unchanged.
|
||||
- MODIFIED crates/news-server/src/notify/mod.rs
|
||||
- Added pub mod digest.
|
||||
|
||||
Test names added
|
||||
----------------
|
||||
notify::digest::tests::
|
||||
- skips_when_no_eligible_stories
|
||||
- sends_digest_with_in_band_stories
|
||||
- second_call_same_day_is_no_op
|
||||
- before_seven_am_is_no_op
|
||||
- excludes_opinion_when_notify_opinions_false
|
||||
- includes_opinion_when_notify_opinions_true
|
||||
|
||||
Opinion flagging representation
|
||||
-------------------------------
|
||||
- news-core/src/model.rs: RawItem.kind is ItemKind::{News, Opinion}.
|
||||
- news-store/migrations/0001_init.sql: raw_items.kind TEXT NOT NULL stores "news" or "opinion".
|
||||
- The digest filters on the joined canonical raw_items.kind column; no new migration or column was needed.
|
||||
|
||||
Verification
|
||||
============
|
||||
|
||||
$ cargo test -p news-server
|
||||
...
|
||||
running 26 tests
|
||||
...
|
||||
test notify::digest::tests::skips_when_no_eligible_stories ... ok
|
||||
test notify::digest::tests::excludes_opinion_when_notify_opinions_false ... ok
|
||||
test notify::digest::tests::includes_opinion_when_notify_opinions_true ... ok
|
||||
test notify::digest::tests::sends_digest_with_in_band_stories ... ok
|
||||
test notify::digest::tests::before_seven_am_is_no_op ... ok
|
||||
test notify::digest::tests::second_call_same_day_is_no_op ... ok
|
||||
...
|
||||
test result: ok. 26 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
|
||||
|
||||
$ cargo fmt --all --check
|
||||
(no output, exit 0)
|
||||
|
||||
$ cargo clippy --workspace --all-targets -- -D warnings
|
||||
Checking news-server v0.1.0 (/home/connor/docs/projects/news/crates/news-server)
|
||||
Finished dev profile [unoptimized + debuginfo] target(s) in 5.29s
|
||||
|
||||
Captured happy-test ntfy request body
|
||||
-------------------------------------
|
||||
(temporarily instrumented sends_digest_with_in_band_stories to eprintln the wiremock request body, then removed the instrumentation)
|
||||
|
||||
CAPTURED_DIGEST_BODY:
|
||||
- [Story 2](https://example.test/2)
|
||||
- [Story 1](https://example.test/1)
|
||||
- [Story 0](https://example.test/0)
|
||||
|
||||
The single POST to /news-triage carried:
|
||||
Title: Daily digest: 3 stories
|
||||
Priority: 2
|
||||
Markdown: yes
|
||||
Tags: newspaper
|
||||
body as shown above.
|
||||
Reference in New Issue
Block a user