Skip to content

Commit 0799946

Browse files
authored
Merge pull request #240 from DaleStudy/add-claude-github-actions-1760895102696
Add Claude Code GitHub Workflow
2 parents d097c4a + 0b0117a commit 0799946

File tree

2 files changed

+380
-0
lines changed

2 files changed

+380
-0
lines changed

.github/workflows/claude.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Claude Code
2+
3+
on:
4+
issue_comment:
5+
types: [created]
6+
pull_request_review_comment:
7+
types: [created]
8+
issues:
9+
types: [opened, assigned]
10+
pull_request_review:
11+
types: [submitted]
12+
13+
jobs:
14+
claude:
15+
if: |
16+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
17+
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
18+
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
19+
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
20+
runs-on: ubuntu-latest
21+
permissions:
22+
contents: read
23+
pull-requests: read
24+
issues: read
25+
id-token: write
26+
actions: read # Required for Claude to read CI results on PRs
27+
steps:
28+
- name: Checkout repository
29+
uses: actions/checkout@v5
30+
with:
31+
fetch-depth: 1
32+
33+
- name: Run Claude Code
34+
id: claude
35+
uses: anthropics/claude-code-action@v1
36+
with:
37+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
38+
39+
# This is an optional setting that allows Claude to read CI results on PRs
40+
additional_permissions: |
41+
actions: read
42+
43+
# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
44+
# prompt: 'Update the pull request description to include a summary of changes.'
45+
46+
# Optional: Add claude_args to customize behavior and configuration
47+
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
48+
# or https://docs.claude.com/en/docs/claude-code/cli-reference for available options
49+
# claude_args: '--allowed-tools Bash(gh pr:*)'

CLAUDE.md

