Thanks for your interest in contributing! This guide explains how to set up your environment, coding standards, how to run tests, and how to contribute new drills and features.
- Requirements
- Node.js: >= 20.19 or >= 22.12
- npm
- Setup
- Fork and clone the repo
- Install dependencies:
npm ci - Start dev server:
npm run dev
- Create a feature branch from
main:git checkout -b feat/your-topic - Keep PRs focused and small where possible
- Reference related issues in your PR description
- Ensure CI is green (tests, coverage, schema validation, Storybook build)
- Unit tests:
npm run test - Coverage threshold (enforced):
npm run test:coverage - Drills JSON validation:
npm run validate:drills - Accessibility smoke check (axe + jsdom):
npm run a11y:axe - Storybook:
npm run storybook, buildnpm run build-storybook
- The project uses modern ESM and Vite; there is no strict linter configured yet
- Prefer TypeScript for new modules
- Keep changes minimal and focused; include unit tests when adding logic
- See
docs/DATA_MODEL.mdfor entities, stores, and persistence - See
docs/WORKFLOWS.mdfor key user flows and where the logic lives
You can add one or more drills to the static catalog, which is validated at build time.
- Open the drills catalog
- File:
src/data/drills.json - This is an array of Drill objects (see
schemas/drills.schema.jsonandsrc/types/index.ts)
- File:
- Add your drill object
- Ensure the object follows the schema with required fields:
id(string, unique),title,categoryequipment,setup,duration,instructions,metric
- Example structure:
- Ensure the object follows the schema with required fields:
{
"id": "your_unique_id",
"title": "Title",
"category": "Chipping Green",
"equipment": { "balls": 6, "clubs": ["Wedge"] },
"setup": { "schema": "Describe the setup", "location": "Chipping Green" },
"duration": { "suggestedMin": 5, "timerPreset": 300 },
"instructions": { "training": "What to do", "test": "Optional test", "tooEasy": "Optional harder variant" },
"metric": {
"type": "streak",
"unit": "Zonen in Serie",
"hcpTargets": { "54-27": [2,3,4], "26-12": [5,7,9], "11-0": [11,13,15] }
},
"tags": ["Längenkontrolle", "Kontakt"]
}- Validate locally
- Run:
npm run validate:drills - The build will fail (exit code ≠ 0) if the JSON is invalid; fix errors shown by Ajv
- Run:
- Preview in the app
npm run devand open the list view (the catalog is loaded bysrc/stores/drillCatalog.ts)
- Commit and open PR
- Commit your change with a clear message, e.g.,
docs(drills): add chip_carry_zone - Open a PR against
main
- Commit your change with a clear message, e.g.,
Notes:
- The schema lives in
schemas/drills.schema.json(Draft 2020-12) - Keep IDs stable and human-readable (kebab_case or snake_case), e.g.,
chip_carry_zone
- When touching stores or utils, add or update unit tests under
tests/ - Ensure coverage thresholds remain satisfied (
npm run test:coverage) - For UI components, consider adding/adjusting Storybook stories in
src/components/*.stories.ts
- CI runs on push/PR: drills validation, unit tests with coverage, axe check, and Storybook build
- PRs should only be merged when all checks pass