Skip to content

Mega-PR: combine open PRs #424-#443 for integration review - #444

Draft
karpikpl wants to merge 32 commits into
mainfrom
mega/all-open-prs-424-plus
Draft

Mega-PR: combine open PRs #424-#443 for integration review#444
karpikpl wants to merge 32 commits into
mainfrom
mega/all-open-prs-424-plus

Conversation

@karpikpl

Copy link
Copy Markdown
Collaborator

Mega-PR that combines all currently-open PRs #424 and above into one branch, resolving conflicts along the way. Verified with npm test (827/827 passing) and npm run build (success).

Included PRs

# Title Notes
#424 Fix synthetic chat model buckets in top model KPIs Clean merge
#425 fix(billing): unify credits definition and add tooltips Clean merge
#426 fix(ui): correct Top token users empty-state guidance Clean merge
#427 fix(a11y): add labels and non-color activity cue Clean merge
#428 fix(billing): rank Top spenders server-side across all users Clean merge
#429 Fix Top spenders for fully-discounted billing plans Conflict resolved — combined with #428: pass server-side topSpendersData.value.users through buildTopSpendersChartData() so gross-fallback ranking still runs against the full dataset
#430 fix(billing): honor table sort order in per-user lazy load Conflict resolved — kept all three imports (billingCredits, billingTopSpenders, billingPerUserLazyLoad)
#431 fix(user-metrics): paginate response to prevent OOM Clean merge
#437 feat(billing): add per-user search to billing breakdown Conflict resolved — combined with #430: onTableOptions now feeds filteredPerUserRowsForLazyLoad into buildPerUserBillingLazyLoadRequest, so search + sort + lazy-load all interact correctly
#438 feat(my-usage): add accepted lines tooltip Clean merge
#439 fix(billing): surface unmatched EMU billing usernames Conflict resolved — additive with #428: response now returns both users and unmatchedBillingUsernames; frontend accumulates both
#440 Structured leveled logging with request IDs Clean merge
#441 Add opt-in structured security audit log Conflict resolved — combined with #440: kept createLogger alongside emitAuditEvent imports in all five auth providers; proxy-agent.ts now logs the redacted proxy URL via logger.info
#443 build(deps): dependabot npm group updates Clean merge

Review notes

Validation

  • npm install
  • npm test827 passed, 0 failed
  • npm run build → ✅
  • Conflicts: 5 files resolved by hand (see table above)

Purpose

Intended as a single integration branch for reviewers to see the full combined behavior. Individual PRs remain the canonical review units — this is a draft and should not be merged directly.

