Sidebar:
- Each connection header now has three inline icon buttons: Sync now
(spins while in flight), Edit (opens the modal), Remove (opens an
inline confirm strip). Removes cascade repos via ON DELETE CASCADE.
- The connection's last_sync_error surfaces as a red inline banner
under the header — no more 'error status with nowhere to see why'.
- Sync is POST /api/repos/connections/:id/sync (already existed);
after either sync or delete the sidebar re-fetches so state stays
consistent.
Edit modal (RepoConnectionEditModal):
- Loads GET /api/repos/connections/:id, pre-fills owner/base_url/label
- PATCHes only the fields that actually changed; empty string on a
Some(&str) field sends explicit null so the backend clears it
- Sync-now + Remove reachable from inside the modal too
- Rotating the token is out of scope: the modal says as much and
points the user at delete + re-create through the wizard (the
broker doesn't expose an update path, and rotating in place would
require duplicating the whole broker->store_secret flow here)
Backend:
- GET /api/repos/connections/:id — same ConnectionSummary shape
- PATCH /api/repos/connections/:id — owner/base_url use Option<Option<T>>
double-nesting so 'omit = leave alone' and 'null = clear' round-trip
distinctly through serde
- repo_connections::update with COALESCE-per-field so the SQL matches
the double-Option semantics without an OR-chain per field