Files
cosmos-explorer/.github/copilot-instructions.md
jawelton74 b483118b99 Copilot instructions and build/test skills (#2444)
* Add copilot instructions and skills for build and tests.

* Add dev-server skill.

* Auth Util changes to fix Entra login while running from copilot.

* Fix lint issue.
2026-04-06 15:51:54 -07:00

164 lines
8.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Copilot Instructions for Cosmos Explorer
## Build, Test, and Lint
**To build the project, use the `/build` skill.** It handles dependency checks (`npm install`) and all build variants. See `.github/skills/build/SKILL.md` for full details.
Quick reference:
```bash
npm install # Install dependencies (runs patch-package and i18n key generation automatically)
npm run build # Full build: format check → lint → compile → strict compile → webpack prod → copy
npm run build:ci # CI build: same as above but uses webpack dev mode (faster)
npm start # Dev server with hot reload at https://localhost:1234 (see /dev-server skill)
npm run compile # TypeScript check only (no emit)
npm run compile:strict # TypeScript strict mode check (subset of files in tsconfig.strict.json)
npm run lint # ESLint across all .ts/.tsx files
npm run format # Prettier format (write)
npm run format:check # Prettier format (check only)
```
### Testing
**To run unit tests, use the `/run-unit-tests` skill.** It handles dependency checks and all test variants. See `.github/skills/run-unit-tests/SKILL.md` for full details.
Quick reference:
```bash
npm test # Run all unit tests with Jest (includes coverage)
npm run test:file -- path/to/file.test.ts # Run a single test file (no coverage)
npm run test:debug # Run tests serially for debugging (--runInBand)
# E2E tests (requires .env config and running dev server)
npm run test:e2e # Playwright E2E tests
npx playwright test test/sql/document.spec.ts # Run a single E2E spec
```
Unit tests live adjacent to source files (`*.test.ts` / `*.test.tsx` in `src/`). E2E tests are in `test/` organized by API type (sql, mongo, cassandra, gremlin, tables).
### Dev Server
**To start the local dev server and connect a browser, use the `/dev-server` skill.** It handles dependency checks, server startup, readiness polling, and Playwright browser navigation. See `.github/skills/dev-server/SKILL.md` for full details.
The dev server runs at `https://localhost:1234` with a `/_ready` health-check endpoint. Entry points include `hostedExplorer.html` (standalone), `explorer.html` (portal iframe), and `index.html` (emulator).
## Architecture
### Platform Modes
The app runs in four hosting contexts, determined by `ConfigContext.platform`:
- **Portal** Embedded as an iframe inside Azure Portal
- **Hosted** Standalone at cosmos.azure.com, supports AAD, connection string, and resource token auth
- **Emulator** Connects to local Cosmos DB Emulator via master key
- **Fabric** Embedded in Microsoft Fabric, communicates via postMessage RPC
Platform-specific code lives in `src/Platform/{Emulator,Hosted,Fabric}/`. The active platform is set during initialization in `src/hooks/useKnockoutExplorer.ts`, which orchestrates bootstrapping for all modes.
### Global State (Module Singletons + Zustand)
State is **not** managed by React Context or Redux for most application concerns. Instead:
- **`userContext`** (`src/UserContext.ts`) Module-level singleton holding current account info, auth tokens, API type, and feature flags. Updated via `updateUserContext()`. Not a React store; components read it directly.
- **`configContext`** (`src/ConfigContext.ts`) Module-level singleton for environment/endpoint configuration. Updated via `updateConfigContext()`.
- **Zustand stores** (`src/hooks/use*.ts`) Used for UI state that React components need to subscribe to reactively. Key stores:
- `useDatabases` Database/collection tree state
- `useTabs` Open tab management
- `useQueryCopilot` Copilot query assistant state
- `useNotificationConsole` Console notifications
- `useSidePanel` Side panel visibility
- `useSelectedNode` Currently selected tree node
### Data Access Layer
`src/Common/dataAccess/` contains all Cosmos DB CRUD operations (createCollection, readDatabases, queryDocuments, etc.). These functions call either the Cosmos SDK (`@azure/cosmos`) directly or go through proxy endpoints depending on the API type and auth method.
ARM (Azure Resource Manager) clients are auto-generated in `src/Utils/arm/generatedClients/` — regenerate with `npm run generateARMClients`.
### Multi-API Support
Cosmos DB supports multiple APIs: SQL, Mongo, Gremlin, Tables, Cassandra, Postgres, and VCoreMongo. The current API type is determined from `userContext.apiType` (derived from the database account's capabilities). API-specific UI components branch on this value.
### Entry Points
Webpack builds multiple independent entry points (see `webpack.config.js`):
- `src/Main.tsx``explorer.html` (Portal iframe)
- `src/Index.tsx``index.html` (Emulator)
- `src/HostedExplorer.tsx``hostedExplorer.html` (cosmos.azure.com)
- Plus: terminal, cellOutputViewer, galleryViewer, selfServe, connectToGitHub, quickstart
### Knockout → React Migration
The codebase is actively migrating from Knockout.js to React. Legacy Knockout code still exists (observables, bindings), but all new UI must be React. The main `Explorer` class (`src/Explorer/Explorer.tsx`) is a large legacy class that orchestrates much of the app — it is not a React component but interacts with React via hooks and stores.
## Key Conventions
### Ignored Directories
The `src/preview/` folder is a separate project and should not be modified or referenced.
### Localization
All user-facing strings must be defined in `src/Localization/en/Resources.json` and referenced via the type-safe `t()` helper:
```typescript
import { t } from "Localization/t";
// Use dot-notation keys matching the JSON structure
const label = t("common.save");
const title = t("splashScreen.title.default");
```
The `ResourceKey` type (derived from `Resources.json`) ensures compile-time safety — invalid keys will cause a type error. When adding new strings, add the English entry to `Resources.json` first, then reference it with `t()`.
### Imports
TypeScript `baseUrl` is set to `src/`, so imports from `src/` are written without a leading `./src/` prefix:
```typescript
import { userContext } from "UserContext"; // src/UserContext.ts
import { configContext } from "ConfigContext"; // src/ConfigContext.ts
import { readDatabases } from "Common/dataAccess/readDatabases";
```
### React Components
- Use **Fluent UI v9** (`@fluentui/react-components`) for new components. Legacy code uses v8 (`@fluentui/react`), but new code should prefer v9.
- Prefer pure functional components; hooks and class components are both acceptable
- Do **not** use component inheritance for shared behavior
- Do **not** suffix file or component names with "Component"
### ESLint Rules to Note
- `no-console`: Only `console.error` and `console.warn` are allowed (not `console.log`)
- `@typescript-eslint/no-explicit-any`: Error — avoid `any` types
- `prefer-arrow/prefer-arrow-functions`: Arrow functions preferred (standalone declarations allowed)
- `eqeqeq`: Strict equality required
- `@typescript-eslint/switch-exhaustiveness-check`: Switch statements must handle all cases
- Do not use `JSON.stringify(error)` — it prints `'{}'`. The linter catches variable names matching `$err`.
### Testing
Any code change should consider both unit and E2E test coverage:
- **Unit tests** Write or update unit tests for all logic, utility, and component changes. Place test files adjacent to the source file (`Foo.test.ts` next to `Foo.ts`). Do not decrease existing coverage.
- **E2E tests** Write or update a Playwright E2E test when a change affects a user-facing workflow (e.g., creating a container, running a query, editing a document). E2E tests live in `test/` organized by API type.
Tooling and conventions:
- Use **Jest** for unit tests with `jest-environment-jsdom`
- Use `@testing-library/react` for new component tests. Enzyme exists in legacy tests but should not be used for new code.
- Use Jest built-in mocking (not sinon.js)
- E2E tests use **Playwright** (configured in `playwright.config.ts`); use accessible attributes (role, title, label) over `data-*` attributes for selectors
### Strict Null Checks
The project is incrementally adopting strict null checks. `tsconfig.strict.json` lists files that compile under `--strictNullChecks`. **New files must be added to `tsconfig.strict.json`** so they compile under strict mode. Use `npm run strict:add` to add eligible files.
### Libraries to Avoid
- **underscore.js** Use native JS methods instead (legacy usage exists)
- **jQuery** Being removed; do not add new usage
- **sinon.js** Deprecated; use Jest mocking
- **TSLint** Removed; use ESLint only
### Formatting
Prettier with `printWidth: 120` and `endOfLine: auto`. Format is enforced in the build pipeline via `npm run format:check`.