Skip to content

feat: MAC-stable device identity + label as primary display name - #115

Merged
reloadfast merged 2 commits into
mainfrom
feat/mac-stable-identity-111
Mar 2, 2026
Merged

reloadfast merged 2 commits into
mainfrom
feat/mac-stable-identity-111

Conversation

@reloadfast

Copy link
Copy Markdown
Owner

Summary

Two-part change: devices now keep their identity (and user data) when their DHCP lease changes; labels are used as the primary display name everywhere.

A — MAC-stable identity (backend)

upsert_device() lookup order

  1. MAC-first: if mac_address provided, find existing device by MAC
    • Same IP → normal field update
    • Different IP → update ip_address in-place, preserving label, trusted, device_type
  2. IP fallback: for devices without a visible MAC (routed traffic)
  3. Create: if nothing found

Index

  • ix_devices_mac_address added to model + idempotent CREATE INDEX IF NOT EXISTS in _migrate_schema

RiskOut

  • New field: label: str | None — populated from r.device.label

scan_runner.py

  • device_appeared detail JSON now includes "label" (parity with device_disappeared)

Tests (3 new)

  • New device created correctly
  • Same MAC + new IP → IP updated, label/trusted preserved
  • No MAC → IP fallback works as before

B — Label as primary display name (frontend)

Display priority everywhere: label ?? hostname ?? ip_address

Location Before After
Risk cards & risk list hostname || ip label ?? hostname ?? ip
Device filter dropdown ip (hostname) label ?? ip (hostname)
Device detail page title always IP label ?? hostname ?? ip
Topology nodes already correct ✅
Changes feed already correct ✅

Testing

  • 277 backend tests pass (3 new)
  • 146 frontend tests pass
  • Ruff + ESLint + Prettier clean

Closes #111

reloadfast and others added 2 commits March 2, 2026 15:21
Backend:
- upsert_device() now matches by MAC first; if MAC seen at a new IP,
  updates ip_address while preserving label/trusted/device_type
- Adds ix_devices_mac_address index (model + idempotent migration)
- RiskOut gains label: str | None populated from r.device.label
- device_appeared event detail now includes 'label' (parity with
  device_disappeared which already had it)
- 3 new tests: create new, MAC-first IP update, no-MAC IP fallback

Frontend:
- Risk interface gains label: string | null
- RisksPage: risk cards + device filter use label ?? hostname ?? ip
- DeviceDetailPage: page title uses label ?? hostname ?? ip_address;
  subtitle shows the next level down (hostname or IP as context)

Closes #111

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@reloadfast
reloadfast merged commit 8e22c72 into main Mar 2, 2026
7 checks passed
@reloadfast
reloadfast deleted the feat/mac-stable-identity-111 branch March 2, 2026 14:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: MAC-stable device identity + label as primary display name

1 participant