Hozifa Elgherbawy commited on
Commit
4d593f3
·
unverified ·
2 Parent(s): 844f343 eb78df6

Merge pull request #48 from Modarb-Ai-Trainer:myWorkout

Browse files

add user-registered-workout.model and update workout.model

src/common/enums/place.enum.ts ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ export enum Place {
2
+ GYM = "gym",
3
+ HOME = "home",
4
+ }
src/common/models/user-registered-workout.model.ts ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import mongoose from "mongoose";
2
+ const { Schema } = mongoose;
3
+
4
+ export interface IUserRegisteredWorkout {
5
+ user: mongoose.Types.ObjectId,
6
+ workout: mongoose.Types.ObjectId,
7
+ is_active: Boolean,
8
+ weeks: [
9
+ {
10
+ week_number: number,
11
+ week_name: string,
12
+ week_description: string,
13
+ is_done: boolean,
14
+ days: [
15
+ {
16
+ day_number: number,
17
+ total_number_exercises: number,
18
+ day_type: string,
19
+ exercises: [mongoose.Types.ObjectId],
20
+ is_done: boolean
21
+ },
22
+ ],
23
+ },
24
+ ]
25
+ }
26
+
27
+ const userRegisteredWorkoutSchema = new Schema({
28
+ user: { type: mongoose.Types.ObjectId, ref: "users" },
29
+ workout: { type: mongoose.Types.ObjectId, ref: "workouts" },
30
+ is_active: { type: Boolean, default: false },
31
+ weeks: [
32
+ {
33
+ week_number: { type: Number },
34
+ week_name: { type: String, required: true, },
35
+ week_description: { type: String, required: true, },
36
+ is_done: { type: Boolean, default: false },
37
+ days: [
38
+ {
39
+ day_number: { type: Number, required: true, },
40
+ total_number_exercises: { type: Number, required: true, },
41
+ day_type: { type: String, required: true, },
42
+ exercises: [
43
+ { type: mongoose.Types.ObjectId, ref: "exercises" },
44
+ ],
45
+ is_done: { type: Boolean, default: false }
46
+ },
47
+ ],
48
+ },
49
+ ]
50
+ });
51
+
52
+
53
+ export type UserRegisteredWorkoutDocument = IUserRegisteredWorkout & mongoose.Document;
54
+
55
+ export const UserRegisteredWorkout = mongoose.model<UserRegisteredWorkoutDocument>("UserRegisteredWorkouts", userRegisteredWorkoutSchema);
src/common/models/user.model.ts CHANGED
@@ -15,13 +15,13 @@ export interface IUser {
15
  name: string;
16
  email: string;
17
  password: string;
18
- image: object;
19
  role: AuthenticatableType;
20
  gender: string;
21
  dob: Date;
22
  height: number;
23
  weight: number;
24
- fitness_level: string;
25
  preferences: {
26
  fitness_goal: FitnessGoal;
27
  target_weight: number;
@@ -37,7 +37,7 @@ const userSchema = new Schema({
37
  name: { type: String, required: true },
38
  email: { type: String, required: true },
39
  password: { type: String, required: true },
40
- image: { type: Object },
41
  gender: {
42
  type: String,
43
  enum: Gender,
 
15
  name: string;
16
  email: string;
17
  password: string;
18
+ image: string;
19
  role: AuthenticatableType;
20
  gender: string;
21
  dob: Date;
22
  height: number;
23
  weight: number;
24
+ fitness_level: FitnessLevel;
25
  preferences: {
26
  fitness_goal: FitnessGoal;
27
  target_weight: number;
 
37
  name: { type: String, required: true },
38
  email: { type: String, required: true },
39
  password: { type: String, required: true },
40
+ image: { type: String },
41
  gender: {
42
  type: String,
43
  enum: Gender,
src/common/models/workout.model.ts CHANGED
@@ -1,20 +1,32 @@
1
  import mongoose from "mongoose";
 
 
 
 
2
  const { Schema } = mongoose;
3
 
4
  export interface IWorkout {
5
  name: string;
 
6
  type: string;
7
  created_by: mongoose.Types.ObjectId;
8
- templateWeeks: [
 
 
 
 
 
 
9
  {
 
 
 
10
  days: [
11
  {
12
- day: number,
13
- exercises: [
14
- {
15
- exercise: mongoose.Types.ObjectId,
16
- },
17
- ],
18
  },
19
  ],
20
  },
@@ -23,13 +35,25 @@ export interface IWorkout {
23
 
24
  const workoutSchema = new Schema({
25
  name: { type: String, required: true, unique: true, dropDups: true },
 
26
  type: { type: String, required: true },
27
  created_by: { type: mongoose.Types.ObjectId, ref: "admins" },
28
- templateWeeks: [
 
 
 
 
 
 
29
  {
 
 
 
30
  days: [
31
  {
32
- day: Number,
 
 
33
  exercises: [
34
  { type: mongoose.Types.ObjectId, ref: "exercises" },
35
  ],
 
1
  import mongoose from "mongoose";
2
+ import { FitnessGoal } from "@common/enums/fitness-goal.enum";
3
+ import { FitnessLevel } from "@common/enums/fitness-level.enum";
4
+ import { Place } from "@common/enums/place.enum";
5
+
6
  const { Schema } = mongoose;
7
 
8
  export interface IWorkout {
9
  name: string;
10
+ description: string;
11
  type: string;
12
  created_by: mongoose.Types.ObjectId;
13
+ image: string;
14
+ fitness_level: FitnessLevel;
15
+ fitness_goal: FitnessGoal;
16
+ place: [Place];
17
+ min_per_day: number;
18
+ total_number_days: number;
19
+ template_weeks: [
20
  {
21
+ week_number: number;
22
+ week_name: string,
23
+ week_description: string,
24
  days: [
25
  {
26
+ day_number: number,
27
+ total_number_exercises: number,
28
+ day_type: string,
29
+ exercises: [mongoose.Types.ObjectId],
 
 
30
  },
31
  ],
32
  },
 
35
 
36
  const workoutSchema = new Schema({
37
  name: { type: String, required: true, unique: true, dropDups: true },
38
+ description: { type: String, required: true },
39
  type: { type: String, required: true },
40
  created_by: { type: mongoose.Types.ObjectId, ref: "admins" },
41
+ image: { type: String },
42
+ fitness_level: { type: String, enum: FitnessLevel, required: true, },
43
+ fitness_goal: { type: String, enum: FitnessGoal, required: true, },
44
+ place: [{ type: String, enum: Place, required: true, }],
45
+ min_per_day: { type: Number, required: true, },
46
+ total_number_days: { type: Number, required: true, },
47
+ template_weeks: [
48
  {
49
+ week_number: { type: Number, required: true, },
50
+ week_name: { type: String, required: true, },
51
+ week_description: { type: String, required: true, },
52
  days: [
53
  {
54
+ day_number: { type: Number, required: true, enum: [1, 2, 3, 4, 5, 6, 7] },
55
+ total_number_exercises: { type: Number, required: true, },
56
+ day_type: { type: String, required: true, },
57
  exercises: [
58
  { type: mongoose.Types.ObjectId, ref: "exercises" },
59
  ],
src/common/serializers/exercise.serialization.ts CHANGED
@@ -1,4 +1,23 @@
1
  import { Expose, Transform } from "class-transformer";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
  export class ExerciseSerialization {
4
  @Expose({ name: "_id" })
@@ -6,4 +25,40 @@ export class ExerciseSerialization {
6
 
7
  @Expose()
8
  name: string;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  }
 
1
  import { Expose, Transform } from "class-transformer";
2
+ import { serialize } from "@helpers/serialize";
3
+
4
+
5
+
6
+ class ExpectedDurationRange {
7
+ @Expose()
8
+ min: number;
9
+
10
+ @Expose()
11
+ max: number;
12
+ }
13
+
14
+ class Media {
15
+ @Expose()
16
+ type: string;
17
+
18
+ @Expose()
19
+ url: string;
20
+ }
21
 
22
  export class ExerciseSerialization {
23
  @Expose({ name: "_id" })
 
25
 
26
  @Expose()
27
  name: string;
28
+
29
+ @Expose()
30
+ category: string;
31
+
32
+ @Expose()
33
+ duration: number | null;
34
+
35
+ @Expose({ name: "expectedDurationRange" })
36
+ @Transform(
37
+ ({ value }) => serialize(value, ExpectedDurationRange)
38
+ )
39
+ expectedDurationRange: object;
40
+
41
+ @Expose()
42
+ reps: number;
43
+
44
+ @Expose()
45
+ sets: number;
46
+
47
+ @Expose()
48
+ instructions: string;
49
+
50
+ @Expose()
51
+ benefits: string;
52
+
53
+ @Expose()
54
+ targetMuscles: any;
55
+
56
+ @Expose()
57
+ equipments: any;
58
+
59
+ @Expose({ name: "media" })
60
+ @Transform(
61
+ ({ value }) => serialize(value, Media)
62
+ )
63
+ media: object;
64
  }
src/common/serializers/user-registered-workout.serialization.ts ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Expose, Transform } from "class-transformer";
2
+ import { serialize } from "@helpers/serialize";
3
+
4
+
5
+ class Days {
6
+ @Expose()
7
+ day_number: number;
8
+
9
+ @Expose()
10
+ total_number_exercises: number;
11
+
12
+ @Expose()
13
+ day_type: string;
14
+
15
+ @Expose({ name: "exercises" })
16
+ exercises: any;
17
+
18
+ @Expose()
19
+ is_done: Boolean
20
+ }
21
+
22
+ class Weeks {
23
+ @Expose()
24
+ week_number: number;
25
+
26
+ @Expose()
27
+ week_name: string;
28
+
29
+ @Expose()
30
+ week_description: string;
31
+
32
+ @Expose({ name: "days" })
33
+ @Transform(
34
+ ({ value }) => serialize(value, Days)
35
+ )
36
+ days: any;
37
+
38
+ @Expose()
39
+ is_done: Boolean
40
+ }
41
+
42
+ export class UserRegisteredWorkoutsSerialization {
43
+ @Expose({ name: "_id" })
44
+ id: string;
45
+
46
+ @Expose()
47
+ user: string;
48
+
49
+ @Expose()
50
+ workout: string;
51
+
52
+ @Expose()
53
+ is_active: Boolean;
54
+
55
+ @Expose({ name: "weeks" })
56
+ @Transform(
57
+ ({ value }) => serialize(value, Weeks)
58
+ )
59
+ weeks: any;
60
+
61
+ }
src/common/serializers/user.serialization.ts CHANGED
@@ -33,7 +33,7 @@ export class UserSerialization {
33
  email: string;
34
 
35
  @Expose()
36
- image: object;
37
 
38
  @Expose()
39
  role: string;
 
33
  email: string;
34
 
35
  @Expose()
36
+ image: string;
37
 
38
  @Expose()
39
  role: string;
src/common/serializers/workout.serialization.ts CHANGED
@@ -5,14 +5,28 @@ import { serialize } from "@helpers/serialize";
5
 
6
  class Days {
7
  @Expose()
8
- day: number;
 
 
 
 
 
 
9
 
10
  @Expose({ name: "exercises" })
11
  exercises: any;
12
  }
13
 
14
-
15
  class TemplateWeeks {
 
 
 
 
 
 
 
 
 
16
  @Expose({ name: "days" })
17
  @Transform(
18
  ({ value }) => serialize(value, Days)
@@ -27,16 +41,37 @@ export class WorkoutSerialization {
27
  @Expose()
28
  name: string;
29
 
 
 
 
30
  @Expose()
31
  type: string;
32
 
 
 
 
33
  @Expose()
34
  created_by: string;
35
 
36
- @Expose({ name: "templateWeeks" })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  @Transform(
38
  ({ value }) => serialize(value, TemplateWeeks)
39
  )
40
- templateWeeks: any;
41
 
42
  }
 
5
 
6
  class Days {
7
  @Expose()
8
+ day_number: number;
9
+
10
+ @Expose()
11
+ total_number_exercises: number;
12
+
13
+ @Expose()
14
+ day_type: string;
15
 
16
  @Expose({ name: "exercises" })
17
  exercises: any;
18
  }
19
 
 
20
  class TemplateWeeks {
21
+ @Expose()
22
+ week_number: number;
23
+
24
+ @Expose()
25
+ week_name: string;
26
+
27
+ @Expose()
28
+ week_description: string;
29
+
30
  @Expose({ name: "days" })
31
  @Transform(
32
  ({ value }) => serialize(value, Days)
 
41
  @Expose()
42
  name: string;
43
 
44
+ @Expose()
45
+ description: string;
46
+
47
  @Expose()
48
  type: string;
49
 
50
+ @Expose()
51
+ image: string;
52
+
53
  @Expose()
54
  created_by: string;
55
 
56
+ @Expose()
57
+ fitness_level: string;
58
+
59
+ @Expose()
60
+ fitness_goal: string;
61
+
62
+ @Expose()
63
+ place: any;
64
+
65
+ @Expose()
66
+ min_per_day: number;
67
+
68
+ @Expose()
69
+ total_number_days: number;
70
+
71
+ @Expose({ name: "template_weeks" })
72
  @Transform(
73
  ({ value }) => serialize(value, TemplateWeeks)
74
  )
75
+ template_weeks: any;
76
 
77
  }
src/lib/services/crud.service.ts CHANGED
@@ -45,7 +45,7 @@ export const CrudService = <ModelDoc extends Document>(
45
  skip: 0,
46
  },
47
  options?: {
48
- populateObject: any
49
  }
50
  ): Promise<{
51
  docs: ModelDoc[];
@@ -59,7 +59,7 @@ export const CrudService = <ModelDoc extends Document>(
59
  .find(filter)
60
  .limit(paginationOptions.limit)
61
  .skip(paginationOptions.skip)
62
- if (options?.populateObject) queryInstruction.populate(options.populateObject);
63
 
64
  const docs = await queryInstruction
65
  const total = await this.model.countDocuments(filter);
@@ -72,14 +72,26 @@ export const CrudService = <ModelDoc extends Document>(
72
  return { docs, paginationData };
73
  }
74
 
75
- async findOne(filter: FilterQuery<ModelDoc>): Promise<ModelDoc | null> {
76
- return this.model.findOne(filter);
 
 
 
 
 
 
 
77
  }
78
 
79
- async findOneOrFail(filter: FilterQuery<ModelDoc>): Promise<ModelDoc> {
 
 
 
 
 
80
  await this.existsOrThrow(filter);
81
- const document = await this.findOne(filter);
82
-
83
  return document;
84
  }
85
 
 
45
  skip: 0,
46
  },
47
  options?: {
48
+ populateArray: any
49
  }
50
  ): Promise<{
51
  docs: ModelDoc[];
 
59
  .find(filter)
60
  .limit(paginationOptions.limit)
61
  .skip(paginationOptions.skip)
62
+ if (options?.populateArray) queryInstruction.populate(options.populateArray);
63
 
64
  const docs = await queryInstruction
65
  const total = await this.model.countDocuments(filter);
 
72
  return { docs, paginationData };
73
  }
74
 
75
+ async findOne(
76
+ filter: FilterQuery<ModelDoc>,
77
+ options?: {
78
+ populateArray: any
79
+ }): Promise<ModelDoc | null> {
80
+ const queryInstruction = this.model.findOne(filter);
81
+ if (options?.populateArray) queryInstruction.populate(options.populateArray);
82
+ const document = await queryInstruction
83
+ return document;
84
  }
85
 
86
+ async findOneOrFail(
87
+ filter: FilterQuery<ModelDoc>,
88
+ options?: {
89
+ populateArray: any
90
+ }
91
+ ): Promise<ModelDoc> {
92
  await this.existsOrThrow(filter);
93
+ let optionsObject = options ? options : { populateArray: [{}] }
94
+ const document = await this.findOne(filter, optionsObject);
95
  return document;
96
  }
97
 
src/modules/console/modules/workouts/validations/create-workout.validation.ts CHANGED
@@ -1,13 +1,37 @@
1
  import * as joi from "joi";
2
  import { createSchema } from "@helpers/create-schema";
 
 
 
3
 
4
- export interface ICreateWorkout {
5
- name: string;
6
- type: string;
7
- created_by: string;
8
- templateWeeks: string[];
9
- };
10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
  export const createWorkoutSchema = createSchema<ICreateWorkout>({
13
  name: joi.string().empty().required().messages({
@@ -15,6 +39,11 @@ export const createWorkoutSchema = createSchema<ICreateWorkout>({
15
  "any.required": "name is required",
16
  "string.empty": "name can not be empty",
17
  }),
 
 
 
 
 
18
  type: joi.string().empty().required().messages({
19
  "string.base": "please enter a valid type",
20
  "any.required": "type is required",
@@ -25,9 +54,110 @@ export const createWorkoutSchema = createSchema<ICreateWorkout>({
25
  "any.required": "created_by is required",
26
  "string.empty": "created_by can not be empty",
27
  }),
28
- templateWeeks: joi.array().empty().required().messages({
29
- "string.base": "please enter a valid templateWeeks",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  "any.required": "templateWeeks is required",
31
- "string.empty": "templateWeeks can not be empty",
32
  }),
33
  });
 
1
  import * as joi from "joi";
2
  import { createSchema } from "@helpers/create-schema";
3
+ import { FitnessGoal } from "@common/enums/fitness-goal.enum";
4
+ import { FitnessLevel } from "@common/enums/fitness-level.enum";
5
+ import { Place } from "@common/enums/place.enum";
6
 
 
 
 
 
 
 
7
 
8
+ export interface ICreateWorkout {
9
+ name: string;
10
+ description: string;
11
+ type: string;
12
+ created_by: string;
13
+ image?: string;
14
+ fitness_level: string;
15
+ fitness_goal: string;
16
+ place: [string];
17
+ min_per_day: number;
18
+ total_number_days: number;
19
+ template_weeks: [
20
+ {
21
+ week_number: number;
22
+ week_name: string,
23
+ week_description: string,
24
+ days: [
25
+ {
26
+ day_number: number,
27
+ total_number_exercises: number,
28
+ day_type: string,
29
+ exercises: [string],
30
+ },
31
+ ],
32
+ },
33
+ ]
34
+ }
35
 
36
  export const createWorkoutSchema = createSchema<ICreateWorkout>({
37
  name: joi.string().empty().required().messages({
 
39
  "any.required": "name is required",
40
  "string.empty": "name can not be empty",
41
  }),
42
+ description: joi.string().empty().required().messages({
43
+ "string.base": "please enter a valid name",
44
+ "any.required": "name is required",
45
+ "string.empty": "name can not be empty",
46
+ }),
47
  type: joi.string().empty().required().messages({
48
  "string.base": "please enter a valid type",
49
  "any.required": "type is required",
 
54
  "any.required": "created_by is required",
55
  "string.empty": "created_by can not be empty",
56
  }),
57
+ image: joi.string().empty().optional().messages({
58
+ "string.base": "please enter a valid image url",
59
+ "string.empty": "image url can not be empty",
60
+ }),
61
+ fitness_level: joi.string().valid(...Object.values(FitnessLevel)).empty().required().messages({
62
+ "string.base": "please enter a valid fitness level",
63
+ "any.required": "fitness level is required",
64
+ "string.empty": "fitness level can not be empty",
65
+ "any.only": `Fitness level must be one of the following values: ${FitnessLevel.ADVANCED}, ${FitnessLevel.BEGINNER} or ${FitnessLevel.INTERMEDIATE}`
66
+ }),
67
+ fitness_goal: joi.string().valid(...Object.values(FitnessGoal)).empty().required().messages({
68
+ "string.base": "please enter a valid fitness goal",
69
+ "any.required": "fitness goal is required",
70
+ "string.empty": "fitness goal can not be empty",
71
+ "any.only": `Fitness goal must be one of the following values: ${FitnessGoal.GAIN_MUSCLE}, ${FitnessGoal.GET_FITTER} or ${FitnessGoal.LOSE_WEIGHT}`
72
+ }),
73
+ place: joi.array().empty().required().items(
74
+ joi.string().empty().required().valid(...Object.values(Place)).messages({
75
+ "string.base": "please enter a valid place",
76
+ "any.required": "place is required",
77
+ "string.empty": "place can not be empty",
78
+ "any.only": `place must be one of the following values: ${Place.GYM} or ${Place.HOME}`
79
+ })
80
+ ).messages({
81
+ "array.base": "please enter a valid place array",
82
+ "any.required": "place array is required",
83
+ "array.empty": "place array can not be empty",
84
+ }),
85
+ min_per_day: joi.number().integer().empty().required().messages({
86
+ "number.base": "please enter a valid min per day",
87
+ "any.required": "min per day is required",
88
+ "number.empty": "min per day can not be empty",
89
+ "number.integer": "day number must be an integer",
90
+ }),
91
+ total_number_days: joi.number().integer().empty().required().messages({
92
+ "number.base": "please enter a valid total number days",
93
+ "any.required": "total number days is required",
94
+ "number.empty": "total number days can not be empty",
95
+ "number.integer": "day number must be an integer",
96
+ }),
97
+ template_weeks: joi.array().empty().required().items(
98
+ joi.object({
99
+ week_number: joi.number().integer().empty().required().messages({
100
+ "number.base": "please enter a valid week number",
101
+ "any.required": "week number is required",
102
+ "number.empty": "week number can not be empty",
103
+ "number.integer": "week number must be an integer",
104
+ }),
105
+ week_name: joi.string().empty().required().messages({
106
+ "string.base": "please enter a valid week name",
107
+ "any.required": "week name is required",
108
+ "string.empty": "week name can not be empty",
109
+ }),
110
+ week_description: joi.string().empty().required().messages({
111
+ "string.base": "please enter a valid week description",
112
+ "any.required": "week description is required",
113
+ "string.empty": "week description can not be empty",
114
+ }),
115
+ days: joi.array().required().items(
116
+ joi.object({
117
+ day_number: joi.number().empty().integer().min(1).max(7).required().messages({
118
+ "number.base": "Please enter a valid day number",
119
+ "any.required": "day number is required",
120
+ "number.empty": "day number cannot be empty",
121
+ "number.integer": "day number must be an integer",
122
+ "number.min": "day number must be between 1 and 7",
123
+ "number.max": "day number must be between 1 and 7"
124
+ }),
125
+ total_number_exercises: joi.number().empty().integer().required().messages({
126
+ "number.base": "Please enter a valid total number exercises",
127
+ "any.required": "total number exercises is required",
128
+ "number.empty": "total number exercises cannot be empty",
129
+ "number.integer": "total number exercises must be an integer",
130
+ }),
131
+ day_type: joi.string().empty().required().messages({
132
+ "string.base": "please enter a valid day type",
133
+ "any.required": "day type is required",
134
+ "string.empty": "day type can not be empty",
135
+ }),
136
+ exercises: joi.array().empty().required().items(
137
+ joi.string().empty().required().messages({
138
+ "string.base": "please enter a valid exercise id",
139
+ "any.required": "exercise id is required",
140
+ "string.empty": "exercise id can not be empty",
141
+ }),).messages({
142
+ "array.base": "please enter a valid exercises array",
143
+ "any.required": "exercises array is required",
144
+ "array.empty": "exercises array can not be empty",
145
+ }),
146
+ }).empty().messages({
147
+ "object.base": "please enter a valid day object",
148
+ "any.required": "day object is required",
149
+ "object.empty": "day object can not be empty",
150
+ })
151
+ ),
152
+ }).empty().messages({
153
+ "array.base": "please enter a valid days array",
154
+ "any.required": "days array is required",
155
+ "array.empty": "days array can not be empty",
156
+
157
+ })
158
+ ).messages({
159
+ "array.base": "please enter a valid templateWeeks",
160
  "any.required": "templateWeeks is required",
161
+ "array.empty": "templateWeeks can not be empty",
162
  }),
163
  });
src/modules/console/modules/workouts/validations/update-workout.validation.ts CHANGED
@@ -1,12 +1,38 @@
1
  import * as joi from "joi";
2
  import { createSchema } from "@helpers/create-schema";
 
 
 
 
 
3
 
4
  export interface IUpdateWorkout {
5
  name?: string;
 
6
  type?: string;
7
  created_by?: string;
8
- templateWeeks?: string[];
9
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
 
12
  export const updateWorkoutSchema = createSchema<IUpdateWorkout>({
@@ -14,6 +40,10 @@ export const updateWorkoutSchema = createSchema<IUpdateWorkout>({
14
  "string.base": "please enter a valid name",
15
  "string.empty": "name can not be empty",
16
  }),
 
 
 
 
17
  type: joi.string().empty().optional().messages({
18
  "string.base": "please enter a valid type",
19
  "string.empty": "type can not be empty",
@@ -22,9 +52,94 @@ export const updateWorkoutSchema = createSchema<IUpdateWorkout>({
22
  "string.base": "please enter a valid created_by",
23
  "string.empty": "created_by can not be empty",
24
  }),
25
- templateWeeks: joi.array().empty().optional().messages({
26
- "string.base": "please enter a valid templateWeeks",
27
- "string.empty": "templateWeeks can not be empty",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  }),
29
 
30
  });
 
1
  import * as joi from "joi";
2
  import { createSchema } from "@helpers/create-schema";
3
+ import { FitnessGoal } from "@common/enums/fitness-goal.enum";
4
+ import { FitnessLevel } from "@common/enums/fitness-level.enum";
5
+ import { Place } from "@common/enums/place.enum";
6
+
7
+
8
 
9
  export interface IUpdateWorkout {
10
  name?: string;
11
+ description?: string;
12
  type?: string;
13
  created_by?: string;
14
+ image?: string;
15
+ fitness_level?: string;
16
+ fitness_goal?: string;
17
+ place?: [string];
18
+ min_per_day?: number;
19
+ total_number_days?: number;
20
+ template_weeks?: [
21
+ {
22
+ week_number?: number;
23
+ week_name?: string,
24
+ week_description?: string,
25
+ days?: [
26
+ {
27
+ day_number?: number,
28
+ total_number_exercises?: number,
29
+ day_type?: string,
30
+ exercises?: [string],
31
+ },
32
+ ],
33
+ },
34
+ ]
35
+ }
36
 
37
 
38
  export const updateWorkoutSchema = createSchema<IUpdateWorkout>({
 
40
  "string.base": "please enter a valid name",
41
  "string.empty": "name can not be empty",
42
  }),
43
+ description: joi.string().empty().optional().messages({
44
+ "string.base": "please enter a valid name",
45
+ "string.empty": "name can not be empty",
46
+ }),
47
  type: joi.string().empty().optional().messages({
48
  "string.base": "please enter a valid type",
49
  "string.empty": "type can not be empty",
 
52
  "string.base": "please enter a valid created_by",
53
  "string.empty": "created_by can not be empty",
54
  }),
55
+ image: joi.string().empty().optional().messages({
56
+ "string.base": "please enter a valid image url",
57
+ "string.empty": "image url can not be empty",
58
+ }),
59
+ fitness_level: joi.string().valid(...Object.values(FitnessLevel)).empty().optional().messages({
60
+ "string.base": "please enter a valid fitness level",
61
+ "string.empty": "fitness level can not be empty",
62
+ "any.only": `Fitness level must be one of the following values: ${FitnessLevel.ADVANCED}, ${FitnessLevel.BEGINNER} or ${FitnessLevel.INTERMEDIATE}`
63
+ }),
64
+ fitness_goal: joi.string().valid(...Object.values(FitnessGoal)).empty().optional().messages({
65
+ "string.base": "please enter a valid fitness goal",
66
+ "string.empty": "fitness goal can not be empty",
67
+ "any.only": `Fitness goal must be one of the following values: ${FitnessGoal.GAIN_MUSCLE}, ${FitnessGoal.GET_FITTER} or ${FitnessGoal.LOSE_WEIGHT}`
68
+ }),
69
+ place: joi.array().empty().optional().items(
70
+ joi.string().empty().optional().valid(...Object.values(Place)).messages({
71
+ "string.base": "please enter a valid place",
72
+ "string.empty": "place can not be empty",
73
+ "any.only": `place must be one of the following values: ${Place.GYM} or ${Place.HOME}`
74
+ })
75
+ ).messages({
76
+ "array.base": "please enter a valid place array",
77
+ "array.empty": "place array can not be empty",
78
+ }),
79
+ min_per_day: joi.number().integer().empty().optional().messages({
80
+ "number.base": "please enter a valid min per day",
81
+ "number.empty": "min per day can not be empty",
82
+ "number.integer": "day number must be an integer",
83
+ }),
84
+ total_number_days: joi.number().integer().empty().optional().messages({
85
+ "number.base": "please enter a valid total number days",
86
+ "number.empty": "total number days can not be empty",
87
+ "number.integer": "day number must be an integer",
88
+ }),
89
+ template_weeks: joi.array().empty().optional().items(
90
+ joi.object({
91
+ week_number: joi.number().integer().empty().optional().messages({
92
+ "number.base": "please enter a valid week number",
93
+ "number.empty": "week number can not be empty",
94
+ "number.integer": "week number must be an integer",
95
+ }),
96
+ week_name: joi.string().empty().optional().messages({
97
+ "string.base": "please enter a valid week name",
98
+ "string.empty": "week name can not be empty",
99
+ }),
100
+ week_description: joi.string().empty().optional().messages({
101
+ "string.base": "please enter a valid week description",
102
+ "string.empty": "week description can not be empty",
103
+ }),
104
+ days: joi.array().optional().items(
105
+ joi.object({
106
+ day_number: joi.number().empty().integer().min(1).max(7).optional().messages({
107
+ "number.base": "Please enter a valid day number",
108
+ "number.empty": "day number cannot be empty",
109
+ "number.integer": "day number must be an integer",
110
+ "number.min": "day number must be between 1 and 7",
111
+ "number.max": "day number must be between 1 and 7"
112
+ }),
113
+ total_number_exercises: joi.number().empty().integer().optional().messages({
114
+ "number.base": "Please enter a valid total number exercises",
115
+ "number.empty": "total number exercises cannot be empty",
116
+ "number.integer": "total number exercises must be an integer",
117
+ }),
118
+ day_type: joi.string().empty().optional().messages({
119
+ "string.base": "please enter a valid day type",
120
+ "string.empty": "day type can not be empty",
121
+ }),
122
+ exercises: joi.array().empty().optional().items(
123
+ joi.string().empty().required().messages({
124
+ "string.base": "please enter a valid exercise id",
125
+ "string.empty": "exercise id can not be empty",
126
+ }),).messages({
127
+ "array.base": "please enter a valid exercises array",
128
+ "array.empty": "exercises array can not be empty",
129
+ }),
130
+ }).empty().messages({
131
+ "object.base": "please enter a valid day object",
132
+ "object.empty": "day object can not be empty",
133
+ })
134
+ ),
135
+ }).empty().messages({
136
+ "array.base": "please enter a valid days array",
137
+ "array.empty": "days array can not be empty",
138
+
139
+ })
140
+ ).messages({
141
+ "array.base": "please enter a valid templateWeeks",
142
+ "array.empty": "templateWeeks can not be empty",
143
  }),
144
 
145
  });
src/modules/users/modules/auth/controllers/auth.controller.ts CHANGED
@@ -13,7 +13,7 @@ import { serialize } from "@helpers/serialize";
13
  import { UserSerialization } from "@common/serializers/user.serialization";
14
  import { UsersAuthService } from "../services/users-auth.service";
15
 
16
- @Prefix("/users/auth")
17
  export class UsersAuthController extends BaseController {
18
  private authService = new UsersAuthService();
19
 
 
13
  import { UserSerialization } from "@common/serializers/user.serialization";
14
  import { UsersAuthService } from "../services/users-auth.service";
15
 
16
+ @Prefix("/user/auth")
17
  export class UsersAuthController extends BaseController {
18
  private authService = new UsersAuthService();
19
 
src/modules/users/modules/exercises/controllers/exercises.controller.ts CHANGED
@@ -7,11 +7,11 @@ import { paramsValidator } from "@helpers/validation.helper";
7
  import { BaseController } from "@lib/controllers/controller.base";
8
  import { Prefix } from "@lib/decorators/prefix.decorator";
9
  import { serialize } from "@helpers/serialize";
10
- import { ExerciseSerialization } from "@common/serializers/exercise.serializtion";
11
  import { ControllerMiddleware } from "@lib/decorators/controller-middleware.decorator";
12
  import { UsersGuardMiddleware } from "modules/users/common/guards/users.guard";
13
 
14
- @Prefix("/users/exercises")
15
  @ControllerMiddleware(UsersGuardMiddleware())
16
  export class ExerciseController extends BaseController {
17
  private exercisesService = new ExerciseService();
 
7
  import { BaseController } from "@lib/controllers/controller.base";
8
  import { Prefix } from "@lib/decorators/prefix.decorator";
9
  import { serialize } from "@helpers/serialize";
10
+ import { ExerciseSerialization } from "@common/serializers/exercise.serialization";
11
  import { ControllerMiddleware } from "@lib/decorators/controller-middleware.decorator";
12
  import { UsersGuardMiddleware } from "modules/users/common/guards/users.guard";
13
 
14
+ @Prefix("/user/exercises")
15
  @ControllerMiddleware(UsersGuardMiddleware())
16
  export class ExerciseController extends BaseController {
17
  private exercisesService = new ExerciseService();
src/modules/users/modules/user-registered-workouts/controllers/user-registered-workouts.controller.ts ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { UserRegisteredWorkoutsService } from "../services/user-registered-workouts.service";
2
+ import { Request, Response } from "express";
3
+ import { JsonResponse } from "@lib/responses/json-response";
4
+ import { parsePaginationQuery } from "@helpers/pagination";
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 { Prefix } from "@lib/decorators/prefix.decorator";
9
+ import { serialize } from "@helpers/serialize";
10
+ import { UserRegisteredWorkoutsSerialization } from "@common/serializers/user-registered-workout.serialization";
11
+ import { ControllerMiddleware } from "@lib/decorators/controller-middleware.decorator";
12
+ import { UsersGuardMiddleware } from "modules/users/common/guards/users.guard";
13
+ import { createUserRegisteredWorkoutsSchema } from "../validations/create-user-registered-workouts.validation";
14
+ import { updateUserRegisteredWorkoutsSchema } from "../validations/update-user-registered-workouts.validation";
15
+
16
+ interface userRequest extends Request {
17
+ jwtPayload?: any;
18
+ }
19
+
20
+ @Prefix("/user/myWorkouts")
21
+ @ControllerMiddleware(UsersGuardMiddleware())
22
+ export class userRegisteredWorkoutsController extends BaseController {
23
+ private userRegisteredWorkoutsService = new UserRegisteredWorkoutsService();
24
+
25
+ setRoutes(): void {
26
+ this.router.get("/:id", paramsValidator("id"), asyncHandler(this.get));
27
+ this.router.get("/", asyncHandler(this.list));
28
+ this.router.post("/",
29
+ bodyValidator(createUserRegisteredWorkoutsSchema),
30
+ asyncHandler(this.create));
31
+ }
32
+
33
+ list = async (req: userRequest, res: Response) => {
34
+ const paginationQuery = parsePaginationQuery(req.query);
35
+ const { docs, paginationData } = await this.userRegisteredWorkoutsService.list(
36
+ { user: req.jwtPayload.id },
37
+ paginationQuery,
38
+ {
39
+ populateArray: [
40
+ { path: "workout", select: "-templateWeeks -created_by" },
41
+ { path: "weeks.days.exercises", select: "name media reps sets" },
42
+ ]
43
+ }
44
+ );
45
+
46
+ return JsonResponse.success(
47
+ {
48
+ data: serialize(docs, UserRegisteredWorkoutsSerialization),
49
+ meta: paginationData,
50
+ },
51
+ res
52
+ );
53
+ };
54
+
55
+ get = async (req: userRequest, res: Response) => {
56
+ const data = await this.userRegisteredWorkoutsService.findOneOrFail(
57
+ { _id: req.params.id },
58
+ {
59
+ populateArray: [
60
+ { path: "workout", select: "-template_weeks -created_by" },
61
+ { path: "weeks.days.exercises", select: "name media reps sets" },
62
+ ]
63
+ }
64
+ );
65
+ return JsonResponse.success(
66
+ {
67
+ data: serialize(data.toJSON(), UserRegisteredWorkoutsSerialization),
68
+ },
69
+ res
70
+ );
71
+ };
72
+
73
+ create = async (req: userRequest, res: Response) => {
74
+ const data = await this.userRegisteredWorkoutsService.create(req.body);
75
+ return JsonResponse.success(
76
+ {
77
+ status: 201,
78
+ data: serialize(data.toJSON(), UserRegisteredWorkoutsSerialization),
79
+ },
80
+ res
81
+ );
82
+ };
83
+
84
+ }
src/modules/users/modules/user-registered-workouts/services/user-registered-workouts.service.ts ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ import { UserRegisteredWorkout } from "@common/models/user-registered-workout.model";
2
+ import { CrudService } from "@lib/services/crud.service";
3
+
4
+ export class UserRegisteredWorkoutsService extends CrudService(UserRegisteredWorkout) {}
src/modules/users/modules/user-registered-workouts/validations/create-user-registered-workouts.validation.ts ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as joi from "joi";
2
+ import { createSchema } from "@helpers/create-schema";
3
+
4
+
5
+ export interface ICreateUserRegisteredWorkouts {
6
+ user: string;
7
+ workout: string;
8
+ is_active?: Boolean;
9
+ weeks: [
10
+ {
11
+ week_number: number;
12
+ week_name: string,
13
+ week_description: string,
14
+ is_done?: boolean,
15
+ days: [
16
+ {
17
+ day_number: number,
18
+ total_number_exercises: number,
19
+ day_type: string,
20
+ exercises: [string],
21
+ is_done?: boolean,
22
+ },
23
+ ],
24
+ },
25
+ ]
26
+ }
27
+
28
+ export const createUserRegisteredWorkoutsSchema = createSchema<ICreateUserRegisteredWorkouts>({
29
+ user: joi.string().empty().required().messages({
30
+ "string.base": "please enter a valid user id",
31
+ "any.required": "user id is required",
32
+ "string.empty": "user id can not be empty",
33
+ }),
34
+ is_active: joi.boolean().empty().optional().messages({
35
+ "boolean.base": "please enter a valid isActive",
36
+ "boolean.empty": "isActive can not be empty",
37
+ }),
38
+ workout: joi.string().empty().required().messages({
39
+ "string.base": "please enter a valid workout id",
40
+ "any.required": "workout id is required",
41
+ "string.empty": "workout id can not be empty",
42
+ }),
43
+ weeks: joi.array().empty().required().items(
44
+ joi.object({
45
+ week_number: joi.number().integer().empty().required().messages({
46
+ "number.base": "please enter a valid week number",
47
+ "any.required": "week number is required",
48
+ "number.empty": "week number can not be empty",
49
+ "number.integer": "week number must be an integer",
50
+ }),
51
+ week_name: joi.string().empty().required().messages({
52
+ "string.base": "please enter a valid week name",
53
+ "any.required": "week name is required",
54
+ "string.empty": "week name can not be empty",
55
+ }),
56
+ week_description: joi.string().empty().required().messages({
57
+ "string.base": "please enter a valid week description",
58
+ "any.required": "week description is required",
59
+ "string.empty": "week description can not be empty",
60
+ }),
61
+ is_done: joi.boolean().empty().optional().messages({
62
+ "boolean.base": "please enter a valid isDone",
63
+ "boolean.empty": "isDone can not be empty",
64
+ }),
65
+ days: joi.array().required().items(
66
+ joi.object({
67
+ day_number: joi.number().empty().integer().min(1).max(7).required().messages({
68
+ "number.base": "Please enter a valid day number",
69
+ "any.required": "day number is required",
70
+ "number.empty": "day number cannot be empty",
71
+ "number.integer": "day number must be an integer",
72
+ "number.min": "day number must be between 1 and 7",
73
+ "number.max": "day number must be between 1 and 7"
74
+ }),
75
+ total_number_exercises: joi.number().empty().integer().required().messages({
76
+ "number.base": "Please enter a valid total number exercises",
77
+ "any.required": "total number exercises is required",
78
+ "number.empty": "total number exercises cannot be empty",
79
+ "number.integer": "total number exercises must be an integer",
80
+ }),
81
+ day_type: joi.string().empty().required().messages({
82
+ "string.base": "please enter a valid day type",
83
+ "any.required": "day type is required",
84
+ "string.empty": "day type can not be empty",
85
+ }),
86
+ exercises: joi.array().empty().required().items(
87
+ joi.string().empty().required().messages({
88
+ "string.base": "please enter a valid exercise id",
89
+ "any.required": "exercise id is required",
90
+ "string.empty": "exercise id can not be empty",
91
+ }),).messages({
92
+ "array.base": "please enter a valid exercises array",
93
+ "any.required": "exercises array is required",
94
+ "array.empty": "exercises array can not be empty",
95
+ }),
96
+ is_done: joi.boolean().empty().optional().messages({
97
+ "boolean.base": "please enter a valid isDone",
98
+ "boolean.empty": "isDone can not be empty",
99
+ }),
100
+ }).empty().messages({
101
+ "object.base": "please enter a valid day object",
102
+ "any.required": "day object is required",
103
+ "object.empty": "day object can not be empty",
104
+ })
105
+ ),
106
+ }).empty().messages({
107
+ "array.base": "please enter a valid days array",
108
+ "any.required": "days array is required",
109
+ "array.empty": "days array can not be empty",
110
+
111
+ })
112
+ ).messages({
113
+ "array.base": "please enter a valid weeks array",
114
+ "any.required": "weeks array is required",
115
+ "array.empty": "weeks array can not be empty",
116
+ }),
117
+ });
src/modules/users/modules/user-registered-workouts/validations/update-user-registered-workouts.validation.ts ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as joi from "joi";
2
+ import { createSchema } from "@helpers/create-schema";
3
+
4
+
5
+
6
+ export interface IUpdateUserRegisteredWorkouts {
7
+ user?: string;
8
+ workout?: string;
9
+ is_active?: Boolean;
10
+ weeks?: [
11
+ {
12
+ week_number?: number;
13
+ week_name?: string,
14
+ week_description?: string,
15
+ is_done?: boolean,
16
+ days?: [
17
+ {
18
+ day_number?: number,
19
+ total_number_exercises?: number,
20
+ day_type?: string,
21
+ exercises?: [string],
22
+ is_done?: boolean,
23
+ },
24
+ ],
25
+ },
26
+ ]
27
+ }
28
+
29
+
30
+ export const updateUserRegisteredWorkoutsSchema = createSchema<IUpdateUserRegisteredWorkouts>({
31
+ user: joi.string().empty().optional().messages({
32
+ "string.base": "please enter a valid user id",
33
+ "string.empty": "user id can not be empty",
34
+ }),
35
+ is_active: joi.boolean().empty().optional().messages({
36
+ "boolean.base": "please enter a valid isActive",
37
+ "boolean.empty": "isActive can not be empty",
38
+ }),
39
+ workout: joi.string().empty().optional().messages({
40
+ "string.base": "please enter a valid workout id",
41
+ "string.empty": "workout id can not be empty",
42
+ }),
43
+ weeks: joi.array().empty().optional().items(
44
+ joi.object({
45
+ week_number: joi.number().integer().empty().optional().messages({
46
+ "number.base": "please enter a valid week number",
47
+ "number.empty": "week number can not be empty",
48
+ "number.integer": "week number must be an integer",
49
+ }),
50
+ week_name: joi.string().empty().optional().messages({
51
+ "string.base": "please enter a valid week name",
52
+ "string.empty": "week name can not be empty",
53
+ }),
54
+ week_description: joi.string().empty().optional().messages({
55
+ "string.base": "please enter a valid week description",
56
+ "string.empty": "week description can not be empty",
57
+ }),
58
+ is_done: joi.boolean().empty().optional().messages({
59
+ "boolean.base": "please enter a valid isDone",
60
+ "boolean.empty": "isDone can not be empty",
61
+ }),
62
+ days: joi.array().optional().items(
63
+ joi.object({
64
+ day_number: joi.number().empty().integer().min(1).max(7).optional().messages({
65
+ "number.base": "Please enter a valid day number",
66
+ "number.empty": "day number cannot be empty",
67
+ "number.integer": "day number must be an integer",
68
+ "number.min": "day number must be between 1 and 7",
69
+ "number.max": "day number must be between 1 and 7"
70
+ }),
71
+ total_number_exercises: joi.number().empty().integer().optional().messages({
72
+ "number.base": "Please enter a valid total number exercises",
73
+ "number.empty": "total number exercises cannot be empty",
74
+ "number.integer": "total number exercises must be an integer",
75
+ }),
76
+ day_type: joi.string().empty().optional().messages({
77
+ "string.base": "please enter a valid day type",
78
+ "string.empty": "day type can not be empty",
79
+ }),
80
+ exercises: joi.array().empty().optional().items(
81
+ joi.string().empty().optional().messages({
82
+ "string.base": "please enter a valid exercise id",
83
+ "string.empty": "exercise id can not be empty",
84
+ }),).messages({
85
+ "array.base": "please enter a valid exercises array",
86
+ "array.empty": "exercises array can not be empty",
87
+ }),
88
+ is_done: joi.boolean().empty().optional().messages({
89
+ "boolean.base": "please enter a valid isDone",
90
+ "boolean.empty": "isDone can not be empty",
91
+ }),
92
+ }).empty().messages({
93
+ "object.base": "please enter a valid day object",
94
+ "object.empty": "day object can not be empty",
95
+ })
96
+ ),
97
+ }).empty().messages({
98
+ "array.base": "please enter a valid days array",
99
+ "array.empty": "days array can not be empty",
100
+
101
+ })
102
+ ).messages({
103
+ "array.base": "please enter a valid weeks array",
104
+ "array.empty": "weeks array can not be empty",
105
+ }),
106
+ });
src/modules/users/modules/workouts/controllers/workouts.controller.ts CHANGED
@@ -11,7 +11,7 @@ import { WorkoutSerialization } from "@common/serializers/workout.serialization"
11
  import { ControllerMiddleware } from "@lib/decorators/controller-middleware.decorator";
12
  import { UsersGuardMiddleware } from "modules/users/common/guards/users.guard";
13
 
14
- @Prefix("/users/workouts")
15
  @ControllerMiddleware(UsersGuardMiddleware())
16
  export class WorkoutController extends BaseController {
17
  private workoutsService = new WorkoutService();
 
11
  import { ControllerMiddleware } from "@lib/decorators/controller-middleware.decorator";
12
  import { UsersGuardMiddleware } from "modules/users/common/guards/users.guard";
13
 
14
+ @Prefix("/user/workouts")
15
  @ControllerMiddleware(UsersGuardMiddleware())
16
  export class WorkoutController extends BaseController {
17
  private workoutsService = new WorkoutService();