Setup wizard: Test connection + Save & configure

Two-step device setup so the admin verifies before committing — and never touches
the device's own web UI.

- POST /api/setup/test (admin-only): healthCheck + checkPreconditions, no save and
  no device change. Returns device health + precondition issues.
- assign (Save) now also runs fixPreconditions (e.g. disables input_link_relay so
  a button press doesn't auto-fire its relay) before configuring the input push.
  Closes a gap where an assigned device could still auto-open. Fails the save with
  no DB row if device configuration fails (no orphan/half-configured rows).
- SetupWizard: wires config fields -> Test connection (health badge + precondition
  warnings) -> Save & configure; editing config resets prior test/save status.

Verified in-browser against the real device: Test -> ● ready + preconditions OK;
Save -> row persisted AND the device's Input Link URL written (push path matches
the saved device id). wiki/first-run-setup updated.
This commit is contained in:
2026-06-14 16:59:36 +02:00
parent 3294f188dd
commit 0375227a16
5 changed files with 212 additions and 36 deletions
+21 -2
View File
@@ -118,13 +118,32 @@ export async function discoverDevices(driverId: string): Promise<DiscoveredDevic
return body.devices;
}
export type DeviceConfig = Record<string, string | number | boolean>;
export interface TestResult {
health: { status: string; detail?: string };
preconditions: {
ok: boolean;
issues: { key: string; message: string; fixable: boolean }[];
};
}
/** Test a device config (reachability + preconditions) without saving. */
export function testDevice(driverId: string, config: DeviceConfig): Promise<TestResult> {
return apiFetch<TestResult>("/api/setup/test", {
method: "POST",
body: JSON.stringify({ driverId, config }),
});
}
export interface AssignBody {
lane: number;
category: DeviceCategory;
driverId: string;
config: Record<string, string | number | boolean>;
config: DeviceConfig;
}
export function assignDevice(body: AssignBody): Promise<unknown> {
/** Save + configure the device (preconditions, push setup), then persist. */
export function assignDevice(body: AssignBody): Promise<{ id: string }> {
return apiFetch("/api/setup/assign", { method: "POST", body: JSON.stringify(body) });
}