# Code Style & Best Practices

### File Structure

```
src/
├── app.module.ts
├── main.ts
├── modules/
│   ├── users/
│   │   ├── users.controller.ts
│   │   ├── users.service.ts
│   │   ├── users.module.ts
│   │   ├── dto/
│   │   │   ├── create-user.dto.ts
│   │   │   └── update-user.dto.ts
│   │   └── entities/
│   │       └── user.entity.ts
│   └── auth/
├── common/
│   ├── decorators/
│   ├── filters/
│   ├── guards/
│   ├── interceptors/
│   └── pipes/
└── config/
```

### Basic Principles

- Use English for all code and documentation.
- Always declare the type of each variable and function (parameters and return value).
  - Avoid using any at all costs.
  - Create necessary types.
- Use JSDoc to document public classes and methods.
- Don't leave blank lines within a function.
- Never use `export default`

### Modules

- Use feature modules to organize code
- Import dependencies in module decorators
- Use global modules sparingly
- Follow single responsibility principle

### Controllers

- Keep controllers thin, delegate business logic to services
- Use proper HTTP status codes
- Implement proper error handling
- Use DTOs for request/response validation

### Services

- Implement business logic in services
- Use dependency injection
- Make services testable
- Follow SOLID principles

### DTOs

- Use class-validator for validation
- Create separate DTOs for create/update operations
- Use class-transformer for data transformation
- Document DTO properties with Swagger decorators

### Functions

- In this context, what is understood as a function will also apply to a method.
- Write short functions with a single purpose. Less than 250 lines of code.
- We preferred the pure function, since it is easier to understand and test
- Always add the tests for function
- Name functions with a verb and something else.
  - If it returns a boolean, use isX or hasX, canX, etc.
  - If it doesn't return anything, use executeX or saveX, etc.
- Avoid nesting blocks by:
  - Early checks and returns.
  - Extraction to utility functions.
- Use higher-order functions (map, filter, reduce, etc.) to avoid function nesting.
  - Use arrow functions for simple functions (less than 3 instructions).
  - Use named functions for non-simple functions.
- Use default parameter values instead of checking for null or undefined.
- Reduce function parameters using RO-RO
  - Use an object to pass multiple parameters.
  - Use an object to return results.
  - Declare necessary types for input arguments and output.
- Use a single level of abstraction.