Lines changed: 331 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,331 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
A React 18 leaderboard application for tracking DaleStudy member progress on LeetCode Blind 75 problems. Members earn grades (SEED → SPROUT → LEAF → BRANCH → FRUIT → TREE) based on solved problem count.
8+
9+
## Development Commands
10+
11+
```bash
12+
# Development
13+
bun install # Install dependencies
14+
bun run dev # Start Vite dev server
15+
bun run build # Production build
16+
bun run preview # Preview production build
17+
18+
# Testing
19+
bun run test # Run Vitest in watch mode
20+
bun run coverage # Generate coverage report (requires 70% threshold)
21+
22+
# Code Quality
23+
bun run lint # Run ESLint
24+
bun run format:check # Check formatting
25+
bun run format:write # Auto-format with Prettier
26+
27+
# Storybook
28+
bun run storybook # Start Storybook dev server (port 6006)
29+
bun run build-storybook # Build static Storybook
30+
bun run test-storybook # Run accessibility tests on all stories
31+
32+
# Run Single Test
33+
bun run test src/components/Card/Card.test.tsx
34+
```
35+
36+
## Architecture
37+
38+
### Tech Stack
39+
40+
- **Framework**: React 18 + TypeScript 5.8
41+
- **Build Tool**: Vite 6.3 (3 entry points: index.html, progress.html, certificate.html)
42+
- **State Management**: Custom hooks (no external state library)
43+
- **API Client**: Apollo Client 3.13 (GraphQL)
44+
- **Testing**: Vitest 3.1 + React Testing Library + Storybook Test Runner
45+
- **Styling**: CSS Modules
46+
- **Package Manager**: Bun
47+
48+
### Data Flow
49+
50+
```
51+
GitHub GraphQL API (https://dalestudy.fly.dev/)
52+
↓ gitHubClient.ts (Apollo Client)
53+
↓ fetchService.ts (extract teams, members, submissions)
54+
↓ processService.ts (calculate progress & grades)
55+
↓ useMembers.ts (React hook with filtering)
56+
↓ Page Components (Leaderboard, Progress, Certificate)
57+
```
58+
59+
### Key Services
60+
61+
**`src/api/getMembers.ts`**: Main orchestrator that combines fetch + process services
62+
63+
**`src/api/services/fetch/fetchService.ts`**:
64+
65+
- Fetches GitHub teams (filters teams starting with "leetcode")
66+
- Parses file paths with regex: `^([^/]+)/([^.]+)\.([a-zA-Z0-9]+)$`
67+
- Extracts: (problemTitle, memberId, language)
68+
69+
**`src/api/services/process/processService.ts`**:
70+
71+
- Calculates grade based on thresholds (TREE: 70+, FRUIT: 60+, BRANCH: 45+, LEAF: 30+, SPROUT: 15+, SEED: 0+)
72+
- Deduplicates submissions per member
73+
- Filters out members with zero submissions
74+
- Business logic is tested in `processService.test.ts`
75+
76+
**`src/api/infra/gitHub/gitHubClient.ts`**: Apollo Client with 3 GraphQL queries:
77+
78+
- `GetTeams`: List all team names
79+
- `GetTeamMembers($teamName)`: Fetch members in a cohort
80+
- `GetGitTrees`: List all solution files in repository tree
81+
82+
### Problem Database
83+
84+
**`src/api/constants/problems.ts`**: Central registry of all 75 LeetCode problems with:
85+
86+
- LeetCode ID (number)
87+
- Title (kebab-case)
88+
- Difficulty (Easy/Med/Hard)
89+
- Pre-computed maps for O(1) lookup
90+
91+
### Custom Hooks
92+
93+
**`src/hooks/useMembers.ts`**:
94+
95+
- Fetches member data via `getMembers()`
96+
- Provides filtering by name (case-insensitive) and cohort
97+
- Returns: `{ members, totalCohorts, isLoading, error, filter, setFilter }`
98+
- Sorts by progress (descending)
99+
100+
**`src/hooks/usePagination.ts`**:
101+
102+
- Generic pagination (default: 16 items/page)
103+
- Auto-resets to page 1 when data changes
104+
- Returns: `{ currentPage, totalPages, paginatedData, goNext, goPrevious }`
105+
106+
## Component Patterns
107+
108+
### Standard Component Structure
109+
110+
```
111+
src/components/ComponentName/
112+
├── ComponentName.tsx # Main component
113+
├── ComponentName.test.tsx # Unit tests (Vitest)
114+
├── ComponentName.stories.tsx # Storybook stories
115+
└── ComponentName.module.css # CSS Modules
116+
```
117+
118+
### Pages (3 HTML Entry Points)
119+
120+
1. **Leaderboard** (`/`): Main rankings with SearchBar + Card grid + Pagination
121+
2. **Progress** (`/progress?member=:id`): Member details with Sidebar + Table
122+
3. **Certificate** (`/certificate?member=:id`): Printable achievement certificate
123+
124+
Navigation uses query parameters (`?member=:id`) for static page compatibility.
125+
126+
## Testing Strategy
127+
128+
### Three-Layer Testing
129+
130+
1. **Unit Tests** (Vitest + React Testing Library):
131+
132+
- All `*.test.tsx` files
133+
- Environment: `happy-dom`
134+
- Coverage requirement: 70% (lines, functions, statements, branches)
135+
- Stories excluded from coverage
136+
137+
2. **Component Stories** (Storybook 8.6):
138+
139+
- All `*.stories.tsx` files
140+
- MSW for GraphQL mocking (setup in `.storybook/preview.ts`)
141+
- Interactive component playground
142+
- Auto-generated documentation
143+
144+
3. **Accessibility Testing** (Storybook Test Runner + Axe):
145+
- Runs on all stories via `bun run test-storybook`
146+
- Configuration in `.storybook/test-runner.ts`
147+
- Automated a11y checks with `axe-playwright`
148+
149+
### Testing Conventions
150+
151+
- Use `screen.getByRole()` for accessibility-first queries
152+
- Mock services with `vi.mock()` and `vi.mocked()`
153+
- Test business logic separately from components (see `processService.test.ts`)
154+
- Use `@testing-library/user-event` for user interactions
155+
- Stories use `fn()` from `@storybook/test` for action tracking
156+
157+
Example:
158+
159+
```typescript
160+
// Unit test
161+
test("renders grade image", () => {
162+
render(<Card id="test" name="test" grade="TREE" cohorts={[1]} />);
163+
expect(screen.getByRole("img", { name: "TREE image" })).toBeInTheDocument();
164+
});
165+
166+
// Story
167+
export const Default: StoryObj<typeof Card> = {
168+
args: {
169+
id: "test",
170+
name: "Test User",
171+
grade: "TREE",
172+
cohorts: [1, 2],
173+
},
174+
};
175+
```
176+
177+
## GraphQL & API
178+
179+
### Apollo Client Configuration
180+
181+
- **Endpoint**: `https://dalestudy.fly.dev/`
182+
- **Cache**: InMemoryCache (default policies)
183+
- **Location**: `src/api/infra/gitHub/gitHubClient.ts`
184+
185+
### Type System
186+
187+
All external API types in `src/api/services/types.ts`:
188+
189+
```typescript
190+
Member {
191+
id: string // lowercase username
192+
name: string // original username
193+
cohorts: number[] // [1, 2, 3]
194+
profileUrl?: string // GitHub avatar
195+
progress: number // 0-100
196+
grade: Grade // SEED|SPROUT|LEAF|BRANCH|FRUIT|TREE
197+
solvedProblems: Problem[]
198+
}
199+
200+
Problem {
201+
id: number // LeetCode ID
202+
title: string // kebab-case
203+
difficulty: "Easy" | "Med" | "Hard"
204+
}
205+
```
206+
207+
## Configuration Files
208+
209+
### Grade Thresholds
210+
211+
**`src/api/config/index.ts`**: Contains grade calculation constants
212+
213+
- `TOTAL_PROBLEMS = 75`
214+
- Grade boundaries (can be modified here)
215+
216+
### Build Configuration
217+
218+
**`vite.config.ts`**:
219+
220+
- Multi-page app with 3 entry points
221+
- Test setup with happy-dom
222+
- Coverage thresholds enforced
223+
224+
### TypeScript
225+
226+
**`tsconfig.app.json`**:
227+
228+
- Strict mode enabled
229+
- `noUnusedLocals`, `noUnusedParameters` enforced
230+
- Module resolution: bundler
231+
232+
## CI/CD
233+
234+
### Integration Workflow (`.github/workflows/integration.yml`)
235+
236+
Runs on every PR:
237+
238+
```bash
239+
bun run format:check # Prettier check
240+
bun run lint # ESLint
241+
bun run coverage # Tests with 70% threshold
242+
bun run build # Production build
243+
```
244+
245+
Plus Chromatic deployment for visual regression testing.
246+
247+
### Pre-commit Hooks
248+
249+
- **lint-staged**: Auto-formats all files with Prettier
250+
- **Husky**: Manages Git hooks
251+
252+
## Special Conventions
253+
254+
### File Naming
255+
256+
- Components: PascalCase (`Card.tsx`)
257+
- Services/utils: camelCase (`processService.ts`)
258+
- Tests: `*.test.ts(x)`
259+
- Stories: `*.stories.ts(x)`
260+
- Styles: `*.module.css`
261+
262+
### Error Handling
263+
264+
- Custom error UI components: `ServerError`, `NotFound`, `Unqualified`
265+
- Loading states: `Spinner` component
266+
- Try-catch in hooks with `setError` state
267+
268+
### Accessibility
269+
270+
- Semantic HTML with ARIA labels
271+
- Role-based test queries
272+
- Automated Axe testing in Storybook
273+
- a11y addon in Storybook dev mode
274+
275+
## Adding New Features
276+
277+
### To Add a New Component:
278+
279+
1. Create folder: `src/components/NewComponent/`
280+
2. Add 4 files: `.tsx`, `.test.tsx`, `.stories.tsx`, `.module.css`
281+
3. Use CSS Modules for styling (import as `styles`)
282+
4. Export from component file
283+
5. Write tests using `screen.getByRole()`
284+
6. Create at least one story with args
285+
286+
### To Modify Data Processing:
287+
288+
1. Update types in `src/api/services/types.ts`
289+
2. Modify business logic in `processService.ts`
290+
3. Update tests in `processService.test.ts`
291+
4. Verify coverage remains above 70%
292+
293+
### To Add GraphQL Queries:
294+
295+
1. Add query to `src/api/infra/gitHub/gitHubClient.ts`
296+
2. Update Apollo Client methods
297+
3. Mock in `.storybook/preview.ts` for Storybook
298+
4. Mock in unit tests with `vi.mock()`
299+
300+
### To Modify Grade System:
301+
302+
1. Update thresholds in `src/api/config/index.ts`
303+
2. Update grade images in `src/assets/`
304+
3. Update tests in `processService.test.ts`
305+
4. Update certificate emoji mapping in `src/pages/Certificate/constants.ts`
306+
307+
## Debugging
308+
309+
### Component Issues:
310+
311+
- Use Storybook for isolated component testing
312+
- Check CSS Module class names (use browser DevTools)
313+
- Verify props with React DevTools
314+
315+
### Data/API Issues:
316+
317+
- Check Apollo Client DevTools in browser
318+
- Add console.log in `fetchService.ts` or `processService.ts`
319+
- Verify GraphQL responses match expected types
320+
321+
### Test Failures:
322+
323+
- Run `bun run test` for watch mode
324+
- Check test coverage: `bun run coverage`
325+
- View HTML coverage report: `open coverage/index.html`
326+
327+
### Build Issues:
328+
329+
- Verify all 3 HTML entry points exist
330+
- Check Vite config for correct input paths
331+
- Ensure TypeScript has no errors: `bunx tsc --noEmit`

0 commit comments

Comments
 (0)