|
1 | 1 | # App features |
2 | 2 |
|
3 | | -This RSS feed reader is designed around three themes: making it easy to subscribe to sources, making it easy to keep up with new items, and giving you control so your feed doesn't become overwhelming. |
| 3 | +This RSS feed reader demonstrates the most basic functionality: subscribing to a feed and viewing its content. |
4 | 4 |
|
5 | | -## MVP cutline (deliver first) |
| 5 | +## MVP scope (proof-of-concept version) |
6 | 6 |
|
7 | | -The MVP is the smallest end-to-end slice that proves the core workflow (subscribe → fetch → store → read) with minimal moving parts. |
| 7 | +The MVP demonstrates the minimal viable workflow: subscribe to a feed and see its items. |
8 | 8 |
|
9 | 9 | For the MVP, the app MUST: |
10 | 10 |
|
11 | | -- Let a user add a feed subscription by pasting a feed URL (and remove it later). |
12 | | -- Let a user manually refresh a feed and see a newest-first list of items. |
13 | | -- Let a user open an item's original link. |
14 | | -- Store subscriptions and items locally so they remain available after restart. |
15 | | -- Show clear per-feed errors (fetch/parse/etc.) without crashing. |
| 11 | +- Let a user add a feed subscription by pasting a feed URL |
| 12 | +- Let a user manually refresh the feed to fetch and display items |
| 13 | +- Display items with at least title and link |
| 14 | +- Show a simple error message if the feed fails to load |
16 | 15 |
|
17 | 16 | For the MVP, the app MAY: |
18 | 17 |
|
19 | | -- Render item content as plain text only (title + summary) to reduce early complexity. |
20 | | -- Treat duplicate items as a later hardening step (best-effort is acceptable initially). |
| 18 | +- Store data only in memory (data is lost when the app closes) |
| 19 | +- Render items as plain text only (title + link) |
| 20 | +- Show items in the order they appear in the feed (sorting is optional) |
21 | 21 |
|
22 | | -## MVP behavior rules (defaults) |
| 22 | +## MVP behavior |
23 | 23 |
|
24 | | -To keep behavior predictable and avoid "mystery waiting", the MVP follows a few simple rules: |
| 24 | +The MVP follows simple rules: |
25 | 25 |
|
26 | | -- Refresh is manual: clicking "refresh now" fetches the selected feed immediately. |
27 | | -- The system should not fetch a feed repeatedly in a tight loop. If a feed was refreshed very recently, the backend should throttle additional refresh attempts. |
28 | | -- Network calls must have timeouts so one slow feed does not stall the system. |
| 26 | +- Users manually click "refresh" to fetch feed content |
| 27 | +- No automatic polling or background updates |
| 28 | +- Basic error handling: show "Failed to load feed" if something goes wrong |
| 29 | +- No throttling or rate limiting in MVP (keep it simple) |
29 | 30 |
|
30 | | -In MVP these values are not user-configurable; they can be hard-coded: |
| 31 | +## Post-MVP features |
31 | 32 |
|
32 | | -- Manual refresh throttle per feed: 60 seconds |
33 | | -- HTTP request timeout: 10 seconds |
34 | | -- Max concurrent feed fetches: 5 |
| 33 | +After developing a successful MVP app, the following features could be considered for future versions: |
35 | 34 |
|
36 | | -Background polling and scheduling are intentionally post-MVP. |
| 35 | +### Essential improvements |
37 | 36 |
|
38 | | -## V1 scope (post-MVP, single-user, local-only) |
| 37 | +- **Persistence**: Store subscriptions and items in a database so they remain available after restarting the app |
| 38 | +- **Remove subscriptions**: Allow users to delete feeds |
| 39 | +- **Better item display**: Show item summaries/content, not just titles |
| 40 | +- **Newest-first sorting**: Display items in chronological order |
39 | 41 |
|
40 | | -At a minimum, the app will let a single user subscribe to RSS/Atom feeds, fetch updates, and read items with a clean read/unread workflow. Subscriptions can be managed directly, including removing feeds you no longer want. |
| 42 | +### Additional capabilities |
41 | 43 |
|
42 | | -The app will support adding feeds in two ways: by pasting a feed URL directly, or by pasting a website URL and letting the app discover the site's feed automatically. Users will be able to manually fetch updates with a "refresh now" action, and the backend will also poll feeds in the background on a schedule. |
| 44 | +- **Background polling**: Automatically refresh feeds on a schedule |
| 45 | +- **Read/unread tracking**: Mark items as read and filter by read status |
| 46 | +- **Website-to-feed discovery**: Let users paste a website URL and automatically find its RSS feed |
| 47 | +- **Folders/organization**: Group feeds into categories |
| 48 | +- **Better error handling**: Show specific error messages (feed moved, access denied, malformed XML, etc.) |
| 49 | +- **De-duplication**: Ensure the same item isn't stored multiple times |
| 50 | +- **HTML rendering**: Safely display rich content from feeds |
43 | 51 |
|
44 | | -All data is stored locally. Feeds and feed items are persisted in a local database, so items remain available between sessions and read/unread state is remembered. |
| 52 | +### Practical notes for developers |
45 | 53 |
|
46 | | -The reading experience includes an items list per feed (with newest items first) and an item view that shows the title and summary/content snippet, with an option to open the original article link. Users can mark individual items as read and also mark all items as read for a feed. |
| 54 | +- Use simple in-memory storage for MVP (List/Dictionary in C#) |
| 55 | +- Test with known-good feeds (e.g., <https://devblogs.microsoft.com/dotnet/feed/>) |
| 56 | +- Avoid complex parsing edge cases in MVP - handle basic RSS/Atom formats only |
47 | 57 |
|
48 | | -Reliability and safety are part of the must-haves. The app should handle common real-world feed issues (redirects, timeouts, and malformed XML) without crashing, and it should show clear error messages when something goes wrong (for example, if a feed moved or access is forbidden). The app should avoid storing the same item multiple times (basic de-duplication). Connections should work over HTTPS, and any HTML from feeds should be rendered safely (sanitized) so it cannot cause unsafe behavior in the UI. |
| 58 | +## Additional features (longer-term) |
49 | 59 |
|
50 | | -Finally, the app will support basic organization by allowing feeds to be grouped into folders/collections (for example: News, Tech, Work). |
| 60 | +If the app grows beyond a basic demonstration, these features could be considered: |
51 | 61 |
|
52 | | -### Website-to-feed discovery behavior (post-MVP) |
53 | | - |
54 | | -When a user pastes a website URL (not a direct feed URL), the system should attempt to discover the site's RSS/Atom feed by: |
55 | | - |
56 | | -- Following redirects. |
57 | | -- Looking for standard feed link tags in the HTML (for example `<link rel="alternate">` RSS/Atom entries). |
58 | | - |
59 | | -If discovery fails, the UI should tell the user a feed could not be found and suggest pasting a direct feed URL. |
60 | | - |
61 | | -### De-duplication behavior |
62 | | - |
63 | | -The system should avoid storing the same item multiple times within a feed. For the MVP, best-effort de-duplication is acceptable; stronger guarantees are post-MVP. |
64 | | - |
65 | | -When computing identity: |
66 | | - |
67 | | -- Prefer a stable unique identifier from the feed (GUID/id) when present. |
68 | | -- Otherwise fall back to a reasonable composite (for example link + published date). |
69 | | - |
70 | | -### HTTP caching optimization (optional) |
71 | | - |
72 | | -If a feed returns caching headers (ETag / Last-Modified), the backend may use conditional requests to reduce bandwidth. This is an optimization and not required for the MVP. |
73 | | - |
74 | | -### MVP (build this first) |
75 | | - |
76 | | -For the first working version, we will focus on the MVP cutline described above. |
77 | | - |
78 | | -Sequencing: deliver the manual end-to-end flow first (subscribe → refresh → items). Only once that success-path works reliably should we add discovery, background polling, read/unread, folders, and other "daily use" features. |
79 | | - |
80 | | -For the MVP, we are intentionally keeping scope tight. We will not build accounts, sync, notifications, OPML import/export, advanced filtering rules, background polling, discovery, folders, or read/unread until the core reader experience is stable. |
81 | | - |
82 | | -### MVP definition of done |
83 | | - |
84 | | -The MVP is complete when the following are true: |
85 | | - |
86 | | -- A user can add a feed by URL and remove it later. |
87 | | -- A user can refresh a feed on demand and see newly fetched items. |
88 | | -- Items are stored locally and remain available after restarting the app. |
89 | | -- The UI shows items per feed in newest-first order. |
90 | | -- A user can open the original article link. |
91 | | -- Feed failures show clear errors and do not crash the app. |
92 | | - |
93 | | -The following are explicitly post-MVP (V1) features: |
94 | | - |
95 | | -- Background polling |
96 | | -- Website-to-feed discovery |
97 | | -- Read/unread and mark-all-read |
98 | | -- Folders/collections |
99 | | -- Strong de-duplication guarantees |
100 | | - |
101 | | -## Practical notes for running the MVP (developer-facing) |
102 | | - |
103 | | -- The UI and API run on different localhost ports; that is expected. The UI must be configured with the API base URL. |
104 | | -- Items appear only after a refresh has successfully run at least once for that subscription. |
105 | | -- Feed URLs should be treated as user input: trim whitespace and normalize before storing to avoid hard-to-debug issues (for example, a trailing space). |
106 | | - |
107 | | -### MVP-first safety fallback |
108 | | - |
109 | | -- If HTML sanitization introduces dependency/tooling friction, MVP is allowed to render **plain text only** (title + summary + original link) and defer HTML rendering until the dependency story is stable. |
110 | | - |
111 | | -### Newest-first ordering note (SQLite) |
112 | | - |
113 | | -- Newest-first should be defined as: order by `PublishedAt` (if present) then fallback to the stored `CreatedAt`. |
114 | | -- When implementing with EF Core + SQLite, be mindful of provider translation limitations for timestamp types (especially `DateTimeOffset`) in `ORDER BY`. |
115 | | - |
116 | | -## Practical verification flow (developer-facing) |
117 | | - |
118 | | -Use at least one known-good feed for the first success-path verification before trying stricter or rate-limited sources. |
119 | | - |
120 | | -Example "known-good" feeds: |
121 | | - |
122 | | -- <https://devblogs.microsoft.com/dotnet/feed/> |
123 | | -- <https://devblogs.microsoft.com/visualstudio/feed/> |
124 | | -- <https://devblogs.microsoft.com/powershell/feed/> |
125 | | - |
126 | | -Golden path: |
127 | | - |
128 | | -1. Start the API and UI. |
129 | | -2. Add the feed URL. |
130 | | -3. Click refresh. |
131 | | -4. Verify items appear newest-first. |
132 | | -5. Open an item's original link. |
133 | | - |
134 | | -Some popular sources may block or rate-limit automated clients (commonly returning 403/429 or HTML instead of RSS). Treat those as robustness tests, not the first success-path test. |
135 | | - |
136 | | -## Nice to have features |
137 | | - |
138 | | -Once the core reader experience is stable, we can improve organization and reading flow with tags/labels, saved/starred ("read later") items, and strong keyboard shortcuts. We can also offer multiple layouts (compact list, magazine/cards, etc.) so users can choose how dense the UI feels. |
139 | | - |
140 | | -Search and filtering is another high-impact upgrade. This includes fast searching across titles and summaries (and potentially full text later), along with rule-based filtering such as including/excluding keywords, authors, or categories. Users may want "mute" rules to hide items containing certain terms, and priority/highlighting rules to surface important items. |
141 | | - |
142 | | -We can also improve freshness controls by allowing configurable refresh intervals, a clearer "refresh now" experience, and smarter backoff/throttling when feeds are failing or rate limiting. |
143 | | - |
144 | | -For portability, we can add OPML import/export so users can move subscriptions between readers, and we can detect duplicate feeds and help merge them. |
145 | | - |
146 | | -## Features that could be added later |
147 | | - |
148 | | -If the app grows beyond a single-device local-only reader, multi-device sync can be added so subscriptions, read state, and saved items follow the user across devices. Offline reading can be expanded by explicitly caching items and content for use without connectivity. |
149 | | - |
150 | | -This would also open the door to first-class web and mobile support, where the same account/data can be used from a browser and mobile devices. |
151 | | - |
152 | | -Content quality can also be improved with full-text fetching (readability mode) when feeds only provide excerpts, and better media handling for images and enclosures such as podcasts or YouTube feeds. |
153 | | - |
154 | | -Notifications can be added later for high-priority feeds or keyword matches. |
155 | | - |
156 | | -Integrations and sharing features can come later as well. This includes sharing items to email and chat tools (for example Slack/Teams), sending items to read-later services (for example Pocket/Instapaper/OneNote), and offering quick actions like copying a clean link. It can also include opening links in the system browser or in an in-app browser view. For some workflows, RSS-to-email could be added so selected feeds (or filtered items) are forwarded to an email inbox. |
157 | | - |
158 | | -Finally, as privacy and data ownership features mature, we can explicitly focus on minimal tracking and clear data ownership/export (for example, ensuring users can always export their data in a usable form). |
| 62 | +- **Search and filtering**: Find items by keyword, filter by date or category |
| 63 | +- **OPML import/export**: Transfer subscriptions between feed readers |
| 64 | +- **Advanced organization**: Tags, saved items, priorities |
| 65 | +- **Multi-device sync**: Share subscriptions and read state across devices |
| 66 | +- **Notifications**: Alert on new items from important feeds |
| 67 | +- **Integrations**: Share to email, chat tools, or read-later services |
| 68 | +- **Offline reading**: Cache full article content for offline access |
| 69 | +- **Mobile apps**: Native apps for phones and tablets |
0 commit comments