Address review feedback on #746:
- applyPageSettingsPatch now deep-merges the mapped patch into the stored
JSON: nested unknown keys survive, untouched siblings survive, and extra
client keys are persisted as the schema's additionalProperties allows
- toApiPageSettings normalizes invalid stored values (unknown layout style,
out-of-range or non-integer history days) so responses always satisfy the
OpenAPI enum and bounds
- new PageSettingsPatch (DeepPartial) type lets TS clients send partial
nested updates like { monitor_status_history_days: { mobile: 14 } }
- incidents / include_maintenances and their known sub-objects are now
validated as objects (incidents: 123 returns 400)
- CONTEXT.md wording: the UI and API expose the same settings, surfaces may
name fields differently
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
DeletePage in pagesController already enforces this invariant for the manage
UI (the UI's delete confirm for home was always rejected server-side), and
the public site root assumes the home page exists. Before the ~home token
the v4 DELETE could never reach the home page; now that it can, it returns
400 like the rest of the app.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
What a consumer reads is now exactly what it can address: the list, single,
and write responses all show ~home for the home page instead of an empty
string, so list -> pick -> PATCH round-trips cleanly. Read-modify-write
bodies that send ~home back are treated as no path change. The token moves
to global-constants as HOME_PAGE_TOKEN.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The home page is stored with an empty page_path, which can not appear as a
URL segment, so /api/v4/pages/{page_path} could not address it at all. The
middleware now maps the special segment ~home to the empty-path lookup. The
token can never collide with a real page because the path sanitizer strips
tildes, and tilde is RFC 3986 unreserved so clients never need to encode it
(percent-encoded %7Ehome works too).
Semantics follow the manage UI: PATCH via ~home accepts every field except
page_path, which is fixed for the home page, and DELETE is allowed.
Requests to /api/ paths with no matching route (e.g. GET /api/pages/) now
return a json NOT_FOUND error instead of SvelteKit's html error page.
Documented in the OpenAPI spec (PagePath parameter + PATCH note), ADR 0004,
and the CONTEXT.md glossary.
Fixes#737
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Address review feedback on #744:
- clamp DATABASE_POOL_MAX to >= 1 and DATABASE_POOL_MIN to <= max so bad
env values can not produce a pool that fails every acquire
- healthcheck redis probe checks client status before PING so commands are
not queued indefinitely while redis is down (maxRetriesPerRequest is null)
- probe() clears its timeout timer once the check settles
- error.html shows only the status code, not the error message
- docs: correct SQLite default to kener.sqlite.db to match knexfile
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Address review feedback on #742:
- GetSiteURL now only returns absolute http(s) origins, falling back to the
ORIGIN env var when the stored siteURL is unset or scheme-less, so the v4
url fields honor the OpenAPI format: uri contract
- event status casts now use the response interface types
(MaintenanceEventResponse["status"], MaintenanceEventDetailResponse["event_status"])
so READY is included and the casts can not drift from the API contract
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The public /maintenances/<id> route is keyed by maintenance EVENT id by
default, while /api/v4/maintenances returns maintenance ids. Consumers
that concatenated API ids onto the public path landed on the wrong page
(#723) — an apparent off-by-one title mismatch with no actual data
corruption.
Instead of flipping the route default (which would break every internal
link, subscriber email, and bookmarked URL), v4 API responses now carry
an absolute `url` field built from the configured Site URL:
- Maintenance responses link via /maintenances/<id>?type=maintenance
- Maintenance event responses link via /maintenances/<event_id>
- Incident responses link via /incidents/<id> (parity)
Also updates the OpenAPI spec, records the decision in
docs/adr/0002, and pins Maintenance vs Maintenance Event in CONTEXT.md.
Fixes#723
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The sticky theme-plus bar has no background, and the gap between it and the
fixed nav stays transparent, so page content shows through both sections as
it scrolls. Paint one blurred layer behind both (above content, below nav
z-10 and bar z-20).