Skip to content

Commit 5528145

Browse files
authored
Merge pull request #4 from frckbrice/chore/refactor
Chore/refactor
2 parents 05fab7a + 9007a95 commit 5528145

52 files changed

Lines changed: 6327 additions & 2930 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.eslintrc

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
11
{
2-
"extends": [
3-
"prettier"
2+
"env": {
3+
"node": true,
4+
"es2021": true
5+
},
6+
"extends": [
7+
"eslint:recommended",
8+
"plugin:prettier/recommended"
9+
],
10+
"plugins": [
11+
"prettier"
12+
],
13+
"rules": {
14+
"prettier/prettier": "error",
15+
"indent": [
16+
"error",
17+
2
418
],
5-
"rules": {
6-
"indent": "error"
19+
"no-unused-vars": "warn",
20+
"no-console": "off"
721
}
8-
}
22+
}

.github/workflows/ci-cd.yml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: CI/CD Pipeline
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
build-test-push:
11+
runs-on: ubuntu-latest
12+
services:
13+
mongo:
14+
image: mongo:6.0
15+
ports:
16+
- 27017:27017
17+
options: >-
18+
--health-cmd "mongosh --eval 'db.adminCommand('ping')'" --health-interval 10s --health-timeout 5s --health-retries 5
19+
env:
20+
MONGODB_URI: mongodb://localhost:27017/cleanarchdb
21+
JWT_SECRET: test_jwt_secret
22+
PORT: 5000
23+
steps:
24+
- name: Checkout code
25+
uses: actions/checkout@v4
26+
27+
- name: Set up Node.js
28+
uses: actions/setup-node@v4
29+
with:
30+
node-version: 18
31+
32+
- name: Install dependencies
33+
run: yarn install
34+
35+
- name: Lint
36+
run: yarn lint
37+
38+
- name: Format
39+
run: yarn format
40+
41+
- name: Run tests
42+
run: yarn test
43+
44+
- name: Build Docker image
45+
run: docker build -t maebrie2017/clean-arch-app:latest .
46+
47+
- name: Log in to Docker Hub
48+
uses: docker/login-action@v3
49+
with:
50+
username: ${{ secrets.DOCKERHUB_USERNAME }}
51+
password: ${{ secrets.DOCKERHUB_TOKEN }}
52+
53+
- name: Push Docker image
54+
run: |
55+
IMAGE=maebrie2017/clean-arch-app
56+
docker tag $IMAGE:latest $IMAGE:${{ github.sha }}
57+
docker push $IMAGE:latest
58+
docker push $IMAGE:${{ github.sha }}

.husky/pre-push

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env sh
2+
. "$(dirname -- "$0")/_/husky.sh"
3+
4+
yarn lint && yarn format && yarn test

.lintstagedrc.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"*.js": ["prettier --write", "eslint --fix"]
3+
}

.prettierrc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"semi": true,
3+
"singleQuote": true,
4+
"tabWidth": 2,
5+
"trailingComma": "es5",
6+
"printWidth": 100
7+
}

Dockerfile

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Use official Node.js LTS image
2+
FROM node:18-alpine
3+
4+
# Set working directory
5+
WORKDIR /usr/src/app
6+
7+
# Copy package.json and yarn.lock
8+
COPY package.json yarn.lock ./
9+
10+
# Install dependencies
11+
RUN yarn install --production
12+
13+
# Copy the rest of the application code
14+
COPY . .
15+
16+
# Expose the port the app runs on
17+
EXPOSE 5000
18+
19+
# Set environment variables
20+
ENV NODE_ENV=production
21+
22+
# Start the app
23+
CMD ["yarn", "start"]

