Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Guillaume committed Dec 9, 2024
1 parent 48c39fd commit 2ec974e
Show file tree
Hide file tree
Showing 2 changed files with 404 additions and 0 deletions.
111 changes: 111 additions & 0 deletions api/src/profile/scripts/sixth-grade-attestation-reward.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import dayjs from 'dayjs';
import Joi from 'joi';

import { CampaignParticipationStatuses } from '../../prescription/shared/domain/constants.js';
import { usecases } from '../../quest/domain/usecases/index.js';
import { Script } from '../../shared/application/scripts/script.js';
import { ScriptRunner } from '../../shared/application/scripts/script-runner.js';
import { DomainTransaction } from '../../shared/domain/DomainTransaction.js';

export const PRODUCTION_SIXTH_GRADE_TARGET_PROFILE_IDS = [107068, 107074, 107078];
const isoDateSchema = Joi.date().iso();

const startDateDefault = '2024-12-01T00:00:00Z';
const endDateDefault = '2024-12-03T23:59:59Z';
const numberOfDaysLimitDefault = 7;

/**
*
* @param {string} startDate
* @param {string} endDate
* @returns {Promise<[number]>}
*/
export const fetchUserIds = async (startDate = startDateDefault, endDate = endDateDefault) => {
const knexConnection = DomainTransaction.getConnection();
const users = await knexConnection('campaign-participations')
.select('campaign-participations.userId')
.join('campaigns', 'campaign-participations.campaignId', 'campaigns.id')
.join('target-profiles', 'campaigns.targetProfileId', 'target-profiles.id')
.where('campaign-participations.createdAt', '>=', startDate)
.where('campaign-participations.createdAt', '<=', endDate)
.where('campaign-participations.status', '<>', CampaignParticipationStatuses.STARTED)
.whereIn('campaigns.targetProfileId', PRODUCTION_SIXTH_GRADE_TARGET_PROFILE_IDS);

return users.map(({ userId }) => userId);
};

/**
* @param {Date} date
*
* @throws {Error}
*/
const checkDateFormat = (date) => {
const dateValidationResult = isoDateSchema.validate(date);

if (dateValidationResult.error) {
throw new Error(dateValidationResult.error.message);
}
};

const checkEndDateBeforeStartDate = (startDate, endDate) => {
if (endDate < startDate) {
throw new Error('The end date must be greater than the start date');
}
};

const checkDifferenceBetweenDates = (startDate, endDate) => {
if (dayjs(endDate).diff(startDate, 'day') > numberOfDaysLimitDefault) {
throw new Error('The difference between the two dates must be less than 7 days');
}
};

export class SixthGradeAttestationRewardScript extends Script {
constructor() {
super({
description:
'This script awards attestations to sixth-grade students who have already completed a campaign linked to a target profile linked to them',
permanent: true,
options: {
firstDateLimitDefault: startDateDefault,
secondDateLimitDefault: endDateDefault,
},
});
}

/**
*
* @param {{startDate:Date, endDate:Date}} options
* @param {{info:function}}logger
* @param {function} rewardUser
* @returns {Promise<void>}
*/
async handle({ options, logger, rewardUser = usecases.rewardUser }) {
const startDate = new Date(options.startDate || startDateDefault);
const endDate = new Date(options.endDate || endDateDefault);

checkDateFormat(startDate);
checkDateFormat(endDate);
checkEndDateBeforeStartDate(startDate, endDate);
checkDifferenceBetweenDates(startDate, endDate);

logger.info(`Fetching users between ${startDate} and ${endDate}`);

const users = await fetchUserIds(startDate.toISOString(), endDate.toISOString());

if (users.length === 0) {
logger.info('No user found');
return;
}

logger.info(`${users.length} users found`);

for (const userId of users) {
await rewardUser({
userId,
});
logger.info(`Traitement de l'utilisateur ${userId}`);
}
}
}

await ScriptRunner.execute(import.meta.url, SixthGradeAttestationRewardScript);
Loading

0 comments on commit 2ec974e

Please sign in to comment.