Added RouteSettingsService to centralize route settings lifecycle - #28965
Conversation
ref https://linear.app/tryghost/issue/HKG-1828/ - the route-settings module previously used module-level variables to hold settingsLoader and routeSettings, with boot.js directly calling routerManager.start() — scattering lifecycle orchestration across files - RouteSettingsService consolidates this: configure() wires storage deps early in boot (so the API surface works even without frontend), and start() wires routing deps and loads settings into the router - this is the first step toward swapping the file-based settings loader for a pluggable store without touching callers - updated test stubs from module getter pattern to direct service method stubs
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughA new Suggested reviewers
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
| Command | Status | Duration | Result |
|---|---|---|---|
nx run ghost:test:ci:integration |
✅ Succeeded | 2m 37s | View ↗ |
nx run ghost:test:integration |
✅ Succeeded | 2m 41s | View ↗ |
nx run ghost:test:legacy |
✅ Succeeded | 2m 52s | View ↗ |
nx run ghost:test:e2e |
✅ Succeeded | 2m 25s | View ↗ |
nx run-many --target=build --projects=tag:publi... |
✅ Succeeded | 1s | View ↗ |
nx run-many -t test:unit -p ghost |
✅ Succeeded | 28s | View ↗ |
nx run-many -t lint -p ghost |
✅ Succeeded | 35s | View ↗ |
nx run @tryghost/admin:build |
✅ Succeeded | 6s | View ↗ |
Additional runs (2) |
✅ Succeeded | ... | View ↗ |
💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗
☁️ Nx Cloud last updated this comment at 2026-06-30 08:19:43 UTC
| return this.settingsLoader.loadSettings(); | ||
| } | ||
|
|
||
| getDefaultHash() { |
There was a problem hiding this comment.
It's worth seeing if you can delete this, pretty sure it's only used in tests, and is unnecessary. Not for this PR tho!
- The service orchestrates more than just settings — it owns the full dynamic routing lifecycle (load settings, start routers, manage hashes). DynamicRoutingService better reflects this responsibility. - Renamed the file from route-settings-service.js to dynamic-routing-service.js to match the class name.

ref https://linear.app/tryghost/issue/HKG-1828/
Summary
Introduces
RouteSettingsServiceas the single orchestrator for route settings lifecycle, replacing scattered module-level variables and directrouterManager.start()calls in boot.js.configure({settingsLoader, routeSettings})— wires storage-layer deps early in boot (duringinitServicesForFrontend), so the API surface (get, setFromFilePath, getCurrentHash) works immediately — even when the frontend is disabledstart({routerManager, urlService})— wires routing deps and loads settings into the router (duringinitDynamicRouting), only when the frontend is enabledloadRouteSettings,getDefaultHash,api.*) now delegate through the service — no caller changes neededThis is the first step toward swapping the file-based settings loader for a pluggable store without touching callers.
Changes
route-settings-service.jsRouteSettingsServiceclass withconfigure(),start(), and delegating API methodsroute-settings/index.jsletvars replaced with a service singleton;init()callsservice.configure(); newservicegetter exposedboot.jsinitDynamicRouting()callsservice.start()instead ofrouterManager.start()directlyapi-vs-frontend.test.js.get(() => () => ...)) to direct service method stubs (.resolves(...))Test plan
test/unit/server/services/route-settings/— 37 tests passtest/unit/server/data/schema/integrity.test.js— 1 test passestest/e2e-api/admin/settings-files.test.js— 2 tests pass (download + upload routes.yaml)test/e2e-api/admin/settings.test.js— 30 tests passtest/legacy/mock-express-style/api-vs-frontend.test.js— 60 tests pass (all frontend routing configs)