Clean Code
Practices and tools applied throughout the project.
Principles
Clear Project Structure — Related files are grouped into folders by functionality (/controllers, /validators, /services, /routes). Files have matching suffixes (e.g., auth.routes.ts, Authorization.controller.ts) for easy navigation and project-wide search.
Single Responsibility — Functions and classes serve only the purpose they are named after. Each module handles one concern, following the Single Responsibility Principle (SRP).
Reusable Components — Common logic (validators, types, workflow DSL, template variables, node registry) lives in packages/shared and is imported by both frontend and backend, eliminating code duplication and inconsistency.
Descriptive Error Handling — Error messages provide clear information and appropriate HTTP status codes. A centralized AppError class and error handler in the API catches all errors and formats consistent responses. Unhandled exceptions are forwarded to Sentry.
Avoiding Nested Code — Nested if-else chains are replaced with guard clauses and early return patterns, keeping code linear and readable.
Pure Functions — Functions work only with their arguments wherever possible. Environment variables are parsed into typed values via Zod (env.ts), allowing dependent functions to be fully pure.
Dependency Injection — Controllers and services accept their dependencies as constructor parameters, enabling isolated unit testing with mocked dependencies.
Code Analysis Tools
Biome — All-in-one linter and formatter replacing ESLint + Prettier. Runs on every commit and PR. Configuration in biome.json:
- Single quotes, 2-space indentation, 80-char line width
- Trailing commas (ES5 style), semicolons as needed
- Custom rule set with strict correctness, complexity, and suspicious pattern checks
- Relaxed
noExplicitAnyrule for test files
TypeScript — Strict mode enabled project-wide via tsconfig.base.json. All code is fully typed, with shared types from the monorepo's shared package. Path aliases (@licenseplate-checker/shared/*, @shared/*) simplify cross-package imports.
CodeQL — GitHub's default CodeQL setup scans for security vulnerabilities on PRs and on a weekly schedule. Also runs a separate typescript typecheck.
Testing
Bun Test Runner — All tests use Bun's native test framework with .test.ts suffix. Test files are co-located with the source they test (e.g., auth.routes.test.ts alongside auth.routes.ts).
Mock Database — Tests run against PrismockClient, an in-memory Prisma mock, when NODE_ENV=test. No external database required for CI.
Dependency Injection — Controllers accept dependencies as constructor parameters, making it straightforward to swap real implementations for mocks in tests.
Monorepo Conventions
- Naming: Scoped packages
@licenseplate-checker/{name}, route files suffixed.routes.ts, controllers.controller.ts - Validation: Zod schemas shared between frontend and backend via
packages/shared/validators - Scripts: Every package includes
lint,format, andtypecheckscripts, orchestrated by Turborepo - Formatting: Biome handles both linting and formatting in a single tool