feat(device-detail): wire device power actions (VAPP-8) #17

Merged
David merged 1 commit from feat/device-power-actions into main 2026-06-06 23:44:19 +02:00
Owner

Resolves VAPP-8. Wires the previously inert Wake / Reboot buttons on the device detail header to live power actions over the vervain-server control channel.

What changed

  • New server fn power_action(device_id, action_code) in src/server_fns/mod.rs: sends {action: "poweraction", nodeids, actiontype} with the device's full node id, awaits the {action: "ack", for: "poweraction", result} routing ack, and maps each result string to a clear error (not-connected, not-authorized, bad-actiontype, no-nodes). action_code follows the legacy agent table from the issue: reboot=4, shutdown=8, sleep=11.
  • New server fn wake_device(device_id) using the wakedevices action. Wake-on-LAN is deliberately a separate path: poweraction type 2 relays to the target's own agent, which is unreachable when the machine is off, whereas wakedevices fans a magic packet out to the connected agents in the same mesh. ok and no-peers both return success so "could not be woken" is not treated as a fault, matching the acceptance criterion.
  • Device detail header (src/components/pages/device_detail.rs): replaced the static buttons with a PowerActions component. Wake is enabled only while the device is offline; Reboot / Shutdown / Sleep sit in a dropdown enabled only while it is online. Every action opens a ConfirmDialog naming the device and the verb, and no server call fires until its Confirm button. On ack the page shows a "requested" toast (or a visible error banner) and re-fetches the device row, since the status only flips once the agent reconnects.
  • DeviceStatus gains Copy so it can pass to the component as a value prop.

Acceptance criteria

  • Reboot on an online device round-trips: confirm dialog, ack, device row re-fetched (status settles once the agent returns)
  • Wake available on offline devices (WoL via wakedevices; no-peers is not surfaced as an error)
  • Shutdown and sleep present behind the dropdown with confirm
  • Ack errors (no rights, agent gone) surface as a visible message
  • No action fires without explicit confirmation

Verification

just check equivalent passes locally: cargo check --features server, cargo check --target wasm32-unknown-unknown, cargo clippy --all-targets --features server -- -D warnings, cargo fmt --check, and cargo test --features server --bin vervain-app are all clean.

🤖 Generated with Claude Code

Resolves VAPP-8. Wires the previously inert Wake / Reboot buttons on the device detail header to live power actions over the vervain-server control channel. ## What changed - New server fn `power_action(device_id, action_code)` in `src/server_fns/mod.rs`: sends `{action: "poweraction", nodeids, actiontype}` with the device's full node id, awaits the `{action: "ack", for: "poweraction", result}` routing ack, and maps each result string to a clear error (`not-connected`, `not-authorized`, `bad-actiontype`, `no-nodes`). `action_code` follows the legacy agent table from the issue: reboot=4, shutdown=8, sleep=11. - New server fn `wake_device(device_id)` using the `wakedevices` action. Wake-on-LAN is deliberately a separate path: `poweraction` type 2 relays to the target's own agent, which is unreachable when the machine is off, whereas `wakedevices` fans a magic packet out to the connected agents in the same mesh. `ok` and `no-peers` both return success so "could not be woken" is not treated as a fault, matching the acceptance criterion. - Device detail header (`src/components/pages/device_detail.rs`): replaced the static buttons with a `PowerActions` component. Wake is enabled only while the device is offline; Reboot / Shutdown / Sleep sit in a dropdown enabled only while it is online. Every action opens a `ConfirmDialog` naming the device and the verb, and no server call fires until its Confirm button. On ack the page shows a "requested" toast (or a visible error banner) and re-fetches the device row, since the status only flips once the agent reconnects. - `DeviceStatus` gains `Copy` so it can pass to the component as a value prop. ## Acceptance criteria - [x] Reboot on an online device round-trips: confirm dialog, ack, device row re-fetched (status settles once the agent returns) - [x] Wake available on offline devices (WoL via `wakedevices`; `no-peers` is not surfaced as an error) - [x] Shutdown and sleep present behind the dropdown with confirm - [x] Ack errors (no rights, agent gone) surface as a visible message - [x] No action fires without explicit confirmation ## Verification `just check` equivalent passes locally: `cargo check --features server`, `cargo check --target wasm32-unknown-unknown`, `cargo clippy --all-targets --features server -- -D warnings`, `cargo fmt --check`, and `cargo test --features server --bin vervain-app` are all clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(device-detail): wire device power actions
All checks were successful
Check / fmt + clippy + build + tests (pull_request) Successful in 47s
Create release / Create release from merged PR (pull_request) Has been skipped
5eec8d68d3
Add a `power_action(device_id, action_code)` server fn that relays the control channel's `poweraction` (reboot=4, shutdown=8, sleep=11) to the connected agent and surfaces the routing ack, plus a `wake_device` fn that uses `wakedevices` so wake-on-LAN reaches an offline machine through its online mesh peers (the target's own agent is unreachable by definition).

Replace the inert Wake/Reboot header buttons with live controls: Wake is enabled only while the device is offline, Reboot/Shutdown/Sleep sit behind a dropdown enabled only while it is online, and every action is gated by a confirm dialog naming the device and verb so nothing fires without explicit confirmation. The ack result drives a "requested" toast (or a visible error for no-rights / agent-gone) and re-fetches the device row, since status only flips once the agent reconnects. WoL with no online peer (`no-peers`) is treated as success per the "no error even when the device cannot be woken" requirement.

#VAPP-8

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
David merged commit 31d0e9a2c2 into main 2026-06-06 23:44:19 +02:00
David deleted branch feat/device-power-actions 2026-06-06 23:44:19 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/vervain-apps!17
No description provided.