Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Models and skills route #3

Merged
merged 40 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
b6f2bda
resume model blank
jackgarritano Feb 15, 2024
4c073ac
adds resume model
jackgarritano Feb 15, 2024
51290a7
Added models
seancrich11 Feb 15, 2024
0a80768
Added models with formatting
seancrich11 Feb 15, 2024
5987f30
Added Model variables
seancrich11 Feb 15, 2024
1da7113
got rid of IDs
seancrich11 Feb 15, 2024
acbb30c
adds folder model
jackgarritano Feb 15, 2024
6099c95
Merge branch 'sr-jg-models' of https://github.com/SprintCV-S24/backen…
seancrich11 Feb 15, 2024
b002ea9
Merge branch 'sr-jg-models' of https://github.com/SprintCV-S24/backen…
seancrich11 Feb 15, 2024
2b02313
skills controller and router
seancrich11 Feb 15, 2024
10c699f
fixes skills router
jackgarritano Feb 15, 2024
ecaa947
updates models to make them more structured
jackgarritano Feb 24, 2024
5b20413
adds userid field to models
jackgarritano Feb 24, 2024
d73c072
adds itemName field to models
jackgarritano Feb 24, 2024
942ed84
adds section heading model
jackgarritano Feb 24, 2024
a1e4fbd
changed userId field to user for compatibility with verifyToken middl…
jackgarritano Feb 24, 2024
fbd9589
adds activity post route
jackgarritano Feb 25, 2024
b86aed9
updates skills route to avoid duplicates
jackgarritano Feb 25, 2024
6b42b5c
adds controllers and modifies education model
jackgarritano Feb 25, 2024
c2fd3d0
adds test for activities controller functions
jackgarritano Feb 25, 2024
386d27e
updates activities controller
jackgarritano Feb 25, 2024
c82bd61
adds tests
jackgarritano Feb 25, 2024
3393640
implements all activities controller functions and their tests
jackgarritano Feb 28, 2024
1f314f2
fully implements activities backend
jackgarritano Feb 28, 2024
047593b
comments activities code
jackgarritano Feb 28, 2024
6db55ac
implements part of skills
jackgarritano Feb 28, 2024
52513e3
implements education controller
jackgarritano Feb 28, 2024
efdcdb3
implements education router
jackgarritano Feb 28, 2024
b7d1fe3
adds education tests
jackgarritano Feb 28, 2024
3b30693
updates tests
jackgarritano Feb 28, 2024
1e2adf2
adds education to root router
jackgarritano Feb 28, 2024
e6565b8
fixes checkDuplicates to work with update controllers
jackgarritano Feb 28, 2024
6def3d4
Merge
seancrich11 Feb 29, 2024
aa800dc
Trying to merge
seancrich11 Feb 29, 2024
838ebbb
Added routers, controllers and tests for the rest of the resume items
seancrich11 Mar 1, 2024
293275d
Fix root.router
seancrich11 Mar 1, 2024
bc25cf1
adjusts project model
jackgarritano Mar 2, 2024
b73a348
implements resume controller, router, test, and correct itemId list u…
jackgarritano Mar 3, 2024
d08e989
implements section heading controller, router, and tests
jackgarritano Mar 3, 2024
a3073b0
adds section heading to root router
jackgarritano Mar 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
472 changes: 472 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"scripts": {
"start": "nodemon src/index.ts",
"build": "tsc",
"test": "vitest",
"test": "vitest run",
"lint": "eslint --ext .ts . --fix",
"typecheck": "tsc --noEmit"
},
Expand Down Expand Up @@ -35,6 +35,7 @@
"eslint-plugin-n": "^16.1.0",
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-promise": "^6.1.1",
"mongodb-memory-server": "^9.1.6",
"nodemon": "^3.0.1",
"prettier": "^3.0.3",
"ts-node": "^10.9.1",
Expand Down
1 change: 0 additions & 1 deletion src/controllers/.gitkeep

This file was deleted.

