Skip to content

Commit 254c0a0

Browse files
committed
added blog pipeline functionality and testings
1 parent 9007a95 commit 254c0a0

File tree

24 files changed

+939
-139
lines changed

24 files changed

+939
-139
lines changed

.husky/pre-push

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
#!/usr/bin/env sh
22
. "$(dirname -- "$0")/_/husky.sh"
33

4-
yarn lint && yarn format && yarn test
4+
yarn lint && yarn format
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Blog use cases (Clean Architecture)
2+
module.exports = {
3+
createBlogUseCase: ({ dbBlogHandler, makeBlogModel, logEvents, errorHandlers }) =>
4+
async function createBlogUseCaseHandler(blogData) {
5+
try {
6+
const validatedBlog = await makeBlogModel({ blogData });
7+
const newBlog = await dbBlogHandler.createBlog(validatedBlog);
8+
return Object.freeze(newBlog);
9+
} catch (error) {
10+
logEvents && logEvents(error.message, 'blogUseCase.log');
11+
throw error;
12+
}
13+
},
14+
15+
findAllBlogsUseCase: ({ dbBlogHandler, logEvents }) =>
16+
async function findAllBlogsUseCaseHandler() {
17+
try {
18+
const blogs = await dbBlogHandler.findAllBlogs();
19+
return blogs || [];
20+
} catch (error) {
21+
logEvents && logEvents(error.message, 'blogUseCase.log');
22+
throw error;
23+
}
24+
},
25+
26+
findOneBlogUseCase: ({ dbBlogHandler, logEvents }) =>
27+
async function findOneBlogUseCaseHandler({ blogId }) {
28+
try {
29+
const blog = await dbBlogHandler.findOneBlog({ blogId });
30+
if (!blog) throw new Error('Blog not found');
31+
return blog;
32+
} catch (error) {
33+
logEvents && logEvents(error.message, 'blogUseCase.log');
34+
throw error;
35+
}
36+
},
37+
38+
updateBlogUseCase: ({ dbBlogHandler, makeBlogModel, logEvents, errorHandlers }) =>
39+
async function updateBlogUseCaseHandler({ blogId, updateData }) {
40+
try {
41+
const existingBlog = await dbBlogHandler.findOneBlog({ blogId });
42+
if (!existingBlog) throw new Error('Blog not found');
43+
const validatedBlog = await makeBlogModel({ blogData: { ...existingBlog, ...updateData } });
44+
const updatedBlog = await dbBlogHandler.updateBlog({ blogId, ...validatedBlog });
45+
return Object.freeze(updatedBlog);
46+
} catch (error) {
47+
logEvents && logEvents(error.message, 'blogUseCase.log');
48+
throw error;
49+
}
50+
},
51+
52+
deleteBlogUseCase: ({ dbBlogHandler, logEvents }) =>
53+
async function deleteBlogUseCaseHandler({ blogId }) {
54+
try {
55+
const deleted = await dbBlogHandler.deleteBlog({ blogId });
56+
return deleted;
57+
} catch (error) {
58+
logEvents && logEvents(error.message, 'blogUseCase.log');
59+
throw error;
60+
}
61+
},
62+
};
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const blogUseCases = require('./blog-handlers');
2+
const { dbBlogHandler } = require('../../../interface-adapters/database-access');
3+
const { makeBlogModel } = require('../../../enterprise-business-rules/entities/blog-model');
4+
const { logEvents } = require('../../../interface-adapters/middlewares/loggers/logger');
5+
const errorHandlers = require('../../../interface-adapters/validators-errors/errors');
6+
7+
module.exports = {
8+
createBlogUseCaseHandler: blogUseCases.createBlogUseCase({ dbBlogHandler, makeBlogModel, logEvents, errorHandlers }),
9+
findAllBlogsUseCaseHandler: blogUseCases.findAllBlogsUseCase({ dbBlogHandler, logEvents }),
10+
findOneBlogUseCaseHandler: blogUseCases.findOneBlogUseCase({ dbBlogHandler, logEvents }),
11+
updateBlogUseCaseHandler: blogUseCases.updateBlogUseCase({ dbBlogHandler, makeBlogModel, logEvents, errorHandlers }),
12+
deleteBlogUseCaseHandler: blogUseCases.deleteBlogUseCase({ dbBlogHandler, logEvents }),
13+
};

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ services:
77
- '5001:5000' # Change 5001 to any free port
88
environment:
99
- PORT=5000
10-
- MONGODB_URI=${MONGODB_URI}
10+
- MONGODB_URI=mongodb://mongo:27017/cleanarchdb
1111
- JWT_SECRET=${JWT_SECRET}
1212
depends_on:
1313
- mongo
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
const blogValidation = require('../validate-models/blog-validation');
2+
3+
module.exports = {
4+
makeBlogModel: ({ blogValidation, logEvents }) => {
5+
return async function makeBlog({ blogData }) {
6+
try {
7+
const validatedBlog = await blogValidation.blogPostValidation({ blogPostData: blogData, errorHandlers: blogValidation });
8+
// Add normalization or additional logic if needed
9+
return Object.freeze(validatedBlog);
10+
} catch (error) {
11+
logEvents && logEvents(`${error.message}`, 'blog-model.log');
12+
throw error;
13+
}
14+
};
15+
},
16+
};

