--- description: Core engineering principles, TypeScript, validation, and definition of done alwaysApply: true --- You are working in a TypeScript-first monorepo for a modern HOA management platform. ## Project structure - This repository uses `pnpm` workspaces. - Top-level workspace structure: - `apps/web` — Next.js frontend - `apps/api` — Fastify backend - `packages/*` — shared packages - Prefer shared packages from the start for reusable concerns such as UI primitives, types, config, i18n, lint config, and tsconfig. ## Core engineering principles - Prefer maintainability, clarity, and explicitness over cleverness. - Prefer fewer dependencies unless a new dependency is clearly justified. - When adding a dependency, always use the latest stable non-beta version. - Do not add packages when platform features or existing dependencies are sufficient. - Do not introduce anti-patterns. - Always follow established patterns in the codebase. - If a requested change conflicts with established architecture or patterns, stop and ask before proceeding. ## Planning and execution - Before making large changes, propose a brief implementation plan first. - “Large changes” include: - modifications across multiple files - schema changes - new dependencies - architecture changes - changes spanning multiple workspaces - Prefer small, reviewable changes over sweeping rewrites unless explicitly instructed otherwise. ## File and code organization - Prefer modifying existing files over creating new abstractions unless a new abstraction is justified. - Avoid speculative abstractions. Generalize after a second real use case. - Do not create multi-thousand-line files. - Split large files into focused modules before they become unwieldy. - Keep modules small and cohesive. - Prefer composition over inheritance. - Prefer pure functions where practical. - Do not create giant utility dumping-ground files. ## TypeScript standards - Use strict TypeScript patterns. - Avoid `any` unless absolutely unavoidable and explicitly justified. - Prefer precise types, discriminated unions, and explicit return types where helpful for maintainability. - Shared types and schemas should live in dedicated packages when reused across workspaces. - **Always use extensionless imports.** Write `import { foo } from './foo'`, never `import { foo } from './foo.js'`. All TypeScript is processed by `tsx`, Next.js, or Vitest — none require explicit extensions. An ESLint rule enforces this. ## Validation and safety - Validate all external boundaries. - This includes: - API request validation - API response validation where appropriate - environment variable validation - form validation - file upload validation - Use Zod as the default schema validation library unless explicitly directed otherwise. - **Examples:** Validate request body and params at every API route boundary; validate environment variables at app startup (e.g. with a Zod schema) and fail fast if invalid. ## Documentation - Add JSDoc for every non-trivial function or method, whether internal or exported. - JSDoc should be useful, not decorative. - Include parameter descriptions, return values, thrown errors where relevant, and examples when useful. - Do not add comments that merely restate obvious code. ## Definition of done - Before considering work complete, run the smallest relevant checks during development and the full validation suite before finalizing. - Full validation includes: - Prettier - lint - typecheck - tests - Never mark work complete if lint, typecheck, or tests fail. - When finalizing, summarize what checks were run and their outcome. ## Documentation and repo hygiene - Keep related documentation up to date when behavior changes. - This includes, where relevant: - README files - environment examples - package scripts - API docs - setup docs - New apps or packages should include appropriate scripts, test setup, lint/typecheck setup, and a README. ## Security and secrets - Never hard-code secrets. - Never commit mock credentials or insecure defaults. - Secrets must only be stored in environment variables or the database, whichever is appropriate for the use case. - Prefer secure defaults.