The Capinetta RP web dashboard is an Express.js application defined inDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/Capinetta-RP/capinetta-discord-bot/llms.txt
Use this file to discover all available pages before exploring further.
web/dashboard.js that runs alongside the bot process. It is served on port 3000 by default (overridden via the PORT environment variable) and provides authenticated staff members with real-time system metrics, ticket browsing with HTML transcript viewing, warning management, per-guild configuration editing via SelectMenus, and a full activity audit log. Security is enforced through Helmet HTTP headers, nonce-based Content Security Policy, rate limiting on all routes, HTTPOnly session cookies, and gzip compression. Sessions can be stored in Redis for multi-process resilience or fall back to an in-memory store if Redis is not configured.
Accessing the Dashboard
- Default URL:
http://your-server-ip:3000 - Login entry point:
GET /auth/discord - OAuth2 scopes requested:
identify,guilds
GENERAL_GUILD_ID) are denied access, regardless of whether they authenticated successfully with Discord.
Authentication Flow
Visit the dashboard URL
http://your-server-ip:3000. Unauthenticated users are redirected to the login page.Initiate Discord OAuth2
GET /auth/discord, which sends the user to Discord’s authorization page requesting the identify and guilds scopes.Discord redirects back
DASHBOARD_CALLBACK_URL (the /auth/discord/callback route). Passport.js validates the OAuth2 code and retrieves the user profile.Guild membership check
config.general.guildId. If the guild is not found in profile.guilds, authentication is rejected and no session is created.Session created
REDIS_HOST is set) or the in-memory MemoryStore. The session cookie capi-dashboard.sid is set as httpOnly, sameSite: 'lax', and secure: true in production. Sessions expire after 12 hours.Dashboard Sections
Overview
Tickets
open, closed, claimed) or category. Click any row to view the full HTML transcript via the authenticated viewer.Warns Management
warnLog history, and top-warned users ranked by infraction count. Supports per-guild filtering.Guild Config
Metrics
Activity Logs
API Endpoints
All API endpoints require an authenticated session (enforced by thecheckAuth middleware). Unauthenticated requests receive a 401 or are redirected to the login page.
A stricter rate limit applies to all /api/* routes: 30 requests per minute per IP (compared to 200 requests per 15 minutes for general routes).
GET /api/metrics
GET /api/metrics
HIGH severity alerts.Also records a sample to the in-memory metrics history for the /api/metrics/history endpoint.GET /api/metrics/history
GET /api/metrics/history
?hours=6 to narrow the range.Used by the dashboard’s time-series charts to render CPU, RAM, and response time trends.GET /api/logs
GET /api/logs
GET /api/logs/search
GET /api/logs/search
level, search, startDate, endDate, guildId, page, limit. Returns paginated results.GET /api/logs/export
GET /api/logs/export
/api/logs/search. Returns Content-Disposition: attachment.GET /api/guild/:guildId/stats
GET /api/guild/:guildId/stats
GET /api/guild/:guildId/top-warned
GET /api/guild/:guildId/top-warned
?limit=10. Used by the Warns Management section.GET /api/guild/:guildId/tickets-status
GET /api/guild/:guildId/tickets-status
open, closed, pending) for a guild. Used by the Overview and Tickets sections.GET /api/guild/:guildId/warns-trend
GET /api/guild/:guildId/warns-trend
?days=7 to narrow the range. Used by the Warns Management charts.GET /api/guilds/comparison
GET /api/guilds/comparison
GET /api/fivem/status
GET /api/fivem/status
FIVEM_BASE_URL to be set in .env.GET /api/fivem/players
GET /api/fivem/players
FIVEM_BASE_URL to be set in .env.GET /api/alerts
GET /api/alerts
POST /api/alerts/send
POST /api/alerts/send
ALERTS_WEBHOOK_URL. Returns { sent, total }. Requires ALERTS_WEBHOOK_URL to be configured.GET /api/logs/statistics
GET /api/logs/statistics
?startDate and ?endDate query parameters.Authentication Routes
The following routes handle Discord OAuth2 and are separate from the/api/* endpoints. They are not subject to the API rate limiter.
GET /auth/discord
GET /auth/discord
identify and guilds scopes.GET /auth/discord/callback
GET /auth/discord/callback
DASHBOARD_CALLBACK_URL exactly.Security Features
| Feature | Implementation |
|---|---|
| Helmet | HTTP security headers on every response (X-Frame-Options, HSTS, X-Content-Type-Options, etc.) |
| CSP with nonces | Content Security Policy applied via configureCSP() middleware; unique token per request, no unsafe-inline |
| Rate limiting | express-rate-limit: 200 req/15 min globally, 30 req/min on /api/* |
| HTTPOnly cookies | Session cookie capi-dashboard.sid is inaccessible to JavaScript (httpOnly: true) |
| Secure cookies | secure: true in production — cookies only sent over HTTPS |
| Trust proxy | app.set('trust proxy', 1) for correct IP resolution behind Nginx/Cloudflare |
| gzip compression | compression middleware reduces response payload size |
Redis Caching
Redis is used to cache frequently-accessed data and reduce database load. All TTL values are configurable through environment variables:| Cache | Env Variable | Default |
|---|---|---|
| User profiles | CACHE_USER_PROFILE_TTL | 10 minutes |
| Stats/overview | CACHE_STATS_TTL | 5 minutes |
| Discord metrics | CACHE_DISCORD_METRICS_TTL | 45 seconds |
REDIS_HOST is not set in .env, the dashboard automatically falls back to an in-memory MemoryStore with a console warning. The bot functions correctly in this mode, but session data is lost on restart and cannot be shared across multiple processes.
Background Jobs
Two background jobs run on intervals afterstartDashboard() is called:
Log Cleanup
Log Cleanup
cleanupOldLogs() on the interval defined by LOGS_CLEANUP_INTERVAL (default: every 24 hours). Removes activityLog records older than the retention window set in LOGS_RETENTION_DAYS (default: 30 days).User Profile Refresh
User Profile Refresh
refreshStaleUserProfiles(discordClient) on the interval set in CACHE_USER_PROFILE_REFRESH (default: every 15 minutes). Processes up to CACHE_USER_PROFILE_BATCH users per run (default: 50) to avoid Discord API rate limits.Metrics History Collection
Metrics History Collection
metricsHistory.recordSample(current) every 30 seconds to populate the time-series data used by the metrics chart.Automated Alert Delivery
Automated Alert Delivery
ALERTS_WEBHOOK_URL is configured, the bot sends any active HIGH severity alerts to the webhook every 5 minutes using Discord’s webhook API.