Add tags to servers, with a tag filter on the Servers page
Servers can be tagged (prod, media, rack-1, ...) for grouping. Operators and admins edit tags inline on a server's detail page; the input suggests tags already used on other servers so the same word ends up spelled the same way everywhere. Tags show as chips that keep one colour per tag, on the server cards, in the Manage table (and its CSV export), and on the detail page, where each chip links to the Servers list filtered by that tag. The Servers page has a tag bar with counts; picking several tags narrows to servers that have all of them. The filter lives in the URL, so it survives a refresh and can be linked to. Tags are also matched by the global search. Tags are normalized on the server (trimmed, lowercased, spaces become "-", duplicates merged, sorted); letters in any language are allowed, plus digits and - _ . : /, at most 30 characters and 12 per server. Invalid input is rejected with a message naming the offending tag, and nothing is saved. Changes are audit-logged with the before and after lists. Stored as a JSON column on servers (migration 0010). Every server response now returns tags as an array, and the shared response shaping strips the token hash in one place instead of five. Verified with 27 backend checks (normalization edge cases including Swedish letters, roles, validation, search, audit, PATCH/detail/list shapes) and by driving the real Servers and detail pages against the real router in a browser (filtering, editing, invalid tag, viewer view). Real dev database mtime untouched. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4c11158e98
commit
9f1609c4ed
13 files changed
+1745
-12
No files matched your search
@@ -222,6 +222,7 @@ export const servers = sqliteTable("servers", {
|
||||
disks: text("disks"), // JSON string: {mount, sizeBytes, usedBytes}[]
|
||||
listeningPorts: text("listening_ports"), // JSON string: {protocol, port, address, process}[] — what the agent sees bound on the host
|
||||
lastPortScan: text("last_port_scan"), // JSON string: summary of the most recent network scan from this app
|
||||
tags: text("tags"), // JSON string: string[] — free-form labels for grouping and filtering, normalized by services/serverTags
|
||||
|
||||
// Optional link to a Proxmox VM/LXC — set by an admin, not the agent.
|
||||
proxmoxIntegrationId: integer("proxmox_integration_id").references(() => integrations.id, {
|
||||
|
||||
Reference in new issue
Block a user