{"id":32527841,"url":"https://github.com/crimsonsunset/hh-dashboard","last_synced_at":"2026-07-09T15:31:26.366Z","repository":{"id":320102903,"uuid":"1080802736","full_name":"crimsonsunset/hh-dashboard","owner":"crimsonsunset","description":"Modern data exploration interface for analyzing LLM response patterns and performance metrics - Built with React, TypeScript, and TanStack Router","archived":false,"fork":false,"pushed_at":"2025-11-06T01:01:04.000Z","size":695,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-11-06T03:05:51.637Z","etag":null,"topics":["ai-metrics","analytics","chart-js","dashboard","data-visualization","llm","react","tanstack-router","typescript"],"latest_commit_sha":null,"homepage":"https://hh-dashboard.netlify.app/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/crimsonsunset.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"docs/roadmap.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-21T22:22:14.000Z","updated_at":"2025-11-06T01:01:07.000Z","dependencies_parsed_at":"2025-10-22T01:07:43.304Z","dependency_job_id":"425cf269-6ea8-4a69-a07c-64d95e2645e8","html_url":"https://github.com/crimsonsunset/hh-dashboard","commit_stats":null,"previous_names":["crimsonsunset/hh-dashboard"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/crimsonsunset/hh-dashboard","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crimsonsunset%2Fhh-dashboard","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crimsonsunset%2Fhh-dashboard/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crimsonsunset%2Fhh-dashboard/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crimsonsunset%2Fhh-dashboard/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/crimsonsunset","download_url":"https://codeload.github.com/crimsonsunset/hh-dashboard/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crimsonsunset%2Fhh-dashboard/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35304874,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-09T02:00:07.329Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-metrics","analytics","chart-js","dashboard","data-visualization","llm","react","tanstack-router","typescript"],"created_at":"2025-10-28T10:52:03.276Z","updated_at":"2026-07-09T15:31:26.360Z","avatar_url":"https://github.com/crimsonsunset.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# LLM Data Explorer\n\nA modern, type-safe data exploration interface for analyzing LLM response patterns and performance metrics. Built with React, TypeScript, and TanStack Router following clean architecture patterns.\n\n## 🎯 Purpose\n\nData exploration tool for AI engineers to understand LLM performance through:\n- Interactive data loading (small/large datasets)\n- Response time visualization with line charts\n- Comprehensive data table with virtual scrolling (1000+ rows)\n- Model comparison (GPT-4, GPT-3.5, Claude)\n- Token usage, cost analysis, and quality metrics\n- Error and timeout tracking\n\n## 🚀 Tech Stack\n\n### Core Framework\n- **React 19** - Latest React with modern features\n- **TypeScript 5.8** - Strict type safety throughout\n- **Vite 7** - Lightning-fast build tool and dev server\n- **TanStack Router 1.x** - Type-safe file-based routing\n\n### UI \u0026 Styling\n- **Ant Design 5.x** - Comprehensive component library with built-in theming\n- **Recharts 3.x** - Composable charting library for data visualization\n\n### State Management\n- **Zustand 5.x** - Lightweight state management for in-memory data and UI state\n\n### Development Tools\n- **ESLint 9** - Code quality and consistency\n- **TypeScript ESLint** - TypeScript-specific linting rules\n\n## ✨ Features\n\n### Foundation (Complete)\n✅ **Type-Safe Architecture** - Strict TypeScript with full inference  \n✅ **Clean Code Patterns** - Maintainable, extensible codebase structure  \n✅ **Theme System** - Dark/light mode with persistent state  \n✅ **Path Aliases** - Clean imports using `@stores`, `@components`, etc.  \n✅ **Mock LLM Data** - Small (~5 responses) and large (~1000 responses) datasets  \n\n### Core MVP (In Development)\n- **Data Loading Interface** - Load small or large datasets with one click\n- **Response Time Chart** - Line chart visualization using Recharts\n- **Virtual Scrolling Table** - Ant Design table handling 1000+ rows smoothly\n- **Data Reset** - Clear current dataset and load a different one\n\n### Future Enhancements\n- **Chart Type Selector** - Toggle between response time, token usage, cost, and quality metrics\n- **File Upload** - Drag-and-drop JSON file support with validation  \n\n## 📁 Project Structure\n\n```\nhh-dashboard/\n├── src/\n│   ├── routes/              # File-based routing (TanStack Router)\n│   ├── components/          # Reusable React components\n│   │   ├── layout/         # Layout components\n│   │   ├── charts/         # Chart components\n│   │   └── ui/             # UI components\n│   ├── stores/             # Zustand state management\n│   ├── types/              # TypeScript type definitions\n│   ├── services/           # API service layer\n│   ├── hooks/              # Custom React hooks\n│   ├── utils/              # Helper utilities\n│   ├── config/             # Configuration files\n│   ├── assets/             # Static assets\n│   └── styles/             # Global styles\n├── docs/                   # Project documentation\n└── public/                 # Public static files\n    └── data/               # Mock LLM response data\n        ├── long.mock-data.json   # Large dataset (~1000 responses)\n        └── short.mock-data.json  # Small dataset (~5 responses)\n```\n\n## 📊 Data Structure\n\nLLM response data structure:\n\n```typescript\ninterface LLMResponse {\n  id: string\n  timestamp: string\n  model: 'gpt-4' | 'gpt-3.5-turbo' | 'claude-3' | string\n  prompt_tokens: number\n  completion_tokens: number\n  total_tokens: number\n  response_time_ms: number\n  status: 'success' | 'error' | 'timeout'\n  cost_usd: number\n  temperature: number\n  max_tokens: number\n  prompt_template: string\n  output: string | null\n  evaluation_metrics: {\n    relevance_score: number\n    factual_accuracy: number\n    coherence_score: number\n    response_quality: number\n  } | null\n  error: {\n    type: string\n    message: string\n  } | null\n}\n```\n\n### Path Aliases\nAll top-level `src` directories use path aliases for clean imports:\n\n```typescript\nimport { useAppStore } from '@stores/app.store'\nimport { DashboardLayout } from '@components/layout/dashboard-layout.component'\nimport { LLMResponse } from '@data/llm.types'\n```\n\n### File Naming Convention\n- **Components**: `kebab-case.component.tsx` (e.g., `dashboard-layout.component.tsx`)\n- **Stores**: `kebab-case.store.ts` (e.g., `app.store.ts`)\n- **Types**: `kebab-case.types.ts` (e.g., `llm.types.ts`)\n- **Services**: `kebab-case.service.ts` (e.g., `llm.service.ts`)\n- **Hooks**: `use-kebab-case.hook.ts` (e.g., `use-llm-data.hook.ts`)\n\n## 🛠️ Getting Started\n\n### Prerequisites\n- Node.js 18+ and npm\n\n### Installation\n\n```bash\n# Install dependencies\nnpm install\n\n# Start development server\nnpm run dev\n\n# Build for production\nnpm run build\n\n# Preview production build\nnpm run preview\n\n# Run linter\nnpm run lint\n```\n\n### Development Server\nThe app runs at `http://localhost:5173` with hot module replacement enabled.\n\n## 🏗️ Architecture Decisions\n\n### State Management Strategy\n- **Zustand** for in-memory loaded dataset and UI state (theme, preferences)\n- Client-side data loading (no API calls, direct JSON parsing)\n- Simple, predictable state flow for data exploration\n\n### Why These Technologies?\n\n**TanStack Router**\n- Type-safe routing with full TypeScript inference\n- File-based routing for intuitive project structure\n- Built-in code splitting for optimal performance\n\n**Zustand**\n- Minimal boilerplate compared to Redux\n- No context provider needed\n- Perfect for in-memory data management\n- Tiny bundle size (~1KB)\n\n**Recharts**\n- React-first charting library\n- Composable, declarative API\n- Responsive by default\n\n**Ant Design**\n- Enterprise-grade components\n- Built-in virtual scrolling for tables\n- Excellent theming system\n\n## 📊 Data Flow\n\n1. **User Action** → Click \"Load Small Dataset\" or \"Load Large Dataset\"\n2. **Data Fetch** → Load JSON file from `/src/data/`\n3. **Parse \u0026 Validate** → Validate against `LLMResponseData` type\n4. **Store Update** → Zustand store receives parsed data\n5. **UI Re-render** → Chart and table components display data\n6. **Reset** → Clear store, return to loading state\n\n## 🎨 Theming\n\nThe app uses Ant Design's built-in theming system with full support for:\n- Light and dark color schemes\n- Consistent component styling across themes\n- Persistent theme preference in Zustand store\n\nToggle theme via the user menu in the top-right corner.\n\n## 📝 Implementation Approach\n\n### Overview\nThis project implements a production-ready LLM response data explorer with emphasis on clean architecture, type safety, and performance optimization.\n\n### Technical Approach\n1. **State Management Pattern**: Three-layer strategy separating UI state (Zustand), server state (React Query), and URL state (TanStack Router)\n2. **Data Loading**: Client-side JSON file loading with React Query for caching and conditional fetching\n3. **File Validation**: Three-layer validation system (extension → JSON syntax → schema validation)\n4. **Performance**: Virtual scrolling for 1000+ row tables, conditional query fetching, memoized chart data\n5. **Error Handling**: User-facing error messages via Ant Design message component with try-catch wrappers\n\n### Key Architectural Decisions\n- **TanStack Router**: Type-safe file-based routing with full TypeScript inference\n- **Zustand**: Minimal state management (~1KB) for UI preferences and dataset selection\n- **React Query**: Server state management with built-in caching and background refetching\n- **Ant Design**: Enterprise-grade components with virtual scrolling and theming support\n- **Recharts**: React-first declarative charting library\n\n### Implementation Status\n- ✅ **Phase 1**: Core data explorer (complete)\n- ✅ **Phase 3**: File upload with validation (completed ahead of schedule)\n- ⏸️ **Phase 2**: Enhanced visualization (deferred)\n\n## 🎯 Design Principles\n\nThis MVP is built as the foundation of a long-term project:\n- **Clean Architecture** - Separation of concerns, maintainable patterns\n- **Type Safety** - Strict TypeScript, no compromises\n- **Simplicity First** - Minimal styling, focus on functionality\n- **Performance** - Smooth handling of 1000+ data points\n- **Extensibility** - Easy to add new chart types and features\n\n## 📋 Assumptions Made\n\n1. **Client-Side Only**: No backend API required for MVP; all data processing happens client-side\n2. **Mock Data Sufficiency**: Two dataset sizes (5 and 1000 responses) are adequate for demonstration\n3. **JSON Format**: Custom uploaded files follow the same schema as mock data (`LLMResponseData` type)\n4. **Browser Support**: Modern browsers with ES2022 support (Chrome, Firefox, Safari, Edge)\n5. **Single User**: No authentication or multi-user considerations needed for MVP\n6. **Static Deployment**: App can be deployed to static hosting (Netlify, Vercel, etc.)\n7. **Theme Persistence**: Theme preference persists in memory only (session-based, no localStorage)\n8. **Virtual Scrolling**: Ant Design's virtual scrolling is sufficient for handling large datasets\n\n## 🚀 Future Improvements\n\nGiven more time, the following enhancements would be prioritized:\n\n### Immediate Priorities\n- **Wire up Date Selection**: Connect the date picker in the header to filter data by timestamp range\n- **Proper URL Routing**: Implement query params for shareable filtered views (`/dashboard?filters=X`)\n- **Graph Selector**: Add dropdown to toggle between different chart types (response time, tokens, cost, quality)\n\n### Architecture \u0026 Quality\n- **Styling System**: Establish design tokens and CSS-in-JS primitives for consistent theming\n- **Responsive Design**: Optimize layout for mobile and tablet devices\n- **Testing Framework**: Add unit tests (React Testing Library) and E2E tests (Playwright)\n\n### Features\n- **Advanced Filtering**: Multi-field filtering (model, status, date range, metrics thresholds)\n- **Data Export**: CSV/JSON export functionality\n- **Chart Interactions**: Tooltips, zoom, brush selection for detailed analysis\n- **Metrics Cards**: Summary statistics at top of dashboard\n- **Error Boundaries**: Route-level and component-level error recovery\n\n### Performance\n- **Code Splitting**: Dynamic imports for chart components\n- **Loading Skeletons**: Replace spinners with skeleton screens\n- **Debounced Search**: Add search/filter inputs with debouncing\n\n## 📄 License\n\nThis project is private and not licensed for public use.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrimsonsunset%2Fhh-dashboard","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcrimsonsunset%2Fhh-dashboard","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrimsonsunset%2Fhh-dashboard/lists"}