Files
discord-rpg-concept/tickets/2026-01-08-dashboard-real-data-integration.md

203 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DASH-001: Dashboard Real Data Integration
**Status:** In Review
**Created:** 2026-01-08
**Tags:** dashboard, api, discord-client, database, real-time
## 1. Context & User Story
* **As a:** Bot Administrator
* **I want to:** See real data on the dashboard instead of mock/hardcoded values
* **So that:** I can monitor actual bot metrics, user activity, and system health in real-time
## 2. Technical Requirements
### Data Model Changes
- [ ] No new tables required
- [ ] SQL migration required? **No** existing schema already has `users`, `transactions`, `moderationCases`, and other relevant tables
### API / Interface
#### New Dashboard Stats Service
Create a new service at `shared/modules/dashboard/dashboard.service.ts`:
```typescript
interface DashboardStats {
guilds: {
count: number;
changeFromLastMonth?: number;
};
users: {
active: number;
changePercentFromLastMonth?: number;
};
commands: {
total: number;
changePercentFromLastMonth?: number;
};
ping: {
avg: number;
changeFromLastHour?: number;
};
recentEvents: RecentEvent[];
activityOverview: ActivityDataPoint[];
}
interface RecentEvent {
type: 'success' | 'error' | 'info';
message: string;
timestamp: Date;
}
```
#### API Endpoints
| Method | Path | Description |
|--------|------|-------------|
| `GET` | `/api/stats` | Returns `DashboardStats` object |
| `GET` | `/api/stats/realtime` | WebSocket/SSE for live updates |
### Discord Client Data
The `AuroraClient` (exported from `bot/lib/BotClient.ts`) provides access to:
| Property | Data Source | Dashboard Metric |
|----------|-------------|------------------|
| `client.guilds.cache.size` | Discord.js | Total Servers |
| `client.users.cache.size` | Discord.js | Active Users (approximate) |
| `client.ws.ping` | Discord.js | Avg Ping |
| `client.commands.size` | Bot commands | Commands Registered |
| `client.lastCommandTimestamp` | Custom property | Last command run time |
### Database Data
Query from existing tables:
| Metric | Query |
|--------|-------|
| User count (registered) | `SELECT COUNT(*) FROM users WHERE is_active = true` |
| Commands executed (today) | `SELECT COUNT(*) FROM transactions WHERE type = 'COMMAND_RUN' AND created_at >= NOW() - INTERVAL '1 day'` |
| Recent moderation events | `SELECT * FROM moderation_cases ORDER BY created_at DESC LIMIT 10` |
| Recent transactions | `SELECT * FROM transactions ORDER BY created_at DESC LIMIT 10` |
> [!IMPORTANT]
> The Discord client instance (`AuroraClient`) is in the `bot` package, while the web server is in the `web` package. Need to establish cross-package communication:
> - **Option A**: Export client reference from `bot` and import in `web` (same process, simple)
> - **Option B**: IPC via shared memory or message queue (separate processes)
> - **Option C**: Internal HTTP/WebSocket between bot and web (microservice pattern)
## 3. Constraints & Validations (CRITICAL)
- **Input Validation:**
- API endpoints must not accept arbitrary query parameters
- Rate limiting on `/api/stats` to prevent abuse (max 60 requests/minute per IP)
- **System Constraints:**
- Discord API rate limits apply when fetching guild/user data
- Cache Discord data and refresh at most every 30 seconds
- Database queries should be optimized with existing indices
- API response timeout: 5 seconds maximum
- **Business Logic Guardrails:**
- Do not expose sensitive user data (only aggregates)
- Do not expose Discord tokens or internal IDs in API responses
- Activity history limited to last 24 hours to prevent performance issues
- User counts should count only registered users, not all Discord users
## 4. Acceptance Criteria
1. [ ] **Given** the dashboard is loaded, **When** the API `/api/stats` is called, **Then** it returns real guild count from Discord client
2. [ ] **Given** the bot is connected to Discord, **When** viewing the dashboard, **Then** the "Total Servers" shows actual `guilds.cache.size`
3. [ ] **Given** users are registered in the database, **When** viewing the dashboard, **Then** "Active Users" shows count from `users` table where `is_active = true`
4. [ ] **Given** the bot is running, **When** viewing the dashboard, **Then** "Avg Ping" shows actual `client.ws.ping` value
5. [ ] **Given** recent bot activity occurred, **When** viewing "Recent Events", **Then** events from `transactions` and `moderation_cases` tables are displayed
6. [ ] **Given** mock data exists in components, **When** the feature is complete, **Then** all hardcoded values in `Dashboard.tsx` are replaced with API data
## 5. Implementation Plan
### Phase 1: Data Layer & Services
- [ ] Create `shared/modules/dashboard/dashboard.service.ts` with statistics aggregation functions
- [ ] Add helper to query active user count from database
- [ ] Add helper to query recent transactions (as events)
- [ ] Add helper to query moderation cases (as events)
---
### Phase 2: Discord Client Exposure
- [ ] Create a client stats provider that exposes Discord metrics
- [ ] Implement caching layer to avoid rate limiting (30-second TTL)
- [ ] Export stats getter from `bot` package for `web` package consumption
---
### Phase 3: API Implementation
- [ ] Add `/api/stats` endpoint in `web/src/server.ts`
- [ ] Wire up `dashboard.service.ts` functions to API
- [ ] Add error handling and response formatting
- [ ] Consider adding rate limiting middleware
---
### Phase 4: Frontend Integration
- [ ] Create custom React hook `useDashboardStats()` for data fetching
- [ ] Replace hardcoded values in `Dashboard.tsx` with hook data
- [ ] Add loading states and error handling
- [ ] Implement auto-refresh (poll every 30 seconds or use SSE/WebSocket)
---
### Phase 5: Activity Overview Chart
- [ ] Query hourly command/transaction counts for last 24 hours
- [ ] Integrate charting library (e.g., Recharts, Chart.js)
- [ ] Replace "Chart Placeholder" with actual chart component
---
## Architecture Decision Required
> [!WARNING]
> **Key Decision: How should the web server access Discord client data?**
>
> The bot and web server currently run in the same process. Recommend:
> - **Short term**: Direct import of `AuroraClient` singleton in API handlers
> - **Long term**: Consider event bus or shared state manager if splitting to microservices
## Out of Scope
- User authentication/authorization for API endpoints
- Historical data beyond 24 hours
- Command execution tracking (would require new database table)
- Guild-specific analytics (separate feature)
---
## Implementation Notes
**Status:** In Review
**Implemented:** 2026-01-08
**Branch:** `feat/dashboard-real-data-integration`
**Commit:** `17cb70e`
### Files Changed
#### New Files Created (7)
1. `shared/modules/dashboard/dashboard.types.ts` - TypeScript interfaces
2. `shared/modules/dashboard/dashboard.service.ts` - Database query service
3. `shared/modules/dashboard/dashboard.service.test.ts` - Service unit tests
4. `bot/lib/clientStats.ts` - Discord client stats provider with caching
5. `bot/lib/clientStats.test.ts` - Client stats unit tests
6. `web/src/hooks/use-dashboard-stats.ts` - React hook for data fetching
7. `tickets/2026-01-08-dashboard-real-data-integration.md` - This ticket
#### Modified Files (3)
1. `web/src/server.ts` - Added `/api/stats` endpoint
2. `web/src/pages/Dashboard.tsx` - Integrated real data with loading/error states
3. `.gitignore` - Removed `tickets/` to track tickets in version control
### Test Results
```
✓ 11 tests passing
✓ TypeScript check clean (bun x tsc --noEmit)
```
### Architecture Decision
Used **Option A** (direct import) for accessing `AuroraClient` from web server, as both run in the same process. This is the simplest approach and avoids unnecessary complexity.