Skip to content

refactor: architecture cleanup#876

Merged
gildesmarais merged 11 commits intofeat/revamp-frontendfrom
feat/architecture-cleanup
Mar 14, 2026
Merged

refactor: architecture cleanup#876
gildesmarais merged 11 commits intofeat/revamp-frontendfrom
feat/architecture-cleanup

Conversation

@gildesmarais
Copy link
Copy Markdown
Member

@gildesmarais gildesmarais commented Mar 14, 2026

This pull request introduces significant refactoring and modernization of the application's feed handling and code organization. The main focus is on removing legacy feed generation and response code, consolidating require statements, and introducing a more modular and pipeline-based approach for feed rendering. Additionally, there are updates to code style enforcement and minor Makefile improvements.

Feed handling and codebase refactoring:

  • Replaces legacy feed generation modules (FeedGenerator, FeedRenderResult, FeedRequestHandler, FeedRouteHandler) with a new, modular pipeline approach using Feeds::RequestParser, Feeds::Resolver, Feeds::Service, and Http::FeedResponse. This simplifies the flow and improves maintainability. ([[1]](https://github.com/html2rss/html2rss-web/pull/876/files#diff-f965f92b425fb2f75d38b491b2625fe21b8af20b7666217546bce8a42b198ea4L9-R9), [[2]](https://github.com/html2rss/html2rss-web/pull/876/files#diff-6c02f8cc2a159ca1004f707322973a17ac6a1e9d175a7ff9b57713f379e5430bL5-L11), [[3]](https://github.com/html2rss/html2rss-web/pull/876/files#diff-6c02f8cc2a159ca1004f707322973a17ac6a1e9d175a7ff9b57713f379e5430bL31-R79), [[4]](https://github.com/html2rss/html2rss-web/pull/876/files#diff-36ceea7bd7ac01437b1724c96e5d09b8a967b998ab02d579335641243e4ba97aL7-L8), [[5]](https://github.com/html2rss/html2rss-web/pull/876/files#diff-36ceea7bd7ac01437b1724c96e5d09b8a967b998ab02d579335641243e4ba97aL66-L89), [[6]](https://github.com/html2rss/html2rss-web/pull/876/files#diff-bf03b2c81491332291f18492a82a4cdc5e2781fec5b940ba474eca5feddf3c0bL1-L132), [[7]](https://github.com/html2rss/html2rss-web/pull/876/files#diff-cdc5e997b333870fbd4569081d1d01279ce42c7ef625adac9a19adc723838854L1-L9), [[8]](https://github.com/html2rss/html2rss-web/pull/876/files#diff-77fce394c2007e55494c14d0389b82e9af8cf6a0d277a800555b66410ccd7effL1-L65), [[9]](https://github.com/html2rss/html2rss-web/pull/876/files#diff-cb4c35caa77fc501ae7cff186b3d4900a666b9a47f40325f99db46de260f3522L1-L81))
  • Updates the main application file (app.rb) to require all Ruby files in the app/ directory dynamically, reducing manual require statements and improving scalability. ([app.rbL9-R9](https://github.com/html2rss/html2rss-web/pull/876/files#diff-f965f92b425fb2f75d38b491b2625fe21b8af20b7666217546bce8a42b198ea4L9-R9))

App context and dependency management:

  • Removes references to obsolete dependencies (feed_runtime, feed_request_handler) from AppContext and its dependency list, reflecting the new feed handling architecture. ([[1]](https://github.com/html2rss/html2rss-web/pull/876/files#diff-baca189ed4797d9f6a3817e0048ea70ad8523202cabe8c28a5543a753c428f64L20-L21), [[2]](https://github.com/html2rss/html2rss-web/pull/876/files#diff-baca189ed4797d9f6a3817e0048ea70ad8523202cabe8c28a5543a753c428f64L45-R43))

Routing and handler updates:

  • Updates route handling to use the new Http::FeedRouteHandler instead of the legacy FeedRouteHandler, ensuring that all feed requests are processed through the new pipeline. ([app.rbL134-R112](https://github.com/html2rss/html2rss-web/pull/876/files#diff-f965f92b425fb2f75d38b491b2625fe21b8af20b7666217546bce8a42b198ea4L134-R112))

Code style and tooling:

  • Adds and updates RuboCop configuration to enforce a maximum line length, limit example length and expectations in RSpec, and disables the RSpec/DescribeClass cop for flexibility in test descriptions. ([[1]](https://github.com/html2rss/html2rss-web/pull/876/files#diff-4f894049af3375c2bd4e608f546f8d4a0eed95464efcdea850993200db9fef5cR15-R17), [[2]](https://github.com/html2rss/html2rss-web/pull/876/files#diff-4f894049af3375c2bd4e608f546f8d4a0eed95464efcdea850993200db9fef5cR39-R47))
  • Minor Makefile improvement to ensure OpenAPI verification runs the client verification step after regenerating documentation. ([MakefileL92-R94](https://github.com/html2rss/html2rss-web/pull/876/files#diff-76ed074a9305c04054cdebb9e9aad2d818052b07091de1f20cad0bbac34ffb52L92-R94))

@gildesmarais gildesmarais changed the title refactor: architecture and conventions refactor: architecture cleanup Mar 14, 2026
@gildesmarais gildesmarais requested a review from Copilot March 14, 2026 15:20
@gildesmarais gildesmarais marked this pull request as ready for review March 14, 2026 15:23
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the feed-serving architecture by introducing a shared “feed pipeline” (RequestParserResolverService → renderers → HTTP response writer) and removing the legacy feed generation/runtime components. It also updates request specs/OpenAPI artifacts and adds a focused test suite for the new pipeline.

Changes:

  • Introduce new Html2rss::Web::Feeds::* and Html2rss::Web::Http::* modules to unify static + token feed rendering and response handling.
  • Remove the previous legacy feed generator/runtime/handlers and update app wiring (AppContext, routes, and API handler).
  • Expand/adjust RSpec coverage and regenerate OpenAPI + frontend types; tweak RuboCop configuration.

Reviewed changes

Copilot reviewed 43 out of 45 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
spec/support/openapi.rb Normalizes OpenAPI output ordering via deep sort to stabilize diffs.
spec/smoke/docker_spec.rb Removes inline RuboCop disables; smoke spec still validates dockerized API endpoints.
spec/html2rss/web/http/feed_response_spec.rb Adds unit tests for the new HTTP feed response writer (status, cache headers).
spec/html2rss/web/feeds/service_spec.rb Adds unit tests for feed service success/empty/error + caching behavior.
spec/html2rss/web/feeds/rss_renderer_spec.rb Adds unit tests for RSS rendering behavior.
spec/html2rss/web/feeds/resolver_spec.rb Adds unit tests for static/token request resolution and generator input normalization.
spec/html2rss/web/feeds/request_parser_spec.rb Adds unit tests for parsing route inputs into a normalized feed request contract.
spec/html2rss/web/feeds/json_renderer_spec.rb Adds unit tests for JSON feed empty-feed rendering path.
spec/html2rss/web/feeds/cache_spec.rb Adds unit tests for the new in-memory feed result cache.
spec/html2rss/web/feed_runtime_spec.rb Removes specs for the deleted async/stale-refresh runtime.
spec/html2rss/web/feed_accept_header_spec.rb Adds tests for Accept header negotiation edge-cases.
spec/html2rss/web/app_spec.rb Updates app specs to use the new feed pipeline + adds HEAD/service-failure cases.
spec/html2rss/web/app_integration_spec.rb Updates integration specs to stub the new service + renderers and covers negotiation/HEAD.
spec/html2rss/web/api/v1_spec.rb Updates API v1 specs to the new pipeline and adds service-failure json-feed assertions.
spec/html2rss/web/account_manager_spec.rb Removes inline RuboCop disables; behavior assertions unchanged.
frontend/src/api/generated/types.gen.ts Updates generated client types to match regenerated OpenAPI.
docs/api/v1/openapi.yaml Regenerates OpenAPI (mostly ordering/shape updates for feed endpoints).
docs/adr/0006-app-context.md Updates ADR to reflect removal of runtime/feed handler wiring.
app/routes/static.rb Updates comment wording (“legacy” → “static”).
app/http/feed_route_handler.rb New static feed route handler that runs requests through the shared pipeline and emits observability events.
app/http/feed_response.rb New response writer that applies status, content-type, cache headers, and uses renderers.
app/feeds/service.rb New canonical feed service that calls Html2rss.feed, normalizes payload, and caches results.
app/feeds/rss_renderer.rb New RSS renderer for ok/empty/error results.
app/feeds/result.rb New result value object (Data.define) for shared feed pipeline outputs.
app/feeds/response_format.rb New feed representation wrapper around existing FeedResponseFormat.
app/feeds/resolver.rb New resolver for static and token-backed feeds, including auth + URL validation for token feeds.
app/feeds/resolved_source.rb New resolved-source value object (Data.define).
app/feeds/request_parser.rb New request parser for extracting representation/identifier/params into a request contract.
app/feeds/request.rb New request value object (Data.define).
app/feeds/payload.rb New normalized payload value object (Data.define).
app/feeds/json_renderer.rb New JSON Feed renderer that maps RSS objects into JSON Feed output.
app/feeds/cache.rb New synchronous in-memory cache for feed results.
app/feeds.rb Removes legacy “generate_feed” interface.
app/feed_runtime.rb Removes legacy async/stale-refresh runtime cache.
app/feed_route_handler.rb Removes legacy route handler.
app/feed_request_handler.rb Removes legacy request handler/TTL resolver.
app/feed_render_result.rb Removes legacy render-result wrapper.
app/feed_generator.rb Removes legacy generator that mixed rendering + empty-feed handling.
app/auto_source.rb Removes now-obsolete generator wrapper methods.
app/app_context.rb Removes runtime/request handler wiring from the app context.
app/api/v1/feeds/show_feed.rb Refactors token feed rendering to use the shared pipeline + Http::FeedResponse.
app.rb Replaces explicit requires with a glob require and switches static feeds to Http::FeedRouteHandler.
Makefile Ensures openapi-verify also checks the generated frontend client/types.
Gemfile.lock Bumps html2rss/html2rss-configs revisions and updates transitive dependencies.
.rubocop.yml Updates RuboCop rules (line length + stricter RSpec example/expectation limits).

You can also share your feedback on Copilot code review. Take the survey.

Comment thread spec/smoke/docker_spec.rb
Comment on lines +70 to +75
emit_failure(
context,
feed_name,
InternalServerError.new(result.error_message || result.message || HttpError::DEFAULT_MESSAGE)
)
end
Comment thread app/feeds/service.rb
Comment on lines +93 to +101
def error_result(error, resolved_source, cache_key)
Result.new(
status: :error,
payload: nil,
message: HttpError::DEFAULT_MESSAGE,
ttl_seconds: resolved_source.ttl_seconds,
cache_key: cache_key,
error_message: error.message
)
Comment thread app/feeds/cache.rb
Comment on lines +23 to +32
def fetch(key, ttl_seconds:, cacheable: true)
entry = read_entry(key)
return entry.result if fresh?(entry)

result = yield
return result unless cacheable_result?(cacheable, result)

write_entry(key, ttl_seconds, result)
result
end
Comment thread docs/api/v1/openapi.yaml
Comment on lines +199 to +216
'401':
content:
application/feed+json:
schema:
type: string
description: returns JSON Feed-shaped errors when requested by json extension
'403':
content:
application/xml:
schema:
type: string
'401':
description: returns unauthorized for invalid tokens
description: returns forbidden when auto source is disabled
'500':
content:
application/json:
application/feed+json:
schema:
type: object
properties:
success:
type: boolean
error:
type: object
properties:
message:
type: string
code:
type: string
required:
- message
- code
required:
- success
- error
description: Render feed by token
parameters:
- name: token
in: path
required: true
schema:
type: string
type: string
description: returns non-cacheable json feed errors when service generation
@gildesmarais gildesmarais merged commit fc5be2a into feat/revamp-frontend Mar 14, 2026
2 of 6 checks passed
@gildesmarais gildesmarais deleted the feat/architecture-cleanup branch March 14, 2026 15:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants