diff --git a/backend/src/controllers/jobController.ts b/backend/src/controllers/jobController.ts index b2af5eb..5c7ab94 100644 --- a/backend/src/controllers/jobController.ts +++ b/backend/src/controllers/jobController.ts @@ -77,3 +77,20 @@ export const updatePublishStatus = async (req: Request, res: Response) => { status: 'success', }); }; + +export const deleteJob = async (req: Request, res: Response) => { + const { companyId, jobId } = req.params; + const deleteJob = await jobServices.deleteJob(companyId, jobId); + + if (!deleteJob) { + res + .status(404) + .json({ message: 'No job found with this id', status: 'fail' }); + return; + } + + res.status(200).json({ + message: 'Job deletion successful', + status: 'success', + }); +}; diff --git a/backend/src/models/job.ts b/backend/src/models/job.ts index 2f3bd92..e815c3f 100644 --- a/backend/src/models/job.ts +++ b/backend/src/models/job.ts @@ -1,6 +1,7 @@ import { model, Schema } from 'mongoose'; import type { Job } from '@/schemas'; import { EmploymentType, WorkPlaceType, JobStatus } from '@/types/index'; +import softDeletePlugin from '@/plugins/softDelete.plugin'; const JobSchema = new Schema( { @@ -22,9 +23,10 @@ const JobSchema = new Schema( vacancy: { type: Number, required: true }, tags: [{ type: String }], status: { type: String, enum: JobStatus, default: 'draft' }, - deletedAt: { type: Date, default: null }, }, { timestamps: true, virtuals: true }, ); +JobSchema.plugin(softDeletePlugin); + export const JobModel = model('Job', JobSchema); diff --git a/backend/src/plugins/softDelete.plugin.ts b/backend/src/plugins/softDelete.plugin.ts new file mode 100644 index 0000000..0525258 --- /dev/null +++ b/backend/src/plugins/softDelete.plugin.ts @@ -0,0 +1,17 @@ +import { Schema } from 'mongoose'; + +export default function softDeletePlugin(schema: Schema) { + schema.add({ + deletedAt: { type: Date, default: null }, + }); + + schema.methods.softDelete = async function () { + this.deletedAt = new Date(); + await this.save(); + }; + + schema.methods.restore = async function () { + this.deletedAt = null; + await this.save(); + }; +} diff --git a/backend/src/routes/jobRouter.ts b/backend/src/routes/jobRouter.ts index c8029b6..fbf48b6 100644 --- a/backend/src/routes/jobRouter.ts +++ b/backend/src/routes/jobRouter.ts @@ -26,5 +26,6 @@ router.patch( validatePayload(UpdateJobStatusSchema), jobController.updatePublishStatus, ); +router.delete('/:companyId/jobs/:jobId', jobController.deleteJob); export default router; diff --git a/backend/src/services/jobServices.ts b/backend/src/services/jobServices.ts index bc4703f..7dccdea 100644 --- a/backend/src/services/jobServices.ts +++ b/backend/src/services/jobServices.ts @@ -69,3 +69,16 @@ export const updateJobStatus = async ( return updateJobStatus; }; + +export const deleteJob = async (companyId: string, jobId: string) => { + const findJob = await JobModel.findOne({ company: companyId, _id: jobId }); + + if (!findJob || findJob?.deletedAt) { + return false; + } + + // @ts-expect-error: softDelete is added by the Mongoose plugin, not in the type definition + await findJob.softDelete(); + + return true; +};