Extend PUT /api/devices/{mac} to accept an optional name and surface an
Edit action from both the device detail screen and the per-row overflow
menu, letting users modify owner, device type, vendor and name without
forgetting and re-registering.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Scanners now call seen() (sighting semantics: stamp last_seen, preserve
registration, conditional vendor/device_type/name writes). update() is
the user-editable mutation (owner, device_type, vendor) wired to
PUT /api/devices/{mac_address}.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Treat an empty->non-empty vendor transition as not a change, so first
deducing a vendor for a device that previously had none no longer raises
a "vendor changed" notification.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Mirror the notifications list paging pattern (offset/limit, fetch one
extra row to detect the next page, First/Prev/Next controls) across the
devices DB query, REST endpoint, API client and UI. Also add a First
page button to the notifications pagination row.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add an mDNS Scanner status card to the Status screen mirroring the ARP
card, and replace the ARP card on the Home screen with a combined Status
card that summarizes both scanners in one line each. Extract the shared
duration formatting helper into utils/duration_formatter.dart.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move select_interface and MAC-resolution logic (resolve_mac_address,
parse_proc_net_arp, probe_mac) out of the device_finders modules into a
single utils::network utility so future scanners can reuse them. Rename
resolve to resolve_mac_address and make parse_proc_net_arp private.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduce a second discovery module that passively listens for mDNS
multicast announcements (224.0.0.251:5353) and feeds discovered devices
into the existing devices/events/notifications pipeline, running in its
own task alongside the ARP scanner.
Since mDNS carries an IP and hostname but no MAC (the device key), the
module resolves IP->MAC via the OS ARP cache with a targeted ARP-probe
fallback. The advertised hostname is stored in a new optional `name`
column on devices (blank for ARP-only devices); the single `update`
writes `name` only when set so ARP rescans never clobber it. Device
names are included in event/notification messages.
Adds a GET /api/mdns_scanner/status endpoint (is_listening, devices_seen,
last_device_seen_seconds_ago) wired into OpenAPI, an optional
[mdns_scanner] config section, and the corresponding Nix module option.
Also aligns the Nix module's stale `timings` section with the current
`arp_scanner` schema.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Swap PagingController/PagedSliverList for explicit page state and
Previous/Next icon buttons below the list
- Fetch pageSize+1 items to detect the last page without a total-count
API; pagination controls are hidden when there is only one page
- Remove unused infinite_scroll_pagination dependency
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
If no interface is set in the config, the ARP scanner now picks the
first non-loopback, up, IPv4-enabled interface automatically. The
setting is optional in the TOML config, sample config, and Nix module.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a responsive Home screen combining the notification list with a
device summary panel and ARP scanner status, visible side-by-side on
wide screens and stacked on narrow ones.
Backend:
- New GET /api/devices/summary endpoint returning registered device
counts and "seen in last 24h / 7 days" breakdowns by registration
status
- Migration 07 adds indexes on (is_registered) and (last_seen,
is_registered) so summary queries use index range scans instead of
full table scans
Frontend:
- HomeScreen replaces NotificationList, embedding notifications,
device summary card, and ArpScannerCard in a LayoutBuilder-driven
two-column (≥700 px) or single-column layout
- ArpScannerCard extracted to a shared public widget reused by both
HomeScreen and StatusScreen
- Nav rail entry renamed to "Home" with home icon
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the old frontend-only `router` type and adds the full set used
by the backend: network_appliance, home_security, home_appliance, watch,
pc, gaming_console. Adds an `apiName` getter to map camelCase enum values
to the snake_case strings the API expects. Updates the unknown device icon
to a question mark.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Loads vendor-device-type.json at compile time (same pattern as mac-vendors-export.json)
and sets device_type when a new device is detected by the ARP scanner.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Centralises all SnackBar calls behind UISnackbars.showError/showSuccess/
showWarning/showInfo, each themed via AppColorExtension. New warning and
info colour tokens added to both themes. Calling any method clears any
visible snackbar before showing the new one.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a context menu to each device card with contextual actions:
- Unregistered devices show a Register option (dialog with owner field
and device type dropdown)
- Registered devices show a Forget option (confirmation dialog)
Also fixes CORS to allow PUT and DELETE methods, adds device type
tooltips on the icon, and renames the "New" filter/badge to
"Not registered".
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add linter commands to CLAUDE.md
- Add clippy to Nix dev shell
- Add TODO.md with project task list
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>