Skip to content

Commit ca06331

Browse files
authored
Merge pull request #2 from frckbrice/feature/product_module
Feature/product module
2 parents 30c269f + 0216ad0 commit ca06331

28 files changed

Lines changed: 1146 additions & 226 deletions

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
node_modules
22
.env
33

4-
/interface-adapters/middleware/logs/
5-
logs
4+
/interface-adapters/middlewares/logs/
5+
/interface-adapters/controllers/examples
Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,32 @@
11
const {
2-
createProductUseCase
2+
createProductUseCase,
3+
findOneProductUseCase,
4+
findAllProductsUseCase,
5+
deleteProductUseCase,
6+
updateProductUseCase,
7+
rateProductUseCase
38
} = require("./product-handlers");
49

510
const {
6-
makeProductModelHandler
11+
makeProductModelHandler,
12+
makeProductRatingModelHandler
713
} = require("../../../enterprise-business-rules/entities");
814

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

1018
const createProductUseCaseHandler = createProductUseCase({ makeProductModelHandler });
19+
const findOneProductUseCaseHandler = findOneProductUseCase({ productValidation });
20+
const findAllProductUseCaseHandler = findAllProductsUseCase();
21+
const deleteProductUseCaseHandler = deleteProductUseCase({ productValidation });
22+
const updateProductUseCaseHandler = updateProductUseCase({ makeProductModelHandler, productValidation });
23+
const rateProductUseCaseHandler = rateProductUseCase({ makeProductRatingModelHandler });
1124

1225
module.exports = {
1326
createProductUseCaseHandler,
14-
}
27+
findOneProductUseCaseHandler,
28+
findAllProductUseCaseHandler,
29+
deleteProductUseCaseHandler,
30+
updateProductUseCaseHandler,
31+
rateProductUseCaseHandler
32+
}

application-business-rules/use-cases/products/product-handlers.js

Lines changed: 133 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,147 @@ const createProductUseCase = ({ makeProductModelHandler }) => async function
1919
const newProduct = await createProductDbHandler(validatedProductData);
2020
return Object.freeze(newProduct)
2121
} catch (error) {
22-
console.log("Error from product handler: ", error);
22+
console.log("Error from create product handler: ", error);
2323
logEvents(
24-
`${error.no}:${error.code}\t${error.name}\t${error.message}`,
25-
"product.log"
24+
`${error.no}:${error.code}\t${error.name || error.TypeError || error.ReferenceError}\t${error.message}`,
25+
"productHandler.log"
2626
);
2727
throw new Error(error.message);
2828
}
2929
}
3030

