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

can't finish (did with in pair prog with Lucile) #4

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 3 additions & 2 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"license": "ISC",
"dependencies": {
"@prisma/client": "^5.13.0",
"arg": "^5.0.2",
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.19.2",
Expand All @@ -37,8 +38,8 @@
"prettier": "^3.2.5",
"prisma": "^5.13.0",
"ts-jest": "^29.1.2",
"ts-node": "^9.1.1",
"ts-node": "^10.9.2",
"ts-node-dev": "^1.1.6",
"typescript": "^4.9.5"
"typescript": "^5.6.3"
}
}
27 changes: 27 additions & 0 deletions backend/src/application/services/positionService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// backend/src/application/positionService.ts
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

export const getCandidatesByPositionIdService = async (positionId: number) => {
return prisma.application.findMany({
where: { positionId },
include: {
candidate: true,
interviews: true,
interviewStep: true,
},
}).then(applications => applications.map(application => ({
fullName: `${application.candidate.firstName} ${application.candidate.lastName}`,
current_interview_step: application.interviewStep.name,
average_score: application.interviews.reduce((acc, interview) => acc + (interview.score || 0), 0) / application.interviews.length,
})));
};

export const updateCandidateStageService = async (candidateId: number, newStage: string) => {
return prisma.application.update({
where: { id: candidateId },
data: { interviewStep: { update: { name: newStage } } },
include: { candidate: true, interviewStep: true },
});
};
3 changes: 3 additions & 0 deletions backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import express from 'express';
import { PrismaClient } from '@prisma/client';
import dotenv from 'dotenv';
import candidateRoutes from './routes/candidateRoutes';
import positionRoutes from './routes/positionRoutes';
import { uploadFile } from './application/services/fileUploadService';
import cors from 'cors';

Expand Down Expand Up @@ -38,6 +39,8 @@ app.use(cors({

// Import and use candidateRoutes
app.use('/candidates', candidateRoutes);
// Import and use positionRoutes
app.use('/positions', positionRoutes);

// Route for file uploads
app.post('/upload', uploadFile);
Expand Down
33 changes: 33 additions & 0 deletions backend/src/presentation/controllers/positionController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// backend/src/presentation/positionController.ts
import { Request, Response } from 'express';
import { getCandidatesByPositionIdService, updateCandidateStageService } from '../../application/services/positionService';

export const getCandidatesByPositionId = async (req: Request, res: Response) => {
const positionId = parseInt(req.params.id, 10);
if (isNaN(positionId)) {
return res.status(400).json({ error: 'Invalid position ID' });
}

try {
const candidates = await getCandidatesByPositionIdService(positionId);
res.json(candidates);
} catch (error) {
res.status(500).json({ error: 'Internal server error' });
}
};

export const updateCandidateStage = async (req: Request, res: Response) => {
const candidateId = parseInt(req.params.id, 10);
const stage = req.body.stage;

if (isNaN(candidateId) || !stage) {
return res.status(400).json({ error: 'Invalid request data' });
}

try {
const updatedCandidate = await updateCandidateStageService(candidateId, stage);
res.json(updatedCandidate);
} catch (error) {
res.status(500).json({ error: 'Internal server error' });
}
};
10 changes: 10 additions & 0 deletions backend/src/routes/positionRoutes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// backend/src/routes/positionRoutes.ts
import { Router } from 'express';
import { getCandidatesByPositionId, updateCandidateStage } from '../presentation/controllers/positionController';

const router = Router();

router.get('/:id/candidates', getCandidatesByPositionId);
router.put('/candidate/:id', updateCandidateStage);

export default router;
28 changes: 28 additions & 0 deletions prompts/prompts-rsa.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#prompt 1
@workspace
Hello how are you?

As a backend expert developer with TypeScript Node, I need you to add a new endpoint in the backend context (directory "/backend").
The path of this endpoint is "/position/:id/candidates" and it will retrieve all the candidates in progress for a specific position, meaning all the applications for a particular positionID. It should provide the following basic information:

- Candidate’s full name (from the candidate table).
- current_interview_step: the phase of the process the candidate is in (from the application table).
- The candidate's average score. That means we retrieve the scores of each interview of the candidate to process the average score.

Of course you'll must respect the project structure (you can find it in README.md).

I don't need you to code immediatly. I first need to know if you need other explanations.

#prompt 2
Ok, please proceed

#prompt 3
In order to respect the current project structure, I'de prefer that positionController.ts be located in src/presentation/controllers and positionService.ts be in src/application/services/ . And I prefer that we add a generic route for "position" operations as for candidates in index.ts ("app.use('/candidates', candidateRoutes)"). I do the modification, I don't need you to generate code.

#prompt 4
@workspace Cool it works. Now I need a new endpoint: /position/candidate/:id This endpoint will update the stage of the moved candidate. It allows modification of the current interview process phase for a specific candidate. Before generating code do you have any question?

#prompt 5
I've got this error when I build the backend context: src/application/services/positionService.ts:23:5 - error TS2322: Type '{ candidateId: number; }' is not assignable to type 'ApplicationWhereUniqueInput'. Type '{ candidateId: number; }' is not assignable to type '{ id: number; } & { id?: number | undefined; AND?: ApplicationWhereInput | ApplicationWhereInput[] | undefined; OR?: ApplicationWhereInput[] | undefined; ... 9 more ...; interviews?: InterviewListRelationFilter | undefined; }'. Property 'id' is missing in type '{ candidateId: number; }' but required in type '{ id: number; }'. 23 where: { candidateId }, ~~~~~ node_modules/.prisma/client/index.d.ts:13144:5 13144 where: ApplicationWhereUniqueInput ~~~~~ The expected type comes from property 'where' which is declared here on type '{ select?: ApplicationSelect<defaultargs> | null | undefined; include?: ApplicationInclude<defaultargs> | null | undefined; data: (Without<...> & ApplicationUncheckedUpdateInput) | (Without<...> & ApplicationUpdateInput); where: ApplicationWhereUniqueInput; }'</defaultargs></defaultargs> Found 1 error in src/application/services/positionService.ts:23

#prompt 6