Skip to content

Architecture

Domekologe edited this page Jun 30, 2026 · 1 revision

Architecture

🌐 English · Deutsch

The PDC Redbot Webapp is a SvelteKit application that acts as a Backend-for-Frontend (BFF) in front of a Red-DiscordBot. The browser never talks to the bot directly; instead it calls the SvelteKit server, which holds all secrets and forwards requests to the bot over a token-secured JSON-RPC gateway provided by the companion cog. This page covers the stack, the BFF pattern, the gateway protocol, the request flow and the project structure.

Stack

Layer Technology
Framework SvelteKit (adapter-node)
Language TypeScript
Styling TailwindCSS (shadcn-svelte tokens)
Charts Chart.js
Auth Discord OAuth2 (server-side)
Transport to the bot JSON-RPC 2.0 over the cog gateway
i18n German + English, full UI translation

The two deployable parts

┌──────────────────────────────┐        ┌─────────────────────────────────┐
│  Red-DiscordBot (Python)     │        │  Web app (Node / SvelteKit)     │
│                              │        │                                 │
│  ┌────────────────────────┐  │ JSON-  │  ┌───────────────────────────┐  │
│  │ pdc_webdashboard (cog)     │  │ RPC    │  │ SvelteKit server (BFF)    │  │
│  │  ├─ RPC gateway        │◄─┼─2.0────┼─►│  ├─ Discord OAuth2        │  │
│  │  │   (localhost+token) │  │ +token │  │  ├─ session / cookies     │  │
│  │  ├─ integration registry│ │        │  │  └─ RPC client            │  │
│  │  └─ permission mapper  │  │        │  └───────────┬───────────────┘  │
│  └────────────────────────┘  │        │              │ /api/* (BFF)     │
│  ┌────────────────────────┐  │        │  ┌───────────▼───────────────┐  │
│  │ third-party cogs       │  │        │  │ Svelte SPA (Tailwind)     │  │
│  │  (widgets/panels/lists)│  │        │  │  widgets · panels · charts│  │
│  └────────────────────────┘  │        │  └───────────────────────────┘  │
└──────────────────────────────┘        └─────────────────────────────────┘
  • pdc_webdashboard cog (in PDC_Redbot_Cogs) runs inside the bot process and exposes the RPC gateway plus an integration registry where other cogs register widgets, panels and lists. See Cog Integration.
  • PDC Redbot Webapp (this repo) is the SvelteKit app. Its server is the BFF: it performs Discord OAuth2, holds the session, and is the only client that knows the gateway token. The Svelte SPA talks only to the SvelteKit server.

The BFF pattern

The single most important rule: all secrets live server-side. They are read at runtime from $env/dynamic/private and never bundled into client code.

  • lib/server/ is the server-only zone: env (env.ts), session (session.ts), OAuth2 (auth.ts) and the RPC client (rpc.ts). Nothing here is importable from the browser.
  • The browser calls the BFF's own /api/* endpoints (and page load functions). Those, in turn, call the gateway with the gateway token attached server-side.
  • DISCORD_CLIENT_SECRET, GATEWAY_TOKEN and SESSION_SECRET therefore never reach the client — the browser only holds a signed session cookie. See Authentication.

JSON-RPC over the gateway

The BFF speaks JSON-RPC 2.0 to the cog. Requests are HTTP POSTs to ${GATEWAY_URL}/rpc with an X-Dashboard-Token header. The cog also defines a WebSocket endpoint at /rpc for bidirectional/streaming use; the current web app uses the HTTP transport.

Each call carries an auth context the gateway re-checks server-side:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "core.guild_detail",
  "params": {
    "auth": { "user_id": "123", "guild_id": "456", "locale": "en-US" },
    "args": { /* method-specific */ }
  }
}

The gateway derives the user's Red permission level from auth and enforces the method's required level on every call. See API & Gateway for the method catalog.

Request flow

Browser ──▶ BFF (SvelteKit server) ──▶ gateway (cog, localhost+token) ──▶ Red bot
   │  page load / /api/* fetch       │  JSON-RPC + X-Dashboard-Token     │  Config / discord.py
   │                                 │                                   │  permission re-check
   ◀── HTML / JSON ──────────────────◀── result / error ────────────────◀──
  1. The browser requests a page or hits a /api/* endpoint.
  2. hooks.server.ts reads and validates the signed session cookie (and checks the session epoch, cached ~60 s).
  3. The BFF builds the auth context and calls the gateway over JSON-RPC with the token.
  4. The cog enforces permissions, runs the method against Red, and returns a result.
  5. The BFF renders or returns JSON to the browser.

Project structure

src/
  hooks.server.ts            Session from cookie + epoch check on every request
  lib/server/                Server-ONLY (secrets!):
    env.ts                   $env/dynamic/private, fail-closed on bad SESSION_SECRET
    session.ts               HMAC-SHA256 signed cookie sessions
    auth.ts                  Discord OAuth2 (authorize URL, code exchange, user fetch)
    rpc.ts                   JSON-RPC client (token header, auth context)
  lib/components/            Widget, PanelForm, ListManager, ModuleTabs, CommandPalette
    charts/                  Chart.js wrappers (Line/Bar/Donut + SeriesToggle)
    ui/                      shadcn-svelte primitives
  lib/i18n/                  de + en (full UI translation)
  lib/markdown.ts            Safe Markdown → HTML renderer (custom pages)
  routes/
    +page.svelte             Landing/overview (public)
    commands/                Public command list
    guilds/[id]/settings/    Server overview + per-guild bot settings
    cogs/                    Cog management (cogs/slash/downloader/global)
    stats/                   Server statistics (needs pdc_webdashboard_stats)
    settings/                Global settings + branding + global panels
    pages/  p/[slug]/        Custom pages (editor + public view)
    announce/                Announcement / embed builder
    audit/  system/          Audit log + health/self-update (owner)
    auth/… logout            OAuth2 flow
    api/…                    BFF endpoints that call the gateway

Key components

Component Role
hooks.server.ts Validates the session cookie and the session epoch on each request; fail-open if the gateway is offline.
Widget.svelte Renders a cog's read-only widget data (KPI/list/status).
PanelForm.svelte Renders a cog's declarative panel form and submits it.
ListManager.svelte View/add/edit/delete rows for a cog's list contribution.
ModuleTabs.svelte Groups one cog's widgets/panels/lists into a single tabbed module.
lib/i18n German + English message stores.
lib/markdown.ts XSS-safe Markdown renderer for custom pages.

Related pages

Clone this wiki locally