Skip to content

Commit

Permalink
[TECH] Refacto des badges des certifications complémentaires (PIX-9862)
Browse files Browse the repository at this point in the history
  • Loading branch information
pix-service-auto-merge authored Nov 29, 2023
2 parents b5b8b64 + caafd89 commit 07f35de
Show file tree
Hide file tree
Showing 54 changed files with 1,452 additions and 1,181 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,26 @@ import { buildComplementaryCertification } from './build-complementary-certifica
import { buildCertificationCourse } from './build-certification-course.js';
import _ from 'lodash';
import { ComplementaryCertificationCourseResult } from '../../../lib/domain/models/ComplementaryCertificationCourseResult.js';
import { buildBadge } from './build-badge.js';
import { buildComplementaryCertificationBadge } from './build-complementary-certification-badge.js';

const buildComplementaryCertificationCourseResult = function ({
id,
complementaryCertificationCourseId,
partnerKey,
complementaryCertificationBadgeId,
source = ComplementaryCertificationCourseResult.sources.PIX,
acquired = true,
}) {
id = id ?? databaseBuffer.getNextId();
complementaryCertificationCourseId = _.isUndefined(complementaryCertificationCourseId)
? _buildComplementaryCertificationCourse().id
: complementaryCertificationCourseId;
complementaryCertificationBadgeId = _.isUndefined(complementaryCertificationBadgeId)
? _buildComplementaryCertificationBadge().id
: complementaryCertificationBadgeId;
return databaseBuffer.pushInsertable({
tableName: 'complementary-certification-course-results',
values: { id, complementaryCertificationCourseId, partnerKey, source, acquired },
values: { id, complementaryCertificationCourseId, complementaryCertificationBadgeId, source, acquired },
});
};

Expand All @@ -32,3 +37,9 @@ function _buildComplementaryCertificationCourse() {
certificationCourseId,
});
}

