--- name: coding-standards description: Coding standards for TypeScript and React in this pnpm monorepo. Use for style, immutability, React, and @repo/* import conventions. --- # Coding Standards & Best Practices Standards for this TypeScript/React frontend. Not a NestJS API. ## Code Quality Principles ### 1. Readability First - Code is read more than written - Clear variable and function names - Self-documenting code over comments - Consistent formatting ### 2. KISS - Simplest solution that works - No premature optimization - Easy to understand over clever code ### 3. DRY - Extract shared logic into functions or `@repo/ui` / `src/core/` - Do not copy-paste modules; copy `example/full-page` then change names ### 4. YAGNI - Do not promote to `packages/` until a second app needs it - Start in the module; lift to `src/core/` when a second module needs it ## TypeScript ### Naming ```typescript const searchQuery = 'widget'; const isAuthenticated = true; async function fetchVehicleType(id: string) {} function isValidCode(code: string): boolean {} ``` ### Immutability (CRITICAL) ```typescript const updated = { ...row, name: 'New' }; const nextItems = [...items, newItem]; ``` Never mutate: no `push`, `splice`, or in-place property assignment on shared state. ### Errors Handle failures; do not swallow. User-facing text via i18n, not raw `error.message` from HTTP. ### Types No `any`. Prefer entity types in `domain/entities` and DTOs next to transformers. ## React - Functional components with typed props - State updates via functional `setState(prev => …)` - Avoid nested ternaries; split into early returns - Lazy-load module routes from the presentation factory ## Imports (this repo) ```ts import { Button, Text } from '@repo/ui/components'; import { FieldTextInput } from '@repo/ui/form'; import { EnterpriseModuleProvider } from '@repo/ui/foundations'; import { compose, required } from '@repo/ui/validators'; import { createHttpClient } from '@repo/core-api/http-client'; import { CommonRemoteDataServices } from '@repo/core-api/data-services'; ``` Do not import `@mantine/core` or axios in `apps/web` feature code. ## Validation Zod + `@repo/ui/validators` (`compose`, `required`, `rangeLength`). No class-validator DTOs. ## File layout - Web features: `apps/web/src/apps/main/modules///` with `data/`, `domain/`, `presentation/` - Shared in one app: `apps/web/src/core/` - Shared across apps: `packages/` Files: 200–400 lines typical, 800 max. Functions under ~50 lines. ## Performance - `useMemo` / `useCallback` only when measured or lists are large - Lazy-load heavy pages - No N+1 UI fetches; use the module data service list endpoint ## Testing Vitest AAA pattern. Descriptive names. See `tdd-workflow`. ## Code smells - Functions > 50 lines — split - Nesting > 4 — early return - Magic numbers — named constants - `console.log` in production - Raw Mantine, raw axios, `import.meta.env` in components