karpikpl and others added 30 commits July 13, 2026 21:38
…top chat model (#420)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: bbf27d66-9aca-451b-85ee-3a32e0775d52
…tiles (#421)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: bbf27d66-9aca-451b-85ee-3a32e0775d52
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: bbf27d66-9aca-451b-85ee-3a32e0775d52
…ity band (#422)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: bbf27d66-9aca-451b-85ee-3a32e0775d52
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: bbf27d66-9aca-451b-85ee-3a32e0775d52
…penders (#419)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: bbf27d66-9aca-451b-85ee-3a32e0775d52
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: bbf27d66-9aca-451b-85ee-3a32e0775d52
…ses (#416)

Add bounded pagination for /api/user-metrics with a default and maximum page size of 500 rows. Historical DB reads now page distinct users before aggregating per-day records, while preserving array responses for existing callers and exposing pagination metadata headers.

Validation: npm test; npm run build.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: bbf27d66-9aca-451b-85ee-3a32e0775d52
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: bbf27d66-9aca-451b-85ee-3a32e0775d52
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: bbf27d66-9aca-451b-85ee-3a32e0775d52
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: bbf27d66-9aca-451b-85ee-3a32e0775d52
…nly usage (#433)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: bbf27d66-9aca-451b-85ee-3a32e0775d52
…s mapping (#432)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: bbf27d66-9aca-451b-85ee-3a32e0775d52
…ring redaction (#435)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: bbf27d66-9aca-451b-85ee-3a32e0775d52
…-access events (#436)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: bbf27d66-9aca-451b-85ee-3a32e0775d52
…dates

Bumps the npm_and_yarn group with 2 updates in the / directory: [svgo](https://github.com/svg/svgo) and [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite).


Updates `svgo` from 4.0.1 to 4.0.2
- [Release notes](https://github.com/svg/svgo/releases)
- [Commits](svg/svgo@v4.0.1...v4.0.2)

Updates `vite` from 7.3.3 to 7.3.6
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v7.3.6/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.3.6/packages/vite)

---
updated-dependencies:
- dependency-name: svgo
  dependency-version: 4.0.2
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: vite
  dependency-version: 7.3.6
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
# Conflicts:
#	app/components/BillingCreditsViewer.vue
…load

# Conflicts:
#	app/components/BillingCreditsViewer.vue
# Conflicts:
#	app/components/BillingCreditsViewer.vue
# Conflicts:
#	app/components/BillingCreditsViewer.vue
#	server/api/billing-credits.get.ts
#	server/services/billing-credit-reader.ts
# Conflicts:
#	server/routes/auth/auth0.get.ts
#	server/routes/auth/github.get.ts
#	server/routes/auth/google.get.ts
#	server/routes/auth/keycloak.get.ts
#	server/routes/auth/microsoft.get.ts
#	server/utils/proxy-agent.ts
Copilot AI review requested due to automatic review settings July 29, 2026 12:36
@karpikpl karpikpl added the deploy Deploys to preview env label Jul 29, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This mega-PR integrates a set of fixes and features across billing, user-metrics pagination, accessibility improvements, and new observability (structured logging + opt-in audit log) in the Nuxt 3 Copilot Metrics Viewer.

Changes:

  • Adds DB-backed billing capabilities (global top spenders endpoint, per-user sorting/paging hooks, EMU billing username aliasing + unmatched username surfacing).
  • Introduces structured, tagged server logging with request IDs and expands coverage with new Vitest suites.
  • Improves UI accessibility (aria-labels, non-color activity cues) and refines UX copy/tooltips across multiple viewers.

Reviewed changes

Copilot reviewed 60 out of 60 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/user-metrics.spec.ts Updates assertions and adds pagination-focused coverage for /api/user-metrics.
tests/top-chat-model.nuxt.spec.ts Nuxt-environment regression tests for skipping synthetic chat model buckets in KPIs.
tests/server-logger.spec.ts Unit tests for new logger behavior and request logging middleware.
tests/MyUsageViewer.source.spec.ts Source-level regression for Accepted lines tooltip presence/copy.
tests/billing-top-spenders.spec.ts Tests for gross fallback ranking logic in top spenders chart data builder.
tests/billing-per-user-search.spec.ts Source-level tests for per-user search wiring + lazy-load behavior.
tests/billing-per-user-lazy-load.spec.ts Tests for building sort-aware per-user lazy-load requests.
tests/billing-credits.db-first.spec.ts Expands DB-first billing tests (by-user sorting/paging + top-users endpoint behavior).
tests/billing-credits-top-token-empty-state.spec.ts Source-level regression for corrected Top token users empty state and test id.
tests/billing-credits-calculation.spec.ts Tests shared credits definition between tiles and per-user rows.
tests/billing-credit-reader.spec.ts Adds tests for EMU aliasing, unmatched billing usernames, paging/sorting, and top-user ranking SQL.
tests/audit.spec.ts Unit tests for opt-in audit logging, field inclusion, and redaction behavior.
tests/audit-call-sites.spec.ts Verifies audit events are emitted from key auth/authz/admin call sites.
tests/a11y-components.spec.ts Enforces aria-labels for icon-only buttons and verifies activity-band cue presence.
shared/utils/billing-user-identity.ts Adds parsing/normalization utilities for EMU billing username ↔ metrics login aliasing.
server/utils/usage-admin.ts Emits audit events for usage-admin allow/deny decisions.
server/utils/proxy-agent.ts Switches proxy initialization logging to structured logger and redacts proxy credentials.
server/utils/logger.ts Introduces tagged logger abstraction with pretty/JSON output support.
server/utils/authorization.ts Emits audit events for OAuth allowlist denials.
server/utils/audit.ts Adds opt-in JSONL audit event emitter with sensitive-detail redaction.
server/storage/user-metrics-storage.ts Adds paging/filter support when reading stored user metrics, including total count.
server/services/sync-service.ts Migrates sync gap logging to structured logger.
server/services/github-saml-service.ts Migrates SAML fetch warnings to structured logger.
server/services/github-copilot-usage-api.ts Migrates error/info logging to structured logger with structured fields.
server/services/billing-credit-reader.ts Adds top-users aggregate + EMU aliasing/unmatched reporting + new sort/paging hooks.
server/routes/auth/microsoft.get.ts Adds structured logger + audit login success for Microsoft OAuth handler.
server/routes/auth/keycloak.get.ts Adds structured logger + audit login success for Keycloak OAuth handler.
server/routes/auth/google.get.ts Adds structured logger + audit login success for Google OAuth handler.
server/routes/auth/github.get.ts Adds structured logger + audit login success for GitHub OAuth handler.
server/routes/auth/auth0.get.ts Adds structured logger + audit login success for Auth0 OAuth handler.
server/plugins/db-init.ts Migrates DB init logs to structured logger.
server/plugins/auth-config-check.ts Migrates auth config warning to structured logger.
server/modules/github-app-auth.ts Migrates JWT build log to structured logger.
server/middleware/log.ts Adds request logging middleware with request IDs and skip/redaction behavior.
server/api/user-metrics.ts Adds pagination (cap at 500) + pagination headers + self-filtering support for storage reads.
server/api/my-usage.get.ts Emits audit event when an admin views another user’s usage.
server/api/billing-credits.get.ts Adds audit event for billing view + extends response shape for users/unmatched usernames.
server/api/billing-credits-top-users.get.ts Adds DB-only endpoint for global top billing users ranking.
server/api/billing-credits-by-user.get.ts Adds audit event, EMU alias fan-out, and client sort/page support for live responses; forwards DB sort/page options.
server/api/ai/chat.post.ts Migrates Models API error logging to structured logger.
server/api/admin/sync.post.ts Emits audit events for admin sync/billing CSV actions; reduces repeated identifier recomputation.
server/api/admin/overview.get.ts Migrates enrichment warning logging to structured logger.
package-lock.json Dependency lock updates (svgo/vite bumps and root dependency spec metadata changes).
nuxt.config.ts Adds runtime-config wiring for log controls and audit log enable flag.
app/utils/billingTopSpenders.ts Adds chart data builder with net→gross fallback behavior.
app/utils/billingPerUserLazyLoad.ts Adds helper to build sort-aware per-user billing lazy-load requests.
app/utils/billingCredits.ts Centralizes credits-used calculation (net + discount).
app/components/UserMetricsViewer.vue Adds aria-labels and non-color activity labels for user activity UI elements.
app/components/TeamsComponent.vue Adds aria-labels for icon-only buttons and layout toggles.
app/components/SeatsAnalysisViewer.vue Adds aria-labels for layout toggle buttons.
app/components/PullRequestViewer.vue Adds aria-labels for layout toggle buttons.
app/components/MyUsageViewer.vue Adds Accepted lines tooltip + filters synthetic chat model buckets for top model.
app/components/MetricsViewer.vue Skips synthetic chat model buckets and adds aria-labels for layout toggles.
app/components/MainComponent.vue Adds aria-labels for toolbar icon buttons; forces user-metrics fetch to page=1/pageSize=500.
app/components/CopilotChatViewer.vue Adds aria-labels for layout toggle buttons.
app/components/BreakdownComponent.vue Adds aria-labels for layout toggle buttons.
app/components/BillingCreditsViewer.vue Unifies credits definition + tooltips; adds per-user search; server-side top spenders; shows unmatched billing usernames.
app/components/AiChatPanel.vue Adds aria-labels for chat panel actions and send button.
app/components/AgentModeViewer.vue Adds aria-labels for layout toggle buttons.
app/components/AgentActivityViewer.vue Adds aria-labels for layout toggle buttons.
app/components/AdminPanel.vue Adds aria-labels for icon-only admin actions.

Comment thread server/utils/logger.ts
Comment on lines +102 to +122
export function createLogger(tag: string): TaggedLogger {
const log = (type: 'error' | 'warn' | 'info' | 'debug', message: string, ...args: unknown[]) => {
const config = getRuntimeLoggingConfig()
const level = normalizeLogLevel(config.logLevel)
if (!isLogLevelAtLeast(level, type)) return

const logger = createConsola({
level: LEVELS.debug,
reporters: [createReporter(shouldUseJsonFormat(config.logFormat))],
}).withTag(tag)

logger[type](message, ...args)
}

return {
error: (message, ...args) => log('error', message, ...args),
warn: (message, ...args) => log('warn', message, ...args),
info: (message, ...args) => log('info', message, ...args),
debug: (message, ...args) => log('debug', message, ...args),
}
}
Comment on lines +82 to +97
await emitAuditEvent('billing.per_user.viewed', {
action: 'view',
outcome: 'allow',
target: options.githubOrg || options.githubEnt || 'unknown',
detail: {
scope: options.scope,
requestedLogins,
requestedCount: requestedLogins.length,
year: query.year,
month: query.month,
day: query.day,
model: query.model,
product: query.product,
costCenterId: query.cost_center_id,
},
}, event);
Comment on lines 354 to +358
FROM billing_credit_usage
WHERE ${conds.join(' AND ')}
GROUP BY username, product, sku, model, unit_type
ORDER BY username, product, sku, model
ORDER BY ${order}, username, product, sku, model
${limitClause}
Copilot AI review requested due to automatic review settings July 29, 2026 12:42
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Preview Deployment Ready

Preview URL: https://cmv-app.purpletree-900a4a21.westus.azurecontainerapps.io

Deployed: PR #444 | 3ed80d7 | 2026-07-29T12:43:37Z

This is a shared preview environment. It shows the latest deploy-labeled PR.
The environment will be cleaned up when the PR is merged.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 60 out of 60 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (2)

server/services/billing-credit-reader.ts:360

  • LIMIT/OFFSET is applied to the per-(username, product, sku, model, unit_type) grouped rows, not to distinct users. This means a "page" can contain partial data for a user (under-counting their totals), and sort keys like models are also incorrect here because COUNT(DISTINCT model) will be 1 for every grouped row when grouping includes model. To support server-side sorted paging by user, the query needs to page a distinct user list (ordered by aggregated metric) and then fetch all grouped rows for just those users.
    server/utils/logger.ts:106
  • createLogger currently constructs a new Consola instance (and reporter) on every log call. On hot paths (e.g., request middleware) this adds avoidable allocation/GC overhead. Consider caching the Consola instance per tag and only recreating it when the log format mode changes.

Comment on lines 210 to 214
const billingHeaders = new Headers({
Authorization: `Bearer ${billingToken}`,
Accept: 'application/vnd.github+json',
'X-GitHub-Api-Version': '2026-03-10',
});
@mfischbacher5600

Copy link
Copy Markdown

Hi Piotr,

It's awesome to see the project growing so quickly!
As soon as this PR has been merged, I'd appreciate it if you could create a new tag so I can start testing again.
Most of the issues I was planning to report after my holiday have already been addressed.

We plan to roll out the Metrics Viewer to our developers next weeks.
I'll make sure they don't overwhelm you with feature requests and bug reports.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

deploy Deploys to preview env

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants