|
| 1 | +# Coding Guidelines for Node.js/TypeScript Boilerplate |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +This repository is a boilerplate for building Node.js applications using TypeScript, following best practices and architectural patterns. It is designed to be a starting point for new projects, providing a solid foundation with modern development tools and methodologies. |
| 6 | + |
| 7 | +## Code Architecture |
| 8 | + |
| 9 | +### Key Patterns |
| 10 | +- **CQRS (Command Query Responsibility Segregation)**: Separates read and write operations for better scalability and maintainability. |
| 11 | +- **Dependency Injection**: Uses Awilix for managing dependencies, promoting loose coupling and easier testing. |
| 12 | +- **Event-driven architecture**: Utilizes an event dispatcher for handling domain events, enabling asynchronous processing and decoupling of components. |
| 13 | +- **Feature-based structure**: Organizes code into features, each encapsulating related functionality, making it easier to navigate and maintain. |
| 14 | +- **REST API**: Exposes a RESTful API for client interactions, following standard HTTP methods and status codes. |
| 15 | + |
| 16 | +### Project Structure |
| 17 | +```src/ |
| 18 | +├── app/ |
| 19 | +│ ├── features/ # Feature-based organization |
| 20 | +│ │ ├── [feature-name]/ # Each feature has its own directory |
| 21 | +│ │ │ ├── actions/ # REST endpoint handlers |
| 22 | +│ │ │ ├── commands/ # State-changing DTOs |
| 23 | +│ │ │ ├── queries/ # Data-retrieval DTOs |
| 24 | +│ │ │ ├── handlers/ # Command/query business logic |
| 25 | +│ │ │ ├── query-handlers/ # Query business logic |
| 26 | +│ │ │ ├── events/ # Domain events |
| 27 | +│ │ │ ├── subscribers/ # Event listeners |
| 28 | +│ │ │ ├── graphql/ # GraphQL resolvers |
| 29 | +│ │ │ ├── models/ # TypeORM entities |
| 30 | +│ │ │ └── routing.ts # Route definitions |
| 31 | +│ ├── infrastructure/ # Infrastructure code (e.g., repositories implementations) |
| 32 | +│ ├── config/ # Configuration files |
| 33 | +│ ├── container/ # Dependency injection container setup |
| 34 | +│ ├── errors/ # Custom error classes |
| 35 | +│ ├── shared/ # Shared utilities and helpers |
| 36 | +│ ├── tests/ # Integration tests files |
| 37 | +│ │ └── bootstrap.ts # Test bootstrap file |
| 38 | +│ └── migrations/ # TypeORM migrations |
| 39 | +├── src/ |
| 40 | +│ ├── index.ts # Application entry point |
| 41 | +│ ├── server.ts # Server setup and configuration |
| 42 | +│ ├── container.ts # Dependency injection container setup |
| 43 | +│ ├── config.ts # Application configuration |
| 44 | +│ ├── logger.ts # Logging setup |
| 45 | +│ ├── database.ts # Database connection setup |
| 46 | +│ └── shared/ # Shared utilities and helpers |
| 47 | +``` |
| 48 | + |
| 49 | +### Key Libraries and Functionalities |
| 50 | +- **TypeScript**: For static typing and modern JavaScript features. |
| 51 | +- **Express**: Web framework for building REST APIs. |
| 52 | +- **TypeORM**: ORM for database interactions. |
| 53 | +- **Awilix**: Dependency injection container. |
| 54 | +- **@tshio/command-bus**: Command bus for handling commands. |
| 55 | +- **@tshio/query-bus**: Query bus for handling queries. |
| 56 | +- **@tshio/event-dispatcher**: Event dispatcher for handling domain events. |
| 57 | +- `src/shared/pagination-utils`: Utility functions for request parameters to TypeORM options conversion and list endpoint responses. |
| 58 | +- **UUID v4**: For unique identifiers in database entities. |
| 59 | +- **Docker**: For containerization and consistent development environment. |
| 60 | +- **Jest**: For unit and integration testing. |
| 61 | +- **Celebrate**: For input validation in REST endpoints. |
| 62 | + |
| 63 | +### Key Development Guidelines |
| 64 | + |
| 65 | +#### Important commands |
| 66 | +- **Linting**: Use `npm run lint` to check code style. |
| 67 | +- **Fixing Lint Issues**: Use `npm run lint-fix` to automatically fix lint issues. |
| 68 | +- **Formatting**: Use `npm run format` to format code according to the project's style guide. |
| 69 | +- **Running Tests**: Use `npm run integration` for integration tests and `npm run units` for unit tests. |
| 70 | +- **Generating Migrations**: Use `npm run generate-migration` to create new migrations. Do not run migrations manually, they are auto-executed at application start. |
| 71 | +- **Running migrations**: Use `npm run migrations` to run all pending migrations. |
| 72 | + |
| 73 | +#### General Guidelines |
| 74 | +- Always use TypeScript for type safety and modern JavaScript features. |
| 75 | +- Follow the project's coding conventions and architecture patterns. |
| 76 | +- Use dependency injection for managing dependencies, avoiding direct instantiation of classes. |
| 77 | +- Never run any commands with `docker-compose` command, use npm scripts instead (e.g., `npm run lint`, `npm run lint-fix`, `npm run forma`). |
| 78 | + |
| 79 | +#### Naming Guidelines |
| 80 | +- Always think in terms of features, not technical layers. |
| 81 | +- Features names should be descriptive and reflect the bounded context (e.g., `planning`, `ordering`, `management`). Avoid naming features by connected entities (e.g., `user`, `product`). |
| 82 | +- Use **kebab-case** for directories, filenames and imports (e.g., `user.controller.ts`). |
| 83 | +- Use **camelCase** for variables and function names (e.g., `getUserById`). |
| 84 | +- Use **PascalCase** for class names and interfaces (e.g., `UserService`). |
| 85 | +- use **snake_case** for database columns and TypeORM entity properties (e.g., `first_name`, `last_name`) but use **camelCase** for variable names in TypeScript code. |
| 86 | +- Use suffixes like `.handler.ts`, `.command.ts`, `.query.ts`, `.event.ts`, `.subscriber.ts`, `.resolver.ts` for files in features (e.g, `create-user.command.ts`, `user.query.ts`). |
| 87 | +- Use suffixes like `Service`, `Repository`, `Controller` for class names (e.g., `UserService`, `UserRepository`, `UserController`). |
| 88 | + |
| 89 | +#### Database Guidelines |
| 90 | +- Use **TypeORM** for database interactions. |
| 91 | +- Use **UUID v4** for unique identifiers, avoid auto-increment IDs. |
| 92 | +- Use repositories for data access in handlers, not direct TypeORM queries. |
| 93 | +- Always generate migrations using the provided npm script (`npm run generate-migration`), do not create them manually. |
| 94 | +- Never add parameters to the `npm run generate-migration` command, as it will fail. |
| 95 | +- All migrations are auto-executed at application start, do not run them manually. |
| 96 | +- Migrations are stored in `src/migrations/`. |
| 97 | + |
| 98 | +#### Testing Guidelines |
| 99 | +- Every endpoint must have a corresponding integration test. |
| 100 | +- Every utility function must have a corresponding unit test. |
| 101 | + |
| 102 | +#### Security Guidelines |
| 103 | +- Use `helmet` for security headers in Express. |
| 104 | +- Use `celebrate` for input validation in REST endpoints. |
| 105 | +- Use global error handling middleware for catching and formatting errors. |
| 106 | +- Add logging for important events and errors using injected logger in handlers and actions. |
| 107 | +- Never expose sensitive information in error messages or responses. |
| 108 | +- Use environment variables for sensitive configuration (e.g., database credentials, API keys) and load them using `dotenv`. |
| 109 | +- Use HTTPS for secure communication, especially in production environments. |
| 110 | +- Implement proper authentication and authorization mechanisms for protected routes. |
| 111 | +- Regularly update dependencies to patch security vulnerabilities. |
| 112 | +- Use `cors` middleware to control cross-origin requests, allowing only trusted origins. |
0 commit comments