import mongoose from "mongoose"; const { Schema, model, Types } = mongoose; /* ---------------------- User Details Schema ---------------------- */ const userDetailsSchema = new Schema({ firstName: { type: String, }, lastName: { type: String, required: true, }, email: { type: String, required: true, unique: true, }, dob: { type: String, }, age: { type: String, }, address: { type: String, }, city: { type: String, }, state: { type: String, }, country: { type: String, }, password: { type: String, }, paymentMethod: { type: String, }, payoneerAccount: { type: String, }, veemAccount: { type: String, }, phone: { type: String, }, skype: { type: String, }, }); /* ---------------------- Tracking Schema ---------------------- */ const trackingSchema = new Schema({ type: { type: String, enum: ["SCREENSHOT", "VIDEO"], default: "SCREENSHOT", }, duration: { type: String, default: "5M", }, }); /* ---------------------- Project Schema ---------------------- */ const projectSchema = new Schema({ name: { type: String, required: true, }, hourlyRate: { type: String, }, totalLoggedHours: { type: Number, default: 0 }, vaAssigned: [ { type: Types.ObjectId, ref: "VA", }, ], clientId: { type: Types.ObjectId, ref: "Client" }, dedicatedHours: { type: Number, default: 0 } }); /* ---------------------- Client Details Schema ---------------------- */ const clientDetailsSchema = new Schema({ name: { type: String, }, email: { type: String, required: true, unique: true, }, address: { type: String, }, city: { type: String, }, state: { type: String, }, zip: { type: String, }, billingName: { type: String, }, billingEmail: { type: String, }, billingAddress: { type: String, }, billingCity: { type: String, }, billingState: { type: String, }, billingZip: { type: String, }, position: { type: String, }, signatoryName: { type: String, }, signatoryEmail: { type: String, }, paymentMethod: { type: String, }, bankName: { type: String, }, accountNumber: { type: String, }, routingNumber: { type: String, }, accountType: { type: String, }, accountHolderName: { type: String, }, cardNumber: { type: String, }, expiryDate: { type: String, }, securityCode: { type: String, }, cardZip: { type: String, }, password: { type: String, }, }); /* ---------------------- Client Schema ---------------------- */ const clientSchema = new Schema({ userDetails: clientDetailsSchema, vaIds: [ { type: Types.ObjectId, ref: "VA", }, ], projectIds: [ { type: Types.ObjectId, ref: "Project", }, ], accessToken: { type: String, default: null }, refreshToken: { type: String, default: null }, passwordResetToken: { type: String, default: null } }); /* ---------------------- logged Schema ---------------------- */ const loggedSchema = new Schema({ loggedType: { type: String, enum: ["LOGIN", "LOGOUT"], default: "LOGIN" }, time: { type: Date, default: Date.now }, vaId: { type: Types.ObjectId, ref: "VA" }, vaEmail: { type: String, required: true }, projectId: { type: Types.ObjectId, ref: "Project" } }) /* ---------------------- VA Schema ---------------------- */ const vaSchema = new Schema( { userDetails: userDetailsSchema, tracking: trackingSchema, clientIds: [ { type: Types.ObjectId, ref: "Client", }, ], projectIds: [ { type: Types.ObjectId, ref: "Project", }, ], schedule: { type: String, }, status: { type: String, enum: ["PARTTIME", "FULLTIME", "INACTIVE"], default: "FULLTIME", }, accessToken: { type: String, default: null }, refreshToken: { type: String, default: null }, passwordResetToken: { type: String, default: null } }, { timestamps: true } ); // Need to add working hours and time zone tooooo in which VA is going to work, need to calculate total work hours of the day - Schedules // Need to add this Schedule feature on SF there we can change the schedulte of VA - Add in form tooo // Need to ask to client if we want to provide schedule changing functionality on Docker toooooo // Add working on Tabs Datils - like which tabs VA is working on while working on project - Tab Model // Add activity level of VA while working on project - Activity Model const vaWorkTrackSchema = new Schema({ vaId: { type: Types.ObjectId, ref: "VA", }, projectId: { type: Types.ObjectId, ref: "Project", }, logId: { type: String, ref: "Logged", }, title: { type: String, }, appName: { type: String, }, from: { type: Date, default: Date.now, }, to: { type: Date, default: Date.now, }, totalTime: { type: Number, default: 0, }, }, { timestamps: true } ) const passwordResetSchema = new mongoose.Schema({ email: { type: String, required: true, lowercase: true, index: true }, token: { type: String, required: true, unique: true, index: true }, userType: { type: String, required: true, enum: ['va', 'client'], index: true }, expiresAt: { type: Date, required: true, index: true, expires: 3600 // TTL index for 1 hour }, used: { type: Boolean, default: false } }, { timestamps: true }); passwordResetSchema.index({ email: 1, used: 1 }); passwordResetSchema.index({ token: 1, used: 1, expiresAt: 1 }); passwordResetSchema.index({ userType: 1, email: 1 }); const adjustedHoursSchema = new Schema({ vaId: { type: Types.ObjectId, ref: "VA", required: true }, projectId: { type: Types.ObjectId, ref: "Project", required: true }, date: { type: Date, required: true }, loginTime: { type: Date, required: true }, logoutTime: { type: Date, required: true }, comment: { type: String, required: true }, status: { type: String, enum: ["PENDING", "APPROVED", "REJECTED"], default: "PENDING" }, reviewedAt: { type: Date }, rejectionReason: { type: String // If rejected, store the reason }, adjustedLogs: [{ loginLogId: { type: Types.ObjectId, ref: "Logged" }, logoutLogId: { type: Types.ObjectId, ref: "Logged" } }] }, { timestamps: true }); /* ---------------------- Model Exports ---------------------- */ const VAModel = model("VA", vaSchema); const ClientModel = model("Client", clientSchema); const ProjectModel = model("Project", projectSchema); const LoggedModel = model("TrackLog", loggedSchema); const WorkTrackModel = model("TrackWork", vaWorkTrackSchema); const PasswordResetModel = model("PasswordReset", passwordResetSchema); const AdjustedHoursModel = model("AdjustedHours", adjustedHoursSchema); export { VAModel, ClientModel, ProjectModel, LoggedModel, WorkTrackModel, PasswordResetModel, AdjustedHoursModel };