Hi Erik — a feature proposal for finding and organising servers as the monitored list grows. Flagging up front what already exists so this is framed as extend + bring to parity, not reinvent.
What's there today
- Viewer already has hierarchical server tags (
config.server_tags with parent_id / sort_order, many-to-many via server_tag_map), and renders them as a collapsible tag tree in the sidebar (servers nested under tag headers). Nice foundation.
- Tags have no colour (no colour column), are not shown as pills, and don't appear on the Overview cards.
- Lite and the web viewer have no tag concept at all — no tree, no grouping.
- Search / filter by server name (or tag) does not exist on any surface — the Viewer's
FleetView even reserves a seam for it, but it's unbuilt. Lite's Overview and the web fleet page have a sort control only.
A bug I hit while auditing this: tag editing silently fails for the viewer role
The "Assign Tags" submenu (and create/rename/delete) appears to do nothing on a managed store. The wiring is fine — AssignTag_Click calls AssignServerTagAsync and reloads — but every tag write routes through ExecuteWriteAsync, and the viewer role has no write grant on config.server_tags / config.server_tag_map (neither provision-roles.sql nor DarlingManagedRoles grants them — custom_views got its viewer write grant, the tag tables were missed). So on a store where the Viewer connects as the least-privilege viewer role, the INSERT hits 42501, ExecuteWriteAsync degrades it to ViewerReadOnlyException, and the click's catch logs "Assign/unassign failed" and shows nothing. Net effect: tags are effectively read-only from the Viewer on any provisioned store.
Happy to send this as a tiny standalone fix (add the viewer INSERT/UPDATE/DELETE grants on the two tag tables, mirroring the custom_views grant) ahead of the feature below, if you'd prefer to decouple it.
The gap
On a large fleet you can't quickly find a server, and — even where tags exist (the Viewer) — they're editable only in theory, invisible except as sidebar grouping, and absent from Lite and the web entirely. DEV/PROD/TEST/etc. live only in people's heads or server names.
Proposal (suggested as two stages)
Stage 1 — search/filter (self-contained, high value). A search box on the servers list and the overview/dashboard, on all three surfaces, filtering by server name (and by tag where tags exist). In the Viewer it slots into the FleetView.Rebuild seam already reserved for it. No schema change; ships independently.
Stage 2 — finish + spread tags.
- Fix the viewer-role grant gap above so tag editing actually persists.
- Add a colour to the tag model — a nullable colour column, auto-assigned from a rotating palette on tag creation and user-overridable — and render a server's tags as distinct coloured pills on the server cards / overview.
- Bring tags to Lite and the web viewer: a tag model mirroring Darling's hierarchical many-to-many shape (cross-surface parity), the Viewer's sidebar tag-tree grouping brought over as opt-in drill-down (SSMS Object-Explorer style), and pills.
Search then narrows within the tree; pills annotate each card.
Per-surface scope
- Viewer: add a colour column to
config.server_tags (migration) + a colour picker in the tag UI; render tags as pills on the Overview cards (today they only group the sidebar tree); add the search box at the Rebuild seam.
- Lite: greenfield — a tag model (DuckDB tables mirroring Darling's shape for parity), a manage-tags UI, tree grouping + pills on the Overview, and the search box next to the existing sort control.
- Web:
/api/fleet gains tag data (it emits none today); the fleet page gains a search input, tag pills on the cards, and tree/group rendering.
Open questions
- Stage it as above, or one PR? And would you want the viewer-grant fix as its own tiny standalone PR first (it's a real bug independent of the feature)?
- Colour — a nullable column on
config.server_tags, auto-assigned + user-overridable as I've proposed? Any palette/convention to match, or a preferred storage shape?
- Lite tag model — mirror Darling's hierarchical many-to-many shape for parity (my assumption), or keep Lite simpler?
- Web tags — read-only on the web with assignment staying in the desktop apps (my assumption), or editable there too?
Happy to shape any of it to fit the project's direction.
Hi Erik — a feature proposal for finding and organising servers as the monitored list grows. Flagging up front what already exists so this is framed as extend + bring to parity, not reinvent.
What's there today
config.server_tagswithparent_id/sort_order, many-to-many viaserver_tag_map), and renders them as a collapsible tag tree in the sidebar (servers nested under tag headers). Nice foundation.FleetVieweven reserves a seam for it, but it's unbuilt. Lite's Overview and the web fleet page have a sort control only.A bug I hit while auditing this: tag editing silently fails for the viewer role
The "Assign Tags" submenu (and create/rename/delete) appears to do nothing on a managed store. The wiring is fine —
AssignTag_ClickcallsAssignServerTagAsyncand reloads — but every tag write routes throughExecuteWriteAsync, and theviewerrole has no write grant onconfig.server_tags/config.server_tag_map(neitherprovision-roles.sqlnorDarlingManagedRolesgrants them —custom_viewsgot its viewer write grant, the tag tables were missed). So on a store where the Viewer connects as the least-privilegeviewerrole, the INSERT hits42501,ExecuteWriteAsyncdegrades it toViewerReadOnlyException, and the click's catch logs"Assign/unassign failed"and shows nothing. Net effect: tags are effectively read-only from the Viewer on any provisioned store.Happy to send this as a tiny standalone fix (add the
viewerINSERT/UPDATE/DELETE grants on the two tag tables, mirroring thecustom_viewsgrant) ahead of the feature below, if you'd prefer to decouple it.The gap
On a large fleet you can't quickly find a server, and — even where tags exist (the Viewer) — they're editable only in theory, invisible except as sidebar grouping, and absent from Lite and the web entirely. DEV/PROD/TEST/etc. live only in people's heads or server names.
Proposal (suggested as two stages)
Stage 1 — search/filter (self-contained, high value). A search box on the servers list and the overview/dashboard, on all three surfaces, filtering by server name (and by tag where tags exist). In the Viewer it slots into the
FleetView.Rebuildseam already reserved for it. No schema change; ships independently.Stage 2 — finish + spread tags.
Search then narrows within the tree; pills annotate each card.
Per-surface scope
config.server_tags(migration) + a colour picker in the tag UI; render tags as pills on the Overview cards (today they only group the sidebar tree); add the search box at theRebuildseam./api/fleetgains tag data (it emits none today); the fleet page gains a search input, tag pills on the cards, and tree/group rendering.Open questions
config.server_tags, auto-assigned + user-overridable as I've proposed? Any palette/convention to match, or a preferred storage shape?Happy to shape any of it to fit the project's direction.