* feat(onboarding): add first-run environment checker
Add a preflight that checks whether the host can run Docker deploys before a
deploy fails for an avoidable reason. It verifies the Docker engine is reachable
and permitted, the Compose plugin is present, the compose directory is writable
and mounted at a matching host path, the dashboard is behind TLS, and the
compose volume has disk headroom. Each result that needs attention carries a
specific fix rather than a generic error, and the checks never block: an
operator who knows their setup can continue.
The checks run as the final step of first-boot setup and can be re-run any time
from the Recovery settings tab. A new admin-only endpoint,
GET /api/diagnostics/environment, backs both surfaces.
* fix(onboarding): distinguish unverified path mapping and support parent binds
Treat a container whose self-inspect fails as an unverified path-mapping warning
instead of a false "not containerized" pass, so an unverifiable mapping never
reads as healthy. Resolve the compose directory through the longest-prefix bind
mount and compare the host path it resolves to, so a parent bind such as
-v /opt:/opt correctly covers COMPOSE_DIR=/opt/compose instead of warning that
the directory is not bind-mounted.
* test(e2e): advance the setup wizard past the environment step in loginAs
The first-run setup helper clicked "Initialize console" and immediately waited
for the dashboard, but setup now shows an environment-preflight step before
landing the console. Click "Enter Sencho" to complete onboarding before
asserting the dashboard, so the first test on a fresh instance passes.
* feat(recovery): add safe-mode recovery surface and emergency CLI
Add a read-only Recovery tab under Settings (admin-only) backed by a new
GET /api/diagnostics endpoint reporting app version, database integrity,
encryption-key status, Docker reachability, account and SSO counts, and
non-secret configuration. The endpoint loads without Docker or live metrics
so it stays available when the dashboard does not, requires a genuine admin
session, and builds its config block from a non-secret allowlist so no
credentials are ever exposed.
Expand the emergency command-line toolkit beyond the two-factor reset with
seven host-level commands: reset-password, create-emergency-admin,
clear-sessions, disable-sso, diagnostics, validate-db, and backup-data. Each
prints its result, exits with a meaningful status code, and writes an audit
entry where it changes state.
Document the toolkit in a new operator guide and link it from the recovery
and two-factor pages.
* feat(recovery): download the emergency command reference as a text file
The recovery commands are needed exactly when the dashboard is unreachable,
so reading them only in-app is a chicken-and-egg problem. Add a Download
button to the command-line section that saves the full
`docker compose exec sencho ...` reference as a text file, letting operators
keep it on hand before they need it. Reuses a shared download helper with the
existing diagnostics export.
* fix(recovery): harden diagnostics, backup, and emergency-admin against edge cases
Address findings from an independent review of the recovery toolkit:
- DiagnosticsService now degrades instead of throwing when a queried table is
missing or corrupt: each read falls back and is folded into database.ok, so a
broken database reports "problem detected" rather than failing the whole
endpoint or showing a misleading healthy state with zeroed counts.
- backup-data refuses a destination that resolves to the live database, which
would otherwise report success while producing no separate copy.
- create-emergency-admin now applies the same username rule as the user-
management route, extracted to a shared helper so both stay in sync.
Adds tests for a missing read table, a malformed emergency-admin username, and
the backup same-target rejection.
Add a consolidated Recovery page that answers "what do I do if Sencho
breaks?" in one place. It covers getting back to a working state when
Sencho itself fails, a stack deploy fails, an admin is locked out of
sign-in, Docker is unavailable, or a remote node is unreachable, and
summarizes each path with a link to the authoritative detail page rather
than duplicating it.
The page opens by stating the core safety fact: Sencho keeps its state in
DATA_DIR and COMPOSE_DIR and treats compose files on disk as the source of
truth, so recovery is mostly file-level and running containers are
unaffected by a Sencho outage. It points to Backup & Restore as the
prerequisite.
Link the guide from the README documentation section, the quickstart
"where to next" cards, and the top of the troubleshooting page.