-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FEATURE] Ajoute un endpoint pour récupérer les résultats de quêtes d…
- Loading branch information
Showing
34 changed files
with
791 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
...src/prescription/campaign/application/usecases/checkCampaignParticipationBelongsToUser.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import * as campaignParticipationRepository from '../../../campaign-participation/infrastructure/repositories/campaign-participation-repository.js'; | ||
import { CampaignParticipationDoesNotBelongToUser } from '../../domain/errors.js'; | ||
|
||
const execute = async function ({ | ||
userId, | ||
campaignParticipationId, | ||
dependencies = { campaignParticipationRepository }, | ||
}) { | ||
const campaignParticipation = await dependencies.campaignParticipationRepository.get(campaignParticipationId); | ||
if (!campaignParticipation || campaignParticipation.userId !== userId) { | ||
throw new CampaignParticipationDoesNotBelongToUser(); | ||
} | ||
}; | ||
|
||
export { execute }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { usecases } from '../../domain/usecases/index.js'; | ||
|
||
export const getByIdAndType = ({ rewardId, rewardType }) => { | ||
return usecases.getRewardByIdAndType({ rewardId, rewardType }); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export const getRewardByIdAndType = ({ rewardId, rewardType, rewardRepository }) => { | ||
return rewardRepository.getByIdAndType({ rewardId, rewardType }); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
api/src/profile/infrastructure/repositories/reward-repository.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { knex } from '../../../../db/knex-database-connection.js'; | ||
import { REWARD_TYPES } from '../../../quest/domain/constants.js'; | ||
import { RewardTypeDoesNotExistError } from '../../domain/errors.js'; | ||
import { Attestation } from '../../domain/models/Attestation.js'; | ||
|
||
export const getByIdAndType = async ({ rewardId, rewardType }) => { | ||
try { | ||
const result = await knex(rewardType).where({ id: rewardId }).first(); | ||
switch (rewardType) { | ||
case REWARD_TYPES.ATTESTATION: | ||
return new Attestation(result); | ||
} | ||
} catch (error) { | ||
throw new RewardTypeDoesNotExistError(error); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import Joi from 'joi'; | ||
|
||
import { securityPreHandlers } from '../../shared/application/security-pre-handlers.js'; | ||
import { identifiersType } from '../../shared/domain/types/identifiers-type.js'; | ||
import { questController } from './quest-controller.js'; | ||
|
||
const register = async function (server) { | ||
server.route([ | ||
{ | ||
method: 'GET', | ||
path: '/api/campaign-participations/{campaignParticipationId}/quest-results', | ||
config: { | ||
pre: [ | ||
{ | ||
method: securityPreHandlers.checkCampaignParticipationBelongsToUser, | ||
}, | ||
], | ||
handler: questController.getQuestResults, | ||
validate: { | ||
params: Joi.object({ | ||
campaignParticipationId: identifiersType.campaignParticipationId, | ||
}), | ||
}, | ||
notes: [ | ||
'- **Route nécessitant une authentification**\n' + | ||
"- Récupère le résultat d'une quête pour une participation et un user donné", | ||
], | ||
tags: ['api', 'quest'], | ||
}, | ||
}, | ||
]); | ||
}; | ||
const name = 'quest-api'; | ||
export { name, register }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import * as requestResponseUtils from '../../shared/infrastructure/utils/request-response-utils.js'; | ||
import { usecases } from '../domain/usecases/index.js'; | ||
import * as questResultSerializer from '../infrastructure/serializers/quest-result-serializer.js'; | ||
|
||
const getQuestResults = async function (request, h, dependencies = { questResultSerializer, requestResponseUtils }) { | ||
const { campaignParticipationId } = request.params; | ||
const userId = dependencies.requestResponseUtils.extractUserIdFromRequest(request); | ||
|
||
const questResults = await usecases.getQuestResultsForCampaignParticipation({ userId, campaignParticipationId }); | ||
|
||
const serializedQuestResults = dependencies.questResultSerializer.serialize(questResults); | ||
|
||
return h.response(serializedQuestResults); | ||
}; | ||
|
||
const questController = { | ||
getQuestResults, | ||
}; | ||
|
||
export { questController }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,33 @@ | ||
export class Eligibility { | ||
#campaignParticipations; | ||
|
||
constructor({ organizationLearner, organization, campaignParticipations = [] }) { | ||
this.organizationLearner = { | ||
MEFCode: organizationLearner?.MEFCode, | ||
}; | ||
this.organization = organization; | ||
this.campaignParticipations = { | ||
targetProfileIds: campaignParticipations.map(({ targetProfileId }) => targetProfileId), | ||
this.#campaignParticipations = campaignParticipations; | ||
} | ||
|
||
get campaignParticipations() { | ||
return { | ||
targetProfileIds: this.#campaignParticipations.map(({ targetProfileId }) => targetProfileId), | ||
}; | ||
} | ||
|
||
hasCampaignParticipation(campaignParticipationId) { | ||
return Boolean( | ||
this.#campaignParticipations.find( | ||
(campaignParticipation) => campaignParticipation.id === campaignParticipationId, | ||
), | ||
); | ||
} | ||
|
||
getTargetProfileForCampaignParticipation(campaignParticipationId) { | ||
const campaignParticipation = this.#campaignParticipations.find( | ||
(campaignParticipation) => campaignParticipation.id === campaignParticipationId, | ||
); | ||
|
||
return campaignParticipation?.targetProfileId ?? null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export class QuestResult { | ||
constructor({ id, obtained, reward }) { | ||
this.id = id; | ||
this.obtained = obtained; | ||
this.reward = reward; | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
api/src/quest/domain/usecases/get-quest-results-for-campaign-participation.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
export const getQuestResultsForCampaignParticipation = async ({ | ||
userId, | ||
campaignParticipationId, | ||
questRepository, | ||
eligibilityRepository, | ||
rewardRepository, | ||
}) => { | ||
const quests = await questRepository.findAll(); | ||
|
||
if (quests.length === 0) { | ||
return []; | ||
} | ||
|
||
const eligibilities = await eligibilityRepository.find({ userId }); | ||
const eligibility = eligibilities.find((e) => e.hasCampaignParticipation(campaignParticipationId)); | ||
|
||
if (!eligibility) return []; | ||
|
||
eligibility.campaignParticipations.targetProfileIds = [ | ||
// getTargetProfileForCampaignParticipation returns null but this usecase is used for campaign participation result page for now, so the campaign participation ID always exists | ||
// if this usecase is to be used in another context, the edge case must be handled | ||
eligibility.getTargetProfileForCampaignParticipation(campaignParticipationId), | ||
]; | ||
|
||
const questResults = []; | ||
for (const quest of quests) { | ||
const isEligibleForQuest = quest.isEligible(eligibility); | ||
|
||
if (!isEligibleForQuest) continue; | ||
|
||
const questResult = await rewardRepository.getByQuestAndUserId({ userId, quest }); | ||
questResults.push(questResult); | ||
} | ||
|
||
return questResults; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
api/src/quest/infrastructure/repositories/reward-repository.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,46 @@ | ||
import { QuestResult } from '../../domain/models/QuestResult.js'; | ||
|
||
export const reward = async ({ userId, rewardId, profileRewardApi }) => { | ||
return profileRewardApi.save(userId, rewardId); | ||
}; | ||
|
||
export const getByUserId = async ({ userId, profileRewardApi }) => { | ||
return profileRewardApi.getByUserId(userId); | ||
}; | ||
|
||
export const getByQuestAndUserId = async ({ | ||
userId, | ||
quest, | ||
rewardApi, | ||
profileRewardApi, | ||
profileRewardTemporaryStorage, | ||
}) => { | ||
const reward = await rewardApi.getByIdAndType({ rewardId: quest.rewardId, rewardType: quest.rewardType }); | ||
const profileRewards = await profileRewardApi.getByUserId(userId); | ||
|
||
const profileRewardForQuest = profileRewards.find( | ||
(profileReward) => profileReward.rewardType === quest.rewardType && profileReward.rewardId === quest.rewardId, | ||
); | ||
|
||
if (profileRewardForQuest) { | ||
return new QuestResult({ | ||
id: quest.id, | ||
obtained: true, | ||
reward, | ||
}); | ||
} | ||
|
||
let obtained = false; | ||
|
||
const isProcessing = Number(await profileRewardTemporaryStorage.get(userId)) > 0; | ||
|
||
if (isProcessing) { | ||
obtained = null; | ||
} | ||
|
||
return new QuestResult({ | ||
id: quest.id, | ||
obtained, | ||
reward, | ||
}); | ||
}; |
11 changes: 11 additions & 0 deletions
11
api/src/quest/infrastructure/serializers/quest-result-serializer.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import jsonapiSerializer from 'jsonapi-serializer'; | ||
|
||
const { Serializer } = jsonapiSerializer; | ||
|
||
const serialize = function (questResult) { | ||
return new Serializer('quest-result', { | ||
attributes: ['obtained', 'reward'], | ||
}).serialize(questResult); | ||
}; | ||
|
||
export { serialize }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import * as questRoute from './application/index.js'; | ||
|
||
const questRoutes = [questRoute]; | ||
|
||
export { questRoutes }; |
Oops, something went wrong.