Skip to content

Commit

Permalink
feat: Add program enrollment type (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
RudraPatel2003 authored Oct 17, 2024
1 parent 86a5cb0 commit 8b81c59
Show file tree
Hide file tree
Showing 12 changed files with 301 additions and 1 deletion.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ Please contact leadership to obtain the following:

Branch protections are enabled on this repository.
To contribute, please create a new branch and make a pull request.
The rules for branch names are lax, just be sure to include your name.

An example branch name for a card that adds a reset password email would be:

```text
rudra-reset-password-email
```

Your pull request title must follow the conventional commits specification. An example of a valid pull request title is:

Expand Down
72 changes: 72 additions & 0 deletions src/server/api/programs/mutations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"use server";

import { ProgramEnrollmentModel } from "@/server/models";
import { ApiResponse, ProgramEnrollment } from "@/types";
import authenticateServerFunction from "@/utils/authenticateServerFunction";
import apiErrors from "@/utils/constants/apiErrors";
import handleMongooseError from "@/utils/handleMongooseError";

export async function createProgramEnrollment(
programEnrollment: ProgramEnrollment,
): Promise<ApiResponse<ProgramEnrollment>> {
try {
// don't create program enrollment if one already exists
const existingProgramEnrollment = await ProgramEnrollmentModel.findOne({
email: programEnrollment.email,
program: programEnrollment.program,
});

if (existingProgramEnrollment) {
return {
success: false,
error: apiErrors.programEnrollment.programEnrollmentAlreadyExists,
};
}

const newProgramEnrollmentDocument =
await ProgramEnrollmentModel.create(programEnrollment);

// convert ObjectId to string
const newProgramEnrollment = newProgramEnrollmentDocument.toObject();
newProgramEnrollment._id = String(newProgramEnrollment._id);

return { success: true, data: newProgramEnrollment };
} catch (error) {
return { success: false, error: handleMongooseError(error) };
}
}

export async function updateProgramEnrollment(
newProgramEnrollment: ProgramEnrollment,
): Promise<ApiResponse<ProgramEnrollment>> {
const authResposne = await authenticateServerFunction("admin");

if (!authResposne.success) {
return authResposne;
}

try {
const updatedProgramEnrollmentDocument =
await ProgramEnrollmentModel.findOneAndUpdate(
{ _id: newProgramEnrollment._id },
newProgramEnrollment,
{ new: true },
);

if (!updatedProgramEnrollmentDocument) {
return {
success: false,
error: apiErrors.programEnrollment.programEnrollmentNotFound,
};
}

// convert ObjectId to string
const updatedProgramEnrollment =
updatedProgramEnrollmentDocument.toObject();
updatedProgramEnrollment._id = String(updatedProgramEnrollment._id);

return { success: true, data: updatedProgramEnrollment };
} catch (error) {
return { success: false, error: handleMongooseError(error) };
}
}
40 changes: 40 additions & 0 deletions src/server/api/programs/queries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import dbConnect from "@/server/dbConnect";
import { ProgramEnrollmentModel } from "@/server/models";
import { ProgramEnrollment } from "@/types";
import authenticateServerFunction from "@/utils/authenticateServerFunction";
import handleMongooseError from "@/utils/handleMongooseError";

type ProgramEnrollmentFilters = Partial<ProgramEnrollment>;

export async function getProgramEnrollments(filters: ProgramEnrollmentFilters) {
await dbConnect();

const authResponse = await authenticateServerFunction();

if (!authResponse.success) {
return authResponse;
}

try {
const programEnrollments = await ProgramEnrollmentModel.find(filters)
.lean<ProgramEnrollment[]>()
.exec();

// convert ObjectId to string
programEnrollments.forEach((programEnrollment) => {
programEnrollment._id = String(programEnrollment._id);
});

return { success: true, data: programEnrollments };
} catch (error) {
return { success: false, error: handleMongooseError(error) };
}
}

export async function getPendingProgramEnrollments() {
return getProgramEnrollments({ status: "pending" });
}

export async function getClientProgramEnrollments(email: string) {
return getProgramEnrollments({ email, status: "accepted" });
}
99 changes: 99 additions & 0 deletions src/server/models/EnrollmentForm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import mongoose, { Schema } from "mongoose";

import { EnrollmentForm } from "@/types";

const EnrollmentFormSchema = new Schema<EnrollmentForm>(
{
_id: {
type: String,
required: true,
},
dateCreated: {
type: String,
required: true,
},
firstName: {
type: String,
required: true,
},
lastName: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
confirmPassword: {
type: String,
required: true,
},
address: {
type: String,
required: true,
},
phoneNumber: {
type: String,
required: true,
},
hasClassACdl: {
type: Boolean,
required: true,
},
classBDescription: {
type: String,
},
dateOfBirth: {
type: String,
required: true,
},
healthConditions: {
type: String,
},
recentIllnessOrInjuryDetails: {
type: String,
},
drivesSemiTruckOverRoad: {
type: Boolean,
required: true,
},
isUsCitizen: {
type: Boolean,
required: true,
},
referralSource: {
type: String,
},
doctors: {
type: Array,
},
employer: {
type: Object,
},
monthlyHouseholdExpenses: {
type: Number,
required: true,
},
ownerOperatorInfo: {
type: Object,
},
healthMetrics: {
type: Object,
},
healthGoals: {
type: Object,
},
devices: {
type: Array,
},
},
{ versionKey: false },
);

export default (mongoose.models
.EnrollmentForm as mongoose.Model<EnrollmentForm>) ||
mongoose.model<EnrollmentForm>("EnrollmentForm", EnrollmentFormSchema);
37 changes: 37 additions & 0 deletions src/server/models/ProgramEnrollment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import mongoose, { Schema } from "mongoose";

import { ProgramEnrollment } from "@/types";

const ProgramEnrollmentSchema = new Schema<ProgramEnrollment>(
{
status: {
type: String,
required: true,
},
program: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
enrollmentForm: {
type: Schema.Types.ObjectId,
ref: "EnrollmentForm",
required: true,
},
dateEnrolled: {
type: String,
required: true,
},
},
{ versionKey: false },
);

export default (mongoose.models
.ProgramEnrollment as mongoose.Model<ProgramEnrollment>) ||
mongoose.model<ProgramEnrollment>(
"ProgramEnrollment",
ProgramEnrollmentSchema,
);
3 changes: 2 additions & 1 deletion src/server/models/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@ const UserSchema = new Schema<User>(
{ versionKey: false },
);

export default mongoose.models.User || mongoose.model<User>("User", UserSchema);
export default (mongoose.models.User as mongoose.Model<User>) ||
mongoose.model<User>("User", UserSchema);
2 changes: 2 additions & 0 deletions src/server/models/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export { default as EnrollmentFormModel } from "@/server/models/EnrollmentForm";
export { default as ProgramEnrollmentModel } from "@/server/models/ProgramEnrollment";
export { default as UserModel } from "@/server/models/User";
6 changes: 6 additions & 0 deletions src/types/Program.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export type Program =
| "Healthy Habits For The Long Haul"
| "Diabetes Prevention"
| "Rigs without Cigs"
| "Vaccine Voucher"
| "GPS (Get Preventative Screenings";
10 changes: 10 additions & 0 deletions src/types/ProgramEnrollment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { EnrollmentForm, Program } from "@/types";

export type ProgramEnrollment = {
_id?: string;
status: "pending" | "accepted" | "rejected";
program: Program;
email: string;
enrollmentForm: EnrollmentForm;
dateEnrolled: string;
};
2 changes: 2 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export * from "@/types/ApiResponse";
export * from "@/types/EnrollmentForm";
export * from "@/types/Program";
export * from "@/types/ProgramEnrollment";
export * from "@/types/User";
19 changes: 19 additions & 0 deletions src/utils/authenticateServerFunction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ApiResponse } from "@/types";
import apiErrors from "@/utils/constants/apiErrors";
import getUserSession from "@/utils/getUserSession";

export default async function authenticateServerFunction(
role?: "admin" | "client",
): Promise<ApiResponse<null>> {
const session = await getUserSession();

if (!session) {
return { success: false, error: apiErrors.unauthorized };
}

if (role && session.user.role !== role) {
return { success: false, error: apiErrors.unauthorized };
}

return { success: true, data: null };
}
5 changes: 5 additions & 0 deletions src/utils/constants/apiErrors.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const apiErrors = {
unauthorized: "You must be logged in to access this resource",
mongoose: {
CastError: "Error casting value",
DivergentArrayError: "You modified an array in the middle of a save.",
Expand All @@ -18,6 +19,10 @@ const apiErrors = {
userNotFound: "User not found",
userAlreadyExists: "User already exists",
},
programEnrollment: {
programEnrollmentNotFound: "Program enrollment not found",
programEnrollmentAlreadyExists: "Program enrollment already exists",
},
};

export default apiErrors;

0 comments on commit 8b81c59

Please sign in to comment.