refactor: Extract shared feed assembly from the RSS and Atom handlers #41

Closed
opened 2026-07-03 00:09:56 +00:00 by rosa · 1 comment
Owner

Problem

get_user_rss (crates/web/src/handlers/users.rs:511-579) and get_user_atom (:581-655) duplicate the whole feed-assembly pipeline: fetch user by name, fetch published posts, hand-format the /u/{user}/{slug} permalink, join against base_url, and unwrap published_at with the same "post from find_posts_published_by_user did not have a published_at date" error. Only the final rendering (rss vs atom_syndication builders) differs.

Proposal

Extract the shared assembly into one step that produces format-agnostic feed data, e.g.:

struct FeedEntry { title: String, url: Url, published_at: DateTime<Utc>, html: String }
struct FeedData { user: User, blog_url: Url, entries: Vec<FeedEntry> }

Each handler then maps FeedData into its format-specific builders. The published_at invariant gets asserted in one place, and permalink construction drops to a single site (or calls the shared permalinks module if that lands first).

Depends usefully on (but is not blocked by) the permalinks-module issue.

## Problem `get_user_rss` (`crates/web/src/handlers/users.rs:511-579`) and `get_user_atom` (`:581-655`) duplicate the whole feed-assembly pipeline: fetch user by name, fetch published posts, hand-format the `/u/{user}/{slug}` permalink, join against `base_url`, and unwrap `published_at` with the same "post from find_posts_published_by_user did not have a published_at date" error. Only the final rendering (rss vs atom_syndication builders) differs. ## Proposal Extract the shared assembly into one step that produces format-agnostic feed data, e.g.: ```rust struct FeedEntry { title: String, url: Url, published_at: DateTime<Utc>, html: String } struct FeedData { user: User, blog_url: Url, entries: Vec<FeedEntry> } ``` Each handler then maps `FeedData` into its format-specific builders. The `published_at` invariant gets asserted in one place, and permalink construction drops to a single site (or calls the shared permalinks module if that lands first). ## Related Depends usefully on (but is not blocked by) the permalinks-module issue.
Author
Owner

This was generated by AI during triage.

Superseded by #101, which describes the same refactor against the current code.

This issue's description has gone stale. Since it was filed, intervening domain work has already resolved most of the duplication it called out:

  • The "fetch user by name, fetch published posts" duplication is now a single resolve_profile(&username, None) call shared by both handlers.
  • The published_at unwrap invariant ("post ... did not have a published_at date") is gone — the handlers call post.published_at() directly, with the invariant enforced in the domain layer.
  • The permalinks-module dependency this issue noted has landed; both handlers already build links via the shared permalinks:: helpers.

What remains is the narrower duplication #101 captures accurately (the per-post loop, blog_url construction, and content-type header shared by the RSS and Atom handlers). Consolidating there. Closing this as a duplicate.

> *This was generated by AI during triage.* Superseded by #101, which describes the same refactor against the current code. This issue's description has gone stale. Since it was filed, intervening domain work has already resolved most of the duplication it called out: - The "fetch user by name, fetch published posts" duplication is now a single `resolve_profile(&username, None)` call shared by both handlers. - The `published_at` unwrap invariant ("post ... did not have a published_at date") is gone — the handlers call `post.published_at()` directly, with the invariant enforced in the domain layer. - The permalinks-module dependency this issue noted has landed; both handlers already build links via the shared `permalinks::` helpers. What remains is the narrower duplication #101 captures accurately (the per-post loop, `blog_url` construction, and content-type header shared by the RSS and Atom handlers). Consolidating there. Closing this as a duplicate.
rosa closed this issue 2026-07-04 19:10:30 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
rosa/vernier#41
No description provided.