Skip to content

Commit

Permalink
#133 [FEAT]: Update application answer logic to use coordinates and a…
Browse files Browse the repository at this point in the history
…llow answer approval
  • Loading branch information
IosBonaldi committed Jan 16, 2025
1 parent 74af106 commit 1834b6c
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 15 deletions.
22 changes: 17 additions & 5 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@ model Address {
state String
country String
institutions Institution[]
applicationAnswers ApplicationAnswer[]
institutions Institution[]
@@unique([city, state, country])
}
Expand All @@ -101,16 +100,16 @@ model ApplicationAnswer {
updatedAt DateTime @updatedAt
date DateTime
approved Boolean @default(false)
approved Boolean @default(false)
itemAnswerGroups ItemAnswerGroup[]
userId Int?
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
applicationId Int
application Application @relation(fields: [applicationId], references: [id], onDelete: Cascade)
addressId Int?
address Address? @relation(fields: [addressId], references: [id], onDelete: SetNull)
coordinateId Int?
coordinate Coordinate? @relation(fields: [coordinateId], references: [id], onDelete: SetNull)
}

model ItemAnswer {
Expand Down Expand Up @@ -432,3 +431,16 @@ model PageDependencyRule {
@@unique([pageId, itemId, type])
}

model Coordinate {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
latitude Float
longitude Float
answers ApplicationAnswer[]
@@unique([latitude, longitude])
}
56 changes: 48 additions & 8 deletions src/controllers/applicationAnswerController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,10 +204,11 @@ const fields = {
date: true,
userId: true,
applicationId: true,
addressId: true,
createdAt: true,
updatedAt: true,
approved: true,
coordinateId: true,
coordinate: { select: { latitude: true, longitude: true } },
itemAnswerGroups: {
select: {
id: true,
Expand Down Expand Up @@ -252,13 +253,14 @@ export const createApplicationAnswer = async (req: Request, res: Response) => {
optionAnswers: yup.array().of(createOptionAnswerSchema).default([]),
})
.noUnknown();
const createCoordinateSchema = yup.object().shape({ latitude: yup.number(), longitude: yup.number() }).noUnknown();
const createApplicationAnswerSchema = yup
.object()
.shape({
id: yup.number(),
date: yup.date().required(),
applicationId: yup.number().required(),
addressId: yup.number(),
coordinate: createCoordinateSchema,
itemAnswerGroups: yup.array().of(createItemAnswerGroupSchema).min(1).required(),
})
.noUnknown();
Expand All @@ -276,11 +278,26 @@ export const createApplicationAnswer = async (req: Request, res: Response) => {
const createdApplicationAnswer = await prismaClient.$transaction(async (prisma) => {
const createdApplicationAnswer: ApplicationAnswer = await prisma.applicationAnswer.create({
data: {
id: applicationAnswer.id,
date: applicationAnswer.date,
userId: user.id,
applicationId: applicationAnswer.applicationId,
addressId: applicationAnswer.addressId,
user: { connect: { id: user.id } },
application: { connect: { id: applicationAnswer.applicationId } },
coordinate:
applicationAnswer.coordinate.latitude !== undefined && applicationAnswer.coordinate.longitude !== undefined
? {
connectOrCreate: {
where: {
latitude_longitude: {
latitude: applicationAnswer.coordinate.latitude,
longitude: applicationAnswer.coordinate.longitude,
},
},
create: {
latitude: applicationAnswer.coordinate.latitude,
longitude: applicationAnswer.coordinate.longitude,
},
},
}
: undefined,
approved: false,
},
});
Expand Down Expand Up @@ -386,11 +403,15 @@ export const updateApplicationAnswer = async (req: Request, res: Response): Prom
optionAnswers: yup.array().of(updateOptionAnswerSchema).default([]),
})
.noUnknown();
const updateCoordinateSchema = yup
.object()
.shape({ latitude: yup.number().required(), longitude: yup.number().required() })
.noUnknown();
const updateApplicationAnswerSchema = yup
.object()
.shape({
date: yup.date(),
addressId: yup.number(),
coordinate: updateCoordinateSchema,
itemAnswerGroups: yup.array().of(updateItemAnswerGroupSchema).min(1).required(),
})
.noUnknown();
Expand All @@ -409,7 +430,26 @@ export const updateApplicationAnswer = async (req: Request, res: Response): Prom
// Update application answer
await prisma.applicationAnswer.update({
where: { id: applicationAnswerId },
data: { date: applicationAnswer.date, addressId: applicationAnswer.addressId },
data: {
date: applicationAnswer.date,
coordinate:
applicationAnswer.coordinate.latitude !== undefined && applicationAnswer.coordinate.longitude !== undefined
? {
connectOrCreate: {
where: {
latitude_longitude: {
latitude: applicationAnswer.coordinate.latitude,
longitude: applicationAnswer.coordinate.longitude,
},
},
create: {
latitude: applicationAnswer.coordinate.latitude,
longitude: applicationAnswer.coordinate.longitude,
},
},
}
: { disconnect: true },
},
});
// Remove item answer groups that are not in the updated application answer
await prisma.itemAnswerGroup.deleteMany({
Expand Down
16 changes: 14 additions & 2 deletions src/controllers/applicationController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ const fields = {
protocol: { select: { id: true, title: true, description: true } },
visibility: true,
answersVisibility: true,
keepLocation: true,
applier: { select: { id: true, username: true, institutionId: true } },
createdAt: true,
updatedAt: true,
Expand Down Expand Up @@ -192,7 +193,15 @@ const fieldsWProtocol = {

const fieldsWAnswers = {
...fieldsWProtocol,
answers: { select: { id: true, date: true, user: { select: { id: true, username: true } } } },
answers: {
select: {
id: true,
date: true,
user: { select: { id: true, username: true } },
coordinate: { select: { latitude: true, longitude: true } },
approved: true,
},
},
};

export const createApplication = async (req: Request, res: Response) => {
Expand Down Expand Up @@ -575,7 +584,10 @@ export const getApplicationWithAnswers = async (req: Request, res: Response): Pr
}
}
applicationWithAnswers.answers = Object.fromEntries(
applicationWithAnswers.answers.map((answer: any) => [answer.id, { date: answer.date, user: answer.user }])
applicationWithAnswers.answers.map((answer: any) => [
answer.id,
{ date: answer.date, user: answer.user, coordinate: answer.coordinate, approved: answer.approved },
])
);

res.status(200).json({ message: 'Application with answers found.', data: applicationWithAnswers });
Expand Down
44 changes: 44 additions & 0 deletions src/routes/applicationAnswerRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
getMyApplicationAnswers,
getApplicationAnswer,
deleteApplicationAnswer,
approveApplicationAnswer,
} from '../controllers/applicationAnswerController';

/**
Expand Down Expand Up @@ -435,6 +436,49 @@ const router = express.Router();
*/
router.post('/createApplicationAnswer', passport.authenticate('jwt', { session: false }), uploader.any(), createApplicationAnswer);

/**
* @swagger
* /api/applicationAnswer/approveApplicationAnswer/{applicationAnswerId}:
* put:
* summary: Approve an application answer by id
* tags: [ApplicationAnswer]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: applicationAnswerId
* schema:
* type: integer
* required: true
* description: The id of the application answer to approve
* responses:
* 200:
* description: The application answer was successfully approved
* content:
* application/json:
* message: Application answer approved.
* data:
* $ref: '#/components/schemas/GetApplicationAnswer'
* 404:
* description: Application answer not found
* content:
* application/json:
* error:
* message: Application answer not found.
* 500:
* description: An error occurred while approving the application answer
* content:
* application/json:
* error:
* message: Internal server error.
*/
router.put(
'/approveApplicationAnswer/:applicationAnswerId',
passport.authenticate('jwt', { session: false }),
uploader.none(),
approveApplicationAnswer
);

/**
* @swagger
* /api/applicationAnswer/updateApplicationAnswer/{applicationAnswerId}:
Expand Down

0 comments on commit 1834b6c

Please sign in to comment.