index.js

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,18 @@ const path = require('path');
55

66
const { dbconnection } = require('./interface-adapters/database-access/db-connection.js');
77
const errorHandler = require('./interface-adapters/middlewares/loggers/errorHandler.js');
8-
const userAndAuthRouter = require('./routes/auth-user.router.js');
98
const { logger } = require('./interface-adapters/middlewares/loggers/logger.js');
10-
const productRouter = require('./routes/product.routes.js');
119
const createIndexFn = require('./interface-adapters/database-access/db-indexes.js');
12-
const blogRouter = require('./routes/blog.router.js');
1310

1411
const app = express();
1512

1613
const PORT = process.env.PORT || 5000;
1714
var cookieParser = require('cookie-parser');
1815
const corsOptions = require('./interface-adapters/middlewares/config/corsOptions.Js');
1916

20-
// databae connetion call function
17+
// database connection call function
2118
dbconnection().then((db) => {
22-
console.log('database connected: ', db.databaseName);
19+
console.log("database connected: ", db.databaseName);
2320
createIndexFn();
2421
});
2522

@@ -29,23 +26,23 @@ app.use(express.json());
2926
app.use(cookieParser());
3027
app.use(express.urlencoded({ extended: false }));
3128

32-
app.use('/users', userAndAuthRouter);
33-
app.use('/products', productRouter);
34-
app.use('/blogs', blogRouter);
29+
// Use the new single entry point for all routes
30+
const mainRouter = require('./routes');
31+
app.use('/', mainRouter);
3532

