Final cleanup before hardware testing. No behaviour changes; 248 tests green,
clippy clean.
#1 AppError newtype (http-api/src/error.rs) with one IntoResponse mapping
(NotFound→404, Invalid→400, _→500) + From<core::Error>/From<io::Error>.
Converted the clearly-safe handlers (sso_put, unattended_upload,
branding_clear) to `?`; intentionally left handlers with bespoke
status semantics (Invalid→404 on category, 409 on duplicate share /
open upload) explicit so no asserted status changes.
#2 figment-based Config::load (defaults → TOML → env). Keeps the historical
flat OPENPXE_* names (Unraid/entrypoint compatible) AND adds the nested
OPENPXE_SECTION__FIELD form; now covers every field (apply_env had
silently skipped unattended_dir + bind addrs). 6 Jail tests prove
backward-compat. Removed the hand-rolled apply_env.
#3 thiserror 1→2; dropped unused mime/mime_guess/once_cell deps.
#4 Re-evaluated: Duration::from_hours/from_mins are stable on the pinned
1.95 toolchain and clippy prefers them — kept the readable form
(the "unstable" premise didn't hold; MSRV is intentionally 1.95).
#5 insta snapshot of the rendered iPXE menu (version-filtered) + wiremock
coverage of the SAML metadata-URL fetch (200 + non-2xx).
#6 api_status → typed StatusResponse struct (was a 25-key json! blob) with
a full_flow guard test asserting every UI key + the started_at string
shape. Deferred the /api/docs typed conversion (lowest value, highest
churn, zero functional benefit).
#7 pct_encode/xml_escape de-duplicated into openpxe_core::encoding (were
copied across app.rs + the SAML modules). No new crates.
#8 UploadSessions registry → parking_lot::RwLock (sync, never held across
.await); per-session lock stays tokio::Mutex.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Add browser-safe chunked ISO uploads with progress, partial-file visibility, offset validation, and abort cleanup while keeping the legacy multipart endpoint for API clients.
Record host-log validation coverage, keep the queue/status UI copy clean, move release docs to 0.4.1, and tighten the dark theme to a near-black Netbox-style palette.