feat(backend,frontend): migrate data APIs from REST to native tRPC over WebSocket

Replace REST module routers with a single typed tRPC appRouter served over
/trpc (HTTP + WebSocket), and rewire the frontend to call it via
@trpc/client wsLink (browser) and httpLink (RSC data layer). Existing
/api/health + /api/metrics stay as plain Express for infra scraping.

Notable fixes surfaced by the live smoke test:
- Express 5 / path-to-regexp v8 rejects the /trpc/* wildcard route; use a
  prefix middleware that computes opts.path from the URL instead.
- nodeHTTPRequestHandler treats opts.path as the literal procedure path, so
  it is derived per-request from req.url.
- Two ws servers on one http.Server (the /ws voice socket + /trpc) collided
  and returned 400 on upgrade; both now use noServer + a manually routed
  server.on('upgrade') keyed by path.

Verified: BE tsc+biome+40 vitest green; FE tsc+biome green; live
HTTP and WebSocket calls returned real prod data.

Co-Authored-By: Claude Opus 4.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
asepharyana
2026-08-16 13:25:10 +07:00
co-authored by Claude Opus 4.5
parent d8552a9fb8
commit 2fa1827f17
47 changed files with 3318 additions and 1049 deletions
+4 -2
View File
@@ -2,6 +2,7 @@ import { createServer, type Server } from "node:http";
import { createChildLogger } from "@/shared/logger/index";
import { config } from "../shared/config/index.js";
import { initializeDatabase } from "../shared/database/index.js";
import { createTRPCWebSocketServer } from "../trpc/ws.js";
import { startRedisBridge } from "../ws/redis-bridge.js";
import { createWebSocketServer } from "../ws/server.js";
import { createHttpApp } from "./app.js";
@@ -16,8 +17,9 @@ export async function startHttpServer(): Promise<Server> {
const server = createServer(app);
// Attach WebSocket server to the same HTTP server
createWebSocketServer(server);
// Attach WebSocket servers to the same HTTP server
createWebSocketServer(server); // /ws — voice PCM + gateway events
createTRPCWebSocketServer(server); // /trpc — structured data RPCs
// Start Redis pub/sub bridge to forward discord-gateway events to WS clients
await startRedisBridge();