Skip to content

Commit

Permalink
feat: add job validation using zod
Browse files Browse the repository at this point in the history
  • Loading branch information
hariscs committed Feb 25, 2024
1 parent c8d972b commit fdffe0e
Show file tree
Hide file tree
Showing 10 changed files with 63 additions and 23 deletions.
2 changes: 1 addition & 1 deletion apps/api/config/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { log } from '@repo/logger'
export const connect_db = async () => {
try {
const conn = await mongoose.connect(process.env.MONGO_URI as string)
log(`MongoDB Connected here: ${conn.connection.name}`)
log(`MongoDB Connected: ${conn.connection.name}`)
} catch (error) {
log(`Error: ${error}`)
process.exit(1)
Expand Down
3 changes: 2 additions & 1 deletion apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
"cors": "^2.8.5",
"express": "^4.18.2",
"mongoose": "^8.1.1",
"morgan": "^1.10.0"
"morgan": "^1.10.0",
"zod": "^3.22.4"
},
"devDependencies": {
"@repo/eslint-config": "*",
Expand Down
22 changes: 12 additions & 10 deletions apps/api/src/controllers/job_controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Request, Response } from 'express'
import { JOB_SCHEMA } from '@models/job_model'
import { JOB_SCHEMA } from '@/models/job_model'
import { isValidObjectId } from 'mongoose'
import { log } from 'console'

//* @desc Get all jobs
//* route GET /api/jobs
Expand All @@ -11,7 +12,7 @@ export async function get_jobs(_: Request, res: Response): Promise<void> {
const jobs = await JOB_SCHEMA.find({}).sort({ createdAt: -1 })
res.status(200).json({ jobs })
} catch (error) {
console.error('Error fetching jobs:', error)
log('Error fetching jobs:', error)
res.status(500).json({ error: 'Internal server error' })
}
}
Expand All @@ -35,7 +36,7 @@ export async function get_job(req: Request, res: Response): Promise<void> {
}
res.status(200).json(job)
} catch (error) {
console.error('Error fetching job:', error)
log('Error fetching job:', error)
res.status(500).json({ error: 'Internal server error' })
}
}
Expand All @@ -45,12 +46,13 @@ export async function get_job(req: Request, res: Response): Promise<void> {
//! @access Private
export async function post_job(req: Request, res: Response): Promise<void> {
try {
// validate job data
const job_data = req.body
//* post job
const jobData = req.body
const newJob = await JOB_SCHEMA.create(jobData)
res.status(201).json(newJob)
const new_job = await JOB_SCHEMA.create(job_data)
res.status(201).json(new_job)
} catch (error) {
console.error('Error posting job:', error)
log('Error posting job:', error)
res.status(500).json({ error: 'Internal server error' })
}
}
Expand All @@ -73,10 +75,10 @@ export async function delete_job(req: Request, res: Response): Promise<void> {
return
}
//* delete job
const deleted_job = await JOB_SCHEMA.findByIdAndDelete(id)
await JOB_SCHEMA.findByIdAndDelete(id)
res.status(200).json({ message: 'Job deleted successfully' })
} catch (error) {
console.error('Error deleting job:', error)
log('Error deleting job:', error)
res.status(500).json({ error: 'Internal server error' })
}
}
Expand Down Expand Up @@ -104,7 +106,7 @@ export async function update_job(req: Request, res: Response): Promise<void> {
})
res.status(200).json(updated_job)
} catch (error) {
console.error('Error updating job:', error)
log('Error updating job:', error)
res.status(500).json({ error: 'Internal server error' })
}
}
2 changes: 1 addition & 1 deletion apps/api/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { log } from '@repo/logger'
import { createServer } from './server'
import job_route from '@routes/job_route'
import job_route from '@/routes/job_route'

const port = process.env.PORT || 5001
const server = createServer()
Expand Down
18 changes: 18 additions & 0 deletions apps/api/src/middleware/job_validation_middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Request, Response, NextFunction } from 'express'
import { z } from 'zod'

export function validate_job_data(schema: z.AnyZodObject) {
return (req: Request, res: Response, next: NextFunction) => {
try {
schema.parse(req.body)
next()
} catch (error) {
if (error instanceof z.ZodError) {
const error_messages = error.errors.map((issue) => ({
message: `${issue.path.join('.')} - ${issue.message}`,
}))
res.status(400).json({ error: 'Invalid data', error_messages })
}
}
}
}
8 changes: 5 additions & 3 deletions apps/api/src/routes/job_route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import {
get_jobs,
post_job,
update_job,
} from '@controllers/job_controller'
} from '@/controllers/job_controller'
import { validate_job_data } from '@/middleware/job_validation_middleware'
import { JOB_VALIDATION_SCHEMA } from '@/validations/job_validation'

const router = express.Router()

Expand All @@ -19,14 +21,14 @@ router.get('/:id', get_job)

//* @desc Post job
//! @access Private
router.post('/', post_job)
router.post('/', validate_job_data(JOB_VALIDATION_SCHEMA), post_job)

//* @desc Delete job
//! @access Private
router.delete('/:id', delete_job)

//* @desc Update job
//! @access Private
router.patch('/:id', update_job)
router.patch('/:id', validate_job_data(JOB_VALIDATION_SCHEMA), update_job)

export default router
2 changes: 1 addition & 1 deletion apps/api/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import express, { type Express } from 'express'
import morgan from 'morgan'
import cors from 'cors'
import { config } from 'dotenv'
import { connect_db } from '@config/db'
import { connect_db } from 'config/db'

config()
connect_db()
Expand Down
13 changes: 13 additions & 0 deletions apps/api/src/validations/job_validation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { z } from 'zod'

export const JOB_VALIDATION_SCHEMA = z.object({
company: z.string(),
logo: z.string().optional(),
position: z.string(),
role: z.string(),
level: z.string(),
contract: z.string(),
location: z.string(),
languages: z.array(z.string()),
tools: z.array(z.string()),
})
5 changes: 0 additions & 5 deletions apps/api/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@lib/*": ["src/lib/*"],
"@controllers/*": ["src/controllers/*"],
"@models/*": ["src/models/*"],
"@config/*": ["config/*"],
"@routes/*": ["src/routes/*"],
},
},
"exclude": ["node_modules"],
Expand Down
11 changes: 10 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit fdffe0e

Please sign in to comment.