Skip to content

Latest commit

 

History

History
167 lines (135 loc) · 7.38 KB

File metadata and controls

167 lines (135 loc) · 7.38 KB

AGENTS.md

Copilot Insights — enterprise analytics dashboard for GitHub Copilot usage data.

Setup commands

cd app
pnpm install              # Install dependencies
pnpm run dev              # Development server (port 3000)
pnpm run build            # Production build (validates types + lint)
pnpm run test             # Run unit tests (vitest)
pnpm run test:watch       # Run tests in watch mode
pnpm run db:generate      # Generate Drizzle migrations after schema changes
pnpm run db:migrate       # Run pending migrations

Deploy

azd deploy               # Deploy app to Azure Container Apps
azd up                   # Full provision + deploy (first time)

Project structure

app/                      # Next.js 16 application
  src/
    app/                  # Pages (App Router) + API routes (/api/*)
      ai-adoption/        # AI adoption cohorts report
      ai-credits/         # AI credits usage + billing report
      enterprise-teams/   # Enterprise Teams page
      settings/app-info/  # Application Info settings page
    components/           # Reusable React components
      layout/             # Sidebar, breadcrumb, report filters, report banner
      ui/                 # DataTable, EmptyState, and shared UI
    lib/
      db/                 # Drizzle ORM: schema, connection, settings
      etl/                # ETL pipeline: ingest + transform
      github/             # GitHub API client (pagination, retry, rate limiting)
      i18n/               # Internationalization: LocaleProvider, translations (en/ar/es/fr)
      theme/              # Dark/light/system theme: ThemeProvider, chart-theme
      utils/              # Model display names and helpers
    types/                # TypeScript type definitions
  drizzle/                # Generated SQL migration files
  public/                 # Static assets (favicon.ico, copilot-icon.svg)
infra/                    # Azure Bicep infrastructure-as-code
docs/                     # Architecture documentation (Mermaid diagrams)
.github/
  copilot-instructions.md # GitHub Copilot workspace instructions
  agents/                 # Copilot custom agent definitions
  instructions/           # File-specific Copilot instructions

Tech stack

  • Next.js 16.2 (App Router), React 19.2, TypeScript 6.0 (strict mode)
  • PostgreSQL 18 with Drizzle ORM 0.45 (star schema)
  • Chart.js 4.5 via react-chartjs-2 5.3 for visualizations
  • Tailwind CSS 4.2 (no custom CSS files)
  • Zod 4.3 for all input validation
  • Vitest for unit testing
  • Azure Container Apps, Key Vault, ACR, Application Insights
  • GitHub Copilot Usage Metrics API v2026-03-10
  • GitHub Enterprise Teams API v2026-03-10

Code style

  • TypeScript strict mode with path alias @/*./src/*
  • Use import type for type-only imports
  • PascalCase for components/types, camelCase for functions, UPPER_SNAKE_CASE for constants
  • snake_case for database columns; dim_ prefix for dimensions, fact_ for facts
  • Tailwind CSS only — use cn() utility (clsx + tailwind-merge) for conditional classes
  • Icons from lucide-react, images via next/image
  • LF line endings enforced via .gitattributes

Logging

Use structured console methods — never console.log:

console.info("Operation completed successfully");
console.warn("Rate limited. Retrying...");
console.error("Failed to fetch data:", error);

API routes

  • All routes under app/src/app/api/ use Zod for query param validation
  • Date format always YYYY-MM-DD, validated with isValidDate() from @/lib/utils
  • Wrap handlers in try-catch, return { error: "Internal server error" } on failure
  • Use Drizzle ORM for all queries — no raw SQL strings
  • Never leak stack traces or internal details in error responses
  • Enterprise Teams API: /api/enterprise-teams, /api/enterprise-teams/[teamId]/members, /api/enterprise-teams/sync
  • Health check: /api/health
  • App info: /api/settings/app-info

Database

  • Star schema: dimension tables (dim_user, dim_feature, dim_model, dim_language, dim_enterprise_team) + fact tables
  • dim_user follows SCD Type 2 with effective_from, effective_to, is_current
  • dim_enterprise_team + dim_enterprise_team_member for enterprise team data
  • Schema defined in app/src/lib/db/schema.ts
  • After schema changes: run cd app && pnpm run db:generate, commit the migration file
  • Migrations run automatically on app startup via instrumentation.ts
  • Use onConflictDoUpdate for ETL upserts

Components

  • Server Components by default — add "use client" only when state/effects are needed
  • Dashboard pages: ReportFilters for date range + user + org + team filter, DataTable for tabular data
  • Report pages include a shared ReportBanner directly after DataSourceBanner
  • Charts: react-chartjs-2 wrappers (Line, Bar, Doughnut)
  • Use useChartOptions() from @/lib/theme/chart-theme for theme-aware Chart.js options
  • Use useTranslation() from @/lib/i18n/locale-provider for i18n strings
  • EmptyState component handles: not configured, not synced, no data, no results for filters

Theme (Dark Mode)

  • Three modes: light, dark, system — toggled via sidebar
  • ThemeProvider in app/src/lib/theme/theme-provider.tsx manages state via localStorage
  • Tailwind class strategy: html.dark class toggles dark mode
  • All components use dark: Tailwind variants for dark mode styling
  • Charts use useChartOptions() hook for theme-aware options (grid, text, tooltip colors)
  • useTheme() returns { theme, setTheme, resolvedTheme }

Internationalization (i18n)

  • Four languages: English, Arabic (RTL), Spanish, French
  • LocaleProvider in app/src/lib/i18n/locale-provider.tsx manages locale via localStorage
  • Translations in app/src/lib/i18n/translations/{en,ar,es,fr}.ts
  • Access via useTranslation() hook: const { t } = useTranslation()
  • Keys use dot-path notation: t("dashboard.activeUsers")
  • Template placeholders: t("dashboard.ofTotal", count) → replaces {0}
  • All page titles, subtitles, KPI labels, chart titles, and table headers use t() calls
  • TypeScript type safety: TranslationKeys type exported from en.ts

Enterprise Teams

  • Enterprise teams are synced from the GitHub Enterprise Teams API (/enterprises/{slug}/teams)
  • Team members are fetched from /enterprises/{slug}/teams/{team_slug}/members
  • Requires read:enterprise scope on the PAT
  • Teams are stored in dim_enterprise_team, members in dim_enterprise_team_member
  • Teams can be used as filters on all reports — resolves to member user IDs
  • Sync is triggered manually via the Enterprise Teams page or during data ingest

Docker

Next.js standalone output mode — the Dockerfile runner stage must explicitly copy:

  • .next/standalone, .next/static, public/, drizzle/

Security

  • All secrets in Azure Key Vault — never in env vars, parameters, or code
  • Validate all user input with Zod at API boundaries
  • No raw SQL — Drizzle ORM parameterized queries only
  • Admin password gate on Settings page
  • Managed Identity for Azure resource access
  • Required PAT scopes: manage_billing:copilot (read), read:org, read:enterprise, manage_billing:enterprise (read)

Testing

  • Unit tests: cd app && pnpm run test (vitest)
  • Build validation: cd app && pnpm run build (validates TypeScript types + lint)
  • Test files: src/**/*.test.ts and src/**/*.test.tsx
  • Tests cover: transform functions, NDJSON parsing, utility functions