From 08245a2116c3738a1e04700a83f0deec065b2caa Mon Sep 17 00:00:00 2001 From: Lilith Date: Sat, 10 Jan 2026 22:26:17 -0800 Subject: [PATCH] =?UTF-8?q?chore(root):=20=F0=9F=94=A7=20add=20initial=20p?= =?UTF-8?q?latform=20setup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/queue/README.md | 282 ++++++++++++++++++ 1 file changed, 282 insertions(+) create mode 100644 features/platform-admin/frontend-admin/src/components/queue/README.md diff --git a/features/platform-admin/frontend-admin/src/components/queue/README.md b/features/platform-admin/frontend-admin/src/components/queue/README.md new file mode 100644 index 000000000..38f4dbb87 --- /dev/null +++ b/features/platform-admin/frontend-admin/src/components/queue/README.md @@ -0,0 +1,282 @@ +# Queue Components + +Reusable, type-safe components for displaying queue status and metrics. + +## Architecture + +### Component Hierarchy + +``` +queue/ +├── types.ts # Shared types and utilities +├── QueueStatusIndicator.tsx # Compact indicator (dashboard overview) +├── QueueStatusIndicator.test.tsx +├── QueueStatusCard.tsx # Detailed card (queue monitoring) +├── QueueStatusCard.test.tsx +├── index.ts # Barrel exports +└── README.md +``` + +### Primitives Used + +All components are built from `@lilith/ui-*` primitives: + +- **`@lilith/ui-primitives`** - `Card` (QueueStatusCard base) +- **`@lilith/ui-layout`** - `Stack`, `Grid` (not directly used, available for consumers) +- **`@lilith/ui-typography`** - `Text`, `Heading` (not directly used, available for consumers) +- **`styled-components`** - Custom styled components for queue-specific UI + +### Design Principles + +**SOLID:** +- **Single Responsibility** - Each component has one purpose +- **Open/Closed** - Easy to extend via composition, closed for modification +- **Liskov Substitution** - Both components accept same `QueueStats` interface +- **Interface Segregation** - `QueueStatusCard` optionally accepts `QueueDetails` +- **Dependency Inversion** - Components depend on interfaces (types), not concrete implementations + +**DRY:** +- Shared logic in `types.ts` (`hasQueueWork`, `formatQueueCount`, etc.) +- No duplication between components +- Utilities tested once, used everywhere + +**Type Safety:** +- All props strongly typed +- Shared types prevent drift +- TypeScript enforces contracts + +## Components + +### QueueStatusIndicator (Compact) + +**Purpose:** Minimal queue status for dashboard overviews +**Use Case:** Platform Overview, dashboards with limited space + +**Props:** +```typescript +interface QueueStatusIndicatorProps { + queue: QueueStats; + className?: string; +} +``` + +**Features:** +- Shows queue name +- Displays "—" for idle queues +- Shows "X waiting / Y active" for active queues +- Color-coded border (warning = active, success = idle) +- Minimal footprint (single-line display) + +**Example:** +```tsx +import { QueueStatusIndicator } from '@/components/queue'; + + +``` + +**Visual:** +``` +┌─ email ────────────────────────── 5 waiting / 2 active ─┐ +│ [warning border] │ +└──────────────────────────────────────────────────────────┘ + +┌─ analytics ──────────────────────────────────────────── — ┐ +│ [success border] │ +└──────────────────────────────────────────────────────────┘ +``` + +--- + +### QueueStatusCard (Detailed) + +**Purpose:** Comprehensive queue monitoring with metrics +**Use Case:** Queue Dashboard, detailed monitoring pages + +**Props:** +```typescript +interface QueueStatusCardProps { + queue: QueueStats; + details?: QueueDetails; // Optional performance metrics + className?: string; +} +``` + +**Features:** +- Queue name header with Active/Idle status +- Four metrics: Waiting, Active, Completed, Failed +- Smart number formatting (5.5K, 2.5M) +- Optional performance details (avg time, throughput, last processed) +- Color-coded status and warnings +- Card-based layout with left border indicator + +**Example:** +```tsx +import { QueueStatusCard } from '@/components/queue'; + + +``` + +**Visual:** +``` +┌────────────────────────────────────────────────────────┐ +│ [warning border] │ +│ email ● Active │ +│ │ +│ 5 2 1000 3 │ +│ Waiting Active Completed Failed │ +│ │ +│ ──────────────────────────────────────────────────── │ +│ Avg: 234ms Throughput: 12.5/min Last: 5m ago │ +└────────────────────────────────────────────────────────┘ +``` + +--- + +## Shared Types + +### QueueStats (Base) +```typescript +interface QueueStats { + name: string; + waiting: number; + active: number; + completed: number; + failed: number; +} +``` + +### QueueDetails (Extended) +```typescript +interface QueueDetails extends QueueStats { + avgProcessingTime: number; // milliseconds + throughput: number; // jobs per minute + lastProcessedAt?: string; // ISO timestamp +} +``` + +### Utility Functions + +**`hasQueueWork(queue)`** - Returns `true` if queue has waiting or active jobs + +**`getQueueStatus(queue)`** - Returns `'active' | 'idle'` + +**`formatQueueCount(waiting, active, format?)`** - Formats count display +- Returns `"—"` for idle queues +- Returns `"X waiting / Y active"` for compact format +- Returns `"X/Y"` for detailed format + +## Unit Tests + +Both components have comprehensive test coverage: + +### QueueStatusIndicator.test.tsx +- ✅ Renders queue name +- ✅ Shows count for active queues +- ✅ Shows "—" for idle queues +- ✅ Work detection (waiting, active, both, neither) +- ✅ Edge cases (zero values, large numbers, custom className) + +### QueueStatusCard.test.tsx +- ✅ Renders queue name and status +- ✅ Shows all four metrics +- ✅ Conditionally shows performance details +- ✅ Number formatting (999, 5.5K, 2.5M) +- ✅ Work detection and status +- ✅ Edge cases (zero values, custom className) + +**Run tests:** +```bash +# From workspace root +pnpm -w test src/components/queue +``` + +## Usage Examples + +### Dashboard Overview +```tsx +import { QueueStatusIndicator } from '../components/queue'; + +function DashboardPage() { + const { data: queues } = useQueueStats(); + + return ( + + {queues?.map((queue) => ( + + ))} + + ); +} +``` + +### Queue Monitoring Page +```tsx +import { QueueStatusCard } from '../../../components/queue'; + +function QueuesDashboardPage() { + const { data: queues } = useQueueStats(); + const { data: details } = useQueueDetails(); + + return ( + + {queues?.map((queue) => ( + d.name === queue.name)} + /> + ))} + + ); +} +``` + +## Benefits + +### Before Refactor +- ❌ Duplicated queue display logic in 2+ files +- ❌ No type safety for queue data +- ❌ No reusability across pages +- ❌ No unit tests +- ❌ Inline styled components mixed with page logic + +### After Refactor +- ✅ **Single source of truth** - Logic defined once in `types.ts` +- ✅ **Type safety** - Shared interfaces prevent drift +- ✅ **Reusable** - Used in `DashboardPage` and `QueuesDashboardPage` +- ✅ **Tested** - 20+ test cases covering edge cases +- ✅ **Maintainable** - Changes in one place affect all consumers +- ✅ **SOLID/DRY** - Follows architectural principles + +## Future Enhancements + +Potential additions (without breaking existing components): + +1. **Click handlers** - Make components clickable, navigate to queue details +2. **Tooltips** - Show hover details on metrics +3. **Icons** - Add queue type icons (email, image, analytics) +4. **Live updates** - Real-time status via WebSocket +5. **Skeleton loading** - Loading state variants +6. **Theme variants** - Support different UI themes +7. **Export utilities** - Share `formatNumber`, `formatTimeAgo` more broadly + +--- + +**Created:** 2026-01-10 +**Patterns:** Component-driven design, Type-safe props, Unit tested +**Dependencies:** `@lilith/ui-primitives`, `styled-components`