From d532b56c3c36c7c2e050b9978ce6df75e6b619a0 Mon Sep 17 00:00:00 2001 From: Arnaud AMBROSELLI Date: Mon, 15 Jan 2024 11:36:35 +0100 Subject: [PATCH] fix: observations metadata --- api/src/controllers/migration.js | 2 +- dashboard/src/components/DataMigrator.js | 77 ++++++++++--------- dashboard/src/recoil/territoryObservations.js | 2 +- dashboard/src/scenes/auth/signin.js | 5 +- 4 files changed, 47 insertions(+), 39 deletions(-) diff --git a/api/src/controllers/migration.js b/api/src/controllers/migration.js index aa7759d325..c2447b9cb5 100644 --- a/api/src/controllers/migration.js +++ b/api/src/controllers/migration.js @@ -89,7 +89,7 @@ router.put( } // End of example of migration. */ - if (req.params.migrationName === "reformat-observedAt-observations") { + if (req.params.migrationName === "reformat-observedAt-observations-fixed") { try { z.array( z.object({ diff --git a/dashboard/src/components/DataMigrator.js b/dashboard/src/components/DataMigrator.js index 67c382023f..3e8a0152de 100644 --- a/dashboard/src/components/DataMigrator.js +++ b/dashboard/src/components/DataMigrator.js @@ -18,7 +18,7 @@ import { prepareMedicalFileForEncryption } from '../recoil/medicalFiles'; import { preparePassageForEncryption } from '../recoil/passages'; import { prepareRencontreForEncryption } from '../recoil/rencontres'; import { prepareTerritoryForEncryption } from '../recoil/territory'; -import { customFieldsObsSelector, prepareObsForEncryption } from '../recoil/territoryObservations'; +import { customFieldsObsSelector, defaultCustomFields, prepareObsForEncryption } from '../recoil/territoryObservations'; import { preparePlaceForEncryption } from '../recoil/places'; import { prepareRelPersonPlaceForEncryption } from '../recoil/relPersonPlace'; @@ -29,7 +29,6 @@ export default function useDataMigrator() { const setLoadingText = useSetRecoilState(loadingTextState); const user = useRecoilValue(userState); const setOrganisation = useSetRecoilState(organisationState); - const customFieldsObs = useRecoilValue(customFieldsObsSelector); const preparePersonForEncryption = usePreparePersonForEncryption(); @@ -67,43 +66,51 @@ export default function useDataMigrator() { } // End of example of migration. */ - // if (!organisation.migrations?.includes('reformat-observedAt-observations')) { - // // some observedAt are timestamp, some are date - // // it messes up the filtering by date in stats - // setLoadingText(LOADING_TEXT); - // const observationsRes = await API.get({ - // path: '/territory-observation', - // query: { organisation: organisationId, after: 0, withDeleted: false }, - // }).then((res) => res.decryptedData || []); + if (!organisation.migrations?.includes('reformat-observedAt-observations-fixed')) { + // some observedAt are timestamp, some are date + // it messes up the filtering by date in stats + setLoadingText(LOADING_TEXT); + const observationsRes = await API.get({ + path: '/territory-observation', + query: { organisation: organisationId, after: 0, withDeleted: false }, + }).then((res) => res.decryptedData || []); + + const observationIdsToDelete = {}; // we create an object for the loop line 87 to be fast enough + for (const observation of observationsRes) { + if (!observation.territory || !observation.team) { + observationIdsToDelete[observation._id] = true; + } + } - // const newObservations = observationsRes.map((obs) => { - // const observedAt = !isNaN(Number(obs.observedAt)) // i.e. is timestamp - // ? dayjsInstance(Number(obs.observedAt)).toISOString() - // : dayjsInstance(obs.observedAt ?? obs.createdAt).toISOString(); - // return { - // ...obs, - // user: obs.user ?? user._id, // in case of old observations missing user - // observedAt, - // }; - // }); + const observationsWithFullData = observationsRes + .filter((obs) => !observationIdsToDelete[obs._id]) + .map((obs) => { + const observedAt = !isNaN(Number(obs.observedAt)) // i.e. is timestamp + ? dayjsInstance(Number(obs.observedAt)).toISOString() + : dayjsInstance(obs.observedAt ?? obs.createdAt).toISOString(); + return { + ...obs, + user: typeof obs.user === 'string' ? obs.user : user._id, // sometimes user is an empty {} instead of a uuid + observedAt, + }; + }); - // const observationIdsToDelete = newObservations.filter((obs) => !obs.territory || !obs.team).map((obs) => obs._id); - // const observationsWithFullData = newObservations.filter((obs) => !!obs.territory && !!obs.team); + const customFieldsObs = Array.isArray(organisation.customFieldsObs) ? organisation.customFieldsObs : defaultCustomFields; - // const encryptedObservations = await Promise.all(observationsWithFullData.map(prepareObsForEncryption(customFieldsObs)).map(encryptItem)); + const encryptedObservations = await Promise.all(observationsWithFullData.map(prepareObsForEncryption(customFieldsObs)).map(encryptItem)); - // const response = await API.put({ - // path: `/migration/reformat-observedAt-observations`, - // body: { encryptedObservations, observationIdsToDelete }, - // query: { migrationLastUpdateAt }, - // }); - // if (response.ok) { - // setOrganisation(response.organisation); - // migrationLastUpdateAt = response.organisation.migrationLastUpdateAt; - // } else { - // return false; - // } - // } + const response = await API.put({ + path: `/migration/reformat-observedAt-observations-fixed`, + body: { encryptedObservations, observationIdsToDelete: Object.keys(observationIdsToDelete) }, + query: { migrationLastUpdateAt }, + }); + if (response.ok) { + setOrganisation(response.organisation); + migrationLastUpdateAt = response.organisation.migrationLastUpdateAt; + } else { + return false; + } + } return true; }, }; diff --git a/dashboard/src/recoil/territoryObservations.js b/dashboard/src/recoil/territoryObservations.js index 109096cacd..e74121073b 100644 --- a/dashboard/src/recoil/territoryObservations.js +++ b/dashboard/src/recoil/territoryObservations.js @@ -28,7 +28,7 @@ export const customFieldsObsSelector = selector({ }, }); -const defaultCustomFields = [ +export const defaultCustomFields = [ { name: 'personsMale', label: 'Nombre de personnes non connues hommes rencontrées', diff --git a/dashboard/src/scenes/auth/signin.js b/dashboard/src/scenes/auth/signin.js index 17e982618b..8ad816b454 100644 --- a/dashboard/src/scenes/auth/signin.js +++ b/dashboard/src/scenes/auth/signin.js @@ -69,6 +69,7 @@ const SignIn = () => { window.localStorage.setItem('mano-organisationId', organisation._id); setOrganisation(organisation); setUserName(user.name); + setUser(user); if (!!organisation.encryptionEnabled && !['superadmin'].includes(user.role)) setShowEncryption(true); } @@ -108,6 +109,8 @@ const SignIn = () => { if (organisation._id !== window.localStorage.getItem('mano-organisationId')) { await resetCache(); } + setOrganisation(organisation); + setUser(user); if (!!organisation.encryptionEnabled && !showEncryption && !['superadmin'].includes(user.role)) { setShowEncryption(true); return setIsSubmitting(false); @@ -115,12 +118,10 @@ const SignIn = () => { if (token) setToken(token); setSessionInitialTimestamp(Date.now()); window.localStorage.setItem('mano-organisationId', organisation._id); - setOrganisation(organisation); if (!['superadmin'].includes(user.role) && !!signinForm.orgEncryptionKey) { const encryptionIsValid = await setOrgEncryptionKey(signinForm.orgEncryptionKey.trim(), organisation); if (!encryptionIsValid) return setIsSubmitting(false); } - setUser(user); // now login ! // superadmin if (['superadmin'].includes(user.role)) {