Commit c8aa964
feat: store per-user Copilot metrics in DB for time-series team queries beyond 28 days (#320)
* Initial plan
* chore: initial progress plan
Co-authored-by: karpikpl <3539908+karpikpl@users.noreply.github.com>
Agent-Logs-Url: https://github.com/github-copilot-resources/copilot-metrics-viewer/sessions/5335ff71-a8b7-4d3b-94c3-ba4e5298fe24
* feat: derive team-level metrics from per-user Copilot Metrics API
- Add UserDayRecord type for the per-user flat-array report format
- Add fetchUsersLatestReport() to fetch from users-28-day/latest endpoint
- Add mockRequestUsersDownloadLinks() for mock mode support
- Create user-metrics-aggregator.ts to filter by team membership and aggregate
- Update metrics-util-v2.ts to use per-user aggregation for team scopes
- Add mock team membership data to fetchAllTeamMembers for mock mode
- Add organization-users-28-day-report.json mock data (4 users across 2 teams)
- Add 13 unit tests covering the aggregation logic
Fixes #319
Co-authored-by: karpikpl <3539908+karpikpl@users.noreply.github.com>
Agent-Logs-Url: https://github.com/github-copilot-resources/copilot-metrics-viewer/sessions/5335ff71-a8b7-4d3b-94c3-ba4e5298fe24
* feat: add user_metrics DB table and daily sync of per-user records
Co-authored-by: karpikpl <3539908+karpikpl@users.noreply.github.com>
Agent-Logs-Url: https://github.com/github-copilot-resources/copilot-metrics-viewer/sessions/a6664e8e-ae95-4975-b09a-d134cfe6581b
* feat: restructure team historical path to always resolve members then aggregate from user_metrics DB
Co-authored-by: karpikpl <3539908+karpikpl@users.noreply.github.com>
Agent-Logs-Url: https://github.com/github-copilot-resources/copilot-metrics-viewer/sessions/a6664e8e-ae95-4975-b09a-d134cfe6581b
* refactor: consolidate user_metrics into user_day_metrics — single table, single sync
Agent-Logs-Url: https://github.com/github-copilot-resources/copilot-metrics-viewer/sessions/df8cca74-2471-4729-8218-e1226e3a2351
Co-authored-by: karpikpl <3539908+karpikpl@users.noreply.github.com>
* refactor: address code review — document active_users threshold change, strengthen window test, extract constant
Agent-Logs-Url: https://github.com/github-copilot-resources/copilot-metrics-viewer/sessions/df8cca74-2471-4729-8218-e1226e3a2351
Co-authored-by: karpikpl <3539908+karpikpl@users.noreply.github.com>
* fix: scope normalization, team-scope sync gate, and batch chunking for user_day_metrics
Agent-Logs-Url: https://github.com/github-copilot-resources/copilot-metrics-viewer/sessions/b6d60a7e-ed39-4ab0-b591-51bb07dcb607
Co-authored-by: karpikpl <3539908+karpikpl@users.noreply.github.com>
* feat: fix tests, v3.0.3, remove CHANGELOG, deploy-info in footer, new preview-deploy workflow
Agent-Logs-Url: https://github.com/github-copilot-resources/copilot-metrics-viewer/sessions/54dbe4e5-0ee3-4edc-a369-c8785cd01293
Co-authored-by: karpikpl <3539908+karpikpl@users.noreply.github.com>
* fix: mock fetchLatestReport uses relative dates so storage pipeline test always passes
Agent-Logs-Url: https://github.com/github-copilot-resources/copilot-metrics-viewer/sessions/73635db5-669c-4657-aa2c-07e961d69053
Co-authored-by: karpikpl <3539908+karpikpl@users.noreply.github.com>
* fix: historical mode fallback — 503 on DB failure without auth, graceful empty for history, unit tests
Agent-Logs-Url: https://github.com/github-copilot-resources/copilot-metrics-viewer/sessions/db83f379-bce8-4f86-989c-73d436e1c4f5
Co-authored-by: karpikpl <3539908+karpikpl@users.noreply.github.com>
* fix: chat mock data (fallback), v3.0.4, remove design docs, DB readiness wait in preview deploy
Agent-Logs-Url: https://github.com/github-copilot-resources/copilot-metrics-viewer/sessions/96e057e3-efd8-4694-b3c7-a95c8da1eab7
Co-authored-by: karpikpl <3539908+karpikpl@users.noreply.github.com>
* fix: same-env guarantee for all containers, fixed Log Analytics workspace name
Agent-Logs-Url: https://github.com/github-copilot-resources/copilot-metrics-viewer/sessions/96e057e3-efd8-4694-b3c7-a95c8da1eab7
Co-authored-by: karpikpl <3539908+karpikpl@users.noreply.github.com>
* fix: filter user-metrics by team membership
/api/user-metrics was returning all org users regardless of team scope.
Added filterByTeamIfNeeded() that resolves team members via GitHub Teams
API and filters UserTotals by user_id (primary) and login (fallback).
- Historical mode + team scope without auth now returns 503
- Added 5 unit tests for team filtering behavior
- Added Playwright real-data test suite (30 tests) for cody-test-org
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: skip real-data Playwright tests in CI
real-data-teams.spec.ts requires a live GitHub API connection and
PostgreSQL. Skip via RUN_REAL_DATA_TESTS env var check, plus
grepInvert: /@real-data/ in Docker Playwright config for defense
in depth.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: align metrics/reportData indices in fetchAndStore
transformReportToMetrics() sorts day_totals by day, but the store loop
iterated the original unsorted report.day_totals array. This caused
metrics[i] (sorted) to be saved with dayData.day from the unsorted
array, corrupting the metrics_date ↔ data.date mapping in the DB.
Fix: use sorted reportData for the store loop so indices stay aligned.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: resolve @/model import in sync container
The standalone sync container runs via tsx which doesn't have Nuxt's
auto-generated tsconfig with @/* path aliases. Added tsconfig.sync.json
with explicit @/* -> app/* path mapping and updated Dockerfile.sync to
use --tsconfig tsconfig.sync.json flag.
This fixes: ERR_MODULE_NOT_FOUND: Cannot find package '@/model'
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: don't coerce undefined premium_requests_total to 0
The GitHub API does not include a premium_requests_total field. The DB
read path was coercing undefined to 0, which made the UI show the
premium column with all zeros. Preserve undefined so the UI's
hasPremiumData check correctly hides the column.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* refactor: remove fabricated premium_requests_total column
The GitHub Copilot Metrics API does not include a premium_requests_total
field. This was entirely fabricated in mock data and caused a phantom
column to appear in the UI. Removed from:
- Vue component (card, filter, table column, chart dataset)
- API types and aggregation logic
- Storage interfaces and DB read functions
- Mock data JSON files
- Unit tests (6 tests removed)
- E2E tests and page objects (3 tests removed)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: remove premium reference from metrics.spec.ts e2e test
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* docs: update README and DEPLOYMENT for v3.0 team metrics and historical mode
- Replace outdated legacy API shutdown banner with past-tense note
- Add Operating Modes section explaining Direct API vs Historical mode
- Document how team metrics are derived from per-user data (no team API)
- Add Per-User Metrics tab documentation
- Remove broken links to non-existent migration docs
- Fix NUXT_PUBLIC_SCOPE values (team-organization/team-enterprise)
- Remove old 5+ team member warning (no longer applies)
- Update API docs link to new Copilot Usage Metrics API
- Make PostgreSQL/sync optional in DEPLOYMENT.md (historical mode only)
- Add Direct API mode Docker Compose instructions
- Remove USE_LEGACY_API from env vars (legacy API shut down)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* docs: update screenshots and fix team metrics requiring historical mode
- Capture fresh screenshots for all tabs using Playwright
- Add new user-metrics.png screenshot for User Metrics tab
- Fix incorrect claim that team views work in Direct API mode
- Team-scoped views require Historical mode (PostgreSQL) because
team data is derived from per-user records stored in the database
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* revert: restore original screenshots, keep only new user-metrics.png
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: karpikpl <3539908+karpikpl@users.noreply.github.com>
Co-authored-by: Piotr Karpala <karpik.pl@gmail.com>
Co-authored-by: Piotr Karpala <piotrkarpala@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent 08881d6 commit c8aa964
44 files changed
Lines changed: 2185 additions & 5077 deletions
File tree
- .github/workflows
- app
- components
- layouts
- e2e-tests
- pages
- images
- public/mock-data/new-api
- server
- api
- admin
- services
- storage
- tasks
- tests
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Large diffs are not rendered by default.
This file was deleted.
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | | - | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
10 | 20 | | |
11 | 21 | | |
12 | 22 | | |
13 | 23 | | |
14 | 24 | | |
15 | 25 | | |
16 | 26 | | |
17 | | - | |
| 27 | + | |
18 | 28 | | |
19 | | - | |
20 | | - | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
21 | 39 | | |
22 | 40 | | |
23 | 41 | | |
| |||
129 | 147 | | |
130 | 148 | | |
131 | 149 | | |
132 | | - | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
133 | 169 | | |
134 | 170 | | |
135 | 171 | | |
| |||
250 | 286 | | |
251 | 287 | | |
252 | 288 | | |
253 | | - | |
254 | | - | |
255 | | - | |
256 | | - | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
257 | 293 | | |
258 | | - | |
259 | | - | |
260 | | - | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
261 | 297 | | |
262 | | - | |
263 | 298 | | |
264 | 299 | | |
265 | 300 | | |
| |||
0 commit comments