function _buildComplementaryCertificationBadge() {
const { id: badgeId } = buildBadge();
const { id: complementaryCertificationId } = buildComplementaryCertification();
return buildComplementaryCertificationBadge({ badgeId, complementaryCertificationId });
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const TABLE_NAME = 'complementary-certification-course-results';
const REF_TABLE_NAME = 'complementary-certification-badges';
const COLUMN_NAME = 'complementaryCertificationBadgeId';

const up = async function (knex) {
await knex.schema.table(TABLE_NAME, function (table) {
table
.integer(COLUMN_NAME)
.defaultTo(null)
.references(`${REF_TABLE_NAME}.id`)
.withKeyName('cccresults-ccbadgeId_foreignkey');
});

await knex(TABLE_NAME).update({
[COLUMN_NAME]: knex(`${REF_TABLE_NAME}`)
.select(`${REF_TABLE_NAME}.id`)
.innerJoin('badges', 'badges.id', `${REF_TABLE_NAME}.badgeId`)
// eslint-disable-next-line knex/avoid-injections
.where('badges.key', '=', knex.raw(`"${TABLE_NAME}"."partnerKey"`)),
});
};

const down = async function (knex) {
await knex.schema.table(TABLE_NAME, function (table) {
table.dropColumn(COLUMN_NAME);
});
};

export { up, down };
2 changes: 2 additions & 0 deletions api/db/seeds/data/common/tooling/session-tooling.js
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,8 @@ function _makeCandidatesPassCertification({
}).id;
databaseBuilder.factory.buildComplementaryCertificationCourseResult({
partnerKey: certificationCandidate.complementaryCertificationBadgeInfo.partnerKey,
complementaryCertificationBadgeId:
certificationCandidate.complementaryCertificationBadgeInfo.complementaryCertificationBadgeId,
acquired: true,
source: 'PIX',
complementaryCertificationCourseId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Joi from 'joi';
import { identifiersType } from '../../domain/types/identifiers-type.js';
import { securityPreHandlers } from '../security-pre-handlers.js';
import { complementaryCertificationCourseResultsController } from './complementary-certification-course-results-controller.js';
import { juryOptions } from '../../domain/models/ComplementaryCertificationCourseResult.js';

const register = async function (server) {
server.route([
Expand All @@ -13,7 +14,12 @@ const register = async function (server) {
payload: Joi.object({
data: {
attributes: {
juryLevel: Joi.string().required(),
juryLevel: Joi.alternatives()
.try(
identifiersType.complementaryCertificationBadgeId,
Joi.string().valid(juryOptions.REJECTED).valid(juryOptions.UNSET),
)
.required(),
complementaryCertificationCourseId: identifiersType.complementaryCertificationCourseId,
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ async function handleComplementaryCertificationsScoring({
const {
minimumReproducibilityRate,
complementaryCertificationCourseId,
complementaryCertificationBadgeId,
complementaryCertificationBadgeKey,
hasComplementaryReferential,
minimumEarnedPix,
Expand All @@ -49,6 +50,7 @@ async function handleComplementaryCertificationsScoring({
_buildComplementaryCertificationScoringWithReferential(
minimumReproducibilityRate,
complementaryCertificationCourseId,
complementaryCertificationBadgeId,
pixPlusChallenges,
pixPlusAnswers,
complementaryCertificationBadgeKey,
Expand All @@ -58,6 +60,7 @@ async function handleComplementaryCertificationsScoring({
complementaryCertificationScoringWithComplementaryReferential =
new ComplementaryCertificationScoringWithoutComplementaryReferential({
complementaryCertificationCourseId,
complementaryCertificationBadgeId,
complementaryCertificationBadgeKey,
reproducibilityRate: assessmentResult.reproducibilityRate,
pixScore: assessmentResult.pixScore,
Expand All @@ -69,6 +72,7 @@ async function handleComplementaryCertificationsScoring({
await complementaryCertificationCourseResultRepository.save(
ComplementaryCertificationCourseResult.from({
...complementaryCertificationScoringWithComplementaryReferential,
source: ComplementaryCertificationCourseResult.sources.PIX,
acquired: complementaryCertificationScoringWithComplementaryReferential.isAcquired(),
}),
);
Expand All @@ -78,6 +82,7 @@ async function handleComplementaryCertificationsScoring({
function _buildComplementaryCertificationScoringWithReferential(
minimumReproducibilityRate,
complementaryCertificationCourseId,
complementaryCertificationBadgeId,
challenges,
answers,
complementaryCertificationBadgeKey,
Expand All @@ -92,6 +97,7 @@ function _buildComplementaryCertificationScoringWithReferential(
return new ComplementaryCertificationScoringWithComplementaryReferential({
minimumReproducibilityRate,
complementaryCertificationCourseId,
complementaryCertificationBadgeId,
reproducibilityRate,
complementaryCertificationBadgeKey,
hasAcquiredPixCertification: assessmentResult.isValidated(),
Expand Down
4 changes: 0 additions & 4 deletions api/lib/domain/models/CertificationResult.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,6 @@ class CertificationResult {
),
];
}

_getCertificationCourseResultByPartnerKeys(partnerKeys) {
return this.complementaryCertificationCourseResults.find(({ partnerKey }) => partnerKeys.includes(partnerKey));
}
}

CertificationResult.status = status;
Expand Down
16 changes: 8 additions & 8 deletions api/lib/domain/models/ComplementaryCertificationCourseResult.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,37 @@ const juryOptions = {
};

class ComplementaryCertificationCourseResult {
constructor({ complementaryCertificationCourseId, partnerKey, source, acquired, label } = {}) {
constructor({ complementaryCertificationCourseId, complementaryCertificationBadgeId, source, acquired, label } = {}) {
this.complementaryCertificationCourseId = complementaryCertificationCourseId;
this.partnerKey = partnerKey;
this.complementaryCertificationBadgeId = complementaryCertificationBadgeId;
this.acquired = acquired;
this.source = source;
this.label = label;
}

static from({ complementaryCertificationCourseId, partnerKey, acquired, source, label }) {
static from({ complementaryCertificationCourseId, complementaryCertificationBadgeId, acquired, source, label }) {
return new ComplementaryCertificationCourseResult({
complementaryCertificationCourseId,
partnerKey,
complementaryCertificationBadgeId,
acquired,
source,
label,
});
}

static buildFromJuryLevel({ complementaryCertificationCourseId, juryLevel, pixPartnerKey }) {
if (juryLevel === juryOptions.REJECTED) {
static buildFromJuryLevel({ complementaryCertificationCourseId, complementaryCertificationBadgeId, juryLevel }) {
if (juryLevel === 'REJECTED') {
return new ComplementaryCertificationCourseResult({
complementaryCertificationCourseId,
partnerKey: pixPartnerKey,
complementaryCertificationBadgeId,
acquired: false,
source: sources.EXTERNAL,
});
}

return new ComplementaryCertificationCourseResult({
complementaryCertificationCourseId,
partnerKey: juryLevel,
complementaryCertificationBadgeId: juryLevel,
acquired: true,
source: sources.EXTERNAL,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ class ComplementaryCertificationScoringCriteria {
complementaryCertificationCourseId,
minimumReproducibilityRate,
complementaryCertificationBadgeKey,
complementaryCertificationBadgeId,
hasComplementaryReferential,
minimumEarnedPix,
} = {}) {
this.complementaryCertificationCourseId = complementaryCertificationCourseId;
this.minimumReproducibilityRate = minimumReproducibilityRate;
this.complementaryCertificationBadgeId = complementaryCertificationBadgeId;
this.complementaryCertificationBadgeKey = complementaryCertificationBadgeKey;
this.hasComplementaryReferential = hasComplementaryReferential;
this.minimumEarnedPix = minimumEarnedPix;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import { PartnerCertificationScoring } from './PartnerCertificationScoring.js';
class ComplementaryCertificationScoringWithComplementaryReferential extends PartnerCertificationScoring {
constructor({
complementaryCertificationCourseId,
complementaryCertificationBadgeId,
complementaryCertificationBadgeKey,
reproducibilityRate,
hasAcquiredPixCertification,
minimumReproducibilityRate,
} = {}) {
super({
complementaryCertificationCourseId,
complementaryCertificationBadgeId,
partnerKey: complementaryCertificationBadgeKey,
source: ComplementaryCertificationCourseResult.sources.PIX,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,17 @@ import { PartnerCertificationScoring } from './PartnerCertificationScoring.js';
class ComplementaryCertificationScoringWithoutComplementaryReferential extends PartnerCertificationScoring {
constructor({
complementaryCertificationCourseId,
complementaryCertificationBadgeKey,
complementaryCertificationBadgeId,
reproducibilityRate,
pixScore,
minimumEarnedPix,
minimumReproducibilityRate,
} = {}) {
super({
complementaryCertificationCourseId,
partnerKey: complementaryCertificationBadgeKey,
complementaryCertificationBadgeId,
});

this.complementaryCertificationCourseId = complementaryCertificationCourseId;
this.reproducibilityRate = reproducibilityRate;
this.pixScore = pixScore;
this.minimumEarnedPix = minimumEarnedPix;
Expand Down
6 changes: 3 additions & 3 deletions api/lib/domain/models/PartnerCertificationScoring.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ const SOURCES = {
};

class PartnerCertificationScoring {
constructor({ complementaryCertificationCourseId, partnerKey, source = SOURCES.PIX } = {}) {
constructor({ complementaryCertificationCourseId, complementaryCertificationBadgeId, source = SOURCES.PIX } = {}) {
this.complementaryCertificationCourseId = complementaryCertificationCourseId;
this.partnerKey = partnerKey;
this.complementaryCertificationBadgeId = complementaryCertificationBadgeId;
this.source = source;
const schema = Joi.object({
complementaryCertificationCourseId: Joi.number().integer().required(),
partnerKey: Joi.string().allow(null).required(),
complementaryCertificationBadgeId: Joi.number().integer().required(),
source: Joi.string()
.required()
.valid(...Object.values(SOURCES)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@ const complementaryCertificationStatus = {
};

class ComplementaryCertificationCourseResultForJuryCertification {
constructor({ id, partnerKey, acquired, label }) {
constructor({ id, complementaryCertificationBadgeId, acquired, label }) {
this.id = id;
this.partnerKey = partnerKey;
this.complementaryCertificationBadgeId = complementaryCertificationBadgeId;
this.acquired = acquired;
this.label = label;
}

static from({ id, partnerKey, acquired, label }) {
return new ComplementaryCertificationCourseResultForJuryCertification({ id, partnerKey, acquired, label });
static from({ id, complementaryCertificationBadgeId, acquired, label }) {
return new ComplementaryCertificationCourseResultForJuryCertification({
id,
complementaryCertificationBadgeId,
acquired,
label,
});
}

get status() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,25 @@ const { EXTERNAL, PIX } = sources;
class ComplementaryCertificationCourseResultForJuryCertificationWithExternal {
constructor({
complementaryCertificationCourseId,
pixPartnerKey,
pixComplementaryCertificationBadgeId,
pixLabel,
pixAcquired,
pixLevel,
externalPartnerKey,
externalComplementaryCertificationBadgeId,
externalLabel,
externalAcquired,
externalLevel,
allowedExternalLevels,
}) {
this.complementaryCertificationCourseId = complementaryCertificationCourseId;
this.pixSection = new Section({
partnerKey: pixPartnerKey,
complementaryCertificationBadgeId: pixComplementaryCertificationBadgeId,
label: pixLabel,
acquired: pixAcquired,
level: pixLevel,
});
this.externalSection = new Section({
partnerKey: externalPartnerKey,
complementaryCertificationBadgeId: externalComplementaryCertificationBadgeId,
label: externalLabel,
acquired: externalAcquired,
level: externalLevel,
Expand All @@ -36,7 +36,7 @@ class ComplementaryCertificationCourseResultForJuryCertificationWithExternal {
this.defaultJuryOptions = Object.values(juryOptions);
}

static from(complementaryCertificationCourseResultWithExternal, badgesKeyAndLabel) {
static from(complementaryCertificationCourseResultWithExternal, badgesIdAndLabels) {
if (!complementaryCertificationCourseResultWithExternal.length) {
return;
}
Expand All @@ -47,16 +47,18 @@ class ComplementaryCertificationCourseResultForJuryCertificationWithExternal {
({ source }) => source === EXTERNAL,
);

const allowedExternalLevels = badgesKeyAndLabel.map(({ key, label }) => ({ label, value: key }));
const allowedExternalLevels = badgesIdAndLabels.map(({ id, label }) => ({ label, value: id }));

return new ComplementaryCertificationCourseResultForJuryCertificationWithExternal({
complementaryCertificationCourseId:
complementaryCertificationCourseResultWithExternal[0].complementaryCertificationCourseId,
pixPartnerKey: pixComplementaryCertificationCourseResult?.partnerKey,
pixComplementaryCertificationBadgeId:
pixComplementaryCertificationCourseResult?.complementaryCertificationBadgeId,
pixLabel: pixComplementaryCertificationCourseResult?.label,
pixAcquired: pixComplementaryCertificationCourseResult?.acquired,
pixLevel: pixComplementaryCertificationCourseResult?.level,
externalPartnerKey: externalComplementaryCertificationCourseResult?.partnerKey,
externalComplementaryCertificationBadgeId:
externalComplementaryCertificationCourseResult?.complementaryCertificationBadgeId,
externalLabel: externalComplementaryCertificationCourseResult?.label,
externalAcquired: externalComplementaryCertificationCourseResult?.acquired,
externalLevel: externalComplementaryCertificationCourseResult?.level,
Expand Down Expand Up @@ -86,15 +88,15 @@ class ComplementaryCertificationCourseResultForJuryCertificationWithExternal {
}

class Section {
constructor({ partnerKey, label, acquired, level }) {
this.partnerKey = partnerKey;
constructor({ complementaryCertificationBadgeId, label, acquired, level }) {
this.complementaryCertificationBadgeId = complementaryCertificationBadgeId;
this.label = label;
this.acquired = acquired ?? false;
this.level = level;
}

get isEvaluated() {
return Boolean(this.partnerKey);
return Boolean(this.complementaryCertificationBadgeId);
}
}

Expand Down
1 change: 1 addition & 0 deletions api/lib/domain/types/identifiers-type.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const typesPositiveInteger32bits = [
'certificationIssueReportId',
'complementaryCertificationId',
'complementaryCertificationCourseId',
'complementaryCertificationBadgeId',
'certificationCenterInvitationId',
'membershipId',
'organizationId',
Expand Down
Loading

0 comments on commit 07f35de

Please sign in to comment.