-
Notifications
You must be signed in to change notification settings - Fork 1
Contributing
Contributions are welcome! This guide covers the key patterns and processes for contributing to Coding Drills.
When adding a new programming or database language, you must update all the locations listed below. Missing any will cause bugs (wrong language displayed, missing from dropdowns, broken modes).
| # | File | What to Update |
|---|---|---|
| 1 | lib/types.ts |
Add to LanguageId union type |
| 2 | app/[language]/config.ts |
Add to SUPPORTED_LANGUAGES array |
| 3 | app/[language]/config.ts |
Add entry to LANGUAGE_CONFIG object (name, colors, docsUrl, version) |
| 4 | app/[language]/config.ts |
If database language: add to isDatabaseLanguage() function |
| 5 | app/[language]/drill/page.tsx |
Add to local SUPPORTED_LANGUAGES array (~line 292) |
| 6 | app/[language]/drill/page.tsx |
Add to problemLoaders object (~line 126) |
| 7 | lib/problems/{language}.ts |
Create problems file with {language}Problems export |
| 8 | lib/problems/index.ts |
Import and export the new problems array |
| 9 | lib/cheatsheets/{language}.ts |
Create cheatsheet file with {language}Cheatsheet export |
| 10 | lib/cheatsheets/index.ts |
Import and add to cheatsheetsByLanguage map |
| 11 | lib/methods/{language}.ts |
Create methods file (programming languages only) |
| 12 | lib/methods/index.ts |
Import and export (programming languages only) |
Database languages (PostgreSQL, MySQL, MongoDB, Redis) have additional requirements:
| # | File | What to Update |
|---|---|---|
| 13 | app/[language]/LanguageSwitcher.tsx |
Add to DATABASE_LANGUAGES array (~line 33) |
| 14 | lib/codeValidator.ts |
Add to local isDatabaseLanguage check (~line 494) |
| 15 | e2e/problems/all-problems-validation.spec.ts |
Add to DATABASE_LANGUAGES array and EXPECTED_DATABASE_COUNTS
|
| 16 | lib/__tests__/config.test.ts |
Add test case for isDatabaseLanguage('{language}')
|
Database languages have different behavior:
| Feature | Programming Languages | Database Languages |
|---|---|---|
| Drill Mode | Method-based problems | Query-based problems |
| Quiz Mode | Methods + complexity | Not available |
| Study Mode | Methods, complexity, patterns | Cheatsheet-based flashcards |
| Building Blocks | Available | Not available |
| Reference | Available | Not available |
| AI Interview | Available | Not available |
| Navbar modes | All modes | Filtered (no quiz, exercises, reference, interview) |
After adding a new language, run these checks:
pnpm typecheck # No TypeScript errors
pnpm test lib/__tests__/config # Config tests pass
pnpm build # Build succeedsThen manually verify:
- Language Switcher: Language appears in the dropdown under the correct category
-
Homepage:
/{language}shows correct name, icon, and colors -
Drill Mode:
/{language}/drillloads the correct problems (not JavaScript) -
Cheatsheet:
/{language}/cheatsheetdisplays content -
Study Mode:
/{language}/studyshows appropriate sources (cheatsheet for DB languages) - Navbar: For database languages, only shows: Drill, Study, Problems, Regex, Cheatsheet
The codebase has some duplicated language lists for historical and performance reasons:
-
Code-splitting:
problemLoadersuses dynamic imports to lazy-load only the needed language -
Type safety: Local arrays are typed as
LanguageId[]for compile-time checks - Test isolation: E2E tests have their own constants to avoid importing app code
The central config (app/[language]/config.ts) is the source of truth. Other files have local copies that must stay in sync. A future refactor could consolidate these using a shared constant, but for now, follow the checklist above.
Problems follow the Problem interface defined in lib/types.ts:
interface Problem {
id: string;
category: string;
difficulty: 'easy' | 'medium' | 'hard';
title: string;
text: string; // Problem description
setup?: string; // Human-readable setup context
setupCode: string; // Code that runs before user answer
expected: unknown; // Expected output
sample: string; // Sample solution
hints?: string[]; // Optional hints
validPatterns?: RegExp[]; // Patterns to validate approach
tags?: string[]; // Optional categorization tags
}All problems should include validPatterns to prevent hardcoded answers. The validator checks that user code:
- Produces the expected output
- Matches at least one valid pattern (uses the intended method/approach)
Use the visualization scripts:
pnpm viz:list # See available exercises
pnpm viz:next # Get next tasks
pnpm viz:generate <id> # Generate boilerplateSee components/visualizations/ for existing patterns. Visualizations use:
- Shared animation hook (
useAnimationState) - Shared controls component (
AnimationControls) - Lazy loading via dynamic imports
Before submitting:
pnpm validate # typecheck + lint:biome + lint
pnpm test # Unit tests (13,995 tests)
pnpm test:e2e # E2E tests