🖥️ Adding a Panel Page¶
This page documents how to add or change a web panel page safely.
It is based on the current live Magikal panel structure.
Current panel structure¶
| Area | Path |
|---|---|
| Panel project | /home/magikalbot/magikal-panel |
| FastAPI backend | /home/magikalbot/magikal-panel/api/main.py |
| Next.js frontend | /home/magikalbot/magikal-panel/web |
| Main frontend page | /home/magikalbot/magikal-panel/web/pages/index.jsx |
| Global CSS | /home/magikalbot/magikal-panel/web/styles/globals.css |
| Next config | /home/magikalbot/magikal-panel/web/next.config.js |
Current frontend model¶
The current frontend is a Next.js static export.
The live config shows:
output: 'export'
This means the frontend builds to:
web/out
The panel web service serves that static output.
Current UI shape
The current panel is mostly a single dashboard in web/pages/index.jsx.
Adding a new panel area usually means adding a new section/card/component inside index.jsx, not creating a separate routed page.
Do not introduce a new routing structure unless that refactor is explicitly approved.
Current backend model¶
The backend is FastAPI in:
api/main.py
The API handles:
- health checks
- database ping
- Discord OAuth login
- Discord OAuth callback
- session logout
- current user lookup
- manageable guild list
- config loading
- config section metadata
- config saving
Current important API routes include:
| Route | Purpose |
|---|---|
/health |
API health check |
/db/ping |
Database connectivity check |
/auth/login |
Start Discord OAuth login |
/auth/callback |
Discord OAuth callback |
/auth/logout |
Clear session |
/user/me |
Current logged-in user |
/user/guilds |
Guilds the user can manage |
/config/{guild_id} |
Load merged guild config |
/config/{guild_id}/sections |
Load config section metadata |
PUT /config/{guild_id} |
Save config updates |
The public site normally reaches these through the Nginx /api/ proxy.
Frontend calls look like:
/api/user/me
/api/user/guilds
/api/config/{guild_id}
/api/config/{guild_id}/sections
Auth model¶
The panel uses Discord OAuth and server-side sessions.
The backend stores user/session information through session middleware.
Guild access is based on the Discord guild list returned through OAuth.
Permission rule
Do not rely on the frontend alone for permissions.
The API must enforce login and save permissions.
Frontend checks are for user experience. Backend checks are for security.
Config save/load model¶
The frontend loads config from:
GET /api/config/{guild_id}
It also loads section metadata from:
GET /api/config/{guild_id}/sections
It saves changed config with:
PUT /api/config/{guild_id}
The current frontend builds a dirty/changed payload, so only changed fields are sent on save.
Config source of truth
Panel-backed settings should save to Postgres-backed config.
The panel must not invent a second source of truth.
Expected flow:
Web panel -> FastAPI -> Postgres/cfg tables -> bot reads config
Before changing the panel¶
Check Git state:
cd /home/magikalbot/magikal-panel
git status --short
For large or risky layout/API changes, create a restore point first:
git add .
git commit -m "restore point before panel change"
Adding a new config section¶
Use this approach for most new panel work:
- Confirm the setting already exists in bot storage/database.
- Confirm the API exposes it through
/config/{guild_id}. - Confirm the API allows saving it through
PUT /config/{guild_id}. - Add the field/section to the frontend.
- Make sure save only sends changed fields.
- Test load, edit, save, reload.
- Check API logs.
- Check the bot reads the saved value.
Backend changes¶
Backend changes usually happen in:
api/main.py
Add or update backend support when:
- the frontend needs a new API route
- a config field is not exposed yet
- save logic needs a new namespace/table
- validation is needed
- permission checks need tightening
Do not bypass backend permission checks
Any route that reads private user/session data must require login.
Any route that saves config must require the correct management permission.
Frontend changes¶
Frontend changes usually happen in:
web/pages/index.jsx
Current frontend responsibilities include:
- loading current user
- loading manageable guilds
- selected guild state
- loading config
- loading config sections
- editing fields
- building dirty save payloads
- saving changed config
- showing save state/errors
- layout for desktop/mobile
Layout rules¶
Panel layout should stay usable on different screen sizes.
Current design direction:
- top/header area should remain easy to reach
- selected server context should remain clear
- server list and section navigation should not fight the main editor
- the config editor can scroll independently
- mobile should not feel like a crushed desktop page
- avoid fixed-width designs that waste large screens
Panel layout test
Test the panel on desktop width and mobile width before calling layout work done.
Adding a frontend section safely¶
When adding a new section inside index.jsx:
- Keep the section small.
- Reuse existing card/field patterns.
- Add clear labels and descriptions.
- Use existing save state handling.
- Avoid hardcoding guild-specific values.
- Keep mobile layout in mind.
- Keep the selected guild context visible.
- Do not duplicate API fetch logic unless needed.
API fetch pattern¶
The frontend currently uses an API helper pattern around fetch.
New frontend calls should follow the existing helper style rather than inventing a separate fetch method.
Good goals:
- include credentials/session where required
- handle non-200 responses
- show useful user-facing errors
- avoid leaking raw backend errors to users
Save behaviour¶
Good save behaviour:
- only send changed fields
- show unsaved changes clearly
- disable/guard save while saving
- show success/failure result
- reload or refresh state after successful save
- avoid silently dropping fields
Save testing
After any save-related change, test this full loop:
- load current config
- change one field
- save
- refresh browser
- confirm the value stayed changed
- confirm bot behaviour matches the saved setting
Backend validation¶
Validate risky or typed fields on the backend.
Examples:
- booleans
- channel IDs
- role IDs
- JSON config
- numeric limits
- feature flags
Frontend validation is useful, but backend validation is the safety net.
JSON fields¶
The current frontend treats fields matching names like json, config, extra, or qa_config as JSON-style fields.
Be careful when adding JSON fields.
Bad JSON should not break the whole panel.
Restarting after changes¶
For backend/API changes:
sudo systemctl restart magikal-panel-api
sudo systemctl status magikal-panel-api --no-pager
sudo journalctl -u magikal-panel-api -n 120 --no-pager
For frontend/static UI changes, rebuild/export using the current panel workflow, then restart:
sudo systemctl restart magikal-panel-web
sudo systemctl status magikal-panel-web --no-pager
sudo journalctl -u magikal-panel-web -n 120 --no-pager
Confirm the deploy workflow
Before doing major panel deployment work, confirm the current live build/export/publish process.
The panel has changed over time, so do not assume old deployment notes are still correct.
Common red flags¶
Stop and review if a panel change:
- changes auth/session behaviour
- changes Discord OAuth setup
- changes save permissions
- changes config save payload shape
- changes
/config/{guild_id} - changes
/config/{guild_id}/sections - changes database table mappings
- breaks mobile layout
- causes static export build errors
- hardcodes a guild/server ID
- introduces a second source of truth
- exposes secrets or raw backend errors
Testing checklist¶
Before calling a panel change done:
git status --shortchecked- frontend builds successfully
- API starts successfully
- login still works
- guild list loads
- selected guild loads config
- sections load
- saving works
- refresh keeps saved values
- mobile layout is checked
- logs have no traceback
- no secrets or raw private data are exposed
Useful log checks¶
Panel API logs:
sudo journalctl -u magikal-panel-api -n 120 --no-pager
Panel web logs:
sudo journalctl -u magikal-panel-web -n 120 --no-pager
Search API errors:
sudo journalctl -u magikal-panel-api -n 300 --no-pager | grep -i error
Rule¶
Panel pages should be added through the existing API/config flow, stay responsive, keep permissions server-side, and never create a second source of truth.