All files / server/src/features/user userSchema.ts

100% Statements 20/20
100% Branches 2/2
100% Functions 10/10
100% Lines 19/19

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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              54x     14776x     54x         1525x 1525x     54x                       3245x         61866x   61845x                   54x         98x         54x           13x       13x           1769x             54x                                 188x               54x       54x  
import mongoose, { ObjectId } from "mongoose";
import mongooseLeanVirtuals from "mongoose-lean-virtuals";
import { z } from "zod";
import dayjs from "dayjs";
import { EventLogAction } from "shared/types/models/eventLog";
import { UserGroup } from "shared/types/models/user";
 
const LotterySignupSchemaDb = z.object({
  programItemId: z.string(),
  priority: z.number(),
  signedToStartTime: z.date().transform((date) => dayjs(date).toISOString()),
});
 
const EventLogItemSchemaDb = z.object({
  eventLogItemId: z.custom<ObjectId>().transform(String),
  action: z.enum(EventLogAction),
  isSeen: z.boolean(),
  programItemId: z.string(),
  programItemStartTime: z.date().transform((date) => dayjs(date).toISOString()),
  createdAt: z.date().transform((date) => dayjs(date).toISOString()),
});
 
export const UserSchemaDb = z
  .object({
    kompassiId: z.number(),
    kompassiUsernameAccepted: z.boolean(),
    username: z.string(),
    password: z.string(),
    userGroup: z.enum(UserGroup),
    serial: z.string(),
    groupCode: z.string(),
    isGroupCreator: z.boolean(),
    favoriteProgramItemIds: z.array(z.string()),
    lotterySignups: z.array(LotterySignupSchemaDb),
    createdAt: z.date().transform((date) => dayjs(date).toISOString()),
    eventLogItems: z.array(EventLogItemSchemaDb),
    email: z.string().refine(
      (email) => {
        // Allow empty string (for unsubscribe)
        if (email === "") return true;
        // Validate email format if not empty
        return /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(email);
      },
      {
        message: "Invalid email format",
      },
    ),
    emailNotificationPermitAsked: z.boolean(),
  })
  .strip();
 
const lotterySignupSchema = new mongoose.Schema({
  programItemId: { type: String, required: true },
  priority: { type: Number, required: true },
  signedToStartTime: {
    type: Date,
    get: (value: Date) => new Date(value),
    required: true,
  },
});
 
const eventLogItemSchema = new mongoose.Schema(
  {
    action: { type: String, required: true },
    programItemId: { type: String, required: true },
    programItemStartTime: {
      type: Date,
      get: (value: Date) => new Date(value),
      required: true,
    },
    isSeen: { type: Boolean, required: true },
    createdAt: { type: Date, get: (value: Date) => new Date(value) },
  },
  {
    virtuals: {
      eventLogItemId: {
        get(this: { _id: ObjectId }) {
          return this._id;
        },
      },
    },
  },
);
 
const userSchema = new mongoose.Schema(
  {
    kompassiId: { type: Number, required: true },
    kompassiUsernameAccepted: { type: Boolean, required: true },
    username: { type: String, required: true },
    password: { type: String, required: true },
    userGroup: { type: String, required: true },
    serial: { type: String, required: true },
    isGroupCreator: { type: Boolean, required: true },
    groupCode: { type: String, required: true },
    favoriteProgramItemIds: { type: [String], required: true },
    lotterySignups: { type: [lotterySignupSchema], required: true },
    eventLogItems: { type: [eventLogItemSchema], required: true },
    email: { type: String, required: false },
    emailNotificationPermitAsked: { type: Boolean, required: true },
    createdAt: {
      type: Date,
      get: (value: Date) => new Date(value),
    },
  },
  {
    timestamps: true,
  },
);
 
userSchema.plugin(mongooseLeanVirtuals, {
  enabledByDefault: true,
});
 
export const UserModel = mongoose.model("user", userSchema);