This is a full migration guide for the v2 rewrite compared to master.
The branch is a large architecture change, not an incremental patch.
Compared to master, v2 includes:
- Full backend API restructuring under
app/api/v1/*andapp/routes/* - New Astro frontend app under
frontend/(components, hooks, tests, docs) - Security/auth/token/error handling rework
- Dev container standardization and expanded Make workflows
- CI/CD workflow overhaul and smoke-test improvements
Change size from master:
- ~134 files changed
- ~16k+ lines added, ~3.6k lines removed
Treat this migration as a major version upgrade.
You must review:
- Port and probe behavior
- Required environment variables and feature flags
- Docker/CI smoke behavior
- Security defaults and startup validation
You must review:
- Health route and auth expectations
- Feed endpoint auth/forbidden semantics
- Error payload behavior for unexpected failures
You must review:
- New devcontainer-first workflow
- New backend/frontend test split
- New repository layout and module boundaries
- v2 standardizes app runtime on
4000by default. - If your infra assumed
3000, update ingress/proxy or setPORTexplicitly.
Affected surfaces:
config/puma.rbDockerfile- local smoke defaults in
Rakefileandspec/smoke/docker_spec.rb - docs/OpenAPI examples
v2 health routes:
GET /api/v1/health(authenticated)GET /api/v1/health/ready(unauthenticated readiness)GET /api/v1/health/live(unauthenticated liveness)
If your orchestrator cannot set auth headers, use ready/live probes.
- Unexpected internal failures now return a generic client message.
- Internal details are not exposed in API responses.
Client impact:
- Depend on
error.code, not raw exception text.
Semantics are now explicit and consistent:
401 UNAUTHORIZEDfor missing/invalid credentials403 FORBIDDENonly for authenticated policy violations- example: auto source disabled
- example: URL not allowed for account
Policy is environment-sensitive:
- Development: enabled unless
AUTO_SOURCE_ENABLED=false - Non-development: enabled only when
AUTO_SOURCE_ENABLED=true
CI/smoke behavior:
SMOKE_AUTO_SOURCE_ENABLEDmust be set to match intended runtime mode.
Removed legacy ERB/helpers/routes stack in favor of API + Astro frontend:
- removed
views/*legacy pages - removed old
helpers/*and legacyroutes/auto_source.rb - frontend assets now built from
frontend/
If you customized old server-rendered pages, port those customizations into Astro.
New module boundaries:
- API contract and handlers:
app/api/v1/* - Route composition:
app/routes/api_v1.rb,app/routes/static.rb - Error policy:
app/error_responder.rb - Env/feature policy:
app/environment_validator.rb - TTL policy:
app/cache_ttl.rb - Feed command split:
app/api/v1/feeds/create_feed.rb,show_feed.rb
Security/auth stack:
- token/account management via
app/auth.rb,app/feed_token.rb,app/account_manager.rb - URL allow-list validation in
app/url_validator.rb - structured security logging in
app/security_logger.rb
New Astro app and docs site under frontend/:
- UI:
frontend/src/components/* - hooks:
frontend/src/hooks/* - docs content:
frontend/src/content/docs/* - tests: Vitest unit + contract suites
Dev container is now first-class:
.devcontainer/*added/updated- Make targets expanded (
make setup,make dev,make test,make ready, etc.)
- Legacy workflow replaced by
.github/workflows/ci.yml - Distinct Ruby and frontend jobs
- Docker smoke coverage now runs in matrix mode for auto-source enabled/disabled
HTML2RSS_SECRET_KEY(required in production)PORT(defaults to4000in v2)AUTO_SOURCE_ENABLED(intentional per-environment behavior)HEALTH_CHECK_TOKENfor authenticated health checks
v2 startup performs stronger production checks:
- secret key presence/strength checks
- account token strength validation
Invalid production config now fails fast at boot.
Primary API doc:
docs/api/v1/openapi.yaml
v2 adds contract-focused specs and smoke tests, but because this rewrite is broad, re-check any custom client assumptions against actual runtime behavior before rollout.
v2 test layers:
- Ruby API request/integration specs
- Frontend unit/contract tests
- Docker smoke tests (now mode-aware with
SMOKE_AUTO_SOURCE_ENABLED)
Pre-commit gate:
make ready(RuboCop + Ruby RSpec)
-
Inventory integrations
- health probes
- API clients
- proxy/routing assumptions
-
Prepare environment
- set
HTML2RSS_SECRET_KEY - set
AUTO_SOURCE_ENABLEDintentionally - verify
PORTassumptions
- set
-
Update probe config
- move readiness/liveness to
/api/v1/health/readyand/api/v1/health/live - keep
/api/v1/healthfor authenticated deep checks
- move readiness/liveness to
-
Update client error handling
- key off
error.code - avoid depending on internal exception strings
- key off
-
Run smoke in both feature modes
SMOKE_AUTO_SOURCE_ENABLED=falseSMOKE_AUTO_SOURCE_ENABLED=true
-
Canary rollout
- monitor auth failures, forbidden rates, feed creation success
- verify probe behavior and cache headers
Because v2 is a broad rewrite, rollback should be version-level (image/tag rollback), not partial cherry-picks.
Keep previous deployment artifacts available until:
- probes are stable
- feed creation/retrieval metrics are healthy
- no client-contract regressions are observed
- App reachable on expected port (
4000unless overridden) - Readiness/liveness probes green
- Authenticated health endpoint works with token
- Feed creation success path works when auto source enabled
- Correct forbidden behavior when auto source disabled
- API clients handle
error.codecontract correctly - Frontend build and API integration flows verified