36-
app.use('/', (_, res) => {
37-
res.sendFile(path.join(__dirname, 'public', 'views', 'index.html'));
33+
app.use("/", (_, res) => {
34+
res.sendFile(path.join(__dirname, "public", "views", "index.html"));
3835
});
3936

4037
//for no specified endpoint that is not found. this must after all the middlewares
41-
app.all('*', (req, res) => {
38+
app.all("*", (req, res) => {
4239
res.status(404);
43-
if (req.accepts('html')) {
44-
res.sendFile(path.join(__dirname, 'public', 'views', '404.html'));
45-
} else if (req.accepts('json')) {
46-
res.json({ msg: '404 Not Found' });
40+
if (req.accepts("html")) {
41+
res.sendFile(path.join(__dirname, "public", "views", "404.html"));
42+
} else if (req.accepts("json")) {
43+
res.json({ msg: "404 Not Found" });
4744
} else {
48-
res.type('txt').send('404 Not Found');
45+
res.type("txt").send("404 Not Found");
4946
}
5047
});
5148

@@ -63,3 +60,5 @@ app.use((req, res, next) => {
6360
app.use(errorHandler);
6461

6562
app.listen(PORT, () => console.log(`Server started on port http://localhost:${PORT}`));
63+
64+
module.exports = app;
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
// Blog controller factories (Clean Architecture)
2+
const defaultHeaders = {
3+
'Content-Type': 'application/json',
4+
'x-content-type-options': 'nosniff',
5+
};
6+
7+
const createBlogController = ({ createBlogUseCaseHandler, errorHandlers, logEvents }) =>
8+
async function createBlogControllerHandler(httpRequest) {
9+
const { body } = httpRequest;
10+
if (!body || Object.keys(body).length === 0) {
11+
return {
12+
headers: defaultHeaders,
13+
statusCode: 400,
14+
errorMessage: 'No blog data provided',
15+
};
16+
}
17+
try {
18+
const createdBlog = await createBlogUseCaseHandler(body);
19+
return {
20+
headers: defaultHeaders,
21+
statusCode: 201,
22+
data: { createdBlog },
23+
};
24+
} catch (e) {
25+
logEvents && logEvents(e.message, 'blogController.log');
26+
return {
27+
headers: defaultHeaders,
28+
statusCode: 500,
29+
errorMessage: e.message,
30+
};
31+
}
32+
};
33+
34+
const findAllBlogsController = ({ findAllBlogsUseCaseHandler, logEvents }) =>
35+
async function findAllBlogsControllerHandler(httpRequest) {
36+
try {
37+
const blogs = await findAllBlogsUseCaseHandler();
38+
return {
39+
headers: defaultHeaders,
40+
statusCode: 200,
41+
data: { blogs },
42+
};
43+
} catch (e) {
44+
logEvents && logEvents(e.message, 'blogController.log');
45+
return {
46+
headers: defaultHeaders,
47+
statusCode: 500,
48+
errorMessage: e.message,
49+
};
50+
}
51+
};
52+
53+
const findOneBlogController = ({ findOneBlogUseCaseHandler, logEvents }) =>
54+
async function findOneBlogControllerHandler(httpRequest) {
55+
const { blogId } = httpRequest.params;
56+
if (!blogId) {
57+
return {
58+
headers: defaultHeaders,
59+
statusCode: 400,
60+
errorMessage: 'No blog Id provided',
61+
};
62+
}
63+
try {
64+
const blog = await findOneBlogUseCaseHandler({ blogId });
65+
return {
66+
headers: defaultHeaders,
67+
statusCode: 200,
68+
data: { blog },
69+
};
70+
} catch (e) {
71+
logEvents && logEvents(e.message, 'blogController.log');
72+
return {
73+
headers: defaultHeaders,
74+
statusCode: 500,
75+
errorMessage: e.message,
76+
};
77+
}
78+
};
79+
80+
const updateBlogController = ({ updateBlogUseCaseHandler, logEvents }) =>
81+
async function updateBlogControllerHandler(httpRequest) {
82+
const { blogId } = httpRequest.params;
83+
const updateData = httpRequest.body;
84+
if (!blogId || !updateData) {
85+
return {
86+
headers: defaultHeaders,
87+
statusCode: 400,
88+
errorMessage: 'No blog Id or update data provided',
89+
};
90+
}
91+
try {
92+
const updatedBlog = await updateBlogUseCaseHandler({ blogId, updateData });
93+
return {
94+
headers: defaultHeaders,
95+
statusCode: 200,
96+
data: { updatedBlog },
97+
};
98+
} catch (e) {
99+
logEvents && logEvents(e.message, 'blogController.log');
100+
return {
101+
headers: defaultHeaders,
102+
statusCode: 500,
103+
errorMessage: e.message,
104+
};
105+
}
106+
};
107+
108+
const deleteBlogController = ({ deleteBlogUseCaseHandler, logEvents }) =>
109+
async function deleteBlogControllerHandler(httpRequest) {
110+
const { blogId } = httpRequest.params;
111+
if (!blogId) {
112+
return {
113+
headers: defaultHeaders,
114+
statusCode: 400,
115+
errorMessage: 'No blog Id provided',
116+
};
117+
}
118+
try {
119+
const deleted = await deleteBlogUseCaseHandler({ blogId });
120+
return {
121+
headers: defaultHeaders,
122+
statusCode: 200,
123+
data: deleted,
124+
};
125+
} catch (e) {
126+
logEvents && logEvents(e.message, 'blogController.log');
127+
return {
128+
headers: defaultHeaders,
129+
statusCode: 500,
130+
errorMessage: e.message,
131+
};
132+
}
133+
};
134+
135+
module.exports = {
136+
createBlogController,
137+
findAllBlogsController,
138+
findOneBlogController,
139+
updateBlogController,
140+
deleteBlogController,
141+
};
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
const blogController = require('./blog-controller');
2+
const blogUseCaseHandlers = require('../../../application-business-rules/use-cases/blogs');
3+
const { logEvents } = require('../../middlewares/loggers/logger');
4+
const errorHandlers = require('../../validators-errors/errors');
5+
6+
module.exports = {
7+
createBlogControllerHandler: blogController.createBlogController({
8+
createBlogUseCaseHandler: blogUseCaseHandlers.createBlogUseCaseHandler,
9+
errorHandlers,
10+
logEvents,
11+
}),
12+
findAllBlogsControllerHandler: blogController.findAllBlogsController({
13+
findAllBlogsUseCaseHandler: blogUseCaseHandlers.findAllBlogsUseCaseHandler,
14+
logEvents,
15+
}),
16+
findOneBlogControllerHandler: blogController.findOneBlogController({
17+
findOneBlogUseCaseHandler: blogUseCaseHandlers.findOneBlogUseCaseHandler,
18+
logEvents,
19+
}),
20+
updateBlogControllerHandler: blogController.updateBlogController({
21+
updateBlogUseCaseHandler: blogUseCaseHandlers.updateBlogUseCaseHandler,
22+
logEvents,
23+
}),
24+
deleteBlogControllerHandler: blogController.deleteBlogController({
25+
deleteBlogUseCaseHandler: blogUseCaseHandlers.deleteBlogUseCaseHandler,
26+
logEvents,
27+
}),
28+
};

0 commit comments

Comments
 (0)