148 changes: 148 additions & 0 deletions src/controllers/activities.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import {
ActivitiesModel,
type ActivitiesType,
} from "../models/activities.model";
import { ResumeModel } from "../models/resume.model";
import mongoose from "mongoose";
import { HttpError, HttpStatus, checkMongooseErrors } from "../utils/errors";
import { checkDuplicateItemName } from "../utils/checkDuplicates";

export const createActivity = async (activitiesFields: ActivitiesType) => {
try {
if (await checkDuplicateItemName(activitiesFields.itemName)) {
throw new HttpError(HttpStatus.BAD_REQUEST, "Duplicate item name");
}

const newActivity = new ActivitiesModel(activitiesFields);
await newActivity.save();
return newActivity;
} catch (err: unknown) {
if (err instanceof HttpError) {
throw err;
}

checkMongooseErrors(err);

throw new HttpError(
HttpStatus.INTERNAL_SERVER_ERROR,
"Activity creation failed",
{ cause: err },
);
}
};

export const getAllActivities = async (user: string) => {
try {
const activities = await ActivitiesModel.find({ user: user });
return activities;
} catch (err: unknown) {
//rethrow any errors as HttpErrors
if (err instanceof HttpError) {
throw err;
}
//checks if mongoose threw and will rethrow with appropriate status code and message
checkMongooseErrors(err);

throw new HttpError(
HttpStatus.INTERNAL_SERVER_ERROR,
"Activities retrieval failed",
{ cause: err },
);
}
};

export const getActivityById = async (user: string, activityId: string) => {
try {
const activity = await ActivitiesModel.findOne({
user: user,
_id: activityId,
});
return activity;
} catch (err: unknown) {
//rethrow any errors as HttpErrors
if (err instanceof HttpError) {
throw err;
}
//checks if mongoose threw and will rethrow with appropriate status code and message
checkMongooseErrors(err);

throw new HttpError(
HttpStatus.INTERNAL_SERVER_ERROR,
"Activity retrieval failed",
{ cause: err },
);
}
};

export const updateActivity = async (
user: string,
activityId: string,
activitiesFields: ActivitiesType,
) => {
try {
if (!activityId) {
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Missing activity ID for update",
);
}

if (await checkDuplicateItemName(activitiesFields.itemName, activityId)) {
throw new HttpError(HttpStatus.BAD_REQUEST, "Duplicate item name");
}

const updatedActivity = await ActivitiesModel.findOneAndUpdate(
{ _id: activityId, user: user }, // Query to match the document by _id and user
{ $set: activitiesFields }, // Update operation
{ new: true, runValidators: true }, // Options: return the updated document and run schema validators
);
return updatedActivity;
} catch (err: unknown) {
//rethrow any errors as HttpErrors
if (err instanceof HttpError) {
throw err;
}
//checks if mongoose threw and will rethrow with appropriate status code and message
checkMongooseErrors(err);

throw new HttpError(
HttpStatus.INTERNAL_SERVER_ERROR,
"Activity update failed",
{ cause: err },
);
}
};

export const deleteActivity = async (user: string, activityId: string) => {
try {
await ResumeModel.updateMany(
{ itemIds: new mongoose.Types.ObjectId(activityId) },
{ $pull: { itemIds: new mongoose.Types.ObjectId(activityId) } }
);

const deletedActivity = await ActivitiesModel.findOneAndDelete({
_id: activityId,
user: user,
});
if (!deletedActivity) {
throw new HttpError(
HttpStatus.NOT_FOUND,
"Activity not found or already deleted",
);
}
return { message: "Activity deleted successfully" };
} catch (err: unknown) {
//rethrow any errors as HttpErrors
if (err instanceof HttpError) {
throw err;
}
//checks if mongoose threw and will rethrow with appropriate status code and message
checkMongooseErrors(err);

throw new HttpError(
HttpStatus.INTERNAL_SERVER_ERROR,
"Activity deletion failed",
{ cause: err },
);
}
};
145 changes: 145 additions & 0 deletions src/controllers/education.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import { EducationModel, type EducationType } from "../models/education.model";
import { ResumeModel } from "../models/resume.model";
import mongoose from "mongoose";
import { HttpError, HttpStatus, checkMongooseErrors } from "../utils/errors";
import { checkDuplicateItemName } from "../utils/checkDuplicates";

