Skip to content

Commit c6f3b8a

Browse files
committed
Merge branch 'master' into wmak/chore/update-all-ifcombinators-to-include-operator
2 parents 5a2489a + 293699a commit c6f3b8a

File tree

1,072 files changed

+18957
-9263
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,072 files changed

+18957
-9263
lines changed

.cursor/rules/tsx_tests.mdc renamed to .cursor/rules/typescript_tests.mdc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030

3131
- **User-centric testing**: Write tests that resemble how users interact with the app.
3232
- **Avoid implementation details**: Focus on behavior, not internal component structure.
33+
- **Do not share state between tests**: Behavior should not be influenced by other tests in the test suite.
3334

3435
## Query Priority (in order of preference)
3536

@@ -99,6 +100,23 @@ PageFiltersStore.onInitializeUrlState(
99100
)
100101
```
101102

103+
### Use fixtures
104+
105+
Sentry fixtures are located in tests/js/fixtures/ while GetSentry fixtures are located in tests/js/getsentry-test/fixtures/.
106+
107+
```tsx
108+
109+
// ❌ Don't import type and initialize it
110+
import type {Project} from 'sentry/types/project';
111+
const project: Project = {...}
112+
113+
// ✅ Import a fixture instead
114+
import {ProjectFixture} from 'sentry-fixture/project';
115+
116+
const project = ProjectFixture(partialProject)
117+
118+
```
119+
102120
### Use `screen` instead of destructuring
103121
```tsx
104122
// ❌ Don't do this

.github/CODEOWNERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,4 +680,6 @@ tests/sentry/api/endpoints/test_organization_dashboard_widget_details.py @ge
680680
/static/app/components/core/ @getsentry/design-engineering
681681
/static/app/icons/ @getsentry/design-engineering
682682
/static/app/stories/ @getsentry/design-engineering
683+
/static/.cursor/BUGBOT.md @getsentry/design-engineering
684+
/static/CLAUDE.md @getsentry/design-engineering
683685
## End of Frontend Platform

CLAUDE.md

Lines changed: 9 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ Sentry is a developer-first error tracking and performance monitoring platform.
66

77
## Tech Stack
88

9+
### Frontend
10+
11+
See `static/CLAUDE.md` for frontend development guide.
12+
913
### Backend
1014

1115
- **Language**: Python 3.13+
@@ -17,15 +21,6 @@ Sentry is a developer-first error tracking and performance monitoring platform.
1721
- **Stream Processing**: Arroyo (Kafka consumer/producer framework)
1822
- **Cloud Services**: Google Cloud Platform (Bigtable, Pub/Sub, Storage, KMS)
1923

20-
### Frontend
21-
22-
- **Language**: TypeScript
23-
- **Framework**: React 19
24-
- **Build Tool**: Rspack (Webpack alternative)
25-
- **State Management**: Reflux, React Query (TanStack Query)
26-
- **Styling**: Emotion (CSS-in-JS), Less
27-
- **Testing**: Jest, React Testing Library
28-
2924
### Infrastructure
3025

3126
- **Container**: Docker (via devservices)
@@ -46,13 +41,7 @@ sentry/
4641
│ │ └── web/ # Web views and middleware
4742
│ ├── sentry_plugins/ # Plugin system
4843
│ └── social_auth/ # Social authentication
49-
├── static/
50-
│ ├── app/ # React application
51-
│ │ ├── components/ # Reusable React components
52-
│ │ ├── views/ # Page components
53-
│ │ ├── stores/ # State management
54-
│ │ └── utils/ # Utility functions
55-
│ └── fonts/ # Font files
44+
├── static/ # Frontend application (see static/CLAUDE.md)
5645
├── tests/ # Test suite
5746
├── fixtures/ # Test fixtures
5847
├── devenv/ # Development environment config
@@ -73,9 +62,6 @@ devenv sync
7362

7463
# Start the development server
7564
pnpm run dev
76-
77-
# Start only the UI development server with hot reload
78-
pnpm run dev-ui
7965
```
8066

8167
### Testing
@@ -84,12 +70,8 @@ pnpm run dev-ui
8470
# Run Python tests
8571
pytest
8672

87-
# Run JavaScript tests
88-
pnpm test
89-
9073
# Run specific test file
9174
pytest tests/sentry/api/test_base.py
92-
CI=true pnpm test components/avatar.spec.tsx
9375
```
9476

9577
### Code Quality
@@ -106,11 +88,6 @@ black --check # Run black first
10688
isort --check
10789
flake8
10890

