Decision: Web Management UI #542

Closed
opened 2026-09-29 17:41:27 +01:00 by Vylpes · 2 comments
Owner

Status

Accepted — 2026-09-29

Supersedes the original idea. Implementation tracked by epic #543.

Context

Operating Card Drop today means editing env/files, Discord slash commands (/resync, /gdrivesync, /give), and Google Drive sync. That does not scale for settings management, card catalog edits, or multi-person admin.

Today:

  • Admin access = BOT_ADMINS (comma-separated Discord user IDs)
  • Runtime settings = Config key/value in the DB (notably safemode)
  • Cards = filesystem JSON + images under $DATA_DIR/cards, optionally synced from Google Drive via rclone
  • Express already runs in-process (EXPRESS_PORT) with an unauthenticated POST /api/reload-db

Original idea goals:

  • Manage settings graphically
  • Add and edit cards through the web
  • Roles and resources for users
  • Build using React

Decision

1) UI framework

Build a React SPA (TypeScript, Vite) for the management UI.

2) Process shape

Run the management UI/API in the same bot process. Expand the existing Express app into a Management API and serve (or reverse-proxy) the React build from that process. One deployable for v1.

3) Authentication

Discord OAuth. Only Discord users listed in BOT_ADMINS may access the UI/API in v1.

4) Authorization / roles

v1 enforces a single Admin capability (membership in BOT_ADMINS). Design API routes and resource checks so finer-grained roles/resources can be added later without rewriting the surface.

5) Settings

Allow admins to view/update safe DB Config keys (e.g. safemode) via the UI. Show non-secret env as read-only. Do not allow editing secrets (tokens, DB passwords, webhooks) through the UI.

6) Card source of truth

The UI reads and writes the local filesystem under $DATA_DIR/cards (series metadata JSON + image upload). Google Drive remains an optional sync path (/gdrivesync / UI ops action), not the editor’s write target in v1.

7) Ops actions

Expose admin ops in the UI: reload card metadata, trigger Drive sync, view/toggle safe mode. Protect existing webhook routes (including /api/reload-db) behind the same auth.

Alternatives considered

Option Why not chosen for v1
Separate web service Extra deploy/ops; Express already runs in-process
Discord-bot-only admin UX Does not satisfy graphical card/settings editing
Keep Drive as SoT; UI only triggers sync Blocks direct add/edit of cards through the web
Move card catalog into the DB Large migration; breaks current folder/Drive workflow
Shared password / static API token Weaker for multi-admin; Discord OAuth matches existing admin identity

Consequences

Positive

  • One process, one deploy; reuses Express + TypeORM
  • Clear path from binary BOT_ADMINS toward roles/resources
  • Card editing matches how the bot already loads metadata

Tradeoffs

  • UI edits vs Drive sync can diverge unless sync discipline is documented
  • Discord OAuth + sessions are new security surface (HTTPS via reverse proxy, CSRF, secure cookies)
  • Serving a SPA from the bot process couples frontend build to the bot release pipeline

Original idea notes

  • Ability to manage settings graphically
  • Add and edit cards through web
  • Roles and resources for users
  • Build using React
## Status **Accepted** — 2026-09-29 Supersedes the original idea. Implementation tracked by epic [#543](https://git.vylpes.xyz/External/card-drop/issues/543). ## Context Operating Card Drop today means editing env/files, Discord slash commands (`/resync`, `/gdrivesync`, `/give`), and Google Drive sync. That does not scale for settings management, card catalog edits, or multi-person admin. Today: - Admin access = `BOT_ADMINS` (comma-separated Discord user IDs) - Runtime settings = `Config` key/value in the DB (notably `safemode`) - Cards = filesystem JSON + images under `$DATA_DIR/cards`, optionally synced from Google Drive via rclone - Express already runs in-process (`EXPRESS_PORT`) with an unauthenticated `POST /api/reload-db` Original idea goals: - Manage settings graphically - Add and edit cards through the web - Roles and resources for users - Build using React ## Decision ### 1) UI framework Build a **React** SPA (TypeScript, Vite) for the management UI. ### 2) Process shape Run the management UI/API in the **same bot process**. Expand the existing Express app into a Management API and serve (or reverse-proxy) the React build from that process. One deployable for v1. ### 3) Authentication **Discord OAuth**. Only Discord users listed in `BOT_ADMINS` may access the UI/API in v1. ### 4) Authorization / roles v1 enforces a single **Admin** capability (membership in `BOT_ADMINS`). Design API routes and resource checks so finer-grained roles/resources can be added later without rewriting the surface. ### 5) Settings Allow admins to view/update safe DB `Config` keys (e.g. `safemode`) via the UI. Show non-secret env as read-only. Do **not** allow editing secrets (tokens, DB passwords, webhooks) through the UI. ### 6) Card source of truth The UI **reads and writes the local filesystem** under `$DATA_DIR/cards` (series metadata JSON + image upload). Google Drive remains an optional sync path (`/gdrivesync` / UI ops action), not the editor’s write target in v1. ### 7) Ops actions Expose admin ops in the UI: reload card metadata, trigger Drive sync, view/toggle safe mode. Protect existing webhook routes (including `/api/reload-db`) behind the same auth. ## Alternatives considered | Option | Why not chosen for v1 | |---|---| | Separate web service | Extra deploy/ops; Express already runs in-process | | Discord-bot-only admin UX | Does not satisfy graphical card/settings editing | | Keep Drive as SoT; UI only triggers sync | Blocks direct add/edit of cards through the web | | Move card catalog into the DB | Large migration; breaks current folder/Drive workflow | | Shared password / static API token | Weaker for multi-admin; Discord OAuth matches existing admin identity | ## Consequences **Positive** - One process, one deploy; reuses Express + TypeORM - Clear path from binary `BOT_ADMINS` toward roles/resources - Card editing matches how the bot already loads metadata **Tradeoffs** - UI edits vs Drive sync can diverge unless sync discipline is documented - Discord OAuth + sessions are new security surface (HTTPS via reverse proxy, CSRF, secure cookies) - Serving a SPA from the bot process couples frontend build to the bot release pipeline ## Original idea notes - Ability to manage settings graphically - Add and edit cards through web - Roles and resources for users - Build using React
Author
Owner

Build using react

Build using react
Vylpes self-assigned this 2026-09-29 18:01:41 +01:00
Smithy-bot changed title from Web Management UI to Decision: Web Management UI 2026-09-29 19:04:04 +01:00
Member

Accepted decision closed. Implementation epic: #543

Accepted decision closed. Implementation epic: #543
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
External/card-drop#542
No description provided.