export const createEducation = async (educationFields: EducationType) => {
try {
if (await checkDuplicateItemName(educationFields.itemName)) {
throw new HttpError(HttpStatus.BAD_REQUEST, "Duplicate item name");
}

const newEducation = new EducationModel(educationFields);
await newEducation.save();
return newEducation;
} catch (err: unknown) {
if (err instanceof HttpError) {
throw err;
}

checkMongooseErrors(err);

throw new HttpError(
HttpStatus.INTERNAL_SERVER_ERROR,
"Education creation failed",
{ cause: err },
);
}
};

export const getAllEducation = async (user: string) => {
try {
const education = await EducationModel.find({ user: user });
return education;
} catch (err: unknown) {
//rethrow any errors as HttpErrors
if (err instanceof HttpError) {
throw err;
}
//checks if mongoose threw and will rethrow with appropriate status code and message
checkMongooseErrors(err);

throw new HttpError(
HttpStatus.INTERNAL_SERVER_ERROR,
"Education retrieval failed",
{ cause: err },
);
}
};

export const getEducationById = async (user: string, educationId: string) => {
try {
const education = await EducationModel.findOne({
user: user,
_id: educationId,
});
return education;
} catch (err: unknown) {
//rethrow any errors as HttpErrors
if (err instanceof HttpError) {
throw err;
}
//checks if mongoose threw and will rethrow with appropriate status code and message
checkMongooseErrors(err);

throw new HttpError(
HttpStatus.INTERNAL_SERVER_ERROR,
"Education retrieval failed",
{ cause: err },
);
}
};

export const updateEducation = async (
user: string,
educationId: string,
educationFields: EducationType,
) => {
try {
if (!educationId) {
throw new HttpError(
HttpStatus.BAD_REQUEST,
"Missing education ID for update",
);
}

if (await checkDuplicateItemName(educationFields.itemName, educationId)) {
throw new HttpError(HttpStatus.BAD_REQUEST, "Duplicate item name");
}

const updatedEducation = await EducationModel.findOneAndUpdate(
{ _id: educationId, user: user }, // Query to match the document by _id and user
{ $set: educationFields }, // Update operation
{ new: true, runValidators: true }, // Options: return the updated document and run schema validators
);
return updatedEducation;
} catch (err: unknown) {
//rethrow any errors as HttpErrors
if (err instanceof HttpError) {
throw err;
}
//checks if mongoose threw and will rethrow with appropriate status code and message
checkMongooseErrors(err);

throw new HttpError(
HttpStatus.INTERNAL_SERVER_ERROR,
"Education update failed",
{ cause: err },
);
}
};

export const deleteEducation = async (user: string, educationId: string) => {
try {
await ResumeModel.updateMany(
{ itemIds: new mongoose.Types.ObjectId(educationId) },
{ $pull: { itemIds: new mongoose.Types.ObjectId(educationId) } }
);

const deletedEducation = await EducationModel.findOneAndDelete({
_id: educationId,
user: user,
});
if (!deletedEducation) {
throw new HttpError(
HttpStatus.NOT_FOUND,
"Education not found or already deleted",
);
}
return { message: "Education deleted successfully" };
} catch (err: unknown) {
//rethrow any errors as HttpErrors
if (err instanceof HttpError) {
throw err;
}
//checks if mongoose threw and will rethrow with appropriate status code and message
checkMongooseErrors(err);

throw new HttpError(
HttpStatus.INTERNAL_SERVER_ERROR,
"Education deletion failed",
{ cause: err },
);
}
};
Loading
Loading