Hozifa Elgharbawy commited on
Commit
eb78df6
·
1 Parent(s): 1524ed4

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

Browse files
src/common/enums/place.enum.ts ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ export enum Place {
2
+ GYM = "gym",
3
+ HOME = "home",
4
+ }
src/{modules/users/common → common}/models/user-registered-workout.model.ts RENAMED
@@ -4,17 +4,20 @@ const { Schema } = mongoose;
4
  export interface IUserRegisteredWorkout {
5
  user: mongoose.Types.ObjectId,
6
  workout: mongoose.Types.ObjectId,
7
- isActive: Boolean,
8
  weeks: [
9
  {
10
- weekNumber: number,
11
- name: string,
12
- description: string,
 
13
  days: [
14
  {
15
- dayNumber: number,
 
 
16
  exercises: [mongoose.Types.ObjectId],
17
- isDone: Boolean
18
  },
19
  ],
20
  },
@@ -24,16 +27,22 @@ export interface IUserRegisteredWorkout {
24
  const userRegisteredWorkoutSchema = new Schema({
25
  user: { type: mongoose.Types.ObjectId, ref: "users" },
26
  workout: { type: mongoose.Types.ObjectId, ref: "workouts" },
27
- isActive: { type: Boolean, default: false },
28
  weeks: [
29
  {
 
 
 
 
30
  days: [
31
  {
32
- day: Number,
 
 
33
  exercises: [
34
  { type: mongoose.Types.ObjectId, ref: "exercises" },
35
  ],
36
- isDone: { type: Boolean, default: false }
37
  },
38
  ],
39
  },
 
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
  },
 
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
  },
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,4 +1,8 @@
1
  import mongoose from "mongoose";
 
 
 
 
2
  const { Schema } = mongoose;
3
 
4
  export interface IWorkout {
@@ -6,15 +10,22 @@ export interface IWorkout {
6
  description: string;
7
  type: string;
8
  created_by: mongoose.Types.ObjectId;
9
- image: object;
10
- templateWeeks: [
 
 
 
 
 
11
  {
12
- weekNumber: number;
13
- name: string,
14
- description: string,
15
  days: [
16
  {
17
- dayNumber: number,
 
 
18
  exercises: [mongoose.Types.ObjectId],
19
  },
20
  ],
@@ -24,14 +35,25 @@ export interface IWorkout {
24
 
25
  const workoutSchema = new Schema({
26
  name: { type: String, required: true, unique: true, dropDups: true },
 
27
  type: { type: String, required: true },
28
  created_by: { type: mongoose.Types.ObjectId, ref: "admins" },
29
- image: { type: Object },
30
- templateWeeks: [
 
 
 
 
 
31
  {
 
 
 
32
  days: [
33
  {
34
- day: Number,
 
 
35
  exercises: [
36
  { type: mongoose.Types.ObjectId, ref: "exercises" },
37
  ],
 
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 {
 
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
  ],
 
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/{modules/users/common → common}/serializers/user-registered-workout.serialization.ts RENAMED
@@ -2,25 +2,41 @@ import { Expose, Transform } from "class-transformer";
2
  import { serialize } from "@helpers/serialize";
3
 
4
 
5
-
6
  class Days {
7
  @Expose()
8
- day: number;
 
 
 
 
 
 
9
 
10
  @Expose({ name: "exercises" })
11
  exercises: any;
12
 
13
  @Expose()
14
- isDone: Boolean
15
  }
16
 
17
-
18
  class Weeks {
 
 
 
 
 
 
 
 
 
19
  @Expose({ name: "days" })
20
  @Transform(
21
  ({ value }) => serialize(value, Days)
22
  )
23
  days: any;
 
 
 
24
  }
25
 
26
  export class UserRegisteredWorkoutsSerialization {
@@ -34,7 +50,7 @@ export class UserRegisteredWorkoutsSerialization {
34
  workout: string;
35
 
36
  @Expose()
37
- isActive: Boolean;
38
 
39
  @Expose({ name: "weeks" })
40
  @Transform(
 
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 {
 
50
  workout: string;
51
 
52
  @Expose()
53
+ is_active: Boolean;
54
 
55
  @Expose({ name: "weeks" })
56
  @Transform(
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,19 +41,37 @@ export class WorkoutSerialization {
27
  @Expose()
28
  name: string;
29
 
 
 
 
30
  @Expose()
31
  type: string;
32
 
33
  @Expose()
34
- image: object;
35
 
36
  @Expose()
37
  created_by: string;
38
 
39
- @Expose({ name: "templateWeeks" })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  @Transform(
41
  ({ value }) => serialize(value, TemplateWeeks)
42
  )
43
- templateWeeks: any;
44
 
45
  }
 
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/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: object[];
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,7 +54,108 @@ 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
  "array.base": "please enter a valid templateWeeks",
30
  "any.required": "templateWeeks is required",
31
  "array.empty": "templateWeeks can not be empty",
 
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",
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?: object[];
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,7 +52,92 @@ 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
  "array.base": "please enter a valid templateWeeks",
27
  "array.empty": "templateWeeks can not be empty",
28
  }),
 
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
  }),
src/modules/users/modules/user-registered-workouts/controllers/user-registered-workouts.controller.ts CHANGED
@@ -7,7 +7,7 @@ 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";
@@ -23,28 +23,22 @@ export class userRegisteredWorkoutsController extends BaseController {
23
  private userRegisteredWorkoutsService = new UserRegisteredWorkoutsService();
24
 
25
  setRoutes(): void {
26
- this.router.get("/get/:id", paramsValidator("id"), asyncHandler(this.get));
27
- this.router.get("/list/:userId", paramsValidator("userId"), asyncHandler(this.list));
28
  this.router.post("/",
29
  bodyValidator(createUserRegisteredWorkoutsSchema),
30
  asyncHandler(this.create));
31
-
32
- this.router.patch("/",
33
- bodyValidator(updateUserRegisteredWorkoutsSchema),
34
- asyncHandler(this.update));
35
  }
36
 
37
  list = async (req: userRequest, res: Response) => {
38
  const paginationQuery = parsePaginationQuery(req.query);
39
- // if (req.jwtPayload.id != req.params.userId) console.log(req.jwtPayload);
40
-
41
  const { docs, paginationData } = await this.userRegisteredWorkoutsService.list(
42
- { user: req.params.userId },
43
  paginationQuery,
44
  {
45
  populateArray: [
46
  { path: "workout", select: "-templateWeeks -created_by" },
47
- { path: "weeks.days.exercises" },
48
  ]
49
  }
50
  );
@@ -63,8 +57,8 @@ export class userRegisteredWorkoutsController extends BaseController {
63
  { _id: req.params.id },
64
  {
65
  populateArray: [
66
- { path: "workout", select: "-templateWeeks -created_by" },
67
- { path: "weeks.days.exercises" },
68
  ]
69
  }
70
  );
@@ -87,16 +81,4 @@ export class userRegisteredWorkoutsController extends BaseController {
87
  );
88
  };
89
 
90
- update = async (req: userRequest, res: Response) => {
91
- const data = await this.userRegisteredWorkoutsService.updateOne(
92
- { _id: req.params.id },
93
- req.body
94
- );
95
- return JsonResponse.success(
96
- {
97
- data: serialize(data.toJSON(), UserRegisteredWorkoutsSerialization),
98
- },
99
- res
100
- );
101
- };
102
  }
 
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";
 
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
  );
 
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
  );
 
81
  );
82
  };
83
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  }
src/modules/users/modules/user-registered-workouts/services/user-registered-workouts.service.ts CHANGED
@@ -1,4 +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) {}
 
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 CHANGED
@@ -1,25 +1,29 @@
1
  import * as joi from "joi";
2
  import { createSchema } from "@helpers/create-schema";
3
 
4
- export interface IDays {
5
- day: string;
6
- exercises: string[];
7
- isDone?: Boolean;
8
- };
9
-
10
-
11
- export interface IWeeks {
12
- days: IDays[];
13
- };
14
-
15
 
16
  export interface ICreateUserRegisteredWorkouts {
17
  user: string;
18
  workout: string;
19
- isActive: Boolean;
20
- weeks: IWeeks[];
21
- };
22
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
  export const createUserRegisteredWorkoutsSchema = createSchema<ICreateUserRegisteredWorkouts>({
25
  user: joi.string().empty().required().messages({
@@ -27,7 +31,7 @@ export const createUserRegisteredWorkoutsSchema = createSchema<ICreateUserRegist
27
  "any.required": "user id is required",
28
  "string.empty": "user id can not be empty",
29
  }),
30
- isActive: joi.boolean().empty().optional().messages({
31
  "boolean.base": "please enter a valid isActive",
32
  "boolean.empty": "isActive can not be empty",
33
  }),
@@ -38,12 +42,46 @@ export const createUserRegisteredWorkoutsSchema = createSchema<ICreateUserRegist
38
  }),
39
  weeks: joi.array().empty().required().items(
40
  joi.object({
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  days: joi.array().required().items(
42
  joi.object({
43
- day: joi.number().empty().required().messages({
44
- "number.base": "please enter a valid day number",
45
  "any.required": "day number is required",
46
- "number.empty": "day number can not be empty",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  }),
48
  exercises: joi.array().empty().required().items(
49
  joi.string().empty().required().messages({
@@ -55,7 +93,7 @@ export const createUserRegisteredWorkoutsSchema = createSchema<ICreateUserRegist
55
  "any.required": "exercises array is required",
56
  "array.empty": "exercises array can not be empty",
57
  }),
58
- isDone: joi.boolean().empty().optional().messages({
59
  "boolean.base": "please enter a valid isDone",
60
  "boolean.empty": "isDone can not be empty",
61
  }),
 
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({
 
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
  }),
 
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({
 
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
  }),
src/modules/users/modules/user-registered-workouts/validations/update-user-registered-workouts.validation.ts CHANGED
@@ -2,23 +2,29 @@ import * as joi from "joi";
2
  import { createSchema } from "@helpers/create-schema";
3
 
4
 
5
- export interface IDays {
6
- day?: string;
7
- exercises?: string[];
8
- isDone?: Boolean;
9
- };
10
-
11
-
12
- export interface IWeeks {
13
- days?: IDays[];
14
- };
15
 
16
  export interface IUpdateUserRegisteredWorkouts {
17
  user?: string;
18
  workout?: string;
19
- isActive?: Boolean;
20
- weeks?: IWeeks[];
21
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
 
24
  export const updateUserRegisteredWorkoutsSchema = createSchema<IUpdateUserRegisteredWorkouts>({
@@ -26,7 +32,7 @@ export const updateUserRegisteredWorkoutsSchema = createSchema<IUpdateUserRegist
26
  "string.base": "please enter a valid user id",
27
  "string.empty": "user id can not be empty",
28
  }),
29
- isActive: joi.boolean().empty().optional().messages({
30
  "boolean.base": "please enter a valid isActive",
31
  "boolean.empty": "isActive can not be empty",
32
  }),
@@ -36,11 +42,40 @@ export const updateUserRegisteredWorkoutsSchema = createSchema<IUpdateUserRegist
36
  }),
37
  weeks: joi.array().empty().optional().items(
38
  joi.object({
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  days: joi.array().optional().items(
40
  joi.object({
41
- day: joi.number().empty().optional().messages({
42
- "number.base": "please enter a valid day number",
43
- "number.empty": "day number can not be empty",
 
 
 
 
 
 
 
 
 
 
 
 
44
  }),
45
  exercises: joi.array().empty().optional().items(
46
  joi.string().empty().optional().messages({
@@ -50,7 +85,7 @@ export const updateUserRegisteredWorkoutsSchema = createSchema<IUpdateUserRegist
50
  "array.base": "please enter a valid exercises array",
51
  "array.empty": "exercises array can not be empty",
52
  }),
53
- isDone: joi.boolean().empty().optional().messages({
54
  "boolean.base": "please enter a valid isDone",
55
  "boolean.empty": "isDone can not be empty",
56
  }),
 
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>({
 
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
  }),
 
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({
 
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
  }),