{"id":26282900,"url":"https://github.com/yavarguliyev/invoice_hub_microservices","last_synced_at":"2025-03-14T17:15:58.218Z","repository":{"id":282293743,"uuid":"936712062","full_name":"yavarguliyev/invoice_hub_microservices","owner":"yavarguliyev","description":"Invoice-hub-microservices","archived":false,"fork":false,"pushed_at":"2025-03-13T19:06:06.000Z","size":2294,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-13T20:25:38.171Z","etag":null,"topics":["dependency-injection-pattern","design-patterns","docker","docker-compose","factory-pattern","inversion-of-control","kafka","microservices","nginx","nodejs","oop","postgresql","redis","routing-controllers","singelton-pattern","solid","typeorm","typescript","winston","yarn-workspaces"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yavarguliyev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"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}},"created_at":"2025-02-21T14:57:04.000Z","updated_at":"2025-03-13T19:06:09.000Z","dependencies_parsed_at":"2025-03-13T20:35:50.596Z","dependency_job_id":null,"html_url":"https://github.com/yavarguliyev/invoice_hub_microservices","commit_stats":null,"previous_names":["yavarguliyev/invoice_hub_microservices"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yavarguliyev%2Finvoice_hub_microservices","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yavarguliyev%2Finvoice_hub_microservices/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yavarguliyev%2Finvoice_hub_microservices/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yavarguliyev%2Finvoice_hub_microservices/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yavarguliyev","download_url":"https://codeload.github.com/yavarguliyev/invoice_hub_microservices/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243615631,"owners_count":20319733,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["dependency-injection-pattern","design-patterns","docker","docker-compose","factory-pattern","inversion-of-control","kafka","microservices","nginx","nodejs","oop","postgresql","redis","routing-controllers","singelton-pattern","solid","typeorm","typescript","winston","yarn-workspaces"],"created_at":"2025-03-14T17:15:57.467Z","updated_at":"2025-03-14T17:15:58.213Z","avatar_url":"https://github.com/yavarguliyev.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Project Overview\n\n##### This Node.js application is built using a microservices architecture, designed for scalability, modularity, and maintainability. It uses TypeScript for strong typing and integrates key technologies such as ExpressJS, PostgreSQL, Redis, Apache Kafka, REST APIs, and Docker to ensure optimal performance and flexibility in scaling individual services. The application applies multiple design patterns and software engineering principles to promote clean, maintainable, and testable code.\n\n---\n\n# 📖 Table of Contents\n\n1. Features\n2. Architecture Overview\n3. Interaction Flow in Microservices and Architecture\n4. Domain-Driven Design Principles and Patterns\n5. Design Patterns\n6. Principles\n7. Technologies\n8. Getting Started\n9. Project Structure\n10. API Documentation\n11. Running the Application\n12. Running Tests\n13. Usage\n14. Contributing\n15. License\n\n---\n\n# ✨ Features\n\n## Order Management\n\n* Order Retrieval\n* Fetches a paginated list of orders with filtering options.\n* Uses Redis caching to optimize data retrieval.\n* Creates a new order with PENDING status.\n* Associates the order with the current authenticated user.\n* Publishes an event to notify admins about the new order.\n* Future enhancement: Email notification to admins for approval.\n* Updates order status from PENDING to COMPLETED.\n* Generates an invoice and marks it as PAID.\n* Publishes an event upon approval.\n* Future enhancement: Email notification with an attached invoice.\n* Updates order status from PENDING to CANCELLED.\n* Generates an invoice and marks it as CANCELLED.\n* Publishes an event upon cancellation.\n* Future enhancement: Email notification with an attached invoice.\n\n---\n\n## User Service\n* Fetches a paginated list of users with filtering options.\n* Retrieves users along with their assigned roles.\n* Uses Redis caching for performance optimization.\n* Fetches a user by ID.\n* Ensures the user exists before returning the data.\n* Validates that an email is unique before creating a user.\n* Assigns a default role if none is specified.\n* Generates a strong password.\n* Publishes an event upon user creation.\n* Future enhancement: Send an email with login credentials.\n* Updates user details, ensuring no duplicate email exists.\n* Publishes an event upon user update.\n* Verifies current password before allowing an update.\n* Ensures password confirmation matches.\n* Encrypts the new password before saving.\n* Publishes an event upon password update.\n\n---\n\n## Future Enhancements\n\n* Implement email notifications for order approvals, cancellations, and user account creation.\n* Enhance Redis caching to improve query performance further.\n* Introduce logging and monitoring to track system performance and user interactions.\n\n---\n\n# 🏗 Architecture Overview\n\n![Architecture Overview](./image/logical-diagram.png)\n\n---\n\n#### This application follows a microservices architecture where each core business function (Order Management, User Management, etc.) is handled by an independent service. This ensures better scalability, fault isolation, and maintainability.\n\n* Microservices: Each business domain (Orders, Users, Invoices) is isolated into its own service, allowing independent scaling and development.\n* Modular Design: Each service follows clear boundaries and can be developed/deployed independently.\n* Event-Driven Communication: Services interact asynchronously via Kafka events (e.g., order creation, user updates).\n* Asynchronous Processing: Redis is used for caching and message queues, ensuring non-blocking operations.\n* Load Balancing: The system scales horizontally using Docker, Kubernetes, and Nginx.\n\n---\n\n# 🧩🔄⚙️🌐 Interaction Flow in Microservices\n\n\n![Interaction Flow in DDD and Microservices](./image/interaction-diagram.png)\n\n---\n\n## 1. Domain Layer:\n\n* Houses the core business logic for each microservice (Orders, Users, Invoices).\n* Encapsulates operations like changing order statuses, creating users, and generating invoices.\n\n## 2. Service Layer:\n\n* Handles interactions between the domain logic and infrastructure.\n* Uses repositories for data persistence and Kafka for event-driven communication.\n\n## 3. Infrastructure Layer:\n\n* Manages PostgreSQL, Redis, Kafka, and email notifications.\n* Redis is leveraged for caching frequently accessed data.\n\n## 4. API Gateway:\n\n* Routes client requests to the appropriate microservice.\n* Can aggregate responses from multiple services, reducing client complexity.\n\n## 5. Event-Driven Communication:\n\n* Kafka publishes and consumes events for system-wide updates.\n* Example: When an order is approved, a Kafka event triggers the invoice generation process.\n\n---\n\n# ⚙️ Domain-Driven Design Principles and Patterns\n\n* REST API with ExpressJS \u0026 TypeScript\n* PostgreSQL with ORM for database management\n* Redis for caching and queue management\n* Dependency Injection using typedi\n* Event-driven architecture with Kafka for inter-service communication\n* Microservices architecture for scalability\n* Robust Logging \u0026 Monitoring\n* Unit \u0026 E2E Testing for reliability\n* Security Best Practices\n* Scalable \u0026 Maintainable Codebase\n\n---\n\n# 🧩⚙️🛠️📐 Design Patterns\n\n##### The following design patterns have been applied to the system to ensure modularity, flexibility, and scalability:\n\n## 1. Singleton Pattern\n\n* Used for managing database connections and Redis cache to ensure only one instance is created.\n\n## 2. Factory Pattern\n\n* Encapsulates object creation, allowing for dynamic service instantiation.\n\n## 3. Dependency Injection (DI)\n\n* Uses TypeDI to inject dependencies, reducing coupling.\n\n## 4. Observer Pattern\n\n* Ensures real-time updates by notifying services of state changes (e.g., via Kafka events).\n\n## 5. Strategy Pattern\n\n* Allows dynamic switching between querying strategies without modifying core logic.\n\n## 6. Command Pattern\n\n* Encapsulates complex workflows like submitting jobs to Redis queues.\n\n## 7. Decorator Pattern\n\n* Adds features like caching and event publishing without modifying core functionality.\n\n## 8. Proxy Pattern\n\n* Implements caching and rate-limiting to optimize API calls.\n\n## 9. Repository Pattern\n\n* Abstracts database interactions, ensuring a clean separation from business logic.\n\n## 10. Builder Pattern\n\n* Constructs complex objects like invoices and user profiles in a systematic way.\n\n## 11. Publisher-Subscriber Pattern\n\n* Uses Kafka for event-driven messaging, allowing services to communicate asynchronously.\n\n---\n\n# 📏🧭💡⚖️ Principles\n\n##### This project follows key software design principles to ensure a robust and maintainable codebase:\n\n## 1. SOLID Principles\n\n* Single Responsibility Principle (SRP): Each class and module has a single responsibility, minimizing changes and complexity.\n* Open/Closed Principle (OCP): Classes and modules are open for extension but closed for modification, enabling easier feature additions without breaking existing functionality.\n* Liskov Substitution Principle (LSP): Derived classes can be used in place of their base classes without altering the correctness of the program.\n* Interface Segregation Principle (ISP): Clients should not be forced to depend on interfaces they do not use. This helps in creating smaller, specialized interfaces.\n* Dependency Inversion Principle (DIP): High-level modules should not depend on low-level modules. Both should depend on abstractions, which is achieved through DI.\n\n## 2. DRY (Don't Repeat Yourself)\n\n* The codebase ensures that redundant logic and code are minimized. Reusable components and functions are created for common tasks such as error handling, logging, and validation.\n\n## 3. KISS (Keep It Simple, Stupid)\n\n* The application follows a simple and clear architecture, avoiding unnecessary complexity in both the design and implementation. We favor simplicity and readability.\n\n## 4. YAGNI (You Aren't Gonna Need It)\n\n* Only essential features and functionality are implemented. The project avoids overengineering, focusing on the current requirements.\n\n## 5. Separation of Concerns\n\n* The project ensures that business logic, data access, and presentation are separated. Each module is responsible for a specific concern, promoting modularity and maintainability.\n\n## 6. Composition Over Inheritance\n\n* The project favors composing objects and reusing behavior through composition rather than relying heavily on inheritance.\n\n---\n\n# 💻 Technologies\n\n* Node.js \u0026 ExpressJS – Backend framework.\n* TypeScript – Statically typed JavaScript.\n* PostgreSQL – Relational database with ORM.\n* Redis – Caching and message queues.\n* Kafka – Event-driven microservices communication.\n* TypeDI – Dependency Injection.\n* Docker \u0026 Kubernetes – Containerization \u0026 orchestration.\n* DataLoader – Optimized database queries.\n\n---\n\n# 🚀 Getting Started\n\n## 1. Prerequisites\n\n### For Docker Usage\n\n* Install Docker Desktop and ensure it is running.\n\n### For Application Usage\n\n* ✅ Node.js (v23.x or higher)\n* ✅ TypeScript\n* ✅ PostgreSQL\n* ✅ Redis\n* ✅ Kafka\n* ✅ Docker \u0026 Kubernetes\n* ✅ yarn\n\n---\n\n## Installation\n\n## 1. Clone the repository:\n\n```javascript\ngit clone git@github.com:yavarguliyev/invoice_hub_microservices.git\n```\n\n## 2. Set Up Environment: \n\n#### The Docker setup is located at {main_root}/deployment/dev. For managing containers, we do not use the docker-compose up -d command directly. Instead, we use specific scripts to handle the container lifecycle.\n\n#### 1. To start the containers:\n\n```javascript\nbash start.sh\n```\n\n#### 2. To stop the containers:\n\n```javascript\nbash stop.sh\n```\n\n#### 3. To remove the containers, images, and volumes:\n\n```javascript\nbash remove.sh \n```\n\n## Environment Configuration\n\n* The .env file located in {main_root}/deployment/dev/.env is required for configuration.\n* You can copy the example file (.env.example) to create your own .env file.\n\n## 3. Install dependencies:\n\n```javascript\nyarn add\n```\n\n## 4. Run Migrations:\n\n##### Run migrations:\n\n```javascript\nyarn mup\n```\n\n##### Revert migrations:\n\n```javascript\nyarn mdn\n```\n\n##### Copy the .env.example file to .env and fill in the appropriate values for your environment.\n\n---\n\n# 📂 Project Structure\n\n```javascript\n/api-gateway    # Manages API routing.\n/common         # Shared utilities and configs.\n/deployment     # Deployment environment configs.\n├── /dev        # Development environment setup.\n├── /prod       # Production environment setup.\n/services       # Individual service modules\n├── /auth       # Handles authentication logic.\n├── /invoices   # Manages invoice operations.\n├── /orders     # Handles order operations.\n/package.json   # Defines workspaces for modular structure.\n└── README.md   # Project documentation.\n```\n\n---\n\n# 📚📄📝💻 API Documentation\n\n#### API documentation is available at:\n\n#### A Postman collection file is also included for testing API use cases:\n\n```javascript\n/postman/invoice_hub_microservices.postman_collection.json\n```\n\n# 🚀▶️💻 Running the Application\n\n##### To start the application:\n\n```javascript\nyarn start\n```\n\n# 🧪✅🔍 Running Tests\n\n##### To run tests, execute the following command:\n\n```javascript\nyarn test\n```\n\n---\n\n# 🛠 Usage\n\n## Example Operations\n\n### 1. Create an Order\n\n#### Endpoint: POST {{URL}}/orders/api/v1/orders\n\n```javascript\n{\n    \"totalAmount\": 180.20\n}\n```\n\n### 2. Approve the Order\n\n```javascript\nEndpoint: PATCH {{URL}}/orders/api/v1/orders/{{id}}/approve\n```\n\n### 3. Cancel the Order\n\n```javascript\nEndpoint: PATCH {{URL}}/orders/api/v1/orders/{{id}}/cancel\n```\n\n---\n\n# 🤝 Contributing\n\n1. Fork the repository.\n2. Create a new branch (git checkout -b feature-name).\n3. Commit your changes (git commit -am 'Add new feature').\n4. Push to the branch (git push origin feature-name).\n5. Create a new Pull Request.\n\n---\n\n# 📝 License\n\n#### This project is licensed under the MIT License. See the [LICENSE](https://github.com/yavarguliyev/invoice_hub_microservices/blob/master/LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyavarguliyev%2Finvoice_hub_microservices","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyavarguliyev%2Finvoice_hub_microservices","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyavarguliyev%2Finvoice_hub_microservices/lists"}