2026-07-26 11:38:53 +07:00
|
|
|
# Bete Frontend — Project Overview
|
2026-07-26 11:27:21 +07:00
|
|
|
|
2026-07-26 11:38:53 +07:00
|
|
|
Next.js 16 (App Router), React 19, TypeScript strict, Tailwind v4, shadcn/ui, base-ui.
|
|
|
|
|
|
|
|
|
|
Key points:
|
|
|
|
|
- **All pages** are `"use client"` — the dashboard is fully client-rendered
|
|
|
|
|
- **API client** at `src/lib/api/` — fetch-based, covers all 30+ backend endpoints
|
|
|
|
|
- **WebSocket** at `src/lib/ws/` — auto-reconnecting client with typed event subscriptions
|
|
|
|
|
- **Static export**: `output: "export"` in next.config.ts, served via nginx
|
|
|
|
|
- **No authentication**: all endpoints are public
|
2026-07-31 16:55:20 +07:00
|
|
|
|
|
|
|
|
## Data flow (match these — do not invent endpoints)
|
|
|
|
|
|
|
|
|
|
```
|
2026-08-02 16:20:27 +07:00
|
|
|
Discord → discord-gateway → Redis pub/sub → backend (Express :4001) ←→ frontend
|
2026-07-31 16:55:20 +07:00
|
|
|
↑ REST /api/* (same-origin)
|
|
|
|
|
└ WS /ws (events + PCM binary)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- **Base URL**: API + WS default to same-origin. `gmw-proxy` nginx (:8080)
|
|
|
|
|
proxies `/api` and `/ws` to the backend on :3001. Public host:
|
|
|
|
|
`imphnen.asepharyana.my.id` (Cloudflare SSL in front of Traefik → :8080).
|
|
|
|
|
- Local dev overrides: `NEXT_PUBLIC_API_URL` and `NEXT_PUBLIC_WS_URL`
|
|
|
|
|
(e.g. https://imphnen.asepharyana.my.id).
|
|
|
|
|
- **Never hardcode a host** in api/ws clients — same-origin or env override only.
|
|
|
|
|
|
|
|
|
|
## Backend response shapes that bite
|
|
|
|
|
|
|
|
|
|
- `GET /api/chat/history` → `{ history: ChatbotHistoryRow[], total }` where
|
|
|
|
|
each row is `{ id, user_id, user_message, bot_response, context, created_at }`.
|
|
|
|
|
Map rows to display messages in `chatbot-context.tsx`.
|
|
|
|
|
- `message_deleted` WS payload → `{ id, deleted_at }` (an object, not a string).
|
|
|
|
|
- `voice_recording_uploaded` WS payload has **no** `duration_bytes` (REST rows do).
|
|
|
|
|
- Dashboard endpoints: `/api/dashboard/stats|users|channels` (+ `/:id` details).
|
|
|
|
|
- Channel/guild names live inside `message.metadata` JSON (`channel.channelName`),
|
|
|
|
|
not top-level.
|