feat: migrate frontend to Astro + expand AI moderation + backend admin/runtime config

Frontend:
- migrate from Vite to Astro (astro.config.mjs, pages/, layouts/)
- add admin panel, settings page, command palette, error boundary
- refactor App.tsx, MascotChatbot, Sidebar, Header, DashboardLayout
- update API client, WebSocket, auth, dashboard features

Backend:
- add admin module and config routes
- refactor middlewares, Redis connection, WebSocket server/bridge
- add runtime config loader

Discord Gateway:
- refactor AI moderation: circuit breaker, concurrency limiter, fallback processor
- add media analysis client, Seaxng search, user profile learner
- add new drizzle migration

Shared:
- extend database schema, add new config fields
This commit is contained in:
asepharyana
2026-07-02 00:02:41 +07:00
parent d5c22a3959
commit d59b59a7a7
91 changed files with 11165 additions and 674 deletions
@@ -6,6 +6,15 @@ import { uiStateService } from "./ui-state.service.js";
const logger = createChildLogger("ui-state.routes");
// Allowed UI state keys — reject any update that does not match these.
const ALLOWED_KEYS = new Set([
"activeTab",
"selectedVoiceGuild",
"selectedVoiceChannel",
"selectedTextChannel",
"sidebarCollapsed",
]);
export function createUiStateRouter(): Router {
const router = express.Router();
@@ -25,7 +34,14 @@ export function createUiStateRouter(): Router {
asyncHandler(async (req: Request, res: Response) => {
const updates = req.body as Record<string, unknown>;
logger.debug({ keys: Object.keys(updates) }, "Updating UI state");
const result = await uiStateService.updateState(updates);
// Filter to only allow known safe keys
const filtered: Record<string, unknown> = {};
for (const key of Object.keys(updates)) {
if (ALLOWED_KEYS.has(key)) {
filtered[key] = updates[key];
}
}
const result = await uiStateService.updateState(filtered);
res.json(result);
}),
);