diff --git a/api/src/controllers/migration.js b/api/src/controllers/migration.js index 0bba2014c..b25a0a6ed 100644 --- a/api/src/controllers/migration.js +++ b/api/src/controllers/migration.js @@ -38,311 +38,32 @@ router.put( try { await sequelize.transaction(async (tx) => { - if (req.params.migrationName === "reports-from-real-date-to-date-id") { + /* + // Example of migration: + if (req.params.migrationName === "migration-name") { try { + z.array(z.string().regex(looseUuidRegex)).parse(req.body.thingsIdsToDestroy); z.array( z.object({ _id: z.string().regex(looseUuidRegex), encrypted: z.string(), encryptedEntityKey: z.string(), }) - ).parse(req.body.reportsToMigrate); + ).parse(req.body.thingsToUpdate); } catch (e) { - const error = new Error(`Invalid request in reports-from-real-date-to-date-id migration: ${e}`); - error.status = 400; - throw error; - } - for (const { _id, encrypted, encryptedEntityKey } of req.body.reportsToMigrate) { - const report = await Report.findOne({ where: { _id, organisation: req.user.organisation }, transaction: tx }); - if (report) { - report.set({ encrypted, encryptedEntityKey }); - await report.save(); - } - } - } - - if (req.params.migrationName === "clean-reports-with-no-team-nor-date") { - try { - z.array(z.string().regex(looseUuidRegex)).parse(req.body.reportIdsToDelete); - } catch (e) { - const error = new Error(`Invalid request in reports-from-real-date-to-date-id migration: ${e}`); - error.status = 400; - throw error; - } - for (const _id of req.body.reportIdsToDelete) { - await Report.destroy({ where: { _id, organisation: req.user.organisation }, transaction: tx }); - } - } - - if (req.params.migrationName === "clean-duplicated-reports-4") { - try { - z.object({ - reportIdsToDelete: z.array(z.string().regex(looseUuidRegex)), - consolidatedReports: z.array( - z.object({ - _id: z.string().regex(looseUuidRegex), - encrypted: z.string(), - encryptedEntityKey: z.string(), - }) - ), - }).parse(req.body); - } catch (e) { - const error = new Error(`Invalid request in clean-duplicated-reports-4: ${e}`); - error.status = 400; - throw error; - } - for (const { _id, encrypted, encryptedEntityKey } of req.body.consolidatedReports) { - const report = await Report.findOne({ where: { _id, organisation: req.user.organisation }, transaction: tx }); - if (report) { - report.set({ encrypted, encryptedEntityKey }); - await report.save(); - } - } - for (const _id of req.body.reportIdsToDelete) { - await Report.destroy({ where: { _id, organisation: req.user.organisation }, transaction: tx }); - } - } - if (req.params.migrationName === "update-outOfActiveListReason-and-healthInsurances-to-multi-choice") { - try { - z.array( - z.object({ - _id: z.string().regex(looseUuidRegex), - encrypted: z.string(), - encryptedEntityKey: z.string(), - }) - ).parse(req.body.personsToUpdate); - } catch (e) { - const error = new Error(`Invalid request in reports-from-real-date-to-date-id migration: ${e}`); - error.status = 400; - throw error; - } - for (const { _id, encrypted, encryptedEntityKey } of req.body.personsToUpdate) { - const person = await Person.findOne({ where: { _id, organisation: req.user.organisation }, transaction: tx }); - if (person) { - person.set({ encrypted, encryptedEntityKey }); - await person.save(); - } - } - - if (Array.isArray(organisation?.fieldsPersonsCustomizableOptions)) { - organisation.set({ - fieldsPersonsCustomizableOptions: organisation?.fieldsPersonsCustomizableOptions.map((field) => { - if (field.name !== "outOfActiveListReason") return field; - return { - name: "outOfActiveListReasons", - type: "multi-choice", - label: "Motif(s) de sortie de file active", - options: field.options, - showInStats: true, - enabled: true, - }; - }), - }); - } - await organisation.save({ transaction: tx }); - } - if (req.params.migrationName === "action-with-multiple-team") { - try { - z.array( - z.object({ - _id: z.string().regex(looseUuidRegex), - encrypted: z.string(), - encryptedEntityKey: z.string(), - }) - ).parse(req.body.actionsToUpdate); - } catch (e) { - const error = new Error(`Invalid request in action-with-multiple-team migration: ${e}`); - error.status = 400; - throw error; - } - for (const { _id, encrypted, encryptedEntityKey } of req.body.actionsToUpdate) { - const action = await Action.findOne({ where: { _id, organisation: req.user.organisation }, transaction: tx }); - if (action) { - action.set({ encrypted, encryptedEntityKey }); - await action.save(); - } - } - } - - if (req.params.migrationName === "services-in-services-table") { - try { - z.array( - z.object({ - _id: z.string().regex(looseUuidRegex), - encrypted: z.string(), - encryptedEntityKey: z.string(), - }) - ).parse(req.body.reportsToUpdate); - z.array( - z.object({ - team: z.string().regex(looseUuidRegex), - date: z.string().regex(dateRegex), - service: z.string(), - count: z.number(), - }) - ).parse(req.body.servicesToSaveInDB); - } catch (e) { - const error = new Error(`Invalid request in services-in-services-table migration: ${e}`); + const error = new Error(`Invalid request in migration-name: ${e}`); error.status = 400; throw error; } - - // Get all teams (to remove services with a team that doesn't exist anymore) - const teams = await Team.findAll({ where: { organisation: req.user.organisation }, transaction: tx }); - - // Filter invalid services - const servicesToSaveInDB = [...req.body.servicesToSaveInDB].filter( - (e) => e.count > 0 && Boolean(e.service) && Boolean(e.date) && Boolean(e.team) && teams.find((t) => t._id === e.team) - ); - - // Update services that already exists (when there is both a service and a report for the same date) - const servicesInDB = await Service.findAll({ - where: { organisation: req.user.organisation }, - transaction: tx, - }); - for (const serviceInDB of servicesInDB) { - const index = servicesToSaveInDB.findIndex( - (service) => service.service === serviceInDB.service && service.date === serviceInDB.date && service.team === serviceInDB.team - ); - if (index !== -1) { - const service = servicesToSaveInDB[index]; - serviceInDB.set({ count: service.count + serviceInDB.count }); - await serviceInDB.save(); - servicesToSaveInDB.splice(index, 1); - } - } - - // Create services entries. - await Service.bulkCreate( - servicesToSaveInDB.map((service) => ({ ...service, organisation: req.user.organisation })), - { transaction: tx } - ); - for (const { _id, encrypted, encryptedEntityKey } of req.body.reportsToUpdate) { - const report = await Report.findOne({ where: { _id, organisation: req.user.organisation }, transaction: tx }); - if (report) { - report.set({ encrypted, encryptedEntityKey }); - await report.save(); - } - } - } - - if (req.params.migrationName === "clean-reports-with-services") { - try { - z.array( - z.object({ - _id: z.string().regex(looseUuidRegex), - encrypted: z.string(), - encryptedEntityKey: z.string(), - }) - ).parse(req.body.reportsToUpdate); - } catch (e) { - const error = new Error(`Invalid request in clean-reports-with-services migration: ${e}`); - error.status = 400; - throw error; - } - - for (const { _id, encrypted, encryptedEntityKey } of req.body.reportsToUpdate) { - const report = await Report.findOne({ where: { _id, organisation: req.user.organisation }, transaction: tx }); - if (report) { - report.set({ encrypted, encryptedEntityKey }); - await report.save(); - } - } - } - - if (req.params.migrationName === "comments-reset-person-id") { - try { - z.array( - z.object({ - _id: z.string().regex(looseUuidRegex), - encrypted: z.string(), - encryptedEntityKey: z.string(), - }) - ).parse(req.body.commentsToUpdate); - } catch (e) { - const error = new Error(`Invalid request in comments-reset-person-id migration: ${e}`); - error.status = 400; - throw error; - } - for (const { _id, encrypted, encryptedEntityKey } of req.body.commentsToUpdate) { - const comment = await Comment.findOne({ where: { _id, organisation: req.user.organisation }, transaction: tx }); - if (comment) { - comment.set({ encrypted, encryptedEntityKey }); - await comment.save(); - } - } - } - if (req.params.migrationName === "remove-medical-docs-from-persons") { - try { - z.array( - z.object({ - _id: z.string().regex(looseUuidRegex), - encrypted: z.string(), - encryptedEntityKey: z.string(), - }) - ).parse(req.body.personsToUpdate); - } catch (e) { - const error = new Error(`Invalid request in remove-medical-docs-from-persons: ${e}`); - error.status = 400; - throw error; - } - for (const { _id, encrypted, encryptedEntityKey } of req.body.personsToUpdate) { - const person = await Person.findOne({ where: { _id, organisation: req.user.organisation }, transaction: tx }); - if (person) { - person.set({ encrypted, encryptedEntityKey }); - await person.save(); - } - } - } - - if (req.params.migrationName === "retrieve-docs-from-persons-backup") { - try { - z.array( - z.object({ - _id: z.string().regex(looseUuidRegex), - encrypted: z.string(), - encryptedEntityKey: z.string(), - }) - ).parse(req.body.personsToUpdate); - } catch (e) { - const error = new Error(`Invalid request in retrieve-docs-from-persons-backup: ${e}`); - error.status = 400; - throw error; - } - for (const { _id, encrypted, encryptedEntityKey } of req.body.personsToUpdate) { - const person = await Person.findOne({ where: { _id, organisation: req.user.organisation }, transaction: tx }); - if (person) { - person.set({ encrypted, encryptedEntityKey }); - await person.save(); - } - } - } - - if (req.params.migrationName === "fix-family-relation-user-deleted") { - try { - z.object({ - groupIdsToDestroy: z.array(z.string().regex(looseUuidRegex)), - groupsToUpdate: z.array( - z.object({ - _id: z.string().regex(looseUuidRegex), - encrypted: z.string(), - encryptedEntityKey: z.string(), - }) - ), - }).parse(req.body); - } catch (e) { - const error = new Error(`Invalid request in fix-family-relation-user-deleted migration: ${e}`); - error.status = 400; - throw error; + for (const _id of req.body.thingsIdsToDestroy) { + await Thing.destroy({ where: { _id, organisation: req.user.organisation }, transaction: tx }); } - for (const { _id, encrypted, encryptedEntityKey } of req.body.groupsToUpdate) { - const group = await Group.findOne({ where: { _id, organisation: req.user.organisation }, transaction: tx }); - if (group) { - group.set({ encrypted, encryptedEntityKey }); - await group.save(); - } + for (const { _id, encrypted, encryptedEntityKey } of req.body.thingsToUpdate) { + await Thing.update({ encrypted, encryptedEntityKey }, { where: { _id }, transaction: tx, paranoid: false }); } } + // End of example of migration. + */ if (req.params.migrationName === "integrate-comments-in-actions-history") { try { diff --git a/dashboard/src/components/DataMigrator.js b/dashboard/src/components/DataMigrator.js index 7cb181881..4d2d14cb4 100644 --- a/dashboard/src/components/DataMigrator.js +++ b/dashboard/src/components/DataMigrator.js @@ -12,6 +12,7 @@ import { prepareGroupForEncryption } from '../recoil/groups'; const LOADING_TEXT = 'Mise à jour des données de votre organisation…'; +/*eslint no-unused-vars: "off"*/ export default function useDataMigrator() { const setLoadingText = useSetRecoilState(loadingTextState); const user = useRecoilValue(userState); @@ -26,376 +27,23 @@ export default function useDataMigrator() { // `migrationLastUpdateAt` should be set after each migration and send in every PUT/POST/PATCH request to server. migrateData: async () => { let migrationLastUpdateAt = organisation.migrationLastUpdateAt; - if (!organisation.migrations?.includes('reports-from-real-date-to-date-id')) { - await new Promise((res) => setTimeout(res, 500)); + /* + // Example of migration: + if (!organisation.migrations?.includes('migration-name')) { setLoadingText(LOADING_TEXT); - const res = await API.get({ - path: '/report', + const somethingRes = await API.get({ + path: '/something-to-update', query: { organisation: organisationId, after: 0, withDeleted: false }, - }); - const reportsToMigrate = (res.decryptedData || []) - .filter((r) => !!r.team && !!r.date) - .map((report) => ({ - ...report, - date: dayjsInstance(report.date).format('YYYY-MM-DD'), - oldDateSystem: report.date, // just to track if we did bad stuff - })); - const encryptedReportsToMigrate = await Promise.all(reportsToMigrate.map(prepareReportForEncryption).map(encryptItem)); - const response = await API.put({ - path: `/migration/reports-from-real-date-to-date-id`, - body: { reportsToMigrate: encryptedReportsToMigrate }, - query: { migrationLastUpdateAt }, - }); - if (response.ok) { - setOrganisation(response.organisation); - migrationLastUpdateAt = response.organisation.migrationLastUpdateAt; - } - } - if (!organisation.migrations?.includes('clean-reports-with-no-team-nor-date')) { - setLoadingText(LOADING_TEXT); - const res = await API.get({ - path: '/report', - query: { organisation: organisationId, after: 0, withDeleted: false }, - }); - const reportIdsToDelete = (res.decryptedData || []).filter((r) => !r.team || !r.date).map((r) => r._id); - - const response = await API.put({ - path: `/migration/clean-reports-with-no-team-nor-date`, - body: { reportIdsToDelete }, - query: { migrationLastUpdateAt }, - }); - if (response.ok) { - setOrganisation(response.organisation); - migrationLastUpdateAt = response.organisation.migrationLastUpdateAt; - } - } - if (!organisation.migrations?.includes('clean-duplicated-reports-4')) { - setLoadingText(LOADING_TEXT); - const res = await API.get({ - path: '/report', - query: { organisation: organisationId, after: 0, withDeleted: false }, - }); - const reportsObjByTeamAndDate = (res.decryptedData || []) - // sorting the oldest first so that - // when we loop over the reports to create a consolidates unique report - // the first to be looped is the oldest one, the last is the newest one - // so that we keep the newest report's data - .sort((a, b) => new Date(b.updatedAt) - new Date(a.updatedAt)) - .reduce((reportsObj, report) => { - if (!reportsObj[`${report.team}-${report.date}`]) reportsObj[`${report.team}-${report.date}`] = []; - reportsObj[`${report.team}-${report.date}`].push(report); - return reportsObj; - }, {}); - const reportIdsToDelete = []; - const consolidatedReports = Object.values(reportsObjByTeamAndDate).map((reports) => { - if (reports.length === 1) return reports[0]; - const consolidatedReport = { - _id: reports[0]._id, - createdAt: reports[0].createdAt, - updatedAt: reports[0].updatedAt, - organisation: reports[0].organisation, - team: reports[0].team, - date: reports[0].date, - // services - // description - // collaborations - }; - for (const [index, report] of Object.entries(reports)) { - if (report.services) { - const oldServices = JSON.parse(consolidatedReport.services || '{}'); - const newServices = JSON.parse(report.services || '{}'); - consolidatedReport.services = {}; - for (const [serviceKey, serviceValue] of Object.entries(oldServices)) { - consolidatedReport.services[serviceKey] = (serviceValue || 0) + (consolidatedReport.services[serviceKey] || 0); - } - for (const [serviceKey, serviceValue] of Object.entries(newServices)) { - consolidatedReport.services[serviceKey] = (serviceValue || 0) + (consolidatedReport.services[serviceKey] || 0); - } - consolidatedReport.services = JSON.stringify(consolidatedReport.services); - } - if (report.description) { - consolidatedReport.description = `${consolidatedReport.description || ''}\n\n${report.description}`; - } - if (report.collaborations) consolidatedReport.collaborations = report.collaborations; - if (Number(index) !== 0) reportIdsToDelete.push(report._id); - } - return consolidatedReport; - }); - - const encryptedConsolidatedReports = await Promise.all(consolidatedReports.map(prepareReportForEncryption).map(encryptItem)); - - const response = await API.put({ - path: `/migration/clean-duplicated-reports-4`, - body: { consolidatedReports: encryptedConsolidatedReports, reportIdsToDelete }, - query: { migrationLastUpdateAt }, - }); - if (response.ok) { - setOrganisation(response.organisation); - migrationLastUpdateAt = response.organisation.migrationLastUpdateAt; - } - } - if (!organisation.migrations?.includes('update-outOfActiveListReason-and-healthInsurances-to-multi-choice')) { - setLoadingText(LOADING_TEXT); - const res = await API.get({ - path: '/person', - query: { organisation: organisationId, after: 0, withDeleted: false }, - }); - const personsToUpdate = (res.decryptedData || []).map((p) => ({ - ...p, - outOfActiveListReasons: p.outOfActiveListReason ? [p.outOfActiveListReason] : [], - healthInsurances: p.healthInsurance ? [p.healthInsurance] : [], - })); - const encryptedPersonsToMigrate = await Promise.all(personsToUpdate.map(preparePersonForEncryption).map(encryptItem)); - const response = await API.put({ - path: `/migration/update-outOfActiveListReason-and-healthInsurances-to-multi-choice`, - body: { personsToUpdate: encryptedPersonsToMigrate }, - query: { migrationLastUpdateAt }, - }); - if (response.ok) { - setOrganisation(response.organisation); - migrationLastUpdateAt = response.organisation.migrationLastUpdateAt; - } - } - if (!organisation.migrations?.includes('action-with-multiple-team')) { - setLoadingText(LOADING_TEXT); - const res = await API.get({ - path: '/action', - query: { organisation: organisationId, after: 0, withDeleted: false }, - }); - const actionsToUpdate = (res.decryptedData || []).map((a) => { - const { team, ...action } = a; - return { ...action, teams: action.teams?.length ? action.teams : [team] }; - }); - const encryptedActionsToMigrate = await Promise.all( - actionsToUpdate.map((action) => prepareActionForEncryption({ ...action, user: action.user || user._id })).map(encryptItem) - ); - const response = await API.put({ - path: `/migration/action-with-multiple-team`, - body: { actionsToUpdate: encryptedActionsToMigrate }, - query: { migrationLastUpdateAt }, - }); - if (response.ok) { - setOrganisation(response.organisation); - migrationLastUpdateAt = response.organisation.migrationLastUpdateAt; - } - } - - if (!organisation.migrations?.includes('services-in-services-table')) { - setLoadingText(LOADING_TEXT); - const res = await API.get({ - path: '/report', - query: { organisation: organisationId, after: 0, withDeleted: false }, - }); - const reportsToUpdate = (res.decryptedData || []).filter((e) => e.services && Object.values(JSON.parse(e.services || '{}')).length); - const reportsWithoutServicesProperty = reportsToUpdate.map((e) => { - const { services, ...report } = e; - return report; - }); - // Save all services in services table - const servicesToSaveInDB = reportsToUpdate.reduce((acc, report) => { - const services = Object.entries(JSON.parse(report.services || '{}')) - .filter(([, value]) => value) - .map(([service, value]) => ({ - team: report.team, - date: report.date, - service: String(service), - count: Number(value), - })); - return [...acc, ...services]; - }, []); - - const encryptedReportsToMigrate = await Promise.all(reportsWithoutServicesProperty.map(prepareReportForEncryption).map(encryptItem)); - const response = await API.put({ - path: `/migration/services-in-services-table`, - body: { reportsToUpdate: encryptedReportsToMigrate, servicesToSaveInDB }, - query: { migrationLastUpdateAt }, - }); - if (response.ok) { - setOrganisation(response.organisation); - migrationLastUpdateAt = response.organisation.migrationLastUpdateAt; - } - } - - if (!organisation.migrations?.includes('comments-reset-person-id')) { - setLoadingText(LOADING_TEXT); - const res = await API.get({ - path: '/comment', - query: { organisation: organisationId, after: 0, withDeleted: false }, - }); - const commentsTransformedFromPersonObjectToPersonUuid = (res.decryptedData || []) - .filter((comment) => { - // we select only comments with person "populated" - if (!!comment.action) return false; - if (!comment.person) return false; - if (looseUuidRegex.test(comment.person)) return false; - if (!comment?.person?._id) return false; - return true; - }) - .map((comment) => ({ - ...comment, - person: comment.person._id, - })); - - const encryptedCommentsToMigrate = await Promise.all( - commentsTransformedFromPersonObjectToPersonUuid.map(prepareCommentForEncryption).map(encryptItem) - ); - const response = await API.put({ - path: `/migration/comments-reset-person-id`, - body: { commentsToUpdate: encryptedCommentsToMigrate }, - query: { migrationLastUpdateAt }, - }); - if (response.ok) { - setOrganisation(response.organisation); - migrationLastUpdateAt = response.organisation.migrationLastUpdateAt; - } - } - - if (!organisation.migrations?.includes('clean-reports-with-services')) { - // this migration comes after the bug writtne in migration "services-in-services-table" - // https://github.com/SocialGouv/mano/commit/7a8ae27972157b77bd6334353201f0786ae1daac - // what we did to fix this bug is: we had a backp with good reports and we replaced the bad ones with the good ones - // so we need to clean the reports with services - and no need to save the services in services table - setLoadingText(LOADING_TEXT); - const res = await API.get({ - path: '/report', - query: { organisation: organisationId, after: 0, withDeleted: false }, - }); - const reportsToUpdate = (res.decryptedData || []).filter((e) => e.services && Object.values(JSON.parse(e.services || '{}')).length); - const reportsWithoutServicesProperty = reportsToUpdate.map((e) => { - const { services, ...report } = e; - return report; - }); - // Save all services in services table - - const encryptedReportsToMigrate = await Promise.all(reportsWithoutServicesProperty.map(prepareReportForEncryption).map(encryptItem)); - const response = await API.put({ - path: `/migration/clean-reports-with-services`, - body: { reportsToUpdate: encryptedReportsToMigrate }, - query: { migrationLastUpdateAt }, - }); - if (response.ok) { - setOrganisation(response.organisation); - migrationLastUpdateAt = response.organisation.migrationLastUpdateAt; - } - } - - if (!organisation.migrations?.includes('remove-medical-docs-from-persons')) { - setLoadingText(LOADING_TEXT); - const personRes = await API.get({ - path: '/person', - query: { organisation: organisationId, after: 0, withDeleted: false }, - }); - const medicalFileRes = await API.get({ - path: '/medical-file', - query: { organisation: organisationId, after: 0, withDeleted: false }, - }); - const personsToUpdate = (personRes.decryptedData || []) - .filter((_person) => { - if (!_person.documents?.length) return false; - const medicalFile = medicalFileRes.decryptedData.find((mf) => mf.person === _person._id); - if (!medicalFile) return false; - return true; - }) - .map((_person) => { - const medicalFile = medicalFileRes.decryptedData.find((mf) => mf.person === _person._id); - if (!medicalFile) return _person; - const medicalFileDocuments = medicalFile.documents || []; - - return { - ..._person, - documents: _person.documents.filter((_doc) => { - if (medicalFileDocuments.find((_medicalDoc) => _medicalDoc._id === _doc._id)) return false; - return true; - }), - }; - }); - const encryptedPersonsToMigrate = await Promise.all(personsToUpdate.map(preparePersonForEncryption).map(encryptItem)); - const response = await API.put({ - path: `/migration/remove-medical-docs-from-persons`, - body: { personsToUpdate: encryptedPersonsToMigrate }, - query: { migrationLastUpdateAt }, - }); - if (response.ok) { - setOrganisation(response.organisation); - migrationLastUpdateAt = response.organisation.migrationLastUpdateAt; - } - } - if (!organisation.migrations?.includes('retrieve-docs-from-persons-backup')) { - setLoadingText(LOADING_TEXT); - const personRes = await API.get({ - path: '/person', - query: { organisation: organisationId, after: 0, withDeleted: false }, - }); - const personBackupRes = await API.get({ - path: '/person-backup', - query: { organisation: organisationId, after: 0, withDeleted: false }, - }); - const personBackupWithDocuments = (personBackupRes.decryptedData || []).filter((e) => e.documents?.length); - const personsThatNeedToBeUpdated = (personRes.decryptedData || []).filter((e) => { - const personBackup = personBackupWithDocuments.find((pb) => pb._id === e._id); - if (!personBackup) return false; - return true; - }); - - const personsToUpdate = personsThatNeedToBeUpdated.map((person) => { - const personBackup = personBackupWithDocuments.find((pb) => pb._id === person._id); - if (!personBackup) return person; - const backupDocuments = personBackup.documents || []; - const personDocuments = (person.documents || []).filter((doc) => !backupDocuments.find((bd) => bd._id === doc._id)); - return { - ...person, - documents: [...backupDocuments, ...personDocuments], - }; - }); + }).then((res) => res.decryptedData || []); - const encryptedPersonsToMigrate = await Promise.all(personsToUpdate.map(preparePersonForEncryption).map(encryptItem)); - const response = await API.put({ - path: `/migration/retrieve-docs-from-persons-backup`, - body: { personsToUpdate: encryptedPersonsToMigrate }, - query: { migrationLastUpdateAt }, - }); - if (response.ok) { - setOrganisation(response.organisation); - migrationLastUpdateAt = response.organisation.migrationLastUpdateAt; - } - } - if (!organisation.migrations?.includes('fix-family-relation-user-deleted')) { - setLoadingText(LOADING_TEXT); - const personRes = await API.get({ - path: '/person', - query: { organisation: organisationId, after: 0, withDeleted: false }, - }); - const persons = personRes.decryptedData; - const groupRes = await API.get({ - path: '/group', - query: { organisation: organisationId, after: 0, withDeleted: false }, + const somethingToUpdate = somethingRes.map((e) => { + // do something }); - const groupsToUpdate = []; - const groupIdsToDestroy = []; - for (const group of groupRes.decryptedData) { - let updateGroup = false; - let updatedGroup = { ...group, persons: group.persons, relations: group.relations }; - for (const personId of group.persons) { - if (!persons.find((p) => p._id === personId)) { - updateGroup = true; - updatedGroup.persons = updatedGroup.persons.filter((p) => p._id !== personId); - updatedGroup.relations = updatedGroup.relations.filter((rel) => !rel.persons.includes(personId)); - } - } - if (updateGroup) { - if (group.relations.length === 0) { - groupIdsToDestroy.push(group._id); - } else { - groupsToUpdate.push(updatedGroup); - } - } - } - - const encryptedGroupsToUpdate = await Promise.all(groupsToUpdate.map(prepareGroupForEncryption).map(encryptItem)); + const encryptedThingsToUpdate = await Promise.all(somethingToUpdate.map(prepareForEncryption).map(encryptItem)); const response = await API.put({ - path: `/migration/fix-family-relation-user-deleted`, - body: { groupsToUpdate: encryptedGroupsToUpdate, groupIdsToDestroy }, + path: `/migration/migration-name`, + body: { thingsToUpdate: encryptedThingsToUpdate, thingsIdsToDestroy: [] }, query: { migrationLastUpdateAt }, }); if (response.ok) { @@ -403,6 +51,8 @@ export default function useDataMigrator() { migrationLastUpdateAt = response.organisation.migrationLastUpdateAt; } } + // End of example of migration. + */ if (!organisation.migrations?.includes('integrate-comments-in-actions-history')) { setLoadingText(LOADING_TEXT);