31+
//find one product from DB
32+
const findOneProductUseCase = ({ productValidation }) => async function
33+
findOneProductUseCaseHandler({ productId, logEvents, findOneProductDbHandler, errorHandlers }) {
34+
const { InvalidPropertyError } = errorHandlers;
35+
const { validateUUID } = productValidation;
36+
try {
37+
// validate id
38+
const uuid = validateUUID(productId, InvalidPropertyError);
39+
// store product in database mongodb
40+
const newProduct = await findOneProductDbHandler({ productId: uuid });
41+
return Object.freeze(newProduct)
42+
} catch (error) {
43+
console.log("Error from fetch one product handler: ", error);
44+
logEvents(
45+
`${error.no}:${error.code}\t${error.name || error.TypeError || error.ReferenceError}\t${error.message}`,
46+
"productHandler.log"
47+
);
48+
throw new Error(error.message);
49+
}
50+
}
51+
52+
53+
// find all product use case handler
54+
const findAllProductsUseCase = () => findAllProductUseCaseHandler = async ({ dbProductHandler, logEvents, filterOptions }) => {
55+
56+
try {
3157

58+
const allProducts = await dbProductHandler.findAllProductsDbHandler(filterOptions);
59+
// console.log("from find all products use case: ", allProducts);
60+
return Object.freeze(allProducts)
61+
} catch (e) {
62+
console.log("Error from fetch all product handler: ", e);
63+
logEvents(
64+
`${error.no}:${error.code}\t${error.name || error.TypeError || error.ReferenceError}\t${error.message}`,
65+
"productHandler.log"
66+
);
67+
throw new Error(e.message);
68+
}
69+
}
70+
71+
// delete product use case
72+
const deleteProductUseCase = () => async function deleteProductUseCaseHandler({ productId, logEvents, dbProductHandler, errorHandlers }) {
73+
74+
const { findOneProductDbHandler, deleteProductDbHandler } = dbProductHandler;
75+
const { InvalidPropertyError } = errorHandlers;
76+
const { validateUUID } = productValidation;
77+
try {
78+
// validate id
79+
const uuid = validateUUID(productId, InvalidPropertyError);
80+
// check first that the product exists
81+
const existingProduct = await findOneProductDbHandler({ productId: uuid });
82+
if (!existingProduct) {
83+
throw new Error("Product not exists! cannot delete it.");
84+
}
85+
// store product in database mongodb
86+
const newProduct = await deleteProductDbHandler({ productId: existingProduct.id });
87+
const result = {
88+
deletedCount: newProduct.id ? 1 : 0,
89+
message: newProduct.id ? 'product successfully deleted' : ' product not found'
90+
}
91+
return Object.freeze(result)
92+
} catch (error) {
93+
console.log("Error from delete product handler: ", error);
94+
logEvents(
95+
`${error.no}:${error.code}\t${error.name || error.TypeError || error.ReferenceError}\t${error.message}`,
96+
"productHandler.log"
97+
);
98+
throw new Error(error.message);
99+
}
100+
}
101+
102+
// update product
103+
const updateProductUseCase = ({ makeProductModelHandler }) => async function
104+
updateProductUseCaseHandler({ productId, updateData, logEvents, dbProductHandler, errorHandlers }) {
105+
106+
const { findOneProductDbHandler, updateProductDbHandler } = dbProductHandler;
107+
const { InvalidPropertyError } = errorHandlers;
108+
const { validateUUID } = productValidation;
109+
try {
110+
// validate id
111+
const uuid = validateUUID(productId, InvalidPropertyError);
112+
// check first that the product exists
113+
const existingProduct = await findOneProductDbHandler({ productId: uuid });
114+
if (!existingProduct) {
115+
throw new RangeError("Product not exists! cannot update it.");
116+
}
117+
118+
// validate data before mutation
119+
const productData = await makeProductModelHandler({ productData: { ...existingProduct, ...updateData }, errorHandlers });
120+
121+
// store product in database mongodb
122+
const newProduct = await updateProductDbHandler({ productId, ...productData });
123+
console.log(" from product handler after DB: ", newProduct);
124+
return Object.freeze(newProduct)
125+
} catch (error) {
126+
console.log("Error from update product handler: ", error);
127+
logEvents(
128+
`${error.no}:${error.code}\t${error.name || error.TypeError || error.ReferenceError}\t${error.message}`,
129+
"productHandler.log"
130+
);
131+
throw new Error(error.message);
132+
}
133+
}
134+
135+
136+
// rate product in transaction with both Rate model and Product model
137+
const rateProductUseCase = ({ makeProductRatingModelHandler }) => async function rateProductUseCaseHandler({
138+
userId, ratingValue, productId, logEvents, dbProductHandler, errorHandlers
139+
}) {
140+
console.log("hit rating use case handler")
141+
const ratingData = { ratingValue, userId, productId };
142+
try {
143+
/* validate and build rating model */
144+
const ratingModel = await makeProductRatingModelHandler({ errorHandlers, ...ratingData });
145+
const newProduct = await dbProductHandler.rateProductDbHandler(ratingModel);
146+
console.log(" from rating product handler after DB: ", newProduct);
147+
return Object.freeze(newProduct)
148+
} catch (error) {
149+
console.log("Error from fetch one product handler: ", error);
150+
logEvents(
151+
`${error.no}:${error.code}\t${error.name || error.TypeError || error.ReferenceError}\t${error.message}`,
152+
"productHandler.log"
153+
);
154+
throw new Error(error.message);
155+
}
156+
}
32157

