On the Cutsheet page, under Patch panels (admins only):
Pick a panel port, press Start, and unplug that cord at the panel.
The page polls /api/cutsheet/live-ports every 3 s. The endpoint is admin-only and reads every switch port's state straight from UniFi, with a 2 s cache and a reused client. The monitor's cached state is minutes old, so it can't be used.
When exactly one port drops, the page shows the port with a Record cable button, which pre-fills switch port ↔ panel port (front). If that switch port is already documented, it shows the existing cable instead.
When the cord is plugged back in, the page confirms the link is back.
Cases where tracing can't give an answer are explained rather than guessed:
Several ports drop at once.
Nothing drops within 3 minutes, for example a jack with nothing plugged in at the far end.
Mismatch alerts
Each poll, the monitor runs the same check as the page:
Each mismatched installed run keeps one cable_mismatch event (severity warning) on its switch. A mismatch means a wrong neighbor, no link, a missing port or a port conflict. The event shows on the dashboard and the switch's page straight away, and resolves itself once fixed.
A run through a panel is reported once, under the cable plugged into the switch.
A mismatch opens a P4 ticket after cutsheet.mismatch_ticket_hours, which defaults to 24; 0 means never. Suppressing the switch or the port stops the ticket.
An empty cutsheet does nothing, and the check can't break the monitor cycle.
Fix
Buttons with the hidden attribute were still displayed, because the button styles set display. This left a Delete button on the new-cable form; clicking it only hit a harmless 404.
Testing
New tests: problems are de-duplicated per run, and only installed runs are reported. Monitor tests cover an event straight away, a ticket after a day of polls, no second ticket, suppression, 0 hours, and resolving once fixed. API tests cover live ports: shape, caching, a 502 without caching, and admin-only.
Full suite: 290 tests, plus flake8, bandit -ll and eslint (no errors), all pass.
Preview: trace mode was run in a local preview against a fake controller that drops one port. It detected the drop and then the re-plug, could restart, and raised no page errors.
Closes #12 (part 2; part 1 was #18).
## Trace a cord
On the Cutsheet page, under Patch panels (admins only):
1. Pick a panel port, press **Start**, and unplug that cord at the panel.
2. The page polls `/api/cutsheet/live-ports` every 3 s. The endpoint is admin-only and reads every switch port's state straight from UniFi, with a 2 s cache and a reused client. The monitor's cached state is minutes old, so it can't be used.
3. When exactly one port drops, the page shows the port with a **Record cable** button, which pre-fills switch port ↔ panel port (front). If that switch port is already documented, it shows the existing cable instead.
4. When the cord is plugged back in, the page confirms the link is back.
Cases where tracing can't give an answer are explained rather than guessed:
- Several ports drop at once.
- Nothing drops within 3 minutes, for example a jack with nothing plugged in at the far end.

## Mismatch alerts
Each poll, the monitor runs the same check as the page:
- Each mismatched **installed** run keeps one `cable_mismatch` event (severity warning) on its switch. A mismatch means a wrong neighbor, no link, a missing port or a port conflict. The event shows on the dashboard and the switch's page straight away, and resolves itself once fixed.
- A run through a panel is reported once, under the cable plugged into the switch.
- A mismatch opens a **P4 ticket** after `cutsheet.mismatch_ticket_hours`, which defaults to 24; `0` means never. Suppressing the switch or the port stops the ticket.
- An empty cutsheet does nothing, and the check can't break the monitor cycle.
## Fix
Buttons with the `hidden` attribute were still displayed, because the button styles set `display`. This left a Delete button on the new-cable form; clicking it only hit a harmless 404.
## Testing
- **New tests:** problems are de-duplicated per run, and only installed runs are reported. Monitor tests cover an event straight away, a ticket after a day of polls, no second ticket, suppression, `0` hours, and resolving once fixed. API tests cover live ports: shape, caching, a 502 without caching, and admin-only.
- **Full suite:** 290 tests, plus `flake8`, `bandit -ll` and `eslint` (no errors), all pass.
- **Preview:** trace mode was run in a local preview against a fake controller that drops one port. It detected the drop and then the re-plug, could restart, and raised no page errors.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Trace a cord: pick a panel port, press Start, and unplug the cord at the
panel. The page polls a new admin-only endpoint that reads every switch
port's state from UniFi (cached 2 s), shows the one port that dropped
with a button to record the cable, and confirms when it's plugged back
in. Several ports dropping at once, or none within 3 minutes, is
explained rather than guessed at.
Mismatch alerts: the monitor runs the cutsheet check every poll. Each
mismatched installed run (wrong neighbor, no link, missing port, port
conflict) keeps one cable_mismatch event on its switch, resolved when
fixed, and opens a P4 ticket after cutsheet.mismatch_ticket_hours
(default 24, 0 never). Suppressing the switch or port stops the ticket.
Also fixes buttons with the hidden attribute still showing, which left a
Delete button on the new-cable form.
Closes#12
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #12 (part 2; part 1 was #18).
Trace a cord
On the Cutsheet page, under Patch panels (admins only):
/api/cutsheet/live-portsevery 3 s. The endpoint is admin-only and reads every switch port's state straight from UniFi, with a 2 s cache and a reused client. The monitor's cached state is minutes old, so it can't be used.Cases where tracing can't give an answer are explained rather than guessed:
Mismatch alerts
Each poll, the monitor runs the same check as the page:
cable_mismatchevent (severity warning) on its switch. A mismatch means a wrong neighbor, no link, a missing port or a port conflict. The event shows on the dashboard and the switch's page straight away, and resolves itself once fixed.cutsheet.mismatch_ticket_hours, which defaults to 24;0means never. Suppressing the switch or the port stops the ticket.Fix
Buttons with the
hiddenattribute were still displayed, because the button styles setdisplay. This left a Delete button on the new-cable form; clicking it only hit a harmless 404.Testing
0hours, and resolving once fixed. API tests cover live ports: shape, caching, a 502 without caching, and admin-only.flake8,bandit -llandeslint(no errors), all pass.🤖 Generated with Claude Code