forked from syntaxbullet/AuroraBot-discord
203 lines
7.6 KiB
Markdown
203 lines
7.6 KiB
Markdown
# 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.
|