-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[TECH] Ajouter les nouvelles tables Quests, Attestations et ProfileRe…
…wards(PIX-13818). (#9890) Co-authored-by: Quentin Lebouc <[email protected]>
- Loading branch information
Showing
10 changed files
with
264 additions
and
4 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { databaseBuffer } from '../database-buffer.js'; | ||
|
||
const buildAttestation = function ({ | ||
id = databaseBuffer.getNextId(), | ||
createdAt = new Date(), | ||
templateName = '6eme-pdf', | ||
} = {}) { | ||
const values = { | ||
id, | ||
createdAt, | ||
templateName, | ||
}; | ||
|
||
return databaseBuffer.pushInsertable({ | ||
tableName: 'attestations', | ||
values, | ||
}); | ||
}; | ||
|
||
export { buildAttestation }; |
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 |
---|---|---|
|
@@ -53,10 +53,10 @@ const buildOrganizationLearner = function ({ | |
birthCityCode = 'PERPICODE', | ||
birthCountryCode = '100', | ||
birthProvinceCode = '66', | ||
MEFCode = '45612312345', | ||
MEFCode = '10010012110', | ||
status = 'ST', | ||
nationalStudentId = null, | ||
division = '3eme', | ||
division = '6eme', | ||
studentNumber = null, | ||
email = '[email protected]', | ||
educationalTeam = 'Enseignants blonds', | ||
|
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,31 @@ | ||
import isUndefined from 'lodash/isUndefined.js'; | ||
|
||
import { databaseBuffer } from '../database-buffer.js'; | ||
import { buildAttestation } from './build-attestation.js'; | ||
import { buildUser } from './build-user.js'; | ||
|
||
const buildProfileReward = function ({ | ||
id = databaseBuffer.getNextId(), | ||
createdAt = new Date(), | ||
rewardType = 'attestations', | ||
rewardId, | ||
userId, | ||
} = {}) { | ||
userId = isUndefined(userId) ? buildUser().id : userId; | ||
rewardId = isUndefined(rewardId) && rewardType === 'attestations' ? buildAttestation().id : rewardId; | ||
|
||
const values = { | ||
id, | ||
createdAt, | ||
rewardType, | ||
rewardId, | ||
userId, | ||
}; | ||
|
||
return databaseBuffer.pushInsertable({ | ||
tableName: 'profile-rewards', | ||
values, | ||
}); | ||
}; | ||
|
||
export { buildProfileReward }; |
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,33 @@ | ||
import isUndefined from 'lodash/isUndefined.js'; | ||
|
||
import { databaseBuffer } from '../database-buffer.js'; | ||
import { buildAttestation } from './build-attestation.js'; | ||
|
||
const buildQuest = function ({ | ||
id = databaseBuffer.getNextId(), | ||
createdAt = new Date(), | ||
rewardType = 'attestations', | ||
rewardId, | ||
eligibilityRequirements, | ||
successRequirements, | ||
} = {}) { | ||
rewardId = isUndefined(rewardId) && rewardType === 'attestations' ? buildAttestation().id : rewardId; | ||
eligibilityRequirements = JSON.stringify(eligibilityRequirements); | ||
successRequirements = JSON.stringify(successRequirements); | ||
|
||
const values = { | ||
id, | ||
createdAt, | ||
rewardType, | ||
rewardId, | ||
eligibilityRequirements, | ||
successRequirements, | ||
}; | ||
|
||
return databaseBuffer.pushInsertable({ | ||
tableName: 'quests', | ||
values, | ||
}); | ||
}; | ||
|
||
export { buildQuest }; |
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,27 @@ | ||
// Make sure you properly test your migration, especially DDL (Data Definition Language) | ||
// ! If the target table is large, and the migration take more than 20 minutes, the deployment will fail ! | ||
|
||
// You can design and test your migration to avoid this by following this guide | ||
// https://1024pix.atlassian.net/wiki/spaces/DEV/pages/2153512965/Cr+er+une+migration | ||
|
||
// If your migrations target `answers` or `knowledge-elements` | ||
// contact @team-captains, because automatic migrations are not active on `pix-datawarehouse-production` | ||
// this may prevent data replication to succeed the day after your migration is deployed on `pix-api-production` | ||
const TABLE_NAME = 'quests'; | ||
|
||
const up = async function (knex) { | ||
await knex.schema.createTable(TABLE_NAME, function (table) { | ||
table.increments('id').primary(); | ||
table.dateTime('createdAt').notNullable().defaultTo(knex.fn.now()); | ||
table.string('rewardType').notNullable(); | ||
table.bigInteger('rewardId').notNullable(); | ||
table.jsonb('eligibilityRequirements').notNullable(); | ||
table.jsonb('successRequirements').notNullable(); | ||
}); | ||
}; | ||
|
||
const down = async function (knex) { | ||
return knex.schema.dropTable(TABLE_NAME); | ||
}; | ||
|
||
export { down, up }; |
24 changes: 24 additions & 0 deletions
24
api/db/migrations/20240820101115_add-attestations-table.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,24 @@ | ||
// Make sure you properly test your migration, especially DDL (Data Definition Language) | ||
// ! If the target table is large, and the migration take more than 20 minutes, the deployment will fail ! | ||
|
||
// You can design and test your migration to avoid this by following this guide | ||
// https://1024pix.atlassian.net/wiki/spaces/DEV/pages/2153512965/Cr+er+une+migration | ||
|
||
// If your migrations target `answers` or `knowledge-elements` | ||
// contact @team-captains, because automatic migrations are not active on `pix-datawarehouse-production` | ||
// this may prevent data replication to succeed the day after your migration is deployed on `pix-api-production` | ||
const TABLE_NAME = 'attestations'; | ||
|
||
const up = async function (knex) { | ||
await knex.schema.createTable(TABLE_NAME, function (table) { | ||
table.increments('id').primary(); | ||
table.dateTime('createdAt').notNullable().defaultTo(knex.fn.now()); | ||
table.string('templateName').notNullable(); | ||
}); | ||
}; | ||
|
||
const down = async function (knex) { | ||
return knex.schema.dropTable(TABLE_NAME); | ||
}; | ||
|
||
export { down, up }; |
26 changes: 26 additions & 0 deletions
26
api/db/migrations/20240820101213_add-profile-rewards-table.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,26 @@ | ||
// Make sure you properly test your migration, especially DDL (Data Definition Language) | ||
// ! If the target table is large, and the migration take more than 20 minutes, the deployment will fail ! | ||
|
||
// You can design and test your migration to avoid this by following this guide | ||
// https://1024pix.atlassian.net/wiki/spaces/DEV/pages/2153512965/Cr+er+une+migration | ||
|
||
// If your migrations target `answers` or `knowledge-elements` | ||
// contact @team-captains, because automatic migrations are not active on `pix-datawarehouse-production` | ||
// this may prevent data replication to succeed the day after your migration is deployed on `pix-api-production` | ||
const TABLE_NAME = 'profile-rewards'; | ||
|
||
const up = async function (knex) { | ||
await knex.schema.createTable(TABLE_NAME, function (table) { | ||
table.increments('id').primary(); | ||
table.dateTime('createdAt').notNullable().defaultTo(knex.fn.now()); | ||
table.bigInteger('userId').index().references('users.id'); | ||
table.string('rewardType').notNullable(); | ||
table.string('rewardId').notNullable(); | ||
}); | ||
}; | ||
|
||
const down = async function (knex) { | ||
return knex.schema.dropTable(TABLE_NAME); | ||
}; | ||
|
||
export { down, up }; |
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,97 @@ | ||
import { TARGET_PROFILE_BADGES_STAGES_ID } from './constants.js'; | ||
|
||
async function createAttestationQuest(databasebuilder) { | ||
const campaigns = await retrieveCampaigns(databasebuilder); | ||
const evaluatedSkills = await retrieveEvaluatedSkills(databasebuilder, campaigns); | ||
const successfulUsers = await retrieveSuccessfulUsers(databasebuilder, campaigns); | ||
|
||
const { id: rewardId } = await databasebuilder.factory.buildAttestation({ | ||
templateName: '6eme-pdf', | ||
}); | ||
|
||
const questEligibilityRequirements = [ | ||
{ | ||
type: 'organization', | ||
data: { | ||
type: 'SCO', | ||
}, | ||
}, | ||
{ | ||
type: 'organization', | ||
data: { | ||
isManagingStudents: true, | ||
tagNames: ['AEFE'], | ||
}, | ||
comparison: 'one-of', | ||
}, | ||
{ | ||
type: 'organization-learner', | ||
data: { | ||
MEFCode: '10010012110', | ||
}, | ||
}, | ||
{ | ||
type: 'campaign-participation', | ||
data: { | ||
targetProfileIds: [TARGET_PROFILE_BADGES_STAGES_ID], | ||
}, | ||
}, | ||
]; | ||
const questSuccessRequirements = [ | ||
{ | ||
type: 'skill', | ||
data: { | ||
ids: evaluatedSkills.map((skill) => skill.skillId), | ||
threshold: 50, | ||
}, | ||
}, | ||
]; | ||
|
||
await databasebuilder.factory.buildQuest({ | ||
rewardType: 'attestation', | ||
rewardId, | ||
eligibilityRequirements: questEligibilityRequirements, | ||
successRequirements: questSuccessRequirements, | ||
}); | ||
|
||
await Promise.all( | ||
successfulUsers.map(({ userId }) => { | ||
return databasebuilder.factory.buildProfileReward({ | ||
userId, | ||
rewardType: 'attestation', | ||
rewardId, | ||
}); | ||
}), | ||
); | ||
} | ||
|
||
export function buildQuests(databaseBuilder) { | ||
return createAttestationQuest(databaseBuilder); | ||
} | ||
|
||
async function retrieveCampaigns(databaseBuilder) { | ||
return databaseBuilder.knex('campaigns').select('id').where({ | ||
targetProfileId: TARGET_PROFILE_BADGES_STAGES_ID, | ||
}); | ||
} | ||
|
||
async function retrieveEvaluatedSkills(databaseBuilder, campaigns) { | ||
return databaseBuilder | ||
.knex('campaign_skills') | ||
.distinct('skillId') | ||
.whereIn( | ||
'campaignId', | ||
campaigns.map((campaign) => campaign.id), | ||
); | ||
} | ||
|
||
async function retrieveSuccessfulUsers(databaseBuilder, campaigns) { | ||
return databaseBuilder | ||
.knex('campaign-participations') | ||
.distinct('userId') | ||
.whereIn( | ||
'campaignId', | ||
campaigns.map((campaign) => campaign.id), | ||
) | ||
.andWhere('masteryRate', '>=', 0.5); | ||
} |
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,13 +1,15 @@ | ||
import { buildCampaigns } from './build-campaigns.js'; | ||
import { buildOrganizationLearners } from './build-learners.js'; | ||
import { buildPlaceLots } from './build-place-lots.js'; | ||
import { buildQuests } from './build-quests.js'; | ||
import { buildTargetProfiles } from './build-target-profiles.js'; | ||
|
||
async function teamPrescriptionDataBuilder({ databaseBuilder }) { | ||
await buildTargetProfiles(databaseBuilder); | ||
await buildCampaigns(databaseBuilder); | ||
await buildOrganizationLearners(databaseBuilder); | ||
await buildPlaceLots(databaseBuilder); | ||
await buildQuests(databaseBuilder); | ||
} | ||
|
||
export { teamPrescriptionDataBuilder }; |