109-
# JavaScript/TypeScript linting
110-
pnpm run lint:js
111-
112-
# Fix linting issues
113-
pnpm run fix
11491
```
11592

11693
### Database Operations
@@ -153,14 +130,6 @@ Sentry uses `devservices` to manage local development dependencies:
153130
- Test: `tests/sentry/api/endpoints/test_{resource}.py`
154131
- Serializer: `src/sentry/api/serializers/models/{model}.py`
155132

156-
### "User wants to modify frontend component"
157-
158-
1. Component location: `static/app/components/` (reusable) or `static/app/views/` (page-specific)
159-
2. ALWAYS use TypeScript
160-
3. ALWAYS write test in same directory with `.spec.tsx`
161-
4. Style with Emotion, NOT inline styles or CSS files
162-
5. State: Use hooks (`useState`), NOT Reflux for new code
163-
164133
### "User wants to add a Celery task"
165134

166135
1. Location: `src/sentry/tasks/{category}.py`
@@ -188,7 +157,7 @@ class OrganizationDetailsEndpoint(OrganizationEndpoint):
188157
"PUT": ApiPublishStatus.PUBLIC,
189158
}
190159

191-
def get(self, request: Request, organization) -> Response:
160+
def get(self, request: Request, organization: Organization) -> Response:
192161
"""Get organization details."""
193162
return Response(
194163
serialize(
@@ -202,46 +171,6 @@ class OrganizationDetailsEndpoint(OrganizationEndpoint):
202171
# path('organizations/<slug:organization_slug>/', OrganizationDetailsEndpoint.as_view()),
203172
```
204173

205-
### React Component Pattern
206-
207-
```typescript
208-
// static/app/components/myComponent.tsx
209-
import {useState} from 'react';
210-
import styled from '@emotion/styled';
211-
import {space} from 'sentry/styles/space';
212-
213-
interface MyComponentProps {
214-
title: string;
215-
onSubmit: (value: string) => void;
216-
}
217-
218-
function MyComponent({title, onSubmit}: MyComponentProps) {
219-
const [value, setValue] = useState('');
220-
221-
const handleSubmit = () => {
222-
onSubmit(value);
223-
};
224-
225-
return (
226-
<Container>
227-
<Title>{title}</Title>
228-
<Input value={value} onChange={e => setValue(e.target.value)} />
229-
<Button onClick={handleSubmit}>Submit</Button>
230-
</Container>
231-
);
232-
}
233-
234-
const Container = styled('div')`
235-
padding: ${space(2)};
236-
`;
237-
238-
const Title = styled('h2')`
239-
margin-bottom: ${space(1)};
240-
`;
241-
242-
export default MyComponent;
243-
```
244-
245174
### Celery Task Pattern
246175

247176
```python
@@ -288,31 +217,6 @@ def send_email(user_id: int, subject: str, body: str) -> None:
288217
5. Implement pagination with `cursor`
289218
6. Use `GET` for read, `POST` for create, `PUT` for update
290219

291-
## Frontend Development
292-
293-
### Component Guidelines
294-
295-
1. Use TypeScript for all new components
296-
2. Place components in `static/app/components/`
297-
3. Use Emotion for styling
298-
4. Write tests alongside components (`.spec.tsx` files)
299-
5. Use React hooks for state management
300-
301-
### Routing
302-
303-
- Routes defined in `static/app/routes.tsx`
304-
- Use React Router v6 patterns
305-
- Lazy load route components when possible
306-
307-
### Frontend Rules
308-
309-
1. NO new Reflux stores
310-
2. NO class components
311-
3. NO CSS files (use Emotion)
312-
4. ALWAYS use TypeScript
313-
5. ALWAYS colocate tests
314-
6. Lazy load routes: `React.lazy(() => import('...'))`
315-
316220
## Testing Best Practices
317221

318222
### Python Tests
@@ -323,13 +227,6 @@ def send_email(user_id: int, subject: str, body: str) -> None:
323227
- Use factories for test data
324228
- For Kafka/Arroyo components: Use `LocalProducer` with `MemoryMessageStorage` instead of mocks
325229

326-
### JavaScript Tests
327-
328-
- Use React Testing Library
329-
- Mock API calls with MSW or jest mocks
330-
- Test user interactions, not implementation
331-
- Snapshot testing for complex UI
332-
333230
### Test Pattern
334231

335232
```python
@@ -370,15 +267,6 @@ class MyPermission(SentryPermission):
370267
}
371268
```
372269

373-
### Frontend API Calls
374-
375-
```typescript
376-
import {Client} from 'sentry/api';
377-
378-
const api = new Client();
379-
const data = await api.requestPromise('/organizations/');
380-
```
381-
382270
### Logging Pattern
383271

384272
```python
@@ -489,32 +377,6 @@ if isinstance(x, str):
489377

