|
| 1 | +# Code Conventions |
| 2 | + |
| 3 | +## Purpose |
| 4 | + |
| 5 | +Use these conventions to keep agent-authored code consistent across features. Prefer existing local patterns when they are more specific than this document. |
| 6 | + |
| 7 | +## Files and Directories |
| 8 | + |
| 9 | +- React component files use `PascalCase.tsx`: `TransportBar.tsx`, `PianoRoll.tsx`. |
| 10 | +- Component CSS Modules use the same base name: `TransportBar.module.css`. |
| 11 | +- Feature folders use `kebab-case`: `drum-step-sequencer`, `piano-roll`. |
| 12 | +- General TypeScript utility files use `kebab-case.ts`: `tick-time.ts`, `sample-loader.ts`. |
| 13 | +- Barrel files may use `index.ts` only when they simplify imports without hiding ownership. |
| 14 | +- Test files use `*.test.ts` or `*.test.tsx` next to the code they cover unless a feature establishes a clearer local pattern. |
| 15 | + |
| 16 | +## TypeScript Naming |
| 17 | + |
| 18 | +- Types, interfaces, classes, enums, and React components use `PascalCase`. |
| 19 | +- Functions, variables, object properties, and module-level helpers use `camelCase`. |
| 20 | +- True constants use `UPPER_SNAKE_CASE`: `DEFAULT_PPQ`, `BAR_TICKS`, `STEP_TICKS`. |
| 21 | +- Generic type parameters should be short and meaningful: `T`, `TEvent`, `TClip`. |
| 22 | +- Avoid abbreviations unless they are common in the domain, such as `MIDI`, `PPQ`, `BPM`, or `ID`. |
| 23 | + |
| 24 | +## React Components |
| 25 | + |
| 26 | +- Component names should match product nouns: `TransportBar`, `ClipEditor`, `DrumStepSequencer`. |
| 27 | +- Event handlers use `handleX`: `handlePlayClick`, `handleStepToggle`. |
| 28 | +- Custom hooks use `useX`: `useTransportState`. |
| 29 | +- Components should not own exact audio timing or scheduling logic. |
| 30 | +- Keep feature-specific UI under `src/features/` unless it is clearly reusable. |
| 31 | +- Keep shared presentational components under `src/components/`. |
| 32 | + |
| 33 | +## Domain Naming |
| 34 | + |
| 35 | +- Tick values should use `Tick` or a `Ticks` suffix when they represent a duration or length: |
| 36 | + - `startTick` |
| 37 | + - `durationTicks` |
| 38 | + - `lengthTicks` |
| 39 | +- Seconds should be explicit: |
| 40 | + - `durationSeconds` |
| 41 | + - `lookaheadSeconds` |
| 42 | + - `scheduleAheadSeconds` |
| 43 | +- Web Audio clock values should make audio-time semantics clear: |
| 44 | + - `audioStartTime` |
| 45 | + - `scheduledAudioTime` |
| 46 | +- IDs use `Id` suffix in property names: |
| 47 | + - `clipId` |
| 48 | + - `trackId` |
| 49 | + - `sampleId` |
| 50 | +- Booleans should start with `is`, `has`, `can`, or `should`: |
| 51 | + - `isPlaying` |
| 52 | + - `hasSelection` |
| 53 | + - `canResizeNote` |
| 54 | + - `shouldLoop` |
| 55 | + |
| 56 | +## CSS Modules |
| 57 | + |
| 58 | +- CSS Module class names use `camelCase`: `root`, `transportBar`, `stepButton`, `activeStep`. |
| 59 | +- Prefer product or component part names over visual-only names. |
| 60 | +- Keep static appearance in CSS Modules. |
| 61 | +- Runtime editor geometry may use inline styles when values are derived from ticks, pitch, or grid dimensions. |
| 62 | +- Do not put component-specific styles in global CSS. |
| 63 | + |
| 64 | +## Design Tokens |
| 65 | + |
| 66 | +- Define primitive tokens first: raw palette, spacing, typography, radius, and timing values. |
| 67 | +- Define semantic tokens from primitive tokens. |
| 68 | +- Component CSS Modules should use semantic tokens, not primitive tokens. |
| 69 | +- Primitive token example: `--color-neutral-900`, `--space-4`, `--radius-2`. |
| 70 | +- Semantic token example: `--color-app-background`, `--space-control-gap`, `--radius-control`. |
| 71 | +- Document exceptions when component code must reference a primitive token directly. |
| 72 | + |
| 73 | +## Tests |
| 74 | + |
| 75 | +- Test names should describe behavior, not implementation. |
| 76 | +- Prefer examples such as: |
| 77 | + - `converts ticks to seconds at 120 bpm` |
| 78 | + - `does not schedule duplicate events at the loop end` |
| 79 | +- Unit-test pure utilities, tick/time conversion, data model transformations, and scheduler calculations. |
| 80 | +- Add component or end-to-end tests later when UI behavior becomes stable enough to justify them. |
| 81 | + |
| 82 | +## Comments |
| 83 | + |
| 84 | +- Prefer clear names and small functions over explanatory comments. |
| 85 | +- Add comments only where the reason is not obvious from the code. |
| 86 | +- Avoid comments that restate the next line of code. |
| 87 | +- Use comments to explain timing assumptions, loop-boundary decisions, browser audio constraints, or non-obvious model migrations. |
0 commit comments