feat(hosts): add instance-wide predefined tag suggestions (#1548)

* feat(hosts): add shared predefined tag suggestions

* style(hosts): format tag catalog routes
This commit is contained in:
ZacharyZcR authored and GitHub committed 2026-10-03 21:04:50 +08:00
1 parent 94a9f815c9
commit b00551c394
9 files changed
+274 -7

No files matched your search

@@ -0,0 +1,40 @@
import type { RequestHandler, Router } from "express";
import { createCurrentSettingsRepository } from "../repositories/factory.js";
const CATALOG_KEY = "host_tag_catalog";
export function registerHostTagRoutes(
router: Router,
authenticate: RequestHandler,
requireAdmin: RequestHandler,
): void {
router.get("/tags", authenticate, async (_req, res) => {
const value = await createCurrentSettingsRepository().get(CATALOG_KEY);
res.json({ tags: value ? JSON.parse(value) : [] });
});
router.put("/tags", authenticate, requireAdmin, async (req, res) => {
const tags: unknown = req.body?.tags;
if (
!Array.isArray(tags) ||
tags.length > 500 ||
tags.some(
(tag) =>
typeof tag !== "string" || !tag.trim() || tag.trim().length > 100,
)
) {
res.status(400).json({
error: "Expected up to 500 non-empty tags of at most 100 characters",
});
return;
}
const normalized = [
...new Set((tags as string[]).map((tag) => tag.trim())),
];
await createCurrentSettingsRepository().set(
CATALOG_KEY,
JSON.stringify(normalized),
);
res.json({ tags: normalized });
});
}
+7
View File
@@ -53,6 +53,7 @@ import { registerHostFolderRoutes } from "./host-folder-routes.js";
import { registerHostNetworkRoutes } from "./host-network-routes.js";
import { registerHostBulkRoutes } from "./host-bulk-routes.js";
import { registerHostDefaultsRoutes } from "./host-defaults-routes.js";
import { registerHostTagRoutes } from "./host-tag-routes.js";
import { registerHostStatusRoutes } from "./host-status-routes.js";
import {
applyHostEnrollmentDefaults,
@@ -136,6 +137,12 @@ const permissionManager = PermissionManager.getInstance();
const authenticateJWT = authManager.createAuthMiddleware();
const requireDataAccess = authManager.createDataAccessMiddleware();
registerHostTagRoutes(
router,
authenticateJWT,
permissionManager.requirePermission("admin.settings.manage"),
);
registerHostStatusRoutes(router, {
authenticateJWT,
requireAdmin: authManager.createAdminMiddleware(),