From 4c07b66a4e9c5a7b12171369fb05899940ba9b0f Mon Sep 17 00:00:00 2001 From: P-Jeremy Date: Wed, 11 Dec 2024 16:23:38 +0100 Subject: [PATCH] feat(api): add script to convert users orga cgu accepted to legal document user acceptances --- .../convert-users-orga-cgu-data.js | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 api/scripts/legal-documents/convert-users-orga-cgu-data.js diff --git a/api/scripts/legal-documents/convert-users-orga-cgu-data.js b/api/scripts/legal-documents/convert-users-orga-cgu-data.js new file mode 100644 index 00000000000..ff25109301a --- /dev/null +++ b/api/scripts/legal-documents/convert-users-orga-cgu-data.js @@ -0,0 +1,92 @@ +import 'dotenv/config'; + +import { DomainTransaction } from '../../lib/infrastructure/DomainTransaction.js'; +import { LegalDocument } from '../../src/legal-documents/domain/models/LegalDocument.js'; +import * as legalDocumentRepository from '../../src/legal-documents/infrastructure/repositories/legal-document.repository.js'; +import { Script } from '../../src/shared/application/scripts/script.js'; +import { ScriptRunner } from '../../src/shared/application/scripts/script-runner.js'; + +const { TOS } = LegalDocument.TYPES; +const { PIX_ORGA } = LegalDocument.SERVICES; + +const BATCH_SIZE = 1000; +const THROTTLE_DELAY = 100; + +export class ConvertUsersOrgaCguData extends Script { + constructor() { + super({ + description: 'Convert users orga CGU data to legal-document-versions-user-acceptances', + permanent: false, + options: {}, + }); + } + + async handle({ logger }) { + const tosOrgaLegalDocument = await legalDocumentRepository.findLastVersionByTypeAndService({ + type: TOS, + service: PIX_ORGA, + }); + + if (!tosOrgaLegalDocument) { + logger.info(`No legal document found for type:${TOS}, service:${PIX_ORGA}`); + return; + } + + const knexConnection = DomainTransaction.getConnection(); + + let hasMoreUsers = true; + let offset = 0; + + while (hasMoreUsers) { + const batch = await this.#findOrgaCguAcceptedUsers({ knexConnection, offset }); + + if (batch.length === 0) { + hasMoreUsers = false; + break; + } + + await this.#createNewLegalDocumentAcceptanceForUsersBatch({ batch, tosOrgaLegalDocument }); + + offset += batch.length; + await this.#throttle(); + } + + logger.info('Processing complete.'); + } + + async #createNewLegalDocumentAcceptanceForUsersBatch({ batch, tosOrgaLegalDocument }) { + await Promise.all( + batch.map((user) => + this.#createLegalDocumentUserAcceptance({ + userId: user.id, + legalDocumentVersionId: tosOrgaLegalDocument.id, + acceptedAt: user.lastPixOrgaTermsOfServiceValidatedAt, + }), + ), + ); + } + + async #findOrgaCguAcceptedUsers({ knexConnection, offset }) { + return knexConnection('users') + .select('*') + .where('pixOrgaTermsOfServiceAccepted', true) + .limit(BATCH_SIZE) + .offset(offset); + } + + async #createLegalDocumentUserAcceptance({ userId, legalDocumentVersionId, acceptedAt }) { + const knexConnection = DomainTransaction.getConnection(); + + await knexConnection('legal-document-version-user-acceptances').insert({ + userId, + legalDocumentVersionId, + acceptedAt, + }); + } + + async #throttle() { + return new Promise((resolve) => setTimeout(resolve, THROTTLE_DELAY)); + } +} + +await ScriptRunner.execute(import.meta.url, ConvertUsersOrgaCguData);