From be17661467ee2b0f58777482a9f71e8b98d1b598 Mon Sep 17 00:00:00 2001 From: daxantz Date: Mon, 29 Sep 2025 19:04:34 -0400 Subject: [PATCH 01/10] migrated prisma schema --- .../20250919221914_create_test_table/migration.sql | 8 -------- .../migration.sql | 4 ++++ prisma/schema.prisma | 9 ++++----- 3 files changed, 8 insertions(+), 13 deletions(-) delete mode 100644 prisma/migrations/20250919221914_create_test_table/migration.sql rename prisma/migrations/{20250923223643_migrate_valet_schemas_to_test_db => 20250929222515_init}/migration.sql (89%) diff --git a/prisma/migrations/20250919221914_create_test_table/migration.sql b/prisma/migrations/20250919221914_create_test_table/migration.sql deleted file mode 100644 index 3c74980..0000000 --- a/prisma/migrations/20250919221914_create_test_table/migration.sql +++ /dev/null @@ -1,8 +0,0 @@ --- CreateTable -CREATE TABLE "public"."Test" ( - "id" SERIAL NOT NULL, - "name" TEXT NOT NULL, - "value" INTEGER NOT NULL, - - CONSTRAINT "Test_pkey" PRIMARY KEY ("id") -); diff --git a/prisma/migrations/20250923223643_migrate_valet_schemas_to_test_db/migration.sql b/prisma/migrations/20250929222515_init/migration.sql similarity index 89% rename from prisma/migrations/20250923223643_migrate_valet_schemas_to_test_db/migration.sql rename to prisma/migrations/20250929222515_init/migration.sql index 324f8f5..9b59e77 100644 --- a/prisma/migrations/20250923223643_migrate_valet_schemas_to_test_db/migration.sql +++ b/prisma/migrations/20250929222515_init/migration.sql @@ -23,6 +23,7 @@ CREATE TABLE "public"."Employee" ( "id" SERIAL NOT NULL, "name" TEXT NOT NULL, "pin" TEXT NOT NULL, + "locationId" INTEGER NOT NULL, CONSTRAINT "Employee_pkey" PRIMARY KEY ("id") ); @@ -56,6 +57,9 @@ CREATE UNIQUE INDEX "Car_ticket_key" ON "public"."Car"("ticket"); -- AddForeignKey ALTER TABLE "public"."Entrance" ADD CONSTRAINT "Entrance_locationId_fkey" FOREIGN KEY ("locationId") REFERENCES "public"."Location"("id") ON DELETE RESTRICT ON UPDATE CASCADE; +-- AddForeignKey +ALTER TABLE "public"."Employee" ADD CONSTRAINT "Employee_locationId_fkey" FOREIGN KEY ("locationId") REFERENCES "public"."Location"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + -- AddForeignKey ALTER TABLE "public"."Car" ADD CONSTRAINT "Car_parkedById_fkey" FOREIGN KEY ("parkedById") REFERENCES "public"."Employee"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 3bac308..8431a44 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -22,16 +22,13 @@ enum CarStatus { } -model Test { - id Int @id @default(autoincrement()) - name String - value Int -} + model Location { id Int @id @default(autoincrement()) name String entrances Entrance[] + employees Employee[] } model Entrance { @@ -45,6 +42,8 @@ model Employee{ id Int @id @default(autoincrement()) name String pin String @unique + location Location @relation(fields: [locationId], references: [id]) + locationId Int ParkedCars Car[] @relation("ParkedCars") CheckedOutCars Car[] @relation("CheckedOutCars") } From 5e97681f378c25f916b0d58679688ac0271b1b07 Mon Sep 17 00:00:00 2001 From: daxantz Date: Tue, 30 Sep 2025 13:35:10 -0400 Subject: [PATCH 02/10] create new prisma migration to fix db schema drift --- .../{20250929222515_init => 20250930021027_init}/migration.sql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename prisma/migrations/{20250929222515_init => 20250930021027_init}/migration.sql (100%) diff --git a/prisma/migrations/20250929222515_init/migration.sql b/prisma/migrations/20250930021027_init/migration.sql similarity index 100% rename from prisma/migrations/20250929222515_init/migration.sql rename to prisma/migrations/20250930021027_init/migration.sql From 027ef95f2f0cc97fc3f21a7241ef8d081587dc66 Mon Sep 17 00:00:00 2001 From: daxantz Date: Tue, 30 Sep 2025 13:39:28 -0400 Subject: [PATCH 03/10] create POST endpoint for creating employees with test --- __tests__/employee.test.ts | 31 ++++++++++++++++++++++++++++ src/resources/employee/controller.ts | 27 ++++++++++++++++++++++++ src/resources/employee/routes.ts | 12 +++++++++++ 3 files changed, 70 insertions(+) create mode 100644 __tests__/employee.test.ts create mode 100644 src/resources/employee/controller.ts create mode 100644 src/resources/employee/routes.ts diff --git a/__tests__/employee.test.ts b/__tests__/employee.test.ts new file mode 100644 index 0000000..bc99d92 --- /dev/null +++ b/__tests__/employee.test.ts @@ -0,0 +1,31 @@ +import request from 'supertest' +import app from '../src/app' +import prisma from '../src/services/prisma' + +beforeEach(async () => { + // Clear tables with foreign keys first + await prisma.car.deleteMany() // Since Car relates to Employee + await prisma.employee.deleteMany() + await prisma.entrance.deleteMany() + + // Then clear tables without dependencies + await prisma.location.deleteMany() +}) + +test('POST /v1/location/:locationId/employee creates a new employee', async () => { + // First, create a location to associate with the employee + const location = await prisma.location.create({ data: { name: 'Test Location - employee' } }) + + const res = await request(app).post(`/v1/location/${location.id}/employee`).send({ name: 'John Doe', pin: '1234' }) + + expect(res.status).toBe(201) + expect(res.body).toHaveProperty('message', 'Employee created') + expect(res.body.employee).toHaveProperty('name', 'John Doe') + expect(res.body.employee).toHaveProperty('pin', '1234') + expect(res.body.employee).toHaveProperty('locationId', location.id) + + // Verify it exists in the DB + const employeeInDb = await prisma.employee.findFirst({ where: { pin: '1234' } }) + expect(employeeInDb).not.toBeNull() + expect(employeeInDb?.locationId).toBe(location.id) +}) diff --git a/src/resources/employee/controller.ts b/src/resources/employee/controller.ts new file mode 100644 index 0000000..7d4bc9a --- /dev/null +++ b/src/resources/employee/controller.ts @@ -0,0 +1,27 @@ +import { Request, Response, NextFunction } from 'express' +import { createEmployee } from '../../services/employeeService' +import prisma from '../../services/prisma' +const makeEmployee = async (req: Request, res: Response, next: NextFunction) => { + try { + const { name, pin } = req.body + const { locationId } = req.params + + if (!name || !pin) { + return res.status(400).json({ error: 'Name and Pin are required' }) + } + + // Check if the PIN already exists + const existingEmployee = await prisma.employee.findUnique({ where: { pin } }) + if (existingEmployee) { + return res.status(409).json({ error: 'An employee with this PIN already exists' }) + } + + const newEmployee = await createEmployee(name, pin, parseInt(locationId)) + + res.status(201).json({ message: 'Employee created', employee: newEmployee }) + } catch (error) { + next(error) + } +} + +export default { makeEmployee } diff --git a/src/resources/employee/routes.ts b/src/resources/employee/routes.ts new file mode 100644 index 0000000..963cc85 --- /dev/null +++ b/src/resources/employee/routes.ts @@ -0,0 +1,12 @@ +import { Router } from 'express' +import employeeController from './controller' + +const router = Router({ mergeParams: true }) + +// define routes +router.post('/', employeeController.makeEmployee) +// router.delete('/:id', entranceController.deleteEntrance) +// router.get('/', entranceController.getEntrancesByLocation) +// router.get('/:id', entranceController.getSingleEntrance) +// router.put('/:id', entranceController.updateEntrance) +export default router From 86294ff792567ac7b5ed16fc9e3002ed13e07fb5 Mon Sep 17 00:00:00 2001 From: daxantz Date: Tue, 30 Sep 2025 13:40:04 -0400 Subject: [PATCH 04/10] create service functions for employee model actions --- src/services/employeeService.ts | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/services/employeeService.ts diff --git a/src/services/employeeService.ts b/src/services/employeeService.ts new file mode 100644 index 0000000..9535d4b --- /dev/null +++ b/src/services/employeeService.ts @@ -0,0 +1,46 @@ +// src/services/employeeService.ts +import prisma from './prisma' +import { Employee } from '@prisma/client' + +// Create a new employee for a location +export const createEmployee = async (name: string, pin: string, locationId: number) => { + try { + const employee = await prisma.employee.create({ + data: { name, pin, locationId }, + }) + return employee + } catch (err) { + console.error('Error in createEmployee:', err) + throw err + } +} + +// Get a single employee by ID +export const getEmployeeById = async (id: number): Promise => { + try { + return await prisma.employee.findUnique({ where: { id } }) + } catch (err) { + console.error('Error in getEmployeeById:', err) + throw err + } +} + +// Delete an employee +export const deleteEmployee = async (id: number): Promise => { + try { + return await prisma.employee.delete({ where: { id } }) + } catch (err) { + console.error('Error in deleteEmployee:', err) + throw err + } +} + +// Get all employees for a specific location +export const getEmployeesByLocation = async (locationId: number): Promise => { + try { + return await prisma.employee.findMany({ where: { locationId } }) + } catch (err) { + console.error('Error in getEmployeesByLocation:', err) + throw err + } +} From 6330dbf1fa6d2ad4151d765b8193302183ae232e Mon Sep 17 00:00:00 2001 From: daxantz Date: Tue, 30 Sep 2025 13:41:01 -0400 Subject: [PATCH 05/10] create nested route for employees under locations --- src/resources/locations/routes.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/resources/locations/routes.ts b/src/resources/locations/routes.ts index 5ad36ad..1893b73 100644 --- a/src/resources/locations/routes.ts +++ b/src/resources/locations/routes.ts @@ -1,6 +1,7 @@ import { Router } from 'express' import locationController from './controller' import entranceRouter from '../entrances/routes' +import employeeRouter from '../employee/routes' const router = Router() // define routes @@ -10,5 +11,7 @@ router.get('/', locationController.getLocations) router.get('/:id', locationController.getSingleLocation) router.put('/:id', locationController.updateLocation) +router.use('/:locationId/employee', employeeRouter) router.use('/:locationId/entrance', entranceRouter) + export default router From e4c988f01cab480396a49ee88f314f7564434eef Mon Sep 17 00:00:00 2001 From: daxantz Date: Tue, 30 Sep 2025 13:41:30 -0400 Subject: [PATCH 06/10] remove before each and add note to readme --- README.md | 8 ++++++++ __tests__/entrance.test.ts | 8 ++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b16db57..24521f3 100644 --- a/README.md +++ b/README.md @@ -122,3 +122,11 @@ Create Express TypeScript Starter was created by [Wubshet Zeleke](https://linked ## License Create Express TypeScript Starter is licensed under the MIT License. + + + +## NOTES + +- this appication is an employee facing app/system so i think im going to make the decision to store pins as they are and not hashing them because +there isnt any private data or information that could be used from the app. Creating an employee is simply to have their name in the app in order +to track whos parking which ever cars \ No newline at end of file diff --git a/__tests__/entrance.test.ts b/__tests__/entrance.test.ts index 97969e4..738327e 100644 --- a/__tests__/entrance.test.ts +++ b/__tests__/entrance.test.ts @@ -2,10 +2,10 @@ import request from 'supertest' import app from '../src/app' import prisma from '../src/services/prisma' -beforeEach(async () => { - await prisma.entrance.deleteMany() - await prisma.location.deleteMany() -}) +// beforeEach(async () => { +// await prisma.entrance.deleteMany() +// await prisma.location.deleteMany() +// }) test('POST /v1/location/:locationId/entrance creates a new entrance', async () => { // First, create a location to associate with the entrance From 5f901fd5c426bcec136663446668121301d12b33 Mon Sep 17 00:00:00 2001 From: daxantz Date: Tue, 30 Sep 2025 14:16:01 -0400 Subject: [PATCH 07/10] create GET endpoint to retrieve all employees for a location --- __tests__/employee.test.ts | 21 +++++++++++++++++++++ src/resources/employee/controller.ts | 16 +++++++++++++++- src/resources/employee/routes.ts | 2 +- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/__tests__/employee.test.ts b/__tests__/employee.test.ts index bc99d92..7b75881 100644 --- a/__tests__/employee.test.ts +++ b/__tests__/employee.test.ts @@ -1,6 +1,7 @@ import request from 'supertest' import app from '../src/app' import prisma from '../src/services/prisma' +import { Employee } from '@prisma/client' beforeEach(async () => { // Clear tables with foreign keys first @@ -29,3 +30,23 @@ test('POST /v1/location/:locationId/employee creates a new employee', async () = expect(employeeInDb).not.toBeNull() expect(employeeInDb?.locationId).toBe(location.id) }) + +test('GET /v1/location/:locationId/employee retrieves employees for a location', async () => { + // Create a location and employees + const location = await prisma.location.create({ data: { name: 'Test Location - get employees' } }) + await prisma.employee.createMany({ + data: [ + { name: 'Alice', pin: '1111', locationId: location.id }, + { name: 'Bob', pin: '2222', locationId: location.id }, + ], + }) + + const res = await request(app).get(`/v1/location/${location.id}/employee`) + + expect(res.status).toBe(200) + expect(res.body).toHaveProperty('message', `Retrieved all employees for location ${location.id}`) + expect(res.body.employees).toHaveLength(2) + const pins = res.body.employees.map((emp: Employee) => emp.pin) + expect(pins).toContain('1111') + expect(pins).toContain('2222') +}) diff --git a/src/resources/employee/controller.ts b/src/resources/employee/controller.ts index 7d4bc9a..9a48925 100644 --- a/src/resources/employee/controller.ts +++ b/src/resources/employee/controller.ts @@ -1,6 +1,7 @@ import { Request, Response, NextFunction } from 'express' import { createEmployee } from '../../services/employeeService' import prisma from '../../services/prisma' + const makeEmployee = async (req: Request, res: Response, next: NextFunction) => { try { const { name, pin } = req.body @@ -24,4 +25,17 @@ const makeEmployee = async (req: Request, res: Response, next: NextFunction) => } } -export default { makeEmployee } +const getEmployees = async (req: Request, res: Response, next: NextFunction) => { + try { + const { locationId } = req.params + if (!locationId) { + return res.status(400).json({ error: 'Location ID is required' }) + } + const employees = await prisma.employee.findMany({ where: { locationId: parseInt(locationId) } }) + res.status(200).json({ message: `Retrieved all employees for location ${locationId}`, employees }) + } catch (error) { + next(error) + } +} + +export default { makeEmployee, getEmployees } diff --git a/src/resources/employee/routes.ts b/src/resources/employee/routes.ts index 963cc85..b419b20 100644 --- a/src/resources/employee/routes.ts +++ b/src/resources/employee/routes.ts @@ -6,7 +6,7 @@ const router = Router({ mergeParams: true }) // define routes router.post('/', employeeController.makeEmployee) // router.delete('/:id', entranceController.deleteEntrance) -// router.get('/', entranceController.getEntrancesByLocation) +router.get('/', employeeController.getEmployees) // router.get('/:id', entranceController.getSingleEntrance) // router.put('/:id', entranceController.updateEntrance) export default router From 3dbfed9a9330f4963b1765bfab36838e92292d94 Mon Sep 17 00:00:00 2001 From: daxantz Date: Tue, 30 Sep 2025 14:52:11 -0400 Subject: [PATCH 08/10] create GET endpoint for retrieving single employee from a location --- __tests__/employee.test.ts | 16 ++++++++++++++++ src/resources/employee/controller.ts | 21 +++++++++++++++++++-- src/resources/employee/routes.ts | 2 +- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/__tests__/employee.test.ts b/__tests__/employee.test.ts index 7b75881..e9aa5e6 100644 --- a/__tests__/employee.test.ts +++ b/__tests__/employee.test.ts @@ -50,3 +50,19 @@ test('GET /v1/location/:locationId/employee retrieves employees for a location', expect(pins).toContain('1111') expect(pins).toContain('2222') }) + +test('GET /v1/location/:locationId/employee/:id retrieves a single employee', async () => { + // Create a location and an employee + const location = await prisma.location.create({ data: { name: 'Test Location - get single employee' } }) + const employee = await prisma.employee.create({ + data: { name: 'Charlie', pin: '3333', locationId: location.id }, + }) + + const res = await request(app).get(`/v1/location/${location.id}/employee/${employee.id}`) + + expect(res.status).toBe(200) + expect(res.body).toHaveProperty('message', `Retrieved employee ${employee.id}`) + expect(res.body.employee).toHaveProperty('name', 'Charlie') + expect(res.body.employee).toHaveProperty('pin', '3333') + expect(res.body.employee).toHaveProperty('locationId', location.id) +}) diff --git a/src/resources/employee/controller.ts b/src/resources/employee/controller.ts index 9a48925..d2e5f59 100644 --- a/src/resources/employee/controller.ts +++ b/src/resources/employee/controller.ts @@ -1,5 +1,5 @@ import { Request, Response, NextFunction } from 'express' -import { createEmployee } from '../../services/employeeService' +import { createEmployee, getEmployeeById } from '../../services/employeeService' import prisma from '../../services/prisma' const makeEmployee = async (req: Request, res: Response, next: NextFunction) => { @@ -38,4 +38,21 @@ const getEmployees = async (req: Request, res: Response, next: NextFunction) => } } -export default { makeEmployee, getEmployees } +const getSingleEmployee = async (req: Request, res: Response, next: NextFunction) => { + try { + const { employeeId } = req.params + if (!employeeId) { + return res.status(400).json({ error: 'Employee ID is required' }) + } + const employee = await getEmployeeById(parseInt(employeeId)) + if (!employee) { + return res.status(404).json({ error: 'Employee not found' }) + } + + res.status(200).json({ message: `Retrieved employee ${employeeId}`, employee }) + } catch (error) { + next(error) + } +} + +export default { makeEmployee, getEmployees, getSingleEmployee } diff --git a/src/resources/employee/routes.ts b/src/resources/employee/routes.ts index b419b20..e80c52e 100644 --- a/src/resources/employee/routes.ts +++ b/src/resources/employee/routes.ts @@ -7,6 +7,6 @@ const router = Router({ mergeParams: true }) router.post('/', employeeController.makeEmployee) // router.delete('/:id', entranceController.deleteEntrance) router.get('/', employeeController.getEmployees) -// router.get('/:id', entranceController.getSingleEntrance) +router.get('/:employeeId', employeeController.getSingleEmployee) // router.put('/:id', entranceController.updateEntrance) export default router From b6f1230a1053be31d36feca7587111c45e7a62ed Mon Sep 17 00:00:00 2001 From: daxantz Date: Tue, 30 Sep 2025 14:57:12 -0400 Subject: [PATCH 09/10] create DELETE endpoint to delete single employee from location --- __tests__/employee.test.ts | 18 ++++++++++++++++++ src/resources/employee/controller.ts | 20 ++++++++++++++++++-- src/resources/employee/routes.ts | 2 +- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/__tests__/employee.test.ts b/__tests__/employee.test.ts index e9aa5e6..96dfa42 100644 --- a/__tests__/employee.test.ts +++ b/__tests__/employee.test.ts @@ -66,3 +66,21 @@ test('GET /v1/location/:locationId/employee/:id retrieves a single employee', as expect(res.body.employee).toHaveProperty('pin', '3333') expect(res.body.employee).toHaveProperty('locationId', location.id) }) + +test('DELETE /v1/location/:locationId/employee/:id deletes an employee', async () => { + // Create a location and an employee + const location = await prisma.location.create({ data: { name: 'Test Location - delete employee' } }) + const employee = await prisma.employee.create({ + data: { name: 'Dave', pin: '4444', locationId: location.id }, + }) + + const res = await request(app).delete(`/v1/location/${location.id}/employee/${employee.id}`) + + expect(res.status).toBe(200) + expect(res.body).toHaveProperty('message', `Deleted employee ${employee.id}`) + expect(res.body.employee).toHaveProperty('id', employee.id) + + // Verify it's deleted from the DB + const employeeInDb = await prisma.employee.findUnique({ where: { id: employee.id } }) + expect(employeeInDb).toBeNull() +}) diff --git a/src/resources/employee/controller.ts b/src/resources/employee/controller.ts index d2e5f59..ded9d64 100644 --- a/src/resources/employee/controller.ts +++ b/src/resources/employee/controller.ts @@ -1,5 +1,5 @@ import { Request, Response, NextFunction } from 'express' -import { createEmployee, getEmployeeById } from '../../services/employeeService' +import { createEmployee, deleteEmployee, getEmployeeById } from '../../services/employeeService' import prisma from '../../services/prisma' const makeEmployee = async (req: Request, res: Response, next: NextFunction) => { @@ -55,4 +55,20 @@ const getSingleEmployee = async (req: Request, res: Response, next: NextFunction } } -export default { makeEmployee, getEmployees, getSingleEmployee } +const removeEmployee = async (req: Request, res: Response, next: NextFunction) => { + try { + const { employeeId } = req.params + if (!employeeId) { + return res.status(400).json({ error: 'Employee ID is required' }) + } + const deletedEmployee = await deleteEmployee(parseInt(employeeId)) + if (!deletedEmployee) { + return res.status(404).json({ error: 'Employee not found' }) + } + res.status(200).json({ message: `Deleted employee ${employeeId}`, employee: deletedEmployee }) + } catch (error) { + next(error) + } +} + +export default { makeEmployee, getEmployees, getSingleEmployee, removeEmployee } diff --git a/src/resources/employee/routes.ts b/src/resources/employee/routes.ts index e80c52e..bdcbbd1 100644 --- a/src/resources/employee/routes.ts +++ b/src/resources/employee/routes.ts @@ -5,7 +5,7 @@ const router = Router({ mergeParams: true }) // define routes router.post('/', employeeController.makeEmployee) -// router.delete('/:id', entranceController.deleteEntrance) +router.delete('/:employeeId', employeeController.removeEmployee) router.get('/', employeeController.getEmployees) router.get('/:employeeId', employeeController.getSingleEmployee) // router.put('/:id', entranceController.updateEntrance) From 3374c19f76246dfa4adf496d48c29c25f4695d99 Mon Sep 17 00:00:00 2001 From: daxantz Date: Tue, 30 Sep 2025 17:13:34 -0400 Subject: [PATCH 10/10] create PUT endpoint to update employee data --- __tests__/employee.test.ts | 23 ++++++++++++++++++ src/resources/employee/controller.ts | 35 +++++++++++++++++++++++++++- src/resources/employee/routes.ts | 2 +- 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/__tests__/employee.test.ts b/__tests__/employee.test.ts index 96dfa42..79f29e9 100644 --- a/__tests__/employee.test.ts +++ b/__tests__/employee.test.ts @@ -84,3 +84,26 @@ test('DELETE /v1/location/:locationId/employee/:id deletes an employee', async ( const employeeInDb = await prisma.employee.findUnique({ where: { id: employee.id } }) expect(employeeInDb).toBeNull() }) + +test('PUT /v1/location/:locationId/employee/:id updates an employee', async () => { + // Create a location and an employee + const location = await prisma.location.create({ data: { name: 'Test Location - update employee' } }) + const employee = await prisma.employee.create({ + data: { name: 'Eve', pin: '5555', locationId: location.id }, + }) + + const res = await request(app) + .put(`/v1/location/${location.id}/employee/${employee.id}`) + .send({ updatedName: 'Eve Updated', pin: '9999' }) + + expect(res.status).toBe(200) + expect(res.body).toHaveProperty('message', `Updated employee ${employee.id}`) + expect(res.body.employee).toHaveProperty('name', 'Eve Updated') + expect(res.body.employee).toHaveProperty('pin', '9999') + + // Verify the updates in the DB + const employeeInDb = await prisma.employee.findUnique({ where: { id: employee.id } }) + expect(employeeInDb).not.toBeNull() + expect(employeeInDb?.name).toBe('Eve Updated') + expect(employeeInDb?.pin).toBe('9999') +}) diff --git a/src/resources/employee/controller.ts b/src/resources/employee/controller.ts index ded9d64..5a435b1 100644 --- a/src/resources/employee/controller.ts +++ b/src/resources/employee/controller.ts @@ -71,4 +71,37 @@ const removeEmployee = async (req: Request, res: Response, next: NextFunction) = } } -export default { makeEmployee, getEmployees, getSingleEmployee, removeEmployee } +const updateEmployee = async (req: Request, res: Response, next: NextFunction) => { + try { + const { employeeId } = req.params + const { updatedName, pin } = req.body + + if (!employeeId) { + return res.status(400).json({ error: 'Employee ID is required' }) + } + + const existingEmployee = await getEmployeeById(parseInt(employeeId)) + if (!existingEmployee) { + return res.status(404).json({ error: 'Employee not found' }) + } + + // If pin is being updated, check for uniqueness + if (pin && pin !== existingEmployee.pin) { + const pinConflict = await prisma.employee.findUnique({ where: { pin } }) + if (pinConflict) { + return res.status(409).json({ error: 'An employee with this PIN already exists' }) + } + } + + const updatedEmployee = await prisma.employee.update({ + where: { id: parseInt(employeeId) }, + data: { name: updatedName || existingEmployee.name, pin: pin || existingEmployee.pin }, + }) + + res.status(200).json({ message: `Updated employee ${employeeId}`, employee: updatedEmployee }) + } catch (error) { + next(error) + } +} + +export default { makeEmployee, getEmployees, getSingleEmployee, removeEmployee, updateEmployee } diff --git a/src/resources/employee/routes.ts b/src/resources/employee/routes.ts index bdcbbd1..b35b687 100644 --- a/src/resources/employee/routes.ts +++ b/src/resources/employee/routes.ts @@ -8,5 +8,5 @@ router.post('/', employeeController.makeEmployee) router.delete('/:employeeId', employeeController.removeEmployee) router.get('/', employeeController.getEmployees) router.get('/:employeeId', employeeController.getSingleEmployee) -// router.put('/:id', entranceController.updateEntrance) +router.put('/:employeeId', employeeController.updateEmployee) export default router