Spaces:
Running
Running
Merge pull request #58 from Modarb-Ai-Trainer/user-profile
Browse files
src/modules/users/modules/users/controllers/users.controller.ts
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { UserService } from "../services/users.service";
|
2 |
+
import { Request, Response } from "express";
|
3 |
+
import { JsonResponse } from "@lib/responses/json-response";
|
4 |
+
import { updateUserSchema } from "../validation/update.validation";
|
5 |
+
import { paramsValidator, bodyValidator } from "@helpers/validation.helper";
|
6 |
+
import { asyncHandler } from "@helpers/async-handler";
|
7 |
+
import { BaseController } from "@lib/controllers/controller.base";
|
8 |
+
import { Controller } from "@lib/decorators/prefix.decorator";
|
9 |
+
import { serialize } from "@helpers/serialize";
|
10 |
+
import { UserSerialization } from "@common/serializers/user.serialization";
|
11 |
+
import { ControllerMiddleware } from "@lib/decorators/controller-middleware.decorator";
|
12 |
+
import { UsersGuardMiddleware } from "modules/users/common/guards/users.guard";
|
13 |
+
import { SwaggerGet, SwaggerPut } from "@lib/decorators/swagger-routes.decorator";
|
14 |
+
import { SwaggerResponse } from "@lib/decorators/swagger-response.decorator";
|
15 |
+
|
16 |
+
@Controller("/users")
|
17 |
+
@ControllerMiddleware(UsersGuardMiddleware())
|
18 |
+
export class UsersController extends BaseController {
|
19 |
+
private userService = new UserService();
|
20 |
+
|
21 |
+
setRoutes(): void {
|
22 |
+
this.router.put("/update/:id", paramsValidator("id"), bodyValidator(updateUserSchema), asyncHandler(this.update));
|
23 |
+
this.router.get("/:id", paramsValidator("id"), asyncHandler(this.get));
|
24 |
+
}
|
25 |
+
|
26 |
+
|
27 |
+
@SwaggerGet("/:id")
|
28 |
+
@SwaggerResponse(UserSerialization)
|
29 |
+
get = async (req: Request, res: Response): Promise<Response> => {
|
30 |
+
const data = await this.userService.findOneOrFail({
|
31 |
+
_id: req.params.id,
|
32 |
+
});
|
33 |
+
|
34 |
+
return JsonResponse.success(
|
35 |
+
{
|
36 |
+
data: serialize(data, UserSerialization),
|
37 |
+
},
|
38 |
+
res
|
39 |
+
);
|
40 |
+
};
|
41 |
+
|
42 |
+
@SwaggerPut("/:id")
|
43 |
+
@SwaggerResponse(UserSerialization)
|
44 |
+
update = async (req: Request, res: Response): Promise<Response> => {
|
45 |
+
const data = await this.userService.updateOne(
|
46 |
+
{
|
47 |
+
_id: req.params.id,
|
48 |
+
},
|
49 |
+
req.body
|
50 |
+
);
|
51 |
+
|
52 |
+
return JsonResponse.success(
|
53 |
+
{
|
54 |
+
data: serialize(data, UserSerialization),
|
55 |
+
},
|
56 |
+
res
|
57 |
+
);
|
58 |
+
};
|
59 |
+
}
|
src/modules/users/modules/users/services/users.service.ts
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { User } from "@common/models/user.model";
|
2 |
+
import { CrudService } from "@lib/services/crud.service";
|
3 |
+
|
4 |
+
export class UserService extends CrudService(User) {}
|
src/modules/users/modules/users/validation/update.validation.ts
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import * as joi from "joi";
|
2 |
+
import { createSchema } from "@helpers/create-schema";
|
3 |
+
|
4 |
+
export interface IUpdateUser {
|
5 |
+
name?: string;
|
6 |
+
email?: string;
|
7 |
+
gender?: string;
|
8 |
+
height?: number;
|
9 |
+
weight?: number;
|
10 |
+
fitness_level?: string;
|
11 |
+
preferences?: {
|
12 |
+
fitness_goal: string;
|
13 |
+
target_weight: number;
|
14 |
+
workout_frequency: number;
|
15 |
+
preferred_days: string[];
|
16 |
+
workout_place: string;
|
17 |
+
preferred_equipment: string[];
|
18 |
+
};
|
19 |
+
injuries?: string[];
|
20 |
+
dob?: Date;
|
21 |
+
}
|
22 |
+
|
23 |
+
export const updateUserSchema = createSchema<IUpdateUser>({
|
24 |
+
name: joi.string().empty().optional().messages({
|
25 |
+
"string.base": "please enter a valid name",
|
26 |
+
"string.empty": "name can not be empty",
|
27 |
+
}),
|
28 |
+
|
29 |
+
email: joi.string().optional().email({
|
30 |
+
minDomainSegments: 2,
|
31 |
+
tlds: { allow: ["com", "net", "org", "eg", "io"] },
|
32 |
+
}).empty().messages({
|
33 |
+
"string.email": "please enter a valid email",
|
34 |
+
"string.empty": "email can not be empty",
|
35 |
+
}),
|
36 |
+
|
37 |
+
gender: joi.string().empty().optional().messages({
|
38 |
+
"string.base": "please enter a valid gender",
|
39 |
+
"string.empty": "gender can not be empty",
|
40 |
+
}),
|
41 |
+
|
42 |
+
height: joi.number().optional().messages({
|
43 |
+
"number.base": "please enter a valid height",
|
44 |
+
"number.empty": "height can not be empty"
|
45 |
+
}),
|
46 |
+
|
47 |
+
weight: joi.number().optional().messages({
|
48 |
+
"number.base": "please enter a valid weight",
|
49 |
+
"number.empty": "weight can not be empty"
|
50 |
+
}),
|
51 |
+
|
52 |
+
fitness_level: joi.string().empty().optional().messages({
|
53 |
+
"string.base": "please enter a valid fitness_level",
|
54 |
+
"string.empty": "fitness_level can not be empty"
|
55 |
+
}),
|
56 |
+
|
57 |
+
preferences: joi.object().keys({
|
58 |
+
fitness_goal: joi.string().empty().optional().messages({
|
59 |
+
"string.base": "please enter a valid fitness goal",
|
60 |
+
"string.empty": "fitness goal can not be empty"
|
61 |
+
}),
|
62 |
+
target_weight: joi.number().optional().messages({
|
63 |
+
"number.base": "please enter a valid target weight",
|
64 |
+
"number.empty": "target weight can not be empty"
|
65 |
+
}),
|
66 |
+
workout_frequency: joi.number().optional().messages({
|
67 |
+
"number.base": "please enter a valid workout frequency",
|
68 |
+
"number.empty": "workout frequency can not be empty"
|
69 |
+
}),
|
70 |
+
preferred_days: joi.array().items(joi.string()).optional().messages({
|
71 |
+
"array.base": "please enter a valid preferred day",
|
72 |
+
"array.empty": "preferred day can not be empty"
|
73 |
+
}),
|
74 |
+
workout_place: joi.string().empty().optional().messages({
|
75 |
+
"string.base": "please enter a valid workout place",
|
76 |
+
"string.empty": "workout place can not be empty"
|
77 |
+
}),
|
78 |
+
preferred_equipment: joi.array().items(joi.string()).optional().messages({
|
79 |
+
"array.base": "please enter a valid preferred equipment",
|
80 |
+
"array.empty": "preferred equipment can not be empty"
|
81 |
+
}),
|
82 |
+
}),
|
83 |
+
injuries: joi.array().items(joi.string()).optional().messages({
|
84 |
+
"array.base": "please enter a valid injury",
|
85 |
+
"array.empty": "injuries can not be empty"
|
86 |
+
}),
|
87 |
+
dob: joi.date().optional().messages({
|
88 |
+
"date.base": "please enter a valid date of birth",
|
89 |
+
"date.empty": "date of birth can not be empty"
|
90 |
+
}),
|
91 |
+
});
|