421 lines
8.3 KiB
JavaScript
421 lines
8.3 KiB
JavaScript
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 }; |