From 43d32918ab72c588f2c1cc3a8121a5e80be6baf1 Mon Sep 17 00:00:00 2001 From: syntaxbullet Date: Thu, 12 Feb 2026 15:09:29 +0100 Subject: [PATCH] feat(api): add guild settings API endpoints Add REST endpoints for managing per-guild configuration: - GET /api/guilds/:guildId/settings - PUT/PATCH /api/guilds/:guildId/settings - DELETE /api/guilds/:guildId/settings --- web/src/routes/guild-settings.routes.ts | 64 +++++++++++++++++++++++++ web/src/routes/index.ts | 2 + 2 files changed, 66 insertions(+) create mode 100644 web/src/routes/guild-settings.routes.ts diff --git a/web/src/routes/guild-settings.routes.ts b/web/src/routes/guild-settings.routes.ts new file mode 100644 index 0000000..be8181e --- /dev/null +++ b/web/src/routes/guild-settings.routes.ts @@ -0,0 +1,64 @@ +/** + * @fileoverview Guild settings endpoints for Aurora API. + * Provides endpoints for reading and updating per-guild configuration + * stored in the database. + */ + +import type { RouteContext, RouteModule } from "./types"; +import { jsonResponse, errorResponse, withErrorHandling } from "./utils"; +import { guildSettingsService } from "@shared/modules/guild-settings/guild-settings.service"; +import { invalidateGuildConfigCache } from "@shared/lib/config"; + +const GUILD_SETTINGS_PATTERN = /^\/api\/guilds\/(\d+)\/settings$/; + +async function handler(ctx: RouteContext): Promise { + const { pathname, method, req } = ctx; + + const match = pathname.match(GUILD_SETTINGS_PATTERN); + if (!match || !match[1]) { + return null; + } + + const guildId = match[1]; + + if (method === "GET") { + return withErrorHandling(async () => { + const settings = await guildSettingsService.getSettings(guildId); + if (!settings) { + return jsonResponse({ guildId, configured: false }); + } + return jsonResponse({ ...settings, guildId, configured: true }); + }, "fetch guild settings"); + } + + if (method === "PUT" || method === "PATCH") { + try { + const body = await req.json() as Record; + const { guildId: _, ...settings } = body; + const result = await guildSettingsService.upsertSettings({ + guildId, + ...settings, + } as Parameters[0]); + invalidateGuildConfigCache(guildId); + return jsonResponse(result); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + return errorResponse("Failed to save guild settings", 400, message); + } + } + + if (method === "DELETE") { + return withErrorHandling(async () => { + await guildSettingsService.deleteSettings(guildId); + invalidateGuildConfigCache(guildId); + return jsonResponse({ success: true }); + }, "delete guild settings"); + } + + return null; +} + +export const guildSettingsRoutes: RouteModule = { + name: "guild-settings", + handler +}; diff --git a/web/src/routes/index.ts b/web/src/routes/index.ts index 216d06f..5ffe98c 100644 --- a/web/src/routes/index.ts +++ b/web/src/routes/index.ts @@ -9,6 +9,7 @@ import { statsRoutes } from "./stats.routes"; import { actionsRoutes } from "./actions.routes"; import { questsRoutes } from "./quests.routes"; import { settingsRoutes } from "./settings.routes"; +import { guildSettingsRoutes } from "./guild-settings.routes"; import { itemsRoutes } from "./items.routes"; import { usersRoutes } from "./users.routes"; import { classesRoutes } from "./classes.routes"; @@ -27,6 +28,7 @@ const routeModules: RouteModule[] = [ actionsRoutes, questsRoutes, settingsRoutes, + guildSettingsRoutes, itemsRoutes, usersRoutes, classesRoutes,