README.md

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
![Clean Architecture Diagram](public/clean-architecture.png)
2+
3+
# Digital Market Place API
4+
5+
A Node.js REST API for a digital marketplace, structured according to Uncle Bob's Clean Architecture principles. This project demonstrates separation of concerns, testability, and scalability by organizing code into distinct layers: Enterprise Business Rules, Application Business Rules, Interface Adapters, and Frameworks & Drivers.
6+
7+
## Table of Contents
8+
9+
- [Introduction](#introduction)
10+
- [Architecture Overview](#architecture-overview)
11+
- [Features](#features)
12+
- [Getting Started](#getting-started)
13+
- [Project Structure](#project-structure)
14+
- [API Endpoints](#api-endpoints)
15+
- [Testing](#testing)
16+
- [Linting & Formatting](#linting--formatting)
17+
- [Docker & Docker Compose](#docker--docker-compose)
18+
- [CI/CD Workflow](#cicd-workflow)
19+
- [Troubleshooting](#troubleshooting)
20+
- [License](#license)
21+
22+
## Introduction
23+
24+
This backend API allows users to register, authenticate, and interact with products, blogs, and ratings. It is designed for maintainability and extensibility, following Clean Architecture best practices.
25+
26+
## Architecture Overview
27+
28+
The project is organized into the following layers:
29+
30+
- **Enterprise Business Rules**: Core business logic and domain models (`enterprise-business-rules/`).
31+
- **Application Business Rules**: Use cases and application-specific logic (`application-business-rules/`).
32+
- **Interface Adapters**: Controllers, database access, adapters, and middlewares (`interface-adapters/`).
33+
- **Frameworks & Drivers**: Express.js, MongoDB, and other external libraries.
34+
35+
```
36+
enterprise-business-rules/
37+
entities/ # Domain models (User, Product, Rating, Blog)
38+
validate-models/ # Validation logic for domain models
39+
application-business-rules/
40+
use-cases/ # Application use cases (products, user)
41+
interface-adapters/
42+
controllers/ # Route controllers for products, users
43+
database-access/ # DB connection and data access logic
44+
adapter/ # Adapters (e.g., request/response)
45+
middlewares/ # Auth, logging, error handling
46+
routes/ # Express route definitions
47+
public/ # Static files and HTML views
48+
```
49+
50+
## Features
51+
52+
- User registration and authentication (JWT)
53+
- Product CRUD operations
54+
- Blog and rating management
55+
- Role-based access control (admin, blocked users)
56+
- Input validation and error handling
57+
- Modular, testable codebase
58+
59+
## Getting Started
60+
61+
### Prerequisites
62+
63+
- Node.js (v18+ recommended)
64+
- MongoDB instance (local or cloud)
65+
66+
### Installation
67+
68+
1. Clone the repository:
69+
```bash
70+
git clone <repo-url>
71+
cd Clean-code-arch-REST-API
72+
```
73+
2. Install dependencies:
74+
```bash
75+
yarn install
76+
```
77+
3. Create a `.env` file in the root with your environment variables (see `.env.example` if available):
78+
```env
79+
PORT=5000
80+
MONGODB_URI=mongodb://localhost:27017/your-db
81+
JWT_SECRET=your_jwt_secret
82+
```
83+
4. Start the server:
84+
```bash
85+
yarn dev
86+
# or
87+
yarn start
88+
```
89+
90+
The server will run at [http://localhost:5000](http://localhost:5000).
91+
92+
## Project Structure
93+
94+
- `index.js` - Main entry point, sets up Express, routes, and middleware
95+
- `routes/` - Express route definitions for products, users, blogs
96+
- `interface-adapters/` - Controllers, DB access, adapters, and middleware
97+
- `application-business-rules/` - Use cases for products and users
98+
- `enterprise-business-rules/` - Domain models and validation logic
99+
- `public/` - Static HTML views (landing page, 404)
100+
101+
## API Endpoints
102+
103+
### Products
104+
105+
- `POST /products/` - Create a new product
106+
- `GET /products/` - Get all products
107+
- `GET /products/:productId` - Get a product by ID
108+
- `PUT /products/:productId` - Update a product
109+
- `DELETE /products/:productId` - Delete a product
110+
- `POST /products/:productId/:userId/rating` - Rate a product
111+
112+
### Users & Auth
113+
114+
- `POST /users/register` - Register a new user
115+
- `POST /users/login` - User login
116+
- `GET /users/profile` - Get user profile (auth required)
117+
118+
### Blogs
119+
120+
- `GET /blogs/` - Get all blogs
121+
- `POST /blogs/` - Create a new blog
122+
123+
> More endpoints and details can be found in the route files under `routes/`.
124+
125+
## Testing
126+
127+
- Tests are written using [Jest](https://jestjs.io/) and [Supertest](https://github.com/visionmedia/supertest).
128+
- To run all tests:
129+
```bash
130+
yarn test
131+
```
132+
- Test files are located in the `tests/` directory.
133+
134+
## Linting & Formatting
135+
136+
- Lint your code:
137+
```bash
138+
yarn lint
139+
```
140+
- Format your code:
141+
```bash
142+
yarn format
143+
```
144+
- Prettier and ESLint are enforced on pre-push via Husky and lint-staged.
145+
146+
## Docker & Docker Compose
147+
148+
- Build and run the app with MongoDB using Docker Compose:
149+
```bash
150+
docker-compose up --build
151+
```
152+
- The app will be available at [http://localhost:5000](http://localhost:5000).
153+
- The MongoDB service runs at `mongodb://localhost:27017/cleanarchdb`.
154+
- To stop and remove containers, networks, and volumes:
155+
```bash
156+
docker-compose down -v
157+
```
158+
159+
## CI/CD Workflow
160+
161+
- GitHub Actions workflow is set up in `.github/workflows/ci-cd.yml`.
162+
- On push to `main`, the workflow:
163+
- Installs dependencies
164+
- Lints and formats code
165+
- Runs tests
166+
- Builds a Docker image
167+
- Pushes the image to Docker Hub (update credentials and repo in workflow and GitHub secrets)
168+
169+
## Troubleshooting
170+
171+
- Common issues and solutions are documented in [troubleshooting.md](./troubleshooting.md).
172+
- Please add new issues and solutions as you encounter them.
173+
174+
## License
175+
176+
This project is licensed under the ISC License. See the [LICENSE](LICENSE) file for details.
Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,35 @@
11
const {
2-
createProductUseCase,
3-
findOneProductUseCase,
4-
findAllProductsUseCase,
5-
deleteProductUseCase,
6-
updateProductUseCase,
7-
rateProductUseCase
8-
} = require("./product-handlers");
2+
createProductUseCase,
3+
findOneProductUseCase,
4+
findAllProductsUseCase,
5+
deleteProductUseCase,
6+
updateProductUseCase,
7+
rateProductUseCase,
8+
} = require('./product-handlers');
99

1010
const {
11-
makeProductModelHandler,
12-
makeProductRatingModelHandler
13-
} = require("../../../enterprise-business-rules/entities");
14-
15-
const productValidation = require("../../../enterprise-business-rules/validate-models/product-validation-fcts")();
11+
makeProductModelHandler,
12+
makeProductRatingModelHandler,
13+
} = require('../../../enterprise-business-rules/entities');
1614

15+
const productValidation =
16+
require('../../../enterprise-business-rules/validate-models/product-validation-fcts')();
1717

1818
const createProductUseCaseHandler = createProductUseCase({ makeProductModelHandler });
1919
const findOneProductUseCaseHandler = findOneProductUseCase({ productValidation });
2020
const findAllProductUseCaseHandler = findAllProductsUseCase();
2121
const deleteProductUseCaseHandler = deleteProductUseCase({ productValidation });
22-
const updateProductUseCaseHandler = updateProductUseCase({ makeProductModelHandler, productValidation });
22+
const updateProductUseCaseHandler = updateProductUseCase({
23+
makeProductModelHandler,
24+
productValidation,
25+
});
2326
const rateProductUseCaseHandler = rateProductUseCase({ makeProductRatingModelHandler });
2427

2528
module.exports = {
26-
createProductUseCaseHandler,
27-
findOneProductUseCaseHandler,
28-
findAllProductUseCaseHandler,
29-
deleteProductUseCaseHandler,
30-
updateProductUseCaseHandler,
31-
rateProductUseCaseHandler
32-
}
29+
createProductUseCaseHandler,
30+
findOneProductUseCaseHandler,
31+
findAllProductUseCaseHandler,
32+
deleteProductUseCaseHandler,
33+
updateProductUseCaseHandler,
34+
rateProductUseCaseHandler,
35+
};

0 commit comments

Comments
 (0)