33158
module.exports = Object.freeze({
34159
createProductUseCase,
160+
findOneProductUseCase,
161+
findAllProductsUseCase,
162+
deleteProductUseCase,
163+
updateProductUseCase,
164+
rateProductUseCase
35165
})
36-

application-business-rules/use-cases/user/index.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@ const { registerUserUseCase,
99
blockUserUseCase,
1010
unBlockUserUseCase
1111
} = require("./user-handlers");
12+
1213
const { dbUserHandler } = require("../../../interface-adapters/database-access")
1314
// const {loginUserUseCase} = require("./login-user");
1415

15-
const registerUserUserCaseHandler = registerUserUseCase({ dbUserHandler });
16+
const entityModels = require("../../../enterprise-business-rules/entities");
17+
18+
const registerUserUseCaseHandler = registerUserUseCase({ dbUserHandler, entityModels });
1619
const loginUserUseCaseHandler = loginUserUseCase({ dbUserHandler });
1720
const findOneUserUseCaseHandler = findOneUserUseCase({ dbUserHandler });
1821
const findAllUsersUseCaseHandler = findAllUsersUseCase({ dbUserHandler });
@@ -33,7 +36,7 @@ module.exports = {
3336
deleteUserUseCaseHandler,
3437
findAllUsersUseCaseHandler,
3538
findOneUserUseCaseHandler,
36-
registerUserUserCaseHandler,
39+
registerUserUseCaseHandler,
3740
loginUserUseCaseHandler,
3841
blockUserUseCaseHandler,
3942
unBlockUserUseCaseHandler

application-business-rules/use-cases/user/user-handlers.js

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,31 @@ module.exports = {
1616
* @return {Promise<Object|Error>} Returns a promise that resolves to the registered user object or rejects with an error.
1717
* @throws {HttpError} Throws an HttpError if the user already exists or if there is an error during registration.
1818
*/
19-
registerUserUseCase: ({ dbUserHandler }) => async function registerUserUseCaseHandler(userData) {
19+
registerUserUseCase: ({ dbUserHandler, entityModels }) => async function registerUserUseCaseHandler(userData) {
20+
21+
const { makeUser } = entityModels;
2022
try {
2123
const validatedUser = await makeUser({ userData });
2224
const { email } = validatedUser;
2325
const existingUser = await dbUserHandler.findUserByEmail({ email });
2426

2527
if (existingUser) {
26-
throw new UniqueConstraintError(`User with email ${email} already exists`);
28+
return makeHttpError({
29+
errorMessage: "this email already exists",
30+
statusCode: 409
31+
});
2732
} else {
2833
return await dbUserHandler.registerUser(validatedUser);
2934
}
3035

31-
} catch (err) {
36+
} catch (error) {
3237
console.log("error from register use case handler: ", err);
3338
logEvents(
34-
`${err.no}:${error.code}\t${error.syscall}\t${error.hostname}`,
35-
"useCaseHandlerErr.log"
39+
`${error.no}:${error.code}\t${error.syscall}\t${error.hostname}`,
40+
"userHandlerErr.log"
3641
);
3742
throw makeHttpError({
38-
errorMessage: err.message,
43+
errorMessage: error.message,
3944
statusCode: 400
4045
});
4146
}
@@ -60,21 +65,30 @@ module.exports = {
6065

6166
//basic verification
6267
if (!email || !password) {
63-
throw new RequiredParameterError("email or password")
68+
return makeHttpError({
69+
errorMessage: "Missing email or password",
70+
statusCode: 400
71+
});
6472
}
6573

6674
try {
6775
//check the existance of this user in DB
6876
let existingUser = await dbUserHandler.findUserByEmailForLogin({ email });
69-
console.log(" checking for the xistence of user in loginUserUseCaseHandler", existingUser);
77+
7078
if (!existingUser?.id) {
71-
throw new Error("USER NOT FOUND! LOGGIN FIRST");
79+
return makeHttpError({
80+
errorMessage: "USER NOT FOUND! LOGGIN FIRST",
81+
statusCode: 401
82+
});
7283
}
7384

7485
//check the password
7586
const matchPasswd = await bcrypt.compare(password, existingUser.password);
7687
if (!matchPasswd) {
77-
throw new InvalidPropertyError("No Matching! UNAUTHORIZED");
88+
return makeHttpError({
89+
errorMessage: "Bad credentials! UNAUTHORIZED",
90+
statusCode: 401
91+
});
7892
}
7993

8094
//create the JWT
@@ -100,9 +114,12 @@ module.exports = {
100114
console.log("error from login use case: ", error);
101115
logEvents(
102116
`${error.no}:${error.code}\t${error.name}\t${error.message}`,
103-
"useCaseHandlerErr.log"
117+
"userHandlerErr.log"
104118
);
105-
throw new Error(" failed to login: ", error.stack);
119+
return makeHttpError({
120+
errorMessage: "failed to log in",
121+
statusCode: 500
122+
});;
106123
}
107124

108125
}
@@ -126,7 +143,7 @@ module.exports = {
126143
} catch (error) {
127144
logEvents(
128145
`${error.no}:${error.code}\t${error.name}\t${error.message}`,
129-
"useCaseHandlerErr.log"
146+
"userHandlerErr.log"
130147
);
131148
throw new Error("Error fetching all users: " + error.stack);
132149
}
@@ -165,7 +182,7 @@ module.exports = {
165182
console.log("Error from fetching user use case handler: ", error);
166183
logEvents(
167184
`${error.no}:${error.code}\t${error.name}\t${error.message}`,
168-
"useCaseHandlerErr.log"
185+
"userHandlerErr.log"
169186
);
170187
throw new Error("Error fetching user use case: " + error.stack);
171188
}
@@ -213,7 +230,7 @@ module.exports = {
213230
console.log("Error from updating use case handler: ", error);
214231
logEvents(
215232
`${error.no}:${error.code}\t${error.name}\t${error.message}`,
216-
"useCaseHandlerErr.log"
233+
"userHandlerErr.log"
217234
);
218235
throw new Error("Error updating user: " + error.stack);
219236
}
@@ -251,7 +268,7 @@ module.exports = {
251268
console.log("Error from deleting use case handler: ", error);
252269
logEvents(
253270
`${error.no}:${error.code}\t${error.name}\t${error.message}`,
254-
"useCaseHandlerErr.log"
271+
"userHandlerErr.log"
255272
);
256273
throw new Error("Error deleting user: " + error.stack);
257274
}
@@ -299,7 +316,7 @@ module.exports = {
299316
console.log("Error from refresh token use case handler: ", error);
300317
logEvents(
301318
`${error.no}:${error.code}\t${error.name}\t${error.message}`,
302-
"useCaseHandlerErr.log"
319+
"userHandlerErr.log"
303320
);
304321
throw new Error("Error refreshing token: ", error);
305322
}
@@ -323,7 +340,7 @@ module.exports = {
323340
console.log("Error from logoutUseCase user use case handler: ", error);
324341
logEvents(
325342
`${error.no}:${error.code}\t${error.name}\t${error.message}`,
326-
"useCaseHandlerErr.log"
343+
"userHandlerErr.log"
327344
);
328345
throw new Error("Error logging out: " + error.stack);
329346
}
@@ -353,7 +370,7 @@ module.exports = {
353370
console.log("Error from block user use case handler: ", error);
354371
logEvents(
355372
`${error.no}:${error.code}\t${error.name}\t${error.message}`,
356-
"useCaseHandlerErr.log"
373+
"userHandlerErr.log"
357374
);
358375
throw new Error("Error block user: " + error.stack);
359376
}
@@ -383,11 +400,10 @@ module.exports = {
383400
console.log("Error from unblock user use case handler: ", error);
384401
logEvents(
385402
`${error.no}:${error.code}\t${error.name}\t${error.message}`,
386-
"useCaseHandlerErr.log"
403+
"userHandlerErr.log"
387404
);
388405
throw new Error("Error unblock user: " + error.stack);
389406
}
390407
}
391408
}
392-
393-
}
409+
}

0 commit comments

Comments
 (0)