File size: 3,189 Bytes
f4fe35f
484fdbc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
eb78df6
484fdbc
fc659a3
484fdbc
 
 
eb78df6
484fdbc
 
 
 
359c042
484fdbc
359c042
484fdbc
359c042
484fdbc
 
 
 
3787f0d
484fdbc
eb78df6
484fdbc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bd555c1
484fdbc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f4fe35f
 
 
 
 
 
484fdbc
 
 
f4fe35f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
484fdbc
 
cefba2c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import mongoose, { UpdateQuery } from "mongoose";
import bcrypt from "bcrypt";
import { AuthenticatableType } from "@common/enums/authenticatable-type.enum";
import { FitnessGoal } from "@common/enums/fitness-goal.enum";
import { FitnessLevel } from "@common/enums/fitness-level.enum";
import { Gender } from "@common/enums/gender.enum";
import { Injury } from "@common/enums/injury.enum";
import { PreferredDay } from "@common/enums/preferred-day.enum";
import { PreferredEquipment } from "@common/enums/preferred-equipment.enum";
import { WorkoutPlace } from "@common/enums/workout-place.enum";
export const saltrounds = 5;
const { Schema } = mongoose;

export interface IUser {
  name: string;
  email: string;
  password: string;
  image: string;
  role: AuthenticatableType;
  gender: Gender;
  dob: Date;
  height: number;
  weight: number;
  fitness_level: FitnessLevel;
  preferences: {
    fitness_goal: FitnessGoal;
    target_weight: number;
    workout_frequency: number;
    preferred_days: PreferredDay[];
    workout_place: WorkoutPlace;
    preferred_equipment: PreferredEquipment[];
  };
  injuries: Injury[];
}

const userSchema = new Schema({
  name: { type: String, required: true },
  email: { type: String, required: true },
  password: { type: String, required: true },
  image: { type: String },
  gender: {
    type: String,
    enum: Gender,
    required: true,
  },
  height: { type: Number, required: true },
  weight: { type: Number, required: true },
  fitness_level: {
    type: String,
    enum: FitnessLevel,
    required: true,
  },
  preferences: {
    fitness_goal: {
      type: String,
      enum: FitnessGoal,
      required: true,
    },
    target_weight: { type: Number, required: true },
    workout_frequency: { type: Number },
    preferred_days: [
      {
        type: String,
        enum: PreferredDay,
      },
    ],
    workout_place: {
      type: String,
      enum: WorkoutPlace,
      required: true,
    },
    preferred_equipment: [
      {
        type: String,
        enum: PreferredEquipment,
        required: true,
      },
    ],
  },
  injuries: [
    {
      type: String,
      enum: Injury,
      required: true,
    },
  ],
  dob: { type: Date },
  role: {
    type: String,
    enum: AuthenticatableType,
    default: AuthenticatableType.USER,
  },
});

userSchema.pre("save", async function (next) {
  if (this.isModified("password")) {
    this.password = await bcrypt.hash(this.password, saltrounds);
  }
  if (this.isModified("email")) {
    this.email = this.email.toLowerCase();
  }
  next();
});

userSchema.pre(["updateOne", "findOneAndUpdate"], async function () {
  const data = this.getUpdate() as UpdateQuery<IUser>;
  if (data.password) {
    data.password = await bcrypt.hash(data.password, saltrounds);
  }
  if (data.email) {
    data.email = data.email.toLowerCase();
  }
});

// pre find make email case insensitive
userSchema.pre(["find", "findOne"], function () {
  const query = this.getQuery();
  if (query.email) {
    query.email = query.email.toLowerCase();
  }
});

export type UserDocument = IUser & mongoose.Document;

export const User = mongoose.model<UserDocument>("users", userSchema);