-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[TECH] Support du format CSV pour le script de rescoring de certifica…
- Loading branch information
Showing
2 changed files
with
71 additions
and
50 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 |
---|---|---|
@@ -1,58 +1,61 @@ | ||
import 'dotenv/config'; | ||
|
||
import * as url from 'node:url'; | ||
import Joi from 'joi'; | ||
|
||
import { disconnect } from '../../db/knex-database-connection.js'; | ||
import { CertificationRescoringByScriptJob } from '../../src/certification/session-management/domain/models/CertificationRescoringByScriptJob.js'; | ||
import { certificationRescoringByScriptJobRepository } from '../../src/certification/session-management/infrastructure/repositories/jobs/certification-rescoring-by-script-job-repository.js'; | ||
import { logger } from '../../src/shared/infrastructure/utils/logger.js'; | ||
import { csvFileParser } from '../../src/shared/application/scripts/parsers.js'; | ||
import { Script } from '../../src/shared/application/scripts/script.js'; | ||
import { ScriptRunner } from '../../src/shared/application/scripts/script-runner.js'; | ||
|
||
const columnsSchemas = [{ name: 'certificationCourseId', schema: Joi.number() }]; | ||
|
||
export class RescoreCertificationScript extends Script { | ||
constructor() { | ||
super({ | ||
description: 'Rescore all certification given by CSV file. This script will schedule job to rescore', | ||
permanent: true, | ||
options: { | ||
file: { | ||
type: 'string', | ||
describe: | ||
'CSV File with only one column with certification-courses.id (integer) to process. Need `certificationCourseId`', | ||
demandOption: true, | ||
coerce: csvFileParser(columnsSchemas), | ||
}, | ||
}, | ||
}); | ||
} | ||
|
||
const modulePath = url.fileURLToPath(import.meta.url); | ||
const isLaunchedFromCommandLine = process.argv[1] === modulePath; | ||
async handle({ options, logger }) { | ||
const { file: certificationCourses } = options; | ||
const certificationCourseIds = certificationCourses.map(({ certificationCourseId }) => certificationCourseId); | ||
|
||
async function main(certificationCourseIds) { | ||
logger.info(`Publishing ${certificationCourseIds.length} rescoring jobs`); | ||
const jobs = await _scheduleRescoringJobs(certificationCourseIds); | ||
logger.info(`Publishing ${certificationCourseIds.length} rescoring jobs`); | ||
const jobs = await this.#scheduleRescoringJobs(certificationCourseIds); | ||
|
||
const errors = jobs.filter((result) => result.status === 'rejected'); | ||
if (errors.length) { | ||
errors.forEach((result) => logger.error(result.reason, 'Some jobs could not be published')); | ||
return 1; | ||
} | ||
const errors = jobs.filter((result) => result.status === 'rejected'); | ||
if (errors.length) { | ||
errors.forEach((result) => logger.error(result.reason, 'Some jobs could not be published')); | ||
return 1; | ||
} | ||
|
||
logger.info(`${jobs.length} jobs successfully published`); | ||
return 0; | ||
} | ||
logger.info(`${jobs.length} jobs successfully published`); | ||
return 0; | ||
} | ||
|
||
const _scheduleRescoringJobs = async (certificationCourseIds) => { | ||
const promisefiedJobs = certificationCourseIds.map(async (certificationCourseId) => { | ||
try { | ||
await certificationRescoringByScriptJobRepository.performAsync( | ||
new CertificationRescoringByScriptJob({ certificationCourseId }), | ||
); | ||
} catch (error) { | ||
throw new Error(`Error for certificationCourseId: [${certificationCourseId}]`, { cause: error }); | ||
} | ||
}); | ||
return Promise.allSettled(promisefiedJobs); | ||
}; | ||
|
||
(async () => { | ||
if (isLaunchedFromCommandLine) { | ||
try { | ||
const certificationCourseIds = process.argv[2] | ||
.split(',') | ||
.map((str) => parseInt(str, 10)) | ||
.filter(Number.isInteger); | ||
const exitCode = await main(certificationCourseIds); | ||
return exitCode; | ||
} catch (error) { | ||
logger.error(error); | ||
process.exitCode = 1; | ||
} finally { | ||
await disconnect(); | ||
} | ||
async #scheduleRescoringJobs(certificationCourseIds) { | ||
const promisefiedJobs = certificationCourseIds.map(async (certificationCourseId) => { | ||
try { | ||
await certificationRescoringByScriptJobRepository.performAsync( | ||
new CertificationRescoringByScriptJob({ certificationCourseId }), | ||
); | ||
} catch (error) { | ||
throw new Error(`Error for certificationCourseId: [${certificationCourseId}]`, { cause: error }); | ||
} | ||
}); | ||
return Promise.allSettled(promisefiedJobs); | ||
} | ||
})(); | ||
} | ||
|
||
export { main }; | ||
await ScriptRunner.execute(import.meta.url, RescoreCertificationScript); |
26 changes: 22 additions & 4 deletions
26
api/tests/integration/scripts/certification/rescore-certifications_test.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