490378
```
491379

492-
### Frontend
493-
494-
```typescript
495-
// WRONG: Class component
496-
class MyComponent extends React.Component // NO!
497-
498-
// RIGHT: Function component
499-
function MyComponent() {}
500-
501-
// WRONG: Direct API call
502-
fetch('/api/0/organizations/') // NO!
503-
504-
// RIGHT: Use API client
505-
import {Client} from 'sentry/api';
506-
const api = new Client();
507-
api.requestPromise('/organizations/');
508-
509-
// WRONG: Inline styles
510-
<div style={{padding: 16}}> // NO!
511-
512-
// RIGHT: Emotion styled
513-
const Container = styled('div')`
514-
padding: ${space(2)};
515-
`;
516-
```
517-
518380
## Performance Considerations
519381

520382
1. Use database indexing appropriately
@@ -537,7 +399,6 @@ const Container = styled('div')`
537399
2. Access Django shell: `sentry django shell`
538400
3. View Celery tasks: monitor RabbitMQ management UI
539401
4. Database queries: use Django Debug Toolbar
540-
5. Frontend debugging: React DevTools
541402

542403
### Quick Debugging
543404

@@ -563,15 +424,10 @@ print(silo_mode_delegation.get_current_mode())
563424
## Important Configuration Files
564425

565426
- `pyproject.toml`: Python project configuration
566-
- `package.json`: Node.js dependencies and scripts
567-
- `rspack.config.ts`: Frontend build configuration
568427
- `setup.cfg`: Python package metadata
569428
- `.github/`: CI/CD workflows
570429
- `devservices/config.yml`: Local service configuration
571430
- `.pre-commit-config.yaml`: Pre-commit hooks configuration
572-
- `tsconfig.json`: TypeScript configuration
573-
- `eslint.config.mjs`: ESLint configuration
574-
- `stylelint.config.js`: CSS/styling linting
575431
- `codecov.yml`: Code coverage configuration
576432

577433
## File Location Map
@@ -587,20 +443,9 @@ print(silo_mode_delegation.get_current_mode())
587443
- **Feature Flags**: `src/sentry/features/permanent.py` or `temporary.py`
588444
- **Utils**: `src/sentry/utils/{category}.py`
589445

590-
### Frontend
591-
592-
- **Components**: `static/app/components/{component}/`
593-
- **Views**: `static/app/views/{area}/{page}.tsx`
594-
- **Stores**: `static/app/stores/{store}Store.tsx`
595-
- **Actions**: `static/app/actionCreators/{resource}.tsx`
596-
- **Utils**: `static/app/utils/{utility}.tsx`
597-
- **Types**: `static/app/types/{area}.tsx`
598-
- **API Client**: `static/app/api.tsx`
599-
600446
### Tests
601447

602448
- **Python**: `tests/` mirrors `src/` structure
603-
- **JavaScript**: Same directory as component with `.spec.tsx`
604449
- **Fixtures**: `fixtures/{type}/`
605450
- **Factories**: `tests/sentry/testutils/factories.py`
606451

@@ -653,10 +498,9 @@ class ExampleIntegrationProvider(IntegrationProvider):
653498
2. **Feature Flags**: Always add for new features
654499
3. **Migrations**: Test rollback, never drop columns immediately
655500
4. **Celery**: Always handle task failures/retries
656-
5. **Frontend**: Component names must be unique globally
657-
6. **API**: Serializers can be expensive, use `@attach_scenarios`
658-
7. **Tests**: Use `self.create_*` helpers, not direct model creation
659-
8. **Permissions**: Check both RBAC and scopes
501+
5. **API**: Serializers can be expensive, use `@attach_scenarios`
502+
6. **Tests**: Use `self.create_*` helpers, not direct model creation
503+
7. **Permissions**: Check both RBAC and scopes
660504

661505
## Useful Resources
662506

@@ -672,7 +516,6 @@ class ExampleIntegrationProvider(IntegrationProvider):
672516
- Always consider the impact of changes on performance and scalability
673517
- Many features are gated behind feature flags for gradual rollout
674518
- The codebase follows Django patterns but with significant customization
675-
- Frontend uses a mix of modern React and some legacy patterns
676519
- Database migrations require special care due to the scale of deployment
677520
- ALWAYS use pre-commit for linting instead of individual tools
678521
- Check silo mode before making cross-silo queries

0 commit comments

Comments
 (0)