-
Notifications
You must be signed in to change notification settings - Fork 93
Expand file tree
/
Copy path.cursorrules
More file actions
88 lines (70 loc) · 4.42 KB
/
.cursorrules
File metadata and controls
88 lines (70 loc) · 4.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# Couchers Project Rules
This is a monorepo containing:
- `/app/web` - Next.js web frontend
- `/app/mobile` - React Native Expo mobile app
- `/app/backend` - Python backend
---
## Web Frontend (`/app/web`)
### Package Manager
This project uses **yarn** as the package manager. Always use `yarn` commands instead of `npm`:
- Use `yarn install` instead of `npm install`
- Use `yarn add` instead of `npm install`
- Use `yarn test` instead of `npm test`
- Use `yarn start` instead of `npm start`
### Linting
- Run linting `yarn lint` to see issues and `yarn lint:fix` to fix them
### Testing
Run tests with: `yarn test`
#### Testing Best Practices
- **Use fixture data when available**: Import test data from `test/fixtures/` (e.g., `hostRequest.json`, `messages.json`, `groupChat.json`) instead of creating mock data inline
- **Query elements by label**: Prefer `getByLabelText()` for form inputs as it tests accessibility
- When there's ambiguity (e.g., both a label and aria-label), use the `selector` option: `getByLabelText(label, { selector: "textarea" })`
- **Text matching with embedded elements**: When text is split by child elements (e.g., links inside text), use function matchers:
```typescript
screen.getByText((content, element) => {
return element?.textContent === "Full text including embedded link text";
})
```
- **Type safety**: Explicitly type mock mutations (e.g., `UseMutationResult<...>`) without using `any`
- **Async queries**: Use `await screen.findByText()` when waiting for elements after loading states, instead of `getByText()` after `waitForElementToBeRemoved()`
### Development
To run the app locally in development, use `yarn start` (not Docker)
### File Imports
- Use our import aliases, e.g. "components/" instead of "../../../components/" and "routes" instead of "../../../routes"
- Import multiple MUI icons together: `import { Favorite, Star, Public } from "@mui/icons-material"` instead of separate imports
### Code Style
- Do not use the `any` type in TypeScript - it's considered bad practice
- Remove extra unnecessary style declarations, including anything that's already a default of MUI or the theme
- Use theme-defined colors instead of ad-hoc gray backgrounds
- Use default Material-UI hover styles instead of custom dark grey on hover
- Prefer modern 2025 design patterns for UI components
- Use StyledLink.tsx component or import from next/link for links to preserve routing, NOT MUI Link
- Always put types at the top of the file below the imports
- Add Tanstack queryKeys to app/web/features/queryKeys.ts if they are used more than one place.
- Use slotProps rather than InputLabelProps for MUI. InputLabelProps is deprecated now.
### Internationalization (i18n)
- **Never hardcode English text** - always use the `t()` function or `<Trans>` component for user-facing text
- Store all English text strings in the appropriate locale files (`features/*/locales/en.json`)
- When adding strings to an `en.json` file, refer to `/docs/localization.md` for string key and text guidance
- Use `<Trans>` component for text with embedded components (like links)
- When using `<Trans>`, make sure components in the translation JSON match the components prop exactly
### Dark Mode
- **Always use CSS variables for theme colors** to ensure dark mode compatibility:
- Use `"var(--mui-palette-primary-main)"` instead of `theme.palette.primary.main` in styled components
- Use `"var(--mui-palette-text-primary)"` for text colors
- Use `"var(--mui-palette-background-paper)"` for backgrounds
- Use `"var(--mui-palette-background-default)"` for page backgrounds
- Use `"var(--mui-palette-divider)"` for borders/dividers
- Use `"var(--mui-palette-grey-XXX)"` for grey shades (e.g., grey-50, grey-200, grey-300)
- Use `"var(--mui-palette-action-hover)"` for hover states
- **Exception**: Use `theme.palette.*` values when you need to pass colors to functions like `alpha()` that require actual color values, not CSS variables
- **For styled components**: Add `({ theme })` parameter only when you need `theme.spacing()`, `theme.breakpoints`, or functions like `alpha()`
- Test all components in both light and dark mode to ensure proper color contrast and visibility
---
## Mobile App (`/app/mobile`)
- Uses npm (not yarn) for package management
- See `/app/mobile/README.md` for setup instructions
---
## Backend (`/app/backend`)
- Run tests with `make test file=<test_name>` in the backend folder
- See `/app/backend/readme.md` for more details