Gateway: - Remove dead barrels (ai-moderation/index, attachment-upload/index, message-capture/index) — all consumers import files directly - Remove orphaned schema/ split dir (analytics/cache/messages/meta) — schema.ts is monolithic - Merge duplicate config singleton: delete shared/config/config.ts, point all 44 imports at shared/config/index Backend: - Remove dead commandHelper.ts (voice-era fallback), ws/index.ts barrel, health.schema.ts, moderationMetrics.ts, analysis.schema.ts (0 importers; metrics/handlers route directly) Frontend: - Remove orphaned CategoryDrilldown/CoverageTiles/TopicTrends, primitives/slot, use-mobile, use-mounted - Remove unused charts donut/sparkline (TopicTrends was only consumer) Kept (verified active): shared/database/index.ts facade (11 importers), hooks/index + lib/api/index barrels (10 importers), orpc/ws.ts, charts/index.ts barrel. Verified: tsc + biome + vitest per service (backend e2e 3 failures pre-existing on main); frontend next build 8 routes.
Bete Frontend
Next.js 16 (React 19) dashboard untuk Discord Moderation Watcher.
Stack: Next.js 16 (App Router, static export), React 19, TypeScript strict, Tailwind v4, shadcn/ui, base-ui, lucide-react.
Dev
bun run dev # next dev — port 3000 (lokal; prod via nginx 4009)
bun run build # next build — static export ke out/
bun run lint # Biome check
Architecture
src/
├── app/ # Pages
│ ├── page.tsx # Redirect ke /dashboard
│ └── dashboard/ # Dashboard layout + tabs
│ ├── layout.tsx # Sidebar, header, WS provider, chatbot
│ └── page.tsx # Tab routing (messages/dashboard)
├── features/
│ ├── messages/ # Message feed, search, review, detail modal
│ ├── dashboard/ # Stats, users, channels overview
│ └── chatbot/ # AI chatbot
├── lib/
│ ├── api/ # Fetch-based API client (all BE endpoints)
│ ├── ws/ # WebSocket client + React context
│ └── hooks/ # Shared hooks (config, auth)
└── components/
└── layout/ # Sidebar, header, mobile tab bar
API
Backend berjalan di port 4001. Frontend mengakses API via window.location (same-origin atau proxy).
WebSocket terhubung otomatis ke /ws di host yang sama.