Skip to content

Commit efe8bda

Browse files
Zaimwa9kyle-ssgpre-commit-ci[bot]khvn26Copilot
authored
docs: add frontend developer documentation (#6486)
Co-authored-by: kyle-ssg <kyle@solidstategroup.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Kim Gustyr <khvn26@gmail.com> Co-authored-by: Kim Gustyr <kim.gustyr@flagsmith.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Matthew Elwell <matthew.elwell@flagsmith.com> Co-authored-by: Talisson <talisson.odcosta@gmail.com>
1 parent 2230ec6 commit efe8bda

29 files changed

Lines changed: 2523 additions & 28 deletions

frontend/.claude/commands/api.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
description: Generate a new RTK Query API service
3+
---
4+
5+
<!-- TODO: Update /api-types-sync once OpenAPI schema is ready -->
6+
7+
Generate a new API service. Follow these steps:
8+
9+
1. Go through the process mentioned in `.claude/context/api-integration.md`
10+
2. If I haven't specified, attempt to find where I'd want to create this component in the frontend
11+
12+
Context file: `.claude/context/api-integration.md`
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
description: Search the backend codebase for endpoint details
3+
---
4+
5+
Search the `../api` codebase for the requested endpoint.
6+
7+
Look for:
8+
1. Route definitions (URL path)
9+
2. HTTP method (GET, POST, PUT, DELETE)
10+
3. Request validation schema (request body/params types)
11+
4. Response structure (what data is returned)
12+
5. Authentication/authorization requirements
13+
14+
If the endpoint isn't found, check swagger docs: https://staging.flagsmith.com/api/v1/docs/
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
description: Run type checking and linting on staged files
3+
---
4+
5+
Run TypeScript checking and linting on all currently staged files, similar to pre-commit hooks. Steps:
6+
1. Run `npm run check:staged` to typecheck and lint only staged files
7+
2. Report any type errors or linting issues found
8+
3. If errors exist, offer to fix them

frontend/.claude/commands/check.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
description: Run type checking and linting
3+
---
4+
5+
Run the following checks on the codebase:
6+
7+
1. `npx lint-staged --allow-empty` - Fix linting issues on staged files only (same as git hook)
8+
9+
Report any errors found and offer to fix them.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
description: Load detailed context files for specific topics
3+
---
4+
5+
Available context files in `.claude/context/`:
6+
7+
1. **api-integration.md** - API integration workflow, Redux setup, cross-platform patterns
8+
2. **architecture.md** - Environment config, tech stack, additional rules
9+
3. **feature-flags/** - Flagsmith feature flags (usage + MCP workflows)
10+
4. **patterns/** - Code patterns (API, mobile)
11+
12+
Which context would you like to explore?
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
description: Create a feature flag
3+
---
4+
5+
1. Create a feature flag using the context defined in `.claude/context/feature-flags/`
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---
2+
description: Find all usages of a component, function, or type
3+
---
4+
5+
Find all usages of `$ARGUMENTS` across the frontend codebase.
6+
7+
## Steps
8+
9+
1. **Identify what we're searching for**
10+
- Component name (e.g., `Switch`, `Button`)
11+
- Function name (e.g., `isFreeEmailDomain`, `formatDate`)
12+
- Type/interface name (e.g., `FeatureState`, `ProjectFlag`)
13+
14+
2. **Find the definition**
15+
- Search for where it's defined/exported
16+
- Note the file path and export type (default vs named)
17+
18+
3. **Search for imports**
19+
```bash
20+
# For named exports
21+
grep -r "import.*{ $SYMBOL" --include="*.ts" --include="*.tsx"
22+
23+
# For default exports
24+
grep -r "import $SYMBOL" --include="*.ts" --include="*.tsx"
25+
```
26+
27+
4. **Search for direct usages**
28+
- JSX usage: `<ComponentName`
29+
- Function calls: `functionName(`
30+
- Type annotations: `: TypeName` or `as TypeName`
31+
32+
5. **Categorise usages**
33+
- Group by file/directory
34+
- Note the context (component, hook, utility, test)
35+
36+
## Output format
37+
38+
```
39+
## Definition
40+
[File path where it's defined]
41+
42+
## Usages (X files)
43+
44+
### components/
45+
- ComponentA.tsx:42 - Used in render
46+
- ComponentB.tsx:15 - Passed as prop
47+
48+
### pages/
49+
- FeaturePage.tsx:88 - Used in modal
50+
51+
### hooks/
52+
- useFeature.ts:12 - Called in effect
53+
54+
## Impact Assessment
55+
[Brief note on how widespread the usage is and what to consider when modifying]
56+
```
57+
58+
## Use cases
59+
60+
- Before refactoring: understand what will be affected
61+
- Before deleting: ensure nothing depends on it
62+
- Before renaming: find all places that need updates
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
---
2+
description: Review a GitHub pull request
3+
---
4+
5+
Review the pull request at `$ARGUMENTS`.
6+
7+
## Steps
8+
9+
1. **Fetch PR details**
10+
```bash
11+
gh pr view <PR_NUMBER_OR_URL> --json title,body,files,additions,deletions,state,headRefName
12+
```
13+
14+
2. **Get the diff**
15+
```bash
16+
gh pr diff <PR_NUMBER_OR_URL>
17+
```
18+
19+
3. **Analyse the changes**
20+
- Summarise what the PR does
21+
- Check if the approach makes sense
22+
- Identify potential issues:
23+
- Missing edge cases
24+
- Inconsistencies with existing patterns
25+
- Code style issues (indentation, naming)
26+
- Missing tests for new functionality
27+
- Check if related files need updates
28+
29+
4. **Review against project patterns**
30+
- Does it follow patterns in `.claude/context/`?
31+
- Are imports using path aliases (`common/`, `components/`)?
32+
- Is state management using RTK Query where appropriate?
33+
34+
5. **Provide feedback**
35+
- Summary of what the PR does
36+
- What's good about the approach
37+
- Potential concerns or suggestions
38+
- Questions for the author (if any)
39+
40+
## Output format
41+
42+
```
43+
## PR Summary
44+
[Brief description of what the PR does]
45+
46+
## Changes
47+
[List of files changed and what each change does]
48+
49+
## Assessment
50+
✅ What looks good
51+
⚠️ Potential concerns
52+
💡 Suggestions
53+
54+
## Questions
55+
[Any clarifying questions for the author]
56+
```
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# UI Patterns & Best Practices
2+
3+
## Confirmation Dialogs
4+
5+
**NEVER use `window.confirm`** - Always use the `openConfirm` function from `components/base/Modal`.
6+
7+
### Correct Usage
8+
9+
```typescript
10+
import { openConfirm } from 'components/base/Modal'
11+
12+
// Signature: openConfirm(title, body, onYes, onNo?, challenge?)
13+
openConfirm(
14+
'Delete Partner',
15+
'Are you sure you want to delete this partner?',
16+
async (closeModal) => {
17+
const res = await deleteAction()
18+
if (!res.error) {
19+
toast(null, 'Partner deleted successfully')
20+
closeModal() // Always call closeModal to dismiss the dialog
21+
}
22+
},
23+
)
24+
```
25+
26+
### Parameters
27+
- `title: string` - Dialog title
28+
- `body: ReactNode` - Dialog content (can be JSX)
29+
- `onYes: (closeModal: () => void) => void` - Callback when user confirms
30+
- `onNo?: () => void` - Optional callback when user cancels
31+
- `challenge?: string` - Optional challenge text user must type to confirm
32+
33+
### Key Points
34+
- The `onYes` callback receives a `closeModal` function
35+
- Always call `closeModal()` when the action completes successfully
36+
- Can be async - use `async (closeModal) => { ... }`
37+
38+
## Backend Integration
39+
40+
### Always Run API Types Sync Before API Work
41+
42+
When using `/api` to generate new API services, the command automatically runs `/api-types-sync` first to:
43+
1. Pull latest backend changes (`git pull` in `../api`)
44+
2. Sync frontend types with backend serializers
45+
3. Ensure types are up-to-date before generating new services
46+
47+
This prevents type mismatches and ensures consistency.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
description: Analyse a frontend file and generate unit tests (Jest)
3+
---
4+
5+
Generate unit tests for the frontend file at `$ARGUMENTS`.
6+
7+
**Note:** This command is for frontend code only. For backend (Python) tests, see `../api/README.md`.
8+
9+
## Steps
10+
11+
1. **Check for existing tests**
12+
- Look for `__tests__/{filename}.test.ts` in the same directory
13+
- If tests exist, analyse them for coverage gaps
14+
15+
2. **Read and analyse the source file**
16+
- Identify all exported functions, classes, and constants
17+
- Note dependencies and imports
18+
- Determine testability:
19+
- Pure functions (no side effects) → highly testable
20+
- React components → may need mocking
21+
- Functions with external dependencies → note what needs mocking
22+
23+
3. **Generate test file**
24+
- Follow the pattern in `common/utils/__tests__/format.test.ts`
25+
- Location: `{sourceDir}/__tests__/{filename}.test.ts`
26+
- Use path aliases for imports (`common/...`, `components/...`)
27+
28+
4. **Test structure requirements**
29+
- Use `describe` block for each exported function
30+
- Use `it.each` for table-driven tests when function has multiple input/output cases
31+
- Include edge cases: `null`, `undefined`, empty strings, empty arrays
32+
- Include boundary cases where applicable
33+
34+
5. **After generating, run the tests**
35+
```bash
36+
npm run test:unit -- --testPathPatterns={filename}
37+
```
38+
39+
## Test file pattern
40+
41+
```typescript
42+
import { functionName } from 'common/path/to/file'
43+
44+
describe('functionName', () => {
45+
it.each`
46+
input | expected
47+
${value1} | ${result1}
48+
${value2} | ${result2}
49+
${null} | ${expectedForNull}
50+
${undefined} | ${expectedForUndefined}
51+
`('functionName($input) returns $expected', ({ input, expected }) => {
52+
expect(functionName(input)).toBe(expected)
53+
})
54+
})
55+
```
56+
57+
## Reference
58+
59+
See existing tests at:
60+
- `common/utils/__tests__/format.test.ts`
61+
- `common/utils/__tests__/featureFilterParams.test.ts`

0 commit comments

Comments
 (0)