3.1 KiB
3.1 KiB
Plan — RSS provider
Executes architecture/rss-provider.md against quality/rss-provider.md.
Two commits: (A) the rssdy crate, (B) wiring (server feature,
clients, docs).
A — The rssdy crate
- A1 —
api::Episode::key_for—blake3(guid)truncated to 16 hex chars. Verifies: G7. - A2 —
api::FeedFetcher—reqwestclient with the timeout, streaming the body while counting bytes somax_feed_bytesrejects before buffering it whole; parse withfeed-rs; map entries toEpisode(guid → key, title, author, published,itunes:durationwhere present, first audio enclosure); skip entries with no enclosure; sort newest first; truncate tolimit. Errors carry no URL. Verifies: G1, G15, G16, G17. - A3 —
slugify+ de-duplication at load and on rename/subscribe. Verifies: G8. - A4 —
parse_pathfor root/feed/episode, rejecting anything else. Verifies: G10. - A5 —
Client::with_api/init— resolve subscriptions with slugs, drop entries without a url (warning), keep the settings for write-back. No feeds still mounts. Verifies: G18. - A6 — Listings —
get_lib_rootlists subscriptions and is creatable;get_lib_node("/rss/<slug>")fetches, replaces the memo, and returns episodes as tracks (queueable, downloadable). Verifies: G3, G9. - A7 — Memo — bounded push/replace, listing-written, read by
get_urls_for_track/get_metadata_for_track/resolve_tracks_into. Verifies: G4, G5. - A8 — Subscription CRUD —
create_lib_node(URL → fetch → name from feed title → add),rename_lib_node,delete_lib_node, andsettings()reserializing the live list. Verifies: G11–G14. - A9 —
rssdy/src/tests.rsover aFakeFeedsfixture backend covering every gate above. - A10 — Commit A: crate tests, clippy, fmt clean.
B — Wiring
- B1 — Server feature
rss— optionaldep:rssdy,all-providersmembership,ALL_PROVIDERS+BUILT_IN_PROVIDERSentries,ProviderToggles.rss,ProviderToggles::all, and the mount registration throughmount_from_config. Verifies: G19. - B2 —
check-featuresgains anrss-alone row. Verifies: G19. - B3 — Clients —
/rssintoMUTABLE_ROOTSincbd-tui/src/rpc.rsandcbd-web/src/state.rs, with their cacheability tests extended. Verifies: G6. - B4 — Docs —
docs/src/providers/rss.md,rssdy/README.md, links fromdocs/src/providers.md,SUMMARY.md,config.md, and the root README (tree + config table). Say plainly that a premium URL is a credential, that listings are never cached, and that bookmarks depend on publisher guids. Verifies: G20. - B5 —
plan/summary.mdentry, then commit B.
Deferred (recorded, not dropped)
- OPML import/export, per-episode played state, background polling, and
artwork (
itunes:image) — the library model has no field for it. - Sharing the episode→
Trackmapping withfyyd; worth extracting only if a third podcast source lands.