--- title: Alerting Squad Guidelines description: Alerting-specific patterns and conventions for Grafana globs: - 'public/app/features/alerting/**' --- # Alerting Squad - Claude Code Configuration This file provides context for Claude Code when working on the Grafana Alerting codebase. It contains alerting-specific patterns and references to Grafana's coding standards. ## Project Context **Location**: `public/app/features/alerting/unified/` **Squad**: Alerting **Focus**: Frontend development for Grafana's unified alerting system **Tech Stack**: React, TypeScript, Redux Toolkit, RTK Query, Emotion, Jest, React Testing Library, MSW ## Grafana Coding Standards **IMPORTANT**: Always follow Grafana's official style guides. Do not duplicate standards here - reference the source files: ### Required Reading 1. **Frontend Style Guide**: [../../../../../contribute/style-guides/frontend.md](../../../../../contribute/style-guides/frontend.md) - Naming conventions, component patterns, TypeScript, exports - Function declarations for components, callback props with "on" prefix 2. **Testing Guidelines**: [../../../../../contribute/style-guides/testing.md](../../../../../contribute/style-guides/testing.md) - React Testing Library, query priorities, user event setup 3. **Styling Guide**: [../../../../../contribute/style-guides/styling.md](../../../../../contribute/style-guides/styling.md) - Emotion usage, `useStyles2` hook patterns 4. **Redux Framework**: [../../../../../contribute/style-guides/redux.md](../../../../../contribute/style-guides/redux.md) - Redux Toolkit patterns, reducer testing 5. **Alerting Testing Guide**: [./TESTING.md](./TESTING.md) - MSW API mocking, permission mocking, data source setup ### Alerting-Specific Conventions **Use @grafana/alerting Package**: - **Always check @grafana/alerting for shared components/hooks** before creating new ones: ```typescript // Good - Use exported components/hooks from @grafana/alerting import { AlertLabel, alertingMatchers } from '@grafana/alerting'; // Check what's available before reimplementing ``` **Layout Components**: - **Prefer @grafana/ui layout components** over styled divs: ```typescript // Good - Use Box for simple layout/spacing import { Box } from '@grafana/ui'; Content // Good - Use Stack for flex layouts import { Stack } from '@grafana/ui';
Item 1
Item 2
// Avoid - Custom styled divs when layout components exist
Content
``` ## Alerting Codebase Structure ### Key Directories - `api/` - RTK Query API slices for data fetching - `components/` - Feature-specific React components organized by domain - `hooks/` - Reusable custom hooks for logic and data fetching - `rule-editor/` - Alert rule creation and editing forms - `rule-list/` - Alert rules list views (v1 and v2) - `state/` - Redux state management and context providers - `utils/` - Utility functions and helpers - `types/` - TypeScript type definitions - `mocks/` - MSW mock server setup for testing - `testSetup/` - Test utilities and configuration ### Component Domains - `alert-groups/` - Alert grouping and filtering - `contact-points/` - Contact point configuration - `notification-policies/` - Notification routing policies - `mute-timings/` - Mute timing windows - `silences/` - Silence management - `receivers/` - Receiver configuration - `templates/` - Notification templates - `permissions/` - Permission management - `settings/` - Alertmanager settings ## State Management Patterns ### RTK Query (Primary - Preferred) **IMPORTANT**: Our direction is to use RTK Query for data fetching, NOT Redux. Do not create new RTKQ endpoints, those should be created manually. - API slices in `api/` directory - Custom base query in `api/alertingApi.ts` - Automatic caching with 2-minute polling: `RULE_LIST_POLL_INTERVAL_MS` - Key APIs: `alertRuleApi`, `alertmanagerApi`, `prometheusApi`, `receiversApi` **For new features**: Always use RTK Query hooks for data fetching: ```typescript import { useGetAlertRulesQuery } from '../api/alertRuleApi'; const { data, isLoading, error } = useGetAlertRulesQuery(params); ``` ### Redux Toolkit (Legacy) **Avoid for new features** - Use RTK Query instead - Legacy reducers exist in `state/reducers/` - Use state selectors: `useUnifiedAlertingSelector` - Only modify if maintaining existing Redux code ### Context Providers - `AlertmanagerContext` - Alertmanager selection state, for managing Alertmanager entities for a specific Alertmanager data source. - `SettingsContext` - Settings state – used in `public/app/features/alerting/unified/components/settings` - `WorkbenchContext` - Workbench state used in the alert triage feature `public/app/features/alerting/unified/triage` ### Forms - Use `react-hook-form` (v7) for all forms - See `rule-editor/alert-rule-form/` for patterns ## Alerting-Specific Testing Patterns See [./TESTING.md](./TESTING.md) for comprehensive testing guide. Key points: ### API Mocking with MSW **REQUIRED**: Use MSW for all API mocking (not `jest.fn()`) – though it's fine to use this function for unit testing. ```typescript import { mockApi } from '../mockApi'; // Mock common endpoints mockApi.eval(); // for AlertingQueryRunner // If helper doesn't exist, add it to mockApi.ts ``` **Why MSW?** Forces proper loading state handling, discovers UI issues early ### Permission Mocking **Default: RBAC enabled** (most common user scenario) ```typescript import { enableRBAC, grantUserPermissions } from '../mocks'; enableRBAC(); // Usually not needed, enabled by default grantUserPermissions([AccessControlAction.AlertingRuleRead]); ``` ### Mock Data Factories Located in `mocks.ts`: ```typescript mockDataSource(); mockPromAlert(); mockRulerGrafanaRule(); mockAlertmanagerAlert(); mockSilence(); ``` ### Data Source Setup Located in `testSetup/datasources.ts` for data source mocking patterns ### Test Data Factories **Use factories for creating test data** - Don't manually create objects. For Kubernetes APIs and new schemas – use the `@grafana/alerting` package. Mock factories are defined in `packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/fakes` MSW handlers in `packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers` And there are "scenarios" that combine the two above. An example of such is `packages/grafana-alerting/src/grafana/contactPoints/components/ContactPointSelector/ContactPointSelector.test.scenario.ts` and is used for integration tests. Additionally alerting uses **`alertingFactory`** from `mocks/server/db` for building test data: ```typescript import { alertingFactory } from './mocks/server/db'; import { mockFolder } from './mocks'; // Build a single alerting rule const alertingRuleBuilder = alertingFactory.ruler.grafana.alertingRule; const rule = alertingRuleBuilder.build(); // Build multiple rules const rules = alertingRuleBuilder.buildList(6); // Override specific fields const customRule = alertingRuleBuilder.build({ grafana_alert: { title: 'CPU Alert' }, labels: { severity: 'critical' }, }); ``` **Common patterns**: ```typescript // Alerting rules alertingFactory.ruler.grafana.alertingRule.build(); alertingFactory.ruler.grafana.alertingRule.buildList(n); // Folders mockFolder(); // Simple mock function // Override fields when building alertingRuleBuilder.build({ grafana_alert: { title: 'Custom Title' }, labels: { key: 'value' }, }); ``` **Benefits**: - Consistent test data across tests - Easy to generate multiple instances with `buildList(n)` - Override only the fields you care about - Automatic sequencing (e.g., "Alerting rule 1", "Alerting rule 2") **Other mock functions** (from `mocks.ts`): ```typescript mockDataSource(); mockPromAlert(); mockRulerGrafanaRule(); mockAlertmanagerAlert(); mockSilence(); mockFolder(); ``` ## Alerting-Specific Patterns ### Feature Toggles & settings A full list of features can be found in `pkg/services/featuremgmt/toggles_gen.csv` – focus on feature toggles owned by `@grafana/alerting-squad`. ```typescript import { config } from '@grafana/runtime'; if (config.featureToggles.alertingTriage) { // Render triage view } ``` A common configuration setting would be `unifiedAlertingEnabled` which allows a user to configure Grafana without any alerting UI or backend enabled at all. ### Data Source Abstractions ```typescript import { isGrafanaRulerRule } from '../utils/rules'; if (isGrafanaRulerRule(rule)) { // Grafana-managed } else { // External alertmanager } ``` ### Access Control (RBAC) ```typescript import { useAbilities } from '../hooks/useAbilities'; function Component() { const [_, { can }] = useAbilities(); const canCreate = can(AccessControlAction.AlertingRuleCreate); return canCreate ? : null; } ``` ### Key Routes Defined in `routes.tsx`: - `/alerting` - Home - `/alerting/list` - Rules list (v1/v2) - `/alerting/new/:type?` - Create rule - `/alerting/:id/edit` - Edit rule - `/alerting/notifications` - Contact points - `/alerting/routes` - Notification policies ### Common Hooks ```typescript useCombinedRuleNamespaces(); // Combines Prometheus + Ruler rules useAlertmanagerConfig(); // Fetch alertmanager config useFolder(); // Folder operations useUnifiedAlertingSelector(); // Redux state – avoid using useAbilities(); // Permission checking ``` ### Link URLs and Navigation **IMPORTANT**: Different navigation components require different URL formats. #### When to use `createRelativeUrl` Use `createRelativeUrl` **only with LinkButton** (and other components that render HTML `` elements): ```typescript import { createRelativeUrl } from '@grafana/data'; import { LinkButton } from '@grafana/ui'; // LinkButton renders tag - needs manual subpath prefix View Rules ``` **Why?** LinkButton renders a native HTML anchor element, so it doesn't use React Router. You must manually add the subpath prefix using `createRelativeUrl`. #### When NOT to use `createRelativeUrl` Do **NOT** use `createRelativeUrl` with: 1. **locationService** - Automatically adds prefix: ```typescript import { locationService } from '@grafana/runtime'; // locationService uses react-router history - prefix added automatically locationService.push('/alerting/list'); // ✅ Correct - no createRelativeUrl locationService.push(createRelativeUrl('/alerting/list')); // ❌ Wrong - double prefix! ``` 2. **TextLink component** - Automatically adds prefix: ```typescript import { TextLink } from '@grafana/ui'; // TextLink uses react-router Link - prefix added automatically View Rules // ✅ Correct View Rules // ❌ Wrong ``` #### Summary | Component/Service | Use `createRelativeUrl`? | Reason | | -------------------- | ------------------------ | --------------------------------------- | | `LinkButton` | ✅ YES | Renders `` tag (native HTML) | | `Button` with `href` | ✅ YES | Renders `` tag when href provided | | `locationService` | ❌ NO | Uses react-router history (auto-prefix) | | `TextLink` | ❌ NO | Uses react-router Link (auto-prefix) | | React Router `Link` | ❌ NO | React Router component (auto-prefix) | **Rule of thumb**: If it renders a native HTML `` tag, use `createRelativeUrl`. If it uses React Router, don't. ## Key Libraries ### Grafana Internal - `@grafana/ui` - UI components (Button, Select, Input, etc.) - `@grafana/data` - Data models and utilities - `@grafana/runtime` - Runtime services (config, backendSrv, locationService) - `@grafana/scenes` - Scene framework (Insights/Triage views) - `@grafana/e2e-selectors` - Test selectors - `@grafana/alerting` - Grafana managed alerting specific package (utility functions, API endpoints, mocks, React components, etc) ### External - `react-hook-form` (v7) - Form state - `@reduxjs/toolkit` - Redux + RTK Query - `@emotion/css` - Styling - `lodash` - Utilities - `msw` - API mocking for tests ## Quick Reference Checklists ### Creating a New Component 1. ✅ Create in appropriate `components/` subdirectory 2. ✅ Use function declaration (not arrow function) 3. ✅ Add TypeScript props interface (no "I" prefix) 4. ✅ Use `useStyles2` for styling (Emotion) 5. ✅ Create colocated test file 6. ✅ Use MSW for API mocking in tests 7. ✅ Query with `*ByRole` queries ### Adding a New API Endpoint 1. ✅ Add to relevant API slice in `api/` (RTK Query) 2. ✅ Add helper to `mockApi.ts` for testing 3. ✅ Handle loading/error states in UI 4. ✅ Test with MSW ### Creating a New Form 1. ✅ Use `react-hook-form` (v7) 2. ✅ See `rule-editor/alert-rule-form/` for patterns 3. ✅ Add validation (schema if needed) 4. ✅ Handle API submission errors 5. ✅ Test user interactions with `userEvent` ### Writing Tests Check https://testing-library.com/docs/queries/about/ for what selectors to prefer when using React Testing Library - [ ] RBAC enabled by default - [ ] MSW for API mocking (not `jest.fn()`) - [ ] Loading states tested - [ ] Error states tested - [ ] User interactions use `userEvent.setup()` - [ ] Queries prefer `*ByRole` - [ ] Async operations use `await` and `findBy*` - [ ] Permissions tested with `grantUserPermissions` ## Using GitHub CLI for Context When working on issues, PRs, or needing repository context, use the GitHub CLI (`gh`) to fetch information directly: ### Common Commands ```bash # View issue details gh issue view # View PR details and diff gh pr view gh pr diff # List recent issues gh issue list --limit 10 # List PRs with specific labels gh pr list --label "alerting" # Search issues gh issue list --search "keyword" # View PR reviews and comments gh pr view --comments # Check CI status gh pr checks # View repository info gh repo view ``` ### When to Use - **Understanding issue context**: Fetch issue descriptions, comments, and linked PRs - **Reviewing PR changes**: Get diffs, review comments, and CI status - **Finding related work**: Search for similar issues or existing implementations - **Checking project status**: List open issues/PRs for the alerting team ### Example Workflow ```bash # Working on issue #12345 gh issue view 12345 # Check if there's an existing PR gh pr list --search "fixes #12345" # Review a related PR gh pr view 67890 gh pr diff 67890 ``` ## Getting Help - Check patterns in existing `components/` code - Review test examples in `*.test.tsx` files - Consult `mockApi.ts` for API mocking - See `mocks.ts` for data factories - Read [./TESTING.md](./TESTING.md) for testing details - Review Grafana style guides (linked at top) - Use `gh` CLI to fetch issue/PR context from GitHub --- **Last Updated**: 2025-11-21 **Maintained By**: Alerting Squad