|
| 1 | +# GitHub Copilot Adoption Dashboard - AI Agent Instructions |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +This is a client-side React dashboard for viewing GitHub Copilot enterprise metrics via the GitHub REST API. The app is deployed to GitHub Pages and requires no backend server - all API calls happen directly from the browser to GitHub's API. |
| 6 | + |
| 7 | +**Key constraint**: GitHub Pages deployment with base path `/github-copilot-adoption-dashboard/` (set in `vite.config.ts`). |
| 8 | + |
| 9 | +## Architecture & Data Flow |
| 10 | + |
| 11 | +### Single-Page Application Structure |
| 12 | +- **`App.tsx`**: Monolithic component handling all logic (form state, API fetching, data processing, rendering) |
| 13 | +- **No component decomposition**: All UI (form, metrics cards, chart, table) lives in one 387-line component |
| 14 | +- **Data flow**: User input → GitHub API fetch → `processMetricsData()` → React state → render |
| 15 | + |
| 16 | +### GitHub API Integration |
| 17 | +``` |
| 18 | +Endpoint: GET https://api.github.com/enterprises/{enterprise}/copilot/metrics |
| 19 | +Headers: |
| 20 | + - Authorization: Bearer {token} |
| 21 | + - Accept: application/vnd.github+json |
| 22 | + - X-GitHub-Api-Version: 2022-11-28 |
| 23 | +``` |
| 24 | + |
| 25 | +Response is `DailyMetrics[]` (array of daily metrics, oldest first). The app: |
| 26 | +1. Takes the **last item** as the latest day's data |
| 27 | +2. Builds historical trend from the full array |
| 28 | +3. Flattens the nested structure (`editors → models → languages`) into a breakdown table |
| 29 | + |
| 30 | +### Critical Data Processing Logic |
| 31 | + |
| 32 | +**Total Seats Estimation** (line 140 in App.tsx): |
| 33 | +```typescript |
| 34 | +const estimated_total_seats = Math.round(latestDay.total_active_users * 1.2); |
| 35 | +``` |
| 36 | +This is a workaround - the API doesn't provide total seats, so we estimate at 120% of active users. |
| 37 | + |
| 38 | +**Breakdown Table Sorting** (lines 127-136): |
| 39 | +1. Primary: Active users (descending) |
| 40 | +2. Secondary: Acceptance rate (descending) |
| 41 | + |
| 42 | +**Historical Data Order**: Dates are rendered left-to-right chronologically (oldest to newest) for the Chart.js line chart. |
| 43 | + |
| 44 | +## Development Workflow |
| 45 | + |
| 46 | +### Local Development |
| 47 | +```bash |
| 48 | +npm install # Install dependencies |
| 49 | +npm run dev # Start Vite dev server on localhost:5173 |
| 50 | +``` |
| 51 | + |
| 52 | +### Testing |
| 53 | +```bash |
| 54 | +npm test # Run Vitest in watch mode |
| 55 | +npm run test:ui # Launch Vitest UI |
| 56 | +npm run test:run # Run tests once (CI mode) |
| 57 | +``` |
| 58 | + |
| 59 | +**Test setup**: Vitest with `@testing-library/react`, jsdom environment (configured in `vite.config.ts`). Chart.js is mocked in tests (see `App.test.tsx` line 6). |
| 60 | + |
| 61 | +### Building & Deployment |
| 62 | +```bash |
| 63 | +npm run build # Vite build → dist/ |
| 64 | +npm run preview # Preview production build locally |
| 65 | +``` |
| 66 | + |
| 67 | +Deployment is automated via GitHub Actions. The app **must** work with the `/github-copilot-adoption-dashboard/` base path. |
| 68 | + |
| 69 | +## Project-Specific Conventions |
| 70 | + |
| 71 | +### TypeScript Patterns |
| 72 | +- **Interface naming**: Domain types use descriptive names (`DailyMetrics`, `CopilotIdeCodeCompletions`), not generic prefixes |
| 73 | +- **Array typing**: Use `Type[]` syntax (e.g., `DailyMetrics[]`), not `Array<Type>` |
| 74 | +- **Type safety on API responses**: Explicit `ErrorResponse` interface for error handling |
| 75 | + |
| 76 | +### React Patterns |
| 77 | +- **No JSX import needed**: Uses new `jsx: "react-jsx"` transform (tsconfig.json) |
| 78 | +- **State management**: Plain `useState` - no external state libraries |
| 79 | +- **Event handlers**: Inline arrow functions in JSX (e.g., `onChange={(e) => setToken(e.target.value)}`) |
| 80 | +- **No component composition**: Everything in `App.tsx` - if adding features, follow this pattern unless refactoring |
| 81 | + |
| 82 | +### Styling Approach |
| 83 | +- **No CSS modules or styled-components**: Plain CSS in `index.css` with class-based styling |
| 84 | +- **Layout**: CSS Grid for metrics cards (`grid-template-columns: repeat(auto-fit, minmax(250px, 1fr))`) |
| 85 | +- **Inline styles**: Only for the breakdown table (lines 344-375 in App.tsx) |
| 86 | + |
| 87 | +### Chart.js Configuration |
| 88 | +Chart.js components must be explicitly registered: |
| 89 | +```typescript |
| 90 | +ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend, Filler); |
| 91 | +``` |
| 92 | +Missing this causes runtime errors. The Line chart uses custom tooltip callbacks to format dates and user counts. |
| 93 | + |
| 94 | +## Common Pitfalls & Gotchas |
| 95 | + |
| 96 | +1. **Base path for GitHub Pages**: If adding routing or asset references, account for `/github-copilot-adoption-dashboard/` |
| 97 | +2. **API data order**: The API returns oldest-first, but we show latest-day metrics. Don't reverse arrays unnecessarily |
| 98 | +3. **Sensitive data**: Tokens are in password inputs but never persisted (no localStorage/cookies) |
| 99 | +4. **ESLint config**: Uses flat config format (`eslint.config.js`), not legacy `.eslintrc` |
| 100 | +5. **Testing Chart.js**: Always mock `react-chartjs-2` in tests to avoid canvas errors |
| 101 | + |
| 102 | +## Key Files Reference |
| 103 | + |
| 104 | +- **`App.tsx`**: Single source of truth for all application logic |
| 105 | +- **`vite.config.ts`**: Defines base path and test configuration |
| 106 | +- **`package.json`**: Note the project name is `copilot-metrics-frontend` (historical) |
| 107 | +- **`setupTests.ts`**: Imports jest-dom matchers for Vitest |
| 108 | + |
| 109 | +## When Adding Features |
| 110 | + |
| 111 | +- **New metrics/charts**: Add to the monolithic `App.tsx` unless complexity demands refactoring |
| 112 | +- **New API fields**: Update the `DailyMetrics` type chain and `processMetricsData()` function |
| 113 | +- **Styling changes**: Prefer updating `index.css` over inline styles |
| 114 | +- **Tests**: Mock external dependencies (Chart.js, fetch) and test user-facing behavior |
0 commit comments