Skip to content

Commit

Permalink
[TECH] Extraire la sélection d'épreuves lors du scoring dans un servi…
Browse files Browse the repository at this point in the history
…ce dédié (PIX-15332).

 #10608
  • Loading branch information
pix-service-auto-merge authored Nov 25, 2024
2 parents 283638a + 7fad384 commit 4182c65
Show file tree
Hide file tree
Showing 24 changed files with 391 additions and 321 deletions.
2 changes: 2 additions & 0 deletions api/lib/domain/events/handle-certification-rescoring.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { services } from '../../../src/certification/evaluation/domain/services/index.js';
import { AssessmentResultFactory } from '../../../src/certification/scoring/domain/models/factories/AssessmentResultFactory.js';
import { AlgorithmEngineVersion } from '../../../src/certification/shared/domain/models/AlgorithmEngineVersion.js';
import { V3_REPRODUCIBILITY_RATE } from '../../../src/shared/domain/constants.js';
Expand Down Expand Up @@ -119,6 +120,7 @@ async function _handleV3CertificationScoring({
emitter,
certificationAssessment,
locale,
dependencies: { findByCertificationCourseId: services.findByCertificationCourseId },
});

if (certificationCourse.isCancelled()) {
Expand Down
4 changes: 2 additions & 2 deletions api/lib/domain/events/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import _ from 'lodash';

import { services as certificationEvaluationServices } from '../../../src/certification/evaluation/domain/services/index.js';
import * as certificationAssessmentHistoryRepository from '../../../src/certification/evaluation/infrastructure/repositories/certification-assessment-history-repository.js';
import * as certificationChallengeForScoringRepository from '../../../src/certification/evaluation/infrastructure/repositories/certification-challenge-for-scoring-repository.js';
import * as challengeCalibrationRepository from '../../../src/certification/evaluation/infrastructure/repositories/challenge-calibration-repository.js';
import * as flashAlgorithmService from '../../../src/certification/flash-certification/domain/services/algorithm-methods/flash.js';
import * as finalizedSessionRepository from '../../../src/certification/session-management/infrastructure/repositories/finalized-session-repository.js';
import * as juryCertificationSummaryRepository from '../../../src/certification/session-management/infrastructure/repositories/jury-certification-summary-repository.js';
Expand Down Expand Up @@ -70,7 +70,7 @@ const dependencies = {
certificationAssessmentHistoryRepository,
certificationAssessmentRepository,
certificationCenterRepository,
certificationChallengeForScoringRepository,
challengeCalibrationRepository,
certificationCourseRepository,
certificationIssueReportRepository,
challengeRepository,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ async function _handleV3CertificationScoring({
certificationAssessment,
emitter,
locale,
dependencies: { findByCertificationCourseId: services.findByCertificationCourseId },
});

if (!certificationCourse.isCancelled()) {
Expand Down
6 changes: 3 additions & 3 deletions api/src/certification/evaluation/domain/services/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import * as flashAlgorithmConfigurationRepository from '../../../shared/infrastr
import * as scoringConfigurationRepository from '../../../shared/infrastructure/repositories/scoring-configuration-repository.js';
import * as certificationAssessmentHistoryRepository from '../../infrastructure/repositories/certification-assessment-history-repository.js';
import * as certificationCandidateRepository from '../../infrastructure/repositories/certification-candidate-repository.js';
import * as certificationChallengeForScoringRepository from '../../infrastructure/repositories/certification-challenge-for-scoring-repository.js';
import * as challengeCalibrationRepository from '../../infrastructure/repositories/challenge-calibration-repository.js';

/**
* Using {@link https://jsdoc.app/tags-type "Closure Compiler's syntax"} to document injected dependencies
Expand All @@ -31,7 +31,7 @@ import * as certificationChallengeForScoringRepository from '../../infrastructur
* @typedef {certificationCourseRepository} CertificationCourseRepository
* @typedef {scoringDegradationService} ScoringDegradationService
* @typedef {certificationAssessmentHistoryRepository} CertificationAssessmentHistoryRepository
* @typedef {certificationChallengeForScoringRepository} CertificationChallengeForScoringRepository
* @typedef {challengeCalibrationRepository} ChallengeCalibrationRepository
* @typedef {scoringConfigurationRepository} ScoringConfigurationRepository
* @typedef {flashAlgorithmConfigurationRepository} FlashAlgorithmConfigurationRepository
* @typedef {answerRepository} AnswerRepository
Expand All @@ -53,7 +53,7 @@ const dependencies = {
answerRepository,
certificationAssessmentHistoryRepository,
flashAlgorithmService,
certificationChallengeForScoringRepository,
challengeCalibrationRepository,
challengeRepository,
areaRepository,
placementProfileService,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import Debug from 'debug';
import differenceBy from 'lodash/differenceBy.js';

const debugScoringForV3Certification = Debug('pix:certif:v3:scoring');

export const findByCertificationCourseId = async ({
certificationCourseId,
challengeCalibrationRepository,
challengeRepository,
}) => {
const flashCompatibleChallenges = await challengeRepository.findFlashCompatibleWithoutLocale({
useObsoleteChallenges: true,
});
debugScoringForV3Certification(`FlashCompatibleChallenges count: ${flashCompatibleChallenges.length}`);

return _findByCertificationCourseId({
compatibleChallenges: flashCompatibleChallenges,
certificationCourseId,
challengeCalibrationRepository,
challengeRepository,
});
};

const _findByCertificationCourseId = async ({
compatibleChallenges,
certificationCourseId,
challengeCalibrationRepository,
challengeRepository,
}) => {
const challengeCalibrations = await challengeCalibrationRepository.getByCertificationCourseId({
certificationCourseId,
});

const askedChallenges = await challengeRepository.getMany(challengeCalibrations.map((challenge) => challenge.id));

_restoreCalibrationValues(challengeCalibrations, askedChallenges);

const flashCompatibleChallengesNotAskedInCertification = differenceBy(compatibleChallenges, askedChallenges, 'id');

const allChallenges = [...askedChallenges, ...flashCompatibleChallengesNotAskedInCertification];

debugScoringForV3Certification(
`Challenges after FlashCompatibleChallenges & CandidateAnswers merge count: ${allChallenges.length}`,
);

return { allChallenges, askedChallenges, challengeCalibrations };
};

function _restoreCalibrationValues(challengeCalibrations, askedChallenges) {
challengeCalibrations.forEach((certificationChallenge) => {
const askedChallenge = askedChallenges.find(({ id }) => id === certificationChallenge.id);
askedChallenge.discriminant = certificationChallenge.discriminant;
askedChallenge.difficulty = certificationChallenge.difficulty;
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* @typedef {import('../index.js').CompetenceMarkRepository} CompetenceMarkRepository
* @typedef {import('../index.js').ScoringDegradationService} ScoringDegradationService
* @typedef {import('../index.js').CertificationAssessmentHistoryRepository} CertificationAssessmentHistoryRepository
* @typedef {import('../index.js').CertificationChallengeForScoringRepository} CertificationChallengeForScoringRepository
* @typedef {import('../index.js').CertificationChallengeRepository} CertificationChallengeRepository
* @typedef {import('../index.js').ScoringConfigurationRepository} ScoringConfigurationRepository
* @typedef {import('../index.js').FlashAlgorithmConfigurationRepository} FlashAlgorithmConfigurationRepository
* @typedef {import('../index.js').AnswerRepository} AnswerRepository
Expand All @@ -13,7 +13,6 @@
* @typedef {import('../index.js').ScoringDegradationService} ScoringDegradationService
*/
import Debug from 'debug';
import differenceBy from 'lodash/differenceBy.js';

import { config } from '../../../../../shared/config.js';
import { CompetenceMark } from '../../../../../shared/domain/models/index.js';
Expand All @@ -30,7 +29,7 @@ const debugScoringForV3Certification = Debug('pix:certif:v3:scoring');
* @param {CertificationCourseRepository} params.certificationCourseRepository
* @param {CompetenceMarkRepository} params.competenceMarkRepository
* @param {CertificationAssessmentHistoryRepository} params.certificationAssessmentHistoryRepository
* @param {CertificationChallengeForScoringRepository} params.certificationChallengeForScoringRepository
* @param {CertificationChallengeRepository} params.certificationChallengeRepository
* @param {ScoringConfigurationRepository} params.scoringConfigurationRepository
* @param {FlashAlgorithmConfigurationRepository} params.flashAlgorithmConfigurationRepository
* @param {AnswerRepository} params.answerRepository
Expand All @@ -46,52 +45,22 @@ export const handleV3CertificationScoring = async ({
answerRepository,
assessmentResultRepository,
certificationAssessmentHistoryRepository,
certificationChallengeForScoringRepository,
certificationCourseRepository,
competenceMarkRepository,
flashAlgorithmConfigurationRepository,
flashAlgorithmService,
scoringDegradationService,
scoringConfigurationRepository,
challengeRepository,
dependencies,
}) => {
const { certificationCourseId, id: assessmentId } = certificationAssessment;
const candidateAnswers = await answerRepository.findByAssessment(assessmentId);
const flashCompatibleChallenges = await challengeRepository.findFlashCompatibleWithoutLocale({
useObsoleteChallenges: true,
});

debugScoringForV3Certification(`FlashCompatibleChallenges count: ${flashCompatibleChallenges.length}`);
const candidateAnswers = await answerRepository.findByAssessment(assessmentId);
debugScoringForV3Certification(`CandidateAnswers count: ${candidateAnswers.length}`);

const certificationChallengesForScoring = await certificationChallengeForScoringRepository.getByCertificationCourseId(
{ certificationCourseId },
);
const askedChallenges = await challengeRepository.getMany(
certificationChallengesForScoring.map((challengeForScoring) => challengeForScoring.id),
);

_restoreCalibrationValues(certificationChallengesForScoring, askedChallenges);

const flashCompatibleChallengesNotAskedInCertification = differenceBy(
flashCompatibleChallenges,
askedChallenges,
'id',
);

const allChallenges = [...askedChallenges, ...flashCompatibleChallengesNotAskedInCertification];

debugScoringForV3Certification(
`Challenges after FlashCompatibleChallenges & CandidateAnswers merge count: ${allChallenges.length}`,
);

if (allChallenges.length > flashCompatibleChallenges.length) {
const addedChallenges = differenceBy(allChallenges, flashCompatibleChallenges, 'id');
const challengeIds = addedChallenges.map((challenge) => challenge.id);

debugScoringForV3Certification(`Added challenges after merge: ${challengeIds}`);
}

const { allChallenges, askedChallenges, challengeCalibrations } = await dependencies.findByCertificationCourseId({
certificationCourseId,
});
const certificationCourse = await certificationCourseRepository.get({ id: certificationCourseId });

const abortReason = certificationCourse.getAbortReason();
Expand Down Expand Up @@ -138,7 +107,7 @@ export const handleV3CertificationScoring = async ({

const certificationAssessmentHistory = CertificationAssessmentHistory.fromChallengesAndAnswers({
algorithm,
challenges: certificationChallengesForScoring,
challenges: challengeCalibrations,
allAnswers: candidateAnswers,
});

Expand All @@ -155,14 +124,6 @@ export const handleV3CertificationScoring = async ({
return certificationCourse;
};

function _restoreCalibrationValues(certificationChallengesForScoring, answeredChallenges) {
certificationChallengesForScoring.forEach((certificationChallengeForScoring) => {
const answeredChallenge = answeredChallenges.find(({ id }) => id === certificationChallengeForScoring.id);
answeredChallenge.discriminant = certificationChallengeForScoring.discriminant;
answeredChallenge.difficulty = certificationChallengeForScoring.difficulty;
});
}

function _createV3AssessmentResult({
allAnswers,
emitter,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
/**
* @typedef {import('../../../session-management/domain/usecases/index.js').CertificationChallengeRepository} CertificationChallengeRepository
* @typedef {import('../../../session-management/domain/usecases/index.js').SessionManagementCertificationChallengeRepository} SessionManagementCertificationChallengeRepository
* @typedef {import('../../../session-management/domain/usecases/index.js').ChallengeRepository} ChallengeRepository
*/

/**
* @param {Object} params
* @param {Object} params.assessment
* @param {CertificationChallengeRepository} params.certificationChallengeRepository
* @param {SessionManagementCertificationChallengeRepository} params.sessionManagementCertificationChallengeRepository
* @param {ChallengeRepository} params.challengeRepository
*/
const getNextChallengeForV2Certification = async function ({
assessment,
certificationChallengeRepository,
sessionManagementCertificationChallengeRepository,
challengeRepository,
}) {
const certificationChallenge = await certificationChallengeRepository.getNextNonAnsweredChallengeByCourseId(
assessment.id,
assessment.certificationCourseId,
);
const certificationChallenge =
await sessionManagementCertificationChallengeRepository.getNextNonAnsweredChallengeByCourseId(
assessment.id,
assessment.certificationCourseId,
);
return challengeRepository.get(certificationChallenge.challengeId);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* @typedef {import('../../../session-management/domain/usecases/index.js').AnswerRepository} AnswerRepository
* @typedef {import('../../../session-management/domain/usecases/index.js').CertificationChallengeRepository} CertificationChallengeRepository
* @typedef {import('../../../session-management/domain/usecases/index.js').SessionManagementCertificationChallengeRepository} SessionManagementCertificationChallengeRepository
* @typedef {import('../../../session-management/domain/usecases/index.js').CertificationChallengeLiveAlertRepository} CertificationChallengeLiveAlertRepository
* @typedef {import('../../../session-management/domain/usecases/index.js').CertificationCourseRepository} CertificationCourseRepository
* @typedef {import('../../../session-management/domain/usecases/index.js').ChallengeRepository} ChallengeRepository
Expand All @@ -20,7 +20,7 @@ const debugGetNextChallengeForV3Certification = Debug('pix:certif:v3:get-next-ch
/**
* @param {Object} params
* @param {AnswerRepository} params.answerRepository
* @param {CertificationChallengeRepository} params.certificationChallengeRepository
* @param {SessionManagementCertificationChallengeRepository} params.sessionManagementCertificationChallengeRepository
* @param {CertificationChallengeLiveAlertRepository} params.certificationChallengeLiveAlertRepository
* @param {CertificationCourseRepository} params.certificationCourseRepository
* @param {ChallengeRepository} params.challengeRepository
Expand All @@ -32,7 +32,7 @@ const debugGetNextChallengeForV3Certification = Debug('pix:certif:v3:get-next-ch
const getNextChallenge = async function ({
assessment,
answerRepository,
certificationChallengeRepository,
sessionManagementCertificationChallengeRepository,
certificationChallengeLiveAlertRepository,
certificationCourseRepository,
challengeRepository,
Expand All @@ -54,10 +54,11 @@ const getNextChallenge = async function ({

const excludedChallengeIds = [...alreadyAnsweredChallengeIds, ...validatedLiveAlertChallengeIds];

const lastNonAnsweredCertificationChallenge = await certificationChallengeRepository.getNextChallengeByCourseIdForV3(
assessment.certificationCourseId,
excludedChallengeIds,
);
const lastNonAnsweredCertificationChallenge =
await sessionManagementCertificationChallengeRepository.getNextChallengeByCourseIdForV3(
assessment.certificationCourseId,
excludedChallengeIds,
);

if (lastNonAnsweredCertificationChallenge) {
return challengeRepository.get(lastNonAnsweredCertificationChallenge.challengeId);
Expand Down Expand Up @@ -114,7 +115,7 @@ const getNextChallenge = async function ({
difficulty: challenge.difficulty,
});

await certificationChallengeRepository.save({ certificationChallenge });
await sessionManagementCertificationChallengeRepository.save({ certificationChallenge });

return challenge;
};
Expand Down
9 changes: 6 additions & 3 deletions api/src/certification/evaluation/domain/usecases/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
answerRepository,
assessmentRepository,
assessmentResultRepository,
certificationChallengeRepository,
certificationChallengeRepository as sessionManagementCertificationChallengeRepository,
challengeRepository,
competenceMarkRepository,
cpfExportRepository,
Expand All @@ -28,12 +28,17 @@ import * as certificationCourseRepository from '../../../shared/infrastructure/r
import * as userRepository from '../../../shared/infrastructure/repositories/user-repository.js';
import * as certificationCandidateRepository from '../../infrastructure/repositories/certification-candidate-repository.js';
import * as certificationCompanionAlertRepository from '../../infrastructure/repositories/certification-companion-alert-repository.js';
import * as challengeCalibrationRepository from '../../infrastructure/repositories/challenge-calibration-repository.js';
/**
* @typedef {certificationCompanionAlertRepository} CertificationCompanionAlertRepository
* @typedef {certificationChallengeRepository} CertificationChallengeRepository
*/

const dependencies = {
...sessionRepositories,
sessionManagementCertificationChallengeRepository,
challengeCalibrationRepository,
certificationCandidateRepository,
assessmentRepository,
sharedCertificationCandidateRepository,
verifyCertificateCodeService,
Expand All @@ -45,15 +50,13 @@ const dependencies = {
competenceMarkRepository,
certificationChallengesService,
cpfExportRepository,
certificationChallengeRepository,
flashAlgorithmConfigurationRepository,
flashAlgorithmService,
languageService,
certificationBadgesService,
pickChallengeService,
placementProfileService,
certificationCenterRepository,
certificationCandidateRepository,
certificationCompanionAlertRepository,
certificationCourseRepository,
};
Expand Down

This file was deleted.

Loading

0 comments on commit 4182c65

Please sign in to comment.