{"id":36985363,"url":"https://github.com/jahidhiron/nestjs-template","last_synced_at":"2026-01-13T23:01:39.006Z","repository":{"id":329069463,"uuid":"1083086632","full_name":"jahidhiron/nestjs-template","owner":"jahidhiron","description":"A starter template for NestJS projects with RabbitMQ messaging, TypeORM, WebSocket support, task scheduling, Swagger API docs, i18n, and a structured testing setup. Includes Docker configs, migration scripts, and linting/formatting tools for rapid development.","archived":false,"fork":false,"pushed_at":"2025-12-24T06:20:43.000Z","size":365,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-13T19:44:39.906Z","etag":null,"topics":["docker","i18n","nestjs","open-source","rabbitmq","socket","sql","swagger","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jahidhiron.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-25T10:15:04.000Z","updated_at":"2026-01-11T19:27:14.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jahidhiron/nestjs-template","commit_stats":null,"previous_names":["jahidhiron/nestjs-template"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/jahidhiron/nestjs-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jahidhiron%2Fnestjs-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jahidhiron%2Fnestjs-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jahidhiron%2Fnestjs-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jahidhiron%2Fnestjs-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jahidhiron","download_url":"https://codeload.github.com/jahidhiron/nestjs-template/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jahidhiron%2Fnestjs-template/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28405148,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-13T21:51:37.118Z","status":"ssl_error","status_checked_at":"2026-01-13T21:45:14.585Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","i18n","nestjs","open-source","rabbitmq","socket","sql","swagger","typescript"],"created_at":"2026-01-13T23:01:37.855Z","updated_at":"2026-01-13T23:01:38.998Z","avatar_url":"https://github.com/jahidhiron.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NestJS Teamplate\n\n[![License](https://img.shields.io/badge/license-Private-blue.svg)]()\n[![Docker](https://img.shields.io/badge/docker-ready-brightgreen.svg)]()\n\nA microservice built with **NestJS** and **MySQL** for handling delayed actions (scheduled or deferred tasks).  \nThe service is containerized with **Docker**.\n\n---\n\n## Table of Contents\n\n- [Features](#features)\n- [Getting Started](#getting-started)\n- [Environment Variables](#environment-variables)\n- [Running the Service](#running-the-service)\n- [API Documentation](#api-documentation)\n- [Database](#database)\n- [Project Structure](#project-structure)\n- [Scripts](#scripts)\n- [Documentation](#documentation)\n- [Contributing](#contributing)\n- [Code of Conduct](#code-of-conduct)\n- [Support](#support)\n- [License](#license)\n\n---\n\n## Features\n\n- ⚡ Built with [NestJS](https://nestjs.com/)\n- 🗄️ MySQL database with Docker volume persistence\n- 🐳 Ready-to-use Docker \u0026 Docker Compose setup\n- 🔒 Environment-based configuration with `.env` files\n- 📖 Integrated Swagger API documentation\n- ✅ Supports automatic database migrations\n- 🐇 RabbitMQ messaging integration for microservices\n- 🌐 WebSocket support for real-time communication\n- ⏱️ Task scheduling with NestJS Schedule module\n- 🌍 Internationalization (i18n) support\n- 🧪 Structured testing setup with Jest and Supertest\n- 🖊️ Code formatting and linting with Prettier \u0026 ESLint\n\n---\n\n## Getting Started\n\n### Prerequisites\n\n- [Docker](https://www.docker.com/get-started)\n- [Docker Compose](https://docs.docker.com/compose/install/)\n- [Node.js](https://nodejs.org/) (if running locally)\n- [pnpm](https://pnpm.io/) (recommended)\n\n### Clone the repository\n\n```bash\ngit clone git@github.com:jahidhiron/nestjs-template.git\ncd nestjs-template\n```\n\n## Environment Variables\n\nBelow is an example of the .env file used on the local machine for the **NestJS Template Project**. You may refer to the **.env.local.example** file for guidance.\n\n```env\n# App\nPORT=8080\nAPPLICATION_MODE=development\nAPI_BASE_URL=\"http://localhost:8080\"\n\n# DB\nDATABASE_URL=mysql://root:123456@localhost:3306/template_db\nMIGRATIONS_RUN=false\n\n# Swagger\nENABLE_SWAGGER_PROTECTION=true\nSWAGGER_USER=swagger-admin\nSWAGGER_PASSWORD=Pass1234?\n\n# RabbitMQ\nENABLE_RABBITMQ=true\nRABBITMQ_URI=amqp://guest:guest@localhost:5672\nRABBITMQ_MANAGEMENT_UI_PORT=15672\nRABBITMQ_QUEUE=nest_template_queue\n\n# Realtime\nCLIENT_SOCKET_URL=\"http://localhost:8080\"\n```\n\nBelow is an example of the .env file used on the Docker for the **NestJS Template Project**. You may refer to the **.env.docker.example** file for guidance.\n\n```env\n# App\nPORT=8080\nAPPLICATION_MODE=production\nAPI_BASE_URL=\"http://localhost:8080\"\n\n# API container\nAPI_CONTAINER_NAME=template-api\n\n# DB\nMYSQL_CONTAINER_NAME=mysql\nMYSQL_ROOT_PASSWORD=root\nMYSQL_DATABASE=template_db\nMYSQL_USERNAME=app_user\nMYSQL_PASSWORD=Pass1234@\nMIGRATIONS_RUN=true\n\n# Swagger\nENABLE_SWAGGER_PROTECTION=true\nSWAGGER_USER=swagger-admin\nSWAGGER_PASSWORD=Pass1234?\n\n# RabbitMQ\nENABLE_RABBITMQ=true\nRABBITMQ_CONTAINER_NAME=rabbitmq\nRABBITMQ_DEFAULT_USER=admin\nRABBITMQ_DEFAULT_PASS=Pass1234!\nRABBITMQ_QUEUE=nest_template_queue\nRABBITMQ_MANAGEMENT_UI_PORT=15672\n\n# Realtime\nCLIENT_SOCKET_URL=\"http://localhost:8080\"\n```\n\nBelow is an example of the .env.example file for the NestJS Template Project. Please refer to the .env.example file for guidance.\n\n```env\n# App\nPORT=8080\nAPPLICATION_MODE=production\nAPI_BASE_URL=\"http://localhost:8080\"\n\n# If you are using docker\nAPI_CONTAINER_NAME=template-api\n\n# DB\n# If using a MySQL database as a Docker container, configure the following variables\nMYSQL_CONTAINER_NAME=mysql\nMYSQL_ROOT_PASSWORD=root\nMYSQL_DATABASE=template_db\nMYSQL_USERNAME=app_user\nMYSQL_PASSWORD=root\n\n# If using a local database or a cloud-based database, set the DATABASE_URL accordingly\nDATABASE_URL=mysql://root:123456@localhost:3306/template_db\n\n# This setting is common for both Docker and direct database URL configurations.\n# Set MIGRATIONS_RUN to true if you want to automatically run database migrations.\nMIGRATIONS_RUN=true\n\n# Swagger\nENABLE_SWAGGER_PROTECTION=true\nSWAGGER_USER=swagger-admin\nSWAGGER_PASSWORD=Pass1234?\n\n# RabbitMQ\n# If using a RabbitMQ as a Docker container, configure the following variables\nRABBITMQ_CONTAINER_NAME=rabbitmq\nRABBITMQ_DEFAULT_USER=admin\nRABBITMQ_DEFAULT_PASS=admin\n\n# If using a local RabbitMQ or a cloud-based RabbitMQ, set the RABBITMQ_URI accordingly\nRABBITMQ_URI=amqp://admin:admin@localhost:5672\n\n# These settings are common for both Docker and direct configurations.\nENABLE_RABBITMQ=true\nRABBITMQ_QUEUE=nest_template_queue\nRABBITMQ_MANAGEMENT_UI_PORT=15672\n\n# Realtime\nCLIENT_SOCKET_URL=\"http://localhost:8080\"\n\n```\n\n\u003e **Important:** Ensure that you create a `.env` file in the root directory and use either the `.env.local.example` or `.env.docker.example` as a template.\n\n## Running the Service\n\nThe NestJS Teamplate can be run locally for development or in a containerized production environment using Docker Compose.\n\n---\n\n### Using Docker Compose\n\n#### Start Service\n\n```bash\npnpm run docker:up\n```\n\n#### Stop Service\n\n```bash\npnpm run docker:down\n```\n\n### Without Docker\n\n#### Start Service\n\n```bash\npnpm run start:dev\n```\n\n## API Documentation\n\nThe NestJS Teamplate uses **Swagger** to provide interactive API documentation.  \nSwagger allows developers to explore and test endpoints directly from the browser.\n\n---\n\n### Accessing Swagger\n\nOnce the service is running (locally or in Docker), you can access Swagger UI at:\n\n```bash\nhttp://localhost:8080/api\n```\n\nExample for .env:\n\n```env\nPORT=8080\n```\n\nFor production or staging environments, replace `localhost:8080` with the corresponding API base URL.\n\nExample:\n\n```bash\nhttps://api.dev.example.com/api\n```\n\n---\n\n## Database\n\nThe NestJS Teamplate uses **MySQL** as its primary database.  \nDatabase configuration is managed via the `.env` file, and data persistence is handled through Docker volumes when running in containers.\n\n---\n\n### Database Configuration\n\nThe database connection is configured using environment variables in `.env`:\n\n```| Variable         | Description                                                                                             |\n| ---------------- | ------------------------------------------------------------------------------------------------------- |\n| `MYSQL_HOST`     | MySQL host (e.g., `mysql-db` for Docker or `localhost` for a local database)                            |\n| `MYSQL_PORT`     | MySQL port (default: `3306`)                                                                            |\n| `MYSQL_USERNAME` | MySQL username                                                                                          |\n| `MYSQL_PASSWORD` | MySQL password                                                                                          |\n| `MYSQL_DATABASE` | Database name                                                                                           |\n| `MIGRATIONS_RUN` | Whether to run migrations automatically (`true`/`false`)                                                |\n| `DATABASE_URL`   | You can use a database URL directly instead of specifying host, port, username, and password separately |\n```\n\nExample:\n\n```env\nMYSQL_HOST=mysql-db\nMYSQL_PORT=3306\nMYSQL_USERNAME=myuser\nMYSQL_PASSWORD=mysecretpassword\nMYSQL_DATABASE=delayed_action_db\nMIGRATIONS_RUN=true\n```\n\n## Project Structure\n\n```bash\n.\n├── dist/\n├── logs/\n├── src/                                           # All application source code\n│   ├── common/                                    # Cross‑cutting utilities\n│   │   ├── constants/\n│   │   ├── decorators/\n│   │   ├── dtos/\n│   │   ├── entities/\n│   │   ├── enums/\n│   │   ├── filters/\n│   │   ├── helpers/\n│   │   ├── helpers/\n│   │   ├── interceptors/\n│   │   ├── interfaces/\n│   │   ├── middlewares/\n│   │   ├── pipes/\n│   │   ├── logger/\n│   │   ├── pipes/\n│   │   ├── providers/\n│   │   ├── repositories/\n│   │   ├── swagger/\n│   │   ├── utils/\n│   ├── config/                                    # Centralised configuration\n│   │   ├── app/\n│   │   ├── cors/\n│   │   ├── db/\n│   │   ├── i18n/\n│   │   ├── logger/\n│   │   ├── rabbitmq/\n│   │   ├── realtime/\n│   │   ├── swagger/\n│   │   ├── config.module.ts\n│   │   ├── config.service.ts\n│   │   └── index.ts\n│   ├── cron/\n│   │   ├── services/                             # Cron scheduler\n│   │   │   ├── update-profile.service.ts\n│   │   │   ├── index.ts\n│   │   └── cron.module.ts\n│   ├── db/                                       # Database Configuration\n│   │   ├── config/\n│   │   │   ├── base-database.config.ts\n│   │   │   ├── database.config\n│   │   │   ├── naming-strategy.config.ts\n│   │   │   └── index.ts\n│   │   ├── interfaces/\n│   │   ├── migrations/\n│   │   └── database.module.ts\n│   ├── modules/                                  # Feature modules containing business logic\n│   │   └── app/\n│   │   └── healths/\n│   │   └── projects/\n│   │       ├── dtos/\n│   │       ├── entities/\n│   │       ├── enums/\n│   │       ├── i18n/\n│   │       ├── providers/\n│   │       ├── repositories/\n│   │       ├── swaggers/\n│   │       ├── project.controller.ts\n│   │       ├── project.service.ts\n│   │       └── project.module.ts\n│   ├── rabbitmq/\n│   │   ├── constants/\n│   │   ├── consumers/\n│   │   └── producers/\n│   │       └── rabitmq.module.ts\n│   ├── realtime/\n│   │   ├── adapters/\n│   │   ├── gateways/\n│   │   └── interfaces/\n│   │   └── services/\n│   │   └── types/\n│   │       └── realtime.module.ts\n│   ├── shared/\n│   │   ├── hash/\n│   │   ├── http-client/\n│   │   └── responses/\n│   │       └── shared.module.ts\n│   └── main.ts\n├── test/\n├── .env\n├── .env.example\n├── .gitattributes\n├── .gitignore\n├── ..prettierrc\n├── docker-compose.yaml\n├── eslint.config.mjs\n├── nest-cli.json\n├── package.json\n├── README.md\n├── tsconfig.build.json\n└── tsconfig.json\n\n```\n\n## Scripts\n\n```\n| Script               | Description                                                |\n| -------------------- | ---------------------------------------------------------- |\n| `clean`              | Remove the `dist` directory.                               |\n| `build`              | Clean and build the project.                               |\n| `format`             | Format source files using Prettier.                        |\n| `start:dev`          | Start the application in development mode with watch mode. |\n| `start:debug`        | Start the application in debug mode with watch mode.       |\n| `start`              | Start the compiled application.                            |\n| `docker:up`          | Build and start containers using Docker Compose.           |\n| `docker:down`        | Stop and remove containers using Docker Compose.           |\n| `migration:create`   | Create a new TypeORM migration.                            |\n| `migration:generate` | Generate a new TypeORM migration.                          |\n| `migration:run`      | Run pending migrations.                                    |\n| `migration:revert`   | Revert the last executed migration.                        |\n| `lint`               | Run ESLint with auto-fix.                                  |\n| `test`               | Run unit tests.                                            |\n| `test:watch`         | Run tests in watch mode.                                   |\n| `test:cov`           | Run tests and generate coverage report.                    |\n| `test:debug`         | Run tests in debug mode.                                   |\n| `test:e2e`           | Run end-to-end tests.                                      |\n```\n\n---\n\n## Code Documentation\n\nThis documentation covers the `BaseRepository`, `AppLogger`, `Response Format`, `Swagger`, `RabbitMQ`, `Cron Job`, `Web Socket`, `i18n internationalization`, and `Application Configuration`, along with their common methods and usage examples.\n\nIt provides guidance on performing CRUD operations, handling pagination, executing raw queries, and using transactions effectively.\n\nEach method includes a brief description and a practical example to help developers quickly understand how to use these components in real projects.\n\n---\n\n# Base Repository\n\nThe BaseRepository is a generic TypeORM repository that provides reusable CRUD operations, advanced query building, pagination, and raw query execution with integrated error handling and logging.\n\nFeatures\n\n⚡ Generic CRUD operations (create, createMany, findOne, update, updateMany, remove, removeMany)\n\n🗄️ Advanced query builder with support for relations, search, sorting, pagination, and field selection\n\n🐳 Execute raw SQL queries\n\n🔒 Integrated error handling via ErrorResponse\n\n📖 Logging using AppLogger\n\n## Common Methods\n\nThe `BaseRepository` provides the following reusable methods:\n\n```\n| Method                                    | Description                                                 |\n| ----------------------------------------- | ----------------------------------------------------------- |\n| `create(data, manager?)`                  | Create a single entity                                      |\n| `createMany(data[], manager?)`            | Create multiple entities                                    |\n| `findOne(where, options?, manager?)`      | Find a single entity                                        |\n| `update(query, data, manager?)`           | Update a single entity                                      |\n| `updateMany(query, data, manager?)`       | Update multiple entities                                    |\n| `remove(query, manager?)`                 | Remove a single entity                                      |\n| `removeMany(query, manager?)`             | Remove multiple entities                                    |\n| `list(params?)`                           | List entities without pagination                            |\n| `paginatedList(params?)`                  | List entities with pagination                               |\n| `rawQuery(query, parameters?, manager?)`  | Execute raw SQL queries                                     |\n\n```\n\n## How Methods Work (Short Examples)\n\n### 1. Create a Single Entity\n\nCreates a single entity in the database.\n\n**Example Usage:**\n\n```ts\nconst project = await projectRepository.create({ title: 'New Project' });\n```\n\n### 2. Create Multiple Entities\n\nCreates multiple entities in a single call.\n\n**Example Usage:**\n\n```ts\nawait taskRepository.createMany([{ title: 'Task 1' }, { title: 'Task 2' }]);\n```\n\n### 3. Find One Entity\n\nFinds a single entity matching the query.\n\n**Example Usage:**\n\n```ts\nawait taskRepository.createMany([{ title: 'Task 1' }, { title: 'Task 2' }]);\n```\n\n### 4. Update a Single Entity\n\nUpdates a single entity matching the query.\n\n**Example Usage:**\n\n```ts\nawait projectRepository.update({ id: 1 }, { title: 'Updated Title' });\n```\n\n### 5. Update Multiple Entities\n\nUpdates multiple entities matching the query.\n\n**Example Usage:**\n\n```ts\nawait taskRepository.updateMany({ projectId: 1 }, { status: 'done' });\n```\n\n### 6. Remove a Single Entity\n\nDeletes a single entity matching the query.\n\n**Example Usage:**\n\n```ts\nawait projectRepository.remove({ id: 1 });\n```\n\n### 7. Remove Multiple Entities\n\nDeletes multiple entities matching the query.\n\n**Example Usage:**\n\n```ts\nawait taskRepository.removeMany({ projectId: 1 });\n```\n\n### 8. List Entities With Pagination\n\nRetrieves a paginated list of entities with optional search and sorting.\n\n**Example Usage:**\n\n```ts\nconst { q, page, limit, sortBy, projectId } = dto;\n\n// Build the query object\nconst query: FindOptionsWhere\u003cTaskEntity\u003e = {};\nif (projectId) {\n  query.project = { id: projectId }; // Filter tasks by projectId\n}\n\n// Use BaseRepository's paginatedList method\nconst result = await this.taskRepository.paginatedList({\n  q, // Optional search query string\n  query, // TypeORM where condition\n  searchBy: ['title'], // Fields to search in (title)\n  page, // Pagination page number\n  limit, // Pagination limit\n  sortBy, // Sorting options [{ whom: 'createdAt', order: 'DESC' }]\n  relations: { project: true }, // Include related project entity\n});\n\n// Return data with meta information\nreturn {\n  meta: result.meta, // Pagination info: total, pages, currentPage\n  tasks: result.items, // List of TaskEntity objects\n};\n```\n\n### 9. List Entities Without Pagination\n\nRetrieves all entities matching the query without pagination.\n\n**Example Usage:**\n\n```ts\nconst { q, sortBy, projectId } = dto;\n\n// Build the query object\nconst query: FindOptionsWhere\u003cTaskEntity\u003e = {};\nif (projectId) {\n  query.project = { id: projectId }; // Filter tasks by projectId\n}\n\n// Use BaseRepository's list method\nconst result = await this.taskRepository.list({\n  q, // Optional search query string\n  query, // TypeORM where condition\n  searchBy: ['title'], // Fields to search in (title)\n  sortBy, // Sorting options [{ whom: 'createdAt', order: 'DESC' }]\n  relations: { project: true }, // Include related project entity\n});\n\n// Return data\nreturn {\n  tasks: result.items, // List of TaskEntity objects\n};\n```\n\n### 10. Execute Raw SQL\n\nExecutes raw SQL queries directly on the database. Useful for complex queries, aggregates, or joins.\n\n**Example Usage:**\n\n```ts\n// Example: Fetch all projects with a search term and task count\nconst sql = `\n      SELECT p.id, p.title, COUNT(t.id) AS totalTasks\n      FROM projects p\n      LEFT JOIN tasks t ON t.project_id = p.id\n      WHERE p.title LIKE ?\n      GROUP BY p.id\n    `;\nconst params = ['%My Project%'];\n\n// Execute raw SQL via repository\nconst projects = await projectRepository.rawQuery(sql, params);\n\nconsole.log(projects);\n/*\n    [\n      { id: 1, title: 'My Project 1', totalTasks: 5 },\n      { id: 2, title: 'My Project 2', totalTasks: 3 }\n    ]\n    */\n```\n\n### 11. Transaction Example\n\nYou can perform multiple repository operations in a single **transaction** using `EntityManager`.  \nIf any step fails, all changes are rolled back automatically.\n\n**Example Usage:**\n\n```ts\nconst result = await dataSource.transaction(async (manager: EntityManager) =\u003e {\n  // Create a project\n  const project = await projectRepository.create({ title: 'New Project' }, manager);\n\n  // Create profile linked to the project\n  await profileRepository.create({ bio: 'Project Bio', project }, manager);\n\n  // Create multiple tasks linked to the project\n  await taskRepository.createMany(\n    [\n      { title: 'Task 1', project },\n      { title: 'Task 2', project },\n    ],\n    manager,\n  );\n\n  // Fetch and return the full project with profile and tasks\n  return projectRepository.findOne(\n    { id: project.id },\n    { relations: { profile: true, tasks: true } },\n    manager,\n  );\n});\n\nconsole.log(result);\n/*\n{\n  id: 1,\n  title: 'New Project',\n  profile: { id: 1, bio: 'Project Bio' },\n  tasks: [\n    { id: 1, title: 'Task 1' },\n    { id: 2, title: 'Task 2' }\n  ]\n}\n*/\n```\n\n## Benefits of Using BaseRepository\n\nUsing `BaseRepository` provides several advantages for building scalable and maintainable applications:\n\n1. **Centralized Common Methods**  \n   All CRUD operations, listing, and raw query execution are centralized. You don’t need to write repetitive repository code for each entity.\n\n2. **Reusability Across Modules**  \n   Methods like `create`, `update`, `remove`, `paginatedList`, and `list` can be used across all modules, ensuring consistency and reducing boilerplate code.\n\n3. **Advanced Pagination \u0026 Filtering**  \n   The `paginatedList` method helps easily implement pagination with search, multi-directional sorting, and filtering out-of-the-box. This saves significant development time for common list endpoints.\n\n4. **Flexible Querying**  \n   Supports advanced queries with relations, dynamic search fields, and custom TypeORM `where` conditions.\n\n5. **Raw SQL Execution**  \n   The `rawQuery` method allows executing complex queries or aggregations directly in SQL when standard ORM methods are insufficient.\n\n6. **Transaction Support**  \n   All methods support `EntityManager`, allowing multiple operations to be executed within a single transaction, ensuring data consistency.\n\n7. **Consistency \u0026 Best Practices**  \n   Using `BaseRepository` ensures that all database interactions follow the same pattern, including error handling and logging (via `ErrorResponse` and `AppLogger`).\n\n8. **Rapid Development**  \n   Developers can focus on business logic rather than implementing repetitive repository methods, speeding up development and reducing bugs.\n\n9. **Easily Extendable**  \n   You can extend `BaseRepository` for custom entity-specific methods without breaking existing functionality.\n\n10. **Improved Maintainability**  \n    Centralized repository logic makes maintenance easier, as updates or bug fixes in the base methods automatically apply across all entities using it.\n\n---\n\n# Supported Response Methods and Status Codes\n\nThe project uses `SuccessResponse` and `ErrorResponse` services to standardize API responses with i18n support and HTTP status codes.\n\n```\n| Method                  | HTTP Status               | Description                              |\n| ----------------------- | ------------------------- | ---------------------------------------- |\n| `ok()`                  | 200 OK                    | Generic success response                 |\n| `created()`             | 201 Created               | When a new resource is created           |\n| `accepted()`            | 202 Accepted              | When request is accepted for processing  |\n| `noContent()`           | 204 No Content            | When action succeeds but returns no data |\n| `badRequest()`          | 400 Bad Request           | Invalid input or request                 |\n| `unauthorized()`        | 401 Unauthorized          | Unauthorized access                      |\n| `forbidden()`           | 403 Forbidden             | Access forbidden                         |\n| `notFound()`            | 404 Not Found             | Resource not found                       |\n| `conflict()`            | 409 Conflict              | Conflict with existing resource          |\n| `tooManyRequests()`     | 429 Too Many Requests     | Rate limit exceeded                      |\n| `requestTimeout()`      | 408 Request Timeout       | Request took too long                    |\n| `internalServerError()` | 500 Internal Server Error | Server-side error                        |\n| `serviceUnavailable()`  | 503 Service Unavailable   | Server temporarily unavailable           |\n```\n\n---\n\n## Features\n\n- Centralized CRUD operations via BaseRepository\n- Pagination, search, filtering, and multi-directional sorting support\n- Raw SQL execution for complex queries\n- Standardized success and error responses\n- i18n support for messages based on request headers\n- Automatic and consistent HTTP status codes for all responses\n\n---\n\n### 1. Success Response Example :\n\n```ts\nreturn this.successResponse.created({\n  module: 'project',\n  key: 'create-project', // i18n key: \"project.success.create-project\"\n  ...project,\n});\n```\n\n### Resulting Response (if language is English):\n\n```\n{\n  \"method\": \"POST\",\n  \"success\": true,\n  \"status\": \"CREATED\",\n  \"statusCode\": 201,\n  \"path\": \"/project\",\n  \"timestamp\": \"2025-11-19T10:00:00.000Z\",\n  \"message\": \"Project created successful\",\n  \"data\": {\n    \"id\": 1,\n    \"title\": \"New Project\"\n  }\n}\n\n```\n\n### i18n Usage:\n\nThe key (create-project) is automatically looked up in the en.json file:\n\n```\n\"success\": {\n  \"create-project\": \"Project created successful\"\n}\n\n```\n\n---\n\n### 2. Error Response Example :\n\n```ts\nreturn this.errorResponse.badRequest({\n  module: 'project',\n  key: 'project-already-exist', // i18n key: \"project.error.project-already-exist\"\n});\n```\n\n### Resulting Response (if language is English):\n\n```\n{\n  \"method\": \"POST\",\n  \"success\": false,\n  \"status\": \"BAD_REQUEST\",\n  \"statusCode\": 400,\n  \"path\": \"/project\",\n  \"timestamp\": \"2025-11-19T10:05:00.000Z\",\n  \"message\": \"Project title already exist\"\n}\n```\n\n### i18n Usage:\n\nThe key (project-already-exist) is automatically looked up in the en.json file:\n\n```\n\"error\": {\n  \"project-already-exist\": \"Project title already exist\"\n}\n```\n\n---\n\n# Custom Logger\n\nCustom Logger (AppLogger)\n\nThe AppLogger is a centralized logging service built on Winston and integrated into NestJS.\nIt provides structured, leveled logging for your application with automatic file rotation and environment-based formatting.\n\nKey Features\n\n- Centralized logger for the entire application\n  Supports multiple log levels: log, error, warn, debug, verbose\n\n- Automatically stores error logs in daily rotated files\n\n- Keeps the last 14 days of error logs\n\n- Console logs formatted for development with colorized, readable output\n\n- Only logs debug/verbose messages in non-production environments\n\n### Available Logger Methods:\n\n```\n| Method      | Log Level | Description                                          |\n| ----------- | --------- | ---------------------------------------------------- |\n| `log()`     | INFO      | Logs general information                             |\n| `error()`   | ERROR     | Logs errors with optional stack trace                |\n| `warn()`    | WARN      | Logs warnings                                        |\n| `debug()`   | DEBUG     | Logs debug messages in non-production environments   |\n| `verbose()` | VERBOSE   | Logs verbose messages in non-production environments |\n```\n\n### Example: Logging an Error\n\n```\ntry {\n  await this.dataSource.query('SELECT 1');\n} catch (err: unknown) {\n  this.logger.error(\n    'Database query failed',\n    err instanceof Error ? err.stack : String(err),\n    'DbHealthProvider'\n  );\n}\n\n```\n\n### What happens:\n\n- The error is logged to console (if not in production)\n- A structured JSON error log is stored in the daily rotated file:\n\n```\n/logs/error-2025-11-19.log\n```\n\n### Log format includes:\n\n```\n{\n  \"level\": \"error\",\n  \"message\": \"Database query failed\",\n  \"stack\": \"Error: ...\",\n  \"context\": \"DbHealthProvider\",\n  \"timestamp\": \"2025-11-19 10:15:00\"\n}\n\n```\n\n### Build and Start Containers\n\n---\n\n# Swaggeer\n\nThis project uses NestJS Swagger to generate API documentation automatically. It provides descriptions, request/response schemas, and example responses for each endpoint, including error and success cases.\n\n## How Swagger Works\n\n### 1. Swagger Decorators\n\nEach endpoint in the controller is decorated with **custom Swagger decorators** to automatically generate API documentation.\n\n**Example:**\n\n```ts\n@Post()\n@CreateProjectSwaggerDocs()\nasync create(@Body() dto: CreateProjectDto) {\n  // controller logic\n}\n```\n\n### 2. Example: Create Project Endpoint\n\nThis example demonstrates how to use the custom Swagger helper `CreateProjectSwaggerDocs` to document the **Create Project** API endpoint.  \nIt shows how to define the operation summary, request body, success response, and standard error responses with optional examples.\n\n```\nexport function CreateProjectSwaggerDocs() {\n  return applyDecorators(\n    // Adds the operation summary and description in Swagger UI\n    ApiOperation({\n      summary: 'Create a new project', // Short description for Swagger endpoint\n      description: 'This endpoint allows creating a new project.' // Detailed explanation\n    }),\n\n    // Defines the request body schema for Swagger UI\n    ApiBody({\n      type: CreateProjectDto // The DTO that represents the structure of the request body\n    }),\n\n    // Defines the success response for the endpoint\n    SwaggerApiSuccessResponse(ProjectResponseDto, {\n      method: HttpMethod.POST,               // HTTP method\n      status: HTTP_STATUS.CREATED.context,   // Status text for Swagger UI\n      statusCode: HTTP_STATUS.CREATED.status,// HTTP status code (201)\n      path: ModuleName.Project,              // Path/module for this endpoint\n      message: 'Project created successful', // Success message\n    }),\n\n    // Defines a Bad Request (400) response with examples\n    BadRequestResponse({\n      path: ModuleName.Project,              // Path/module\n      method: HttpMethod.POST,               // HTTP method\n      examples: {\n        // Example for validation error\n        validationError: {\n          summary: 'Validation Error',      // Short description for Swagger UI\n          message: 'Validation Error',      // Error message returned\n          errors: [{ field: 'title', message: 'Title should not be empty' }] // Field-level errors\n        },\n        // Example for duplicate project title\n        duplicateTitle: {\n          summary: 'Duplicate Project Title',\n          message: 'Project title already exist'\n        },\n      },\n    }),\n\n    // Defines Internal Server Error (500) response\n    InternalServerErrorResponse({\n      path: ModuleName.Project,              // Path/module\n      method: HttpMethod.POST                // HTTP method\n    })\n  );\n}\n```\n\n## Available Swagger Helpers\n\nThis table lists the custom Swagger helpers used throughout the Project module.  \nThese helpers standardize the API documentation by defining consistent success and error responses, including optional example payloads for better clarity in Swagger UI.\n\n```\n| Swagger Helper                | HTTP Status / Type        | Description                                                                                        |\n| ----------------------------- | ------------------------- | -------------------------------------------------------------------------------------------------- |\n| `SwaggerApiSuccessResponse`   | 200 / 201 / custom        | Defines successful response structure with optional examples.                                      |\n| `BadRequestResponse`          | 400 Bad Request           | Standard response for validation errors or bad requests, supports examples.                        |\n| `UnauthorizedResponse`        | 401 Unauthorized          | Standard response for unauthorized access.                                                         |\n| `ForbiddenResponse`           | 403 Forbidden             | Standard response for forbidden access.                                                            |\n| `NotFoundResponse`            | 404 Not Found             | Standard response for resource not found.                                                          |\n| `ConflictResponse`            | 409 Conflict              | Standard response for conflicts, e.g., duplicate entries.                                          |\n| `UnprocessableEntityResponse` | 422 Unprocessable Entity  | Response for invalid business logic or unprocessable data.                                         |\n| `TooManyRequestsResponse`     | 429 Too Many Requests     | Rate-limit exceeded response.                                                                      |\n| `InternalServerErrorResponse` | 500 Internal Server Error | Response for unexpected server errors.                                                             |\n| `ServiceUnavailableResponse`  | 503 Service Unavailable   | Response when the service is temporarily unavailable.                                              |\n| `buildSchema`                 | N/A                       | Internal helper that generates full Swagger schema for a specific HTTP status, including examples. |\n```\n\n---\n\n# Others\n\n## Config Module\n\nThe `ConfigModule` centralizes all application configuration, including environment variables, database settings, Swagger, logging, RabbitMQ, WebSocket, Cron Jobs, and internationalization.  \nIt ensures every part of the system can easily access configuration through dependency injection.\n\n### How It Works\n\n1. **Global Configuration Loading**\n\n   The module loads multiple configuration files globally via `@nestjs/config`:\n\n```ts\nNestConfigModule.forRoot({\n  isGlobal: true,\n  load: [appConfig, swaggerConfig, dbConfig, rabbitmqConfig, realtimeConfig],\n});\n```\n\n## Realtime Module\n\nThe `RealtimeModule` enables WebSocket-based real-time communication across the application.  \nIt uses `socket.io` and NestJS gateways to allow broadcasting and targeted communication between the server and connected clients.\n\n### How It Works\n\n- The module provides a `SocketService` that abstracts:\n  - Emitting events to all clients\n  - Emitting events to a specific client\n  - Storing and sharing the active Socket.io namespace\n\n- Two WebSocket gateways are included:\n  - **MainGateway** – Handles global connection initialization and connection logs.\n  - **ProfileGateway** – Handles profile-related WebSocket events (e.g., `get_profile`).\n\n### Features\n\n- Real-time communication using WebSockets\n- Broadcast events to all connected clients\n- Send updates to a specific user\n- Extendable for new event channels\n- Optionally integrates JWT authentication middleware\n- Can be triggered by internal events (e.g., RabbitMQ consumers)\n\n### Example\n\nSending an event to all connected clients:\n\n```ts\nthis.socketService.emitToAll('profile_update', payload);\n```\n\n## Cron Module\n\nThe `CronModule` is responsible for running scheduled background tasks in the application.  \nThese tasks run automatically at fixed intervals using NestJS `@nestjs/schedule` cron decorators.\n\n### Responsibilities\n\n- Periodically pick pending work items (e.g., profiles that need updates)\n- Dispatch jobs into RabbitMQ for asynchronous processing\n- Log status and failures\n- Auto-handle queue failures by reverting profile states\n\n### How It Works\n\nThe module includes a main service:\n\n#### `UpdateProfileService`\n\nThis is a scheduled background worker that:\n\n1. Runs every **30 seconds** using:\n\n```ts\n@Cron(CronExpression.EVERY_30_SECONDS)\n```\n\n## RabbitMQ Module\n\nThe `RabbitMqModule` handles all asynchronous message-based communication in the application.  \nIt is responsible for publishing jobs, consuming jobs, and managing retry logic using RabbitMQ.\n\nThis module enables high-performance background processing and decoupled service interactions.\n\n---\n\n## Responsibilities\n\n- Configure and initialize the RabbitMQ microservice client\n- Publish messages (producers)\n- Consume messages (consumers)\n- Handle failures using DLX (Dead Letter Exchange)\n- Support real-time updates with WebSocket broadcasting\n- Ensure reliable job delivery with retries and backoff\n\n---\n\n## How It Works\n\nThe module contains:\n\n### **1. A Producer**\n\n`UpdateProfileProducerService`\n\nThis service publishes messages into RabbitMQ.  \nIt uses lazy connection handling to ensure the RMQ client connects **once** and safely retries on failure.\n\n**Key features:**\n\n- Ensures RMQ connection (`ensureConnected()`)\n- Emits events with a **2-second timeout**\n- Logs failures without throwing exceptions\n- Returns `true/false` depending on queue success\n\n**Publish Flow:**\n\n```\nvalidate payload → ensure connection → emit event → handle timeout → log → return status\n```\n\n---\n\n### **2. A Consumer**\n\n`UpdateProfileConsumerController`\n\nThis controller listens for events and processes profile update jobs.\n\n**Processing Logic:**\n\n1. Validate and lock the profile (`Queued → Processing`)\n2. Apply update (increment version, set timestamps, mark completed)\n3. Broadcast updates via WebSocket\n4. Acknowledge on success (`ack`)\n5. On failure:\n   - Mark for retry with `nextRunAt +5 minutes`\n   - Push message to DLX using `nack`\n\n**Failure Flow:**\n\n```\nprocessing fail → update profile with retry time → nack (DLX) → auto retry by cron\n```\n\n---\n\n## RabbitMQ Client Configuration\n\nThe client is registered dynamically using application configuration (`ConfigService`):\n\n```ts\nClientsModule.registerAsync([\n  {\n    name: ServiceNames.NEST_TEMPLATE_SYNC,\n    useFactory: (configService: ConfigService) =\u003e ({\n      transport: Transport.RMQ,\n      options: {\n        urls: [configService.rabbitmq.rabbitmqUri],\n        queue: configService.rabbitmq.rabbitmqQueue,\n        queueOptions: { durable: true },\n      },\n    }),\n  },\n]);\n```\n\n### High-Level Flow\n\n```\nCron → Pick Profiles → Producer Publishes Jobs → RabbitMQ → Consumer Processes → Real-time Emit\n```\n\n### Key Features\n\n- Fully decoupled async processing\n- Lazy + safe RMQ connection handling\n- Timeout-protected message publishing\n- Dead-letter exchange retry logic\n- Real-time WebSocket broadcasting\n- Robust error recovery\n- Clean separation between Producer and Consumer\n\n### Testing Real-Time Socket\n\nIf you want to test the real-time WebSocket functionality, you can use the provided `test-socket.html` file located in the root directory of the project.\n\n- Open the file in your browser: [`test-socket.html`](./test-socket.html)\n- It allows you to connect to the `/realtime` namespace and test emitting/listening to events.\n\n\u003e **Note:** Make sure your server is running and the WebSocket endpoint is accessible.\n\n# Contributing to NestJS Template\n\nWe welcome contributions to this project! To get started, fork the repository and clone it to your local machine. Here are some guidelines to follow:\n\n## Reporting Issues\n\nPlease create a new issue for any bugs or suggestions you have. Be sure to provide clear details about the problem, including steps to reproduce.\n\n## Submitting Pull Requests\n\n- Fork the repository and clone it locally.\n- Create a new branch (`git checkout -b feature-name`).\n- Write your code and tests.\n- Commit your changes (`git commit -am 'Add new feature'`).\n- Push your branch to your fork (`git push origin feature-name`).\n- Submit a pull request.\n\n## Contributing\n\nWe welcome contributions to improve the NestJS Template! Please follow the guidelines in the [CONTRIBUTING.md](./CONTRIBUTING.md) file for details on how to contribute.\n\n### How to Contribute\n\n1. **Fork the repository**\n2. **Clone your fork**\n   ```bash\n   git clone git@github.com:jahidhiron/nestjs-template.git\n   cd nestjs-template\n   ```\n\n## Code of Conduct\n\nWe are committed to maintaining a positive and inclusive environment for all contributors. Please review our [Code of Conduct](./CODE_OF_CONDUCT.md) to understand the expectations for participation in this project.\n\nBy participating, you agree to uphold these standards and contribute positively to the community.\n\n## Support\n\nIf you need help or have questions, feel free to reach out:\n\n📧 **Email:** **[namehiron.96@gmail.com](mailto:namehiron.96@gmail.com)**\n\n## License\n\nThis project is licensed under the MIT License.  \nSee the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjahidhiron%2Fnestjs-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjahidhiron%2Fnestjs-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjahidhiron%2Fnestjs-template/lists"}