Closes#113, #102.
#113 — RouterBOOT as a follow-on rollout step
Firmware rollouts upgraded RouterOS and stopped, leaving the bootloader to be
done by hand on every device — the exact task staged rollouts exist to remove.
The data was already collected and the collector already had the two methods; the
orchestrator simply never called them.
An optional "Then RouterBOOT" step now runs per device after the RouterOS upgrade
has been verified, rides out the second reboot, and confirms the firmware version
actually moved.
Ordering is deliberate: the bootloader ships inside the RouterOS package, so
upgrading it first would apply the old one. It runs only once the OS half is
confirmed good, and off by default, because it is a second flash and a second
reboot per device.
A device with nothing pending is a success rather than a failure — most of a fleet
is already current, and treating "nothing to do" as an error would halt rollouts
for no reason. When RouterBOOT does fail after a successful RouterOS upgrade the
error says so explicitly, rather than reporting the device as simply failed and
sending someone to re-run an upgrade it already has.
#102 — snooze an item in "Things to handle"
Insights are recomputed from live state on every request and have no id, so a
dismissal is keyed on a fingerprint of category, target and title. That survives a
reworded title without swallowing a different device's version of the same issue.
Dismissals expire, defaulting to 24 hours. "Handled" and "not now" look identical
to the code, and an item that is genuinely resolved stops being generated anyway —
so a permanent dismissal could only ever hide something still true. Expired rows
are cleared on read, so a lapse needs no scheduled job, and the panel reports how
many items are currently hidden rather than quietly shrinking.
Verified against the fleet: snoozing took the list from 8 items to 7 with
dismissedCount 1, and removing the dismissal restored it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- New GET /api/firmware/changelog/:version proxies MikroTik's official
per-version release notes (download.mikrotik.com/routeros/<ver>/CHANGELOG)
with strict version validation and process-lifetime caching
- ChangelogModal: "What's new in X.Y.Z" on the device Config tab's
update box and on the Firmware page's latest-version cells opens the
changelog in-app, with an external mikrotik.com link and graceful
fallback when the CDN is unreachable
- Security posture: a pending RouterOS update is now a medium-severity
finding and a pending RouterBOOT upgrade a low-severity one; titles
are version-free so Common Findings aggregates the fleet into one row
- chore(deps): npm audit fix bumps morgan (GHSA-4vj7-5mj6-jm8m); both
workspaces audit clean
Validation: backend tsc/lint/92 tests, frontend tsc/lint/build/11 tests,
endpoint tested (valid/invalid/unknown versions), browser-verified on
Firmware page, device Config tab, Security Center, and device Security
tab; security review of the diff found no findings.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Guest WiFi (Hotspot): one-click captive-portal wizard that creates the guest
SSID (virtual AP per radio), VLAN/bridge segregation + L3 VLAN interface, pool,
DHCP, portal, rate-limited guest profile, and masquerade; vouchers with limits +
printable sheets; live guest sessions; walled garden.
Network intelligence: per-client device fingerprinting (vendor/hostname →
category) with a persisted per-client override on the detail page; rogue/neighbor
AP detection from stored AP scans (evil-twin flagging); Mist-style anomaly
insights (client-count/CPU vs same-hour 14-day baseline + error bursts) in the
Operations engine.
Firmware orchestration: staged wave-based RouterOS rollouts (canary first) with
pre-upgrade backup, reboot-ride-out, version verification, halt-on-failure, and
scheduling; live per-device progress + cancel.
Platform & automation: scoped API tokens (mtm_, read/write, hashed at rest,
Bearer auth in requireAuth); outbound webhooks (12 events, HMAC-signed) fired
from the alert pipeline + firmware orchestrator; scheduled email reports.
api-ssl: RouterOSClient negotiates TLS on port 8729 and accepts RouterOS's
default self-signed certs (rejectUnauthorized:false), so SSL-secured API devices
connect without manual cert trust. Fixes#57.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>