diff --git a/src/migrations/scripts/1695375219601-new-structure-types.ts b/src/migrations/scripts/1695375219601-new-structure-types.ts new file mode 100644 index 0000000000000000000000000000000000000000..8265a4eadf19b17b7e5f22974419214e8fd9f235 --- /dev/null +++ b/src/migrations/scripts/1695375219601-new-structure-types.ts @@ -0,0 +1,132 @@ +import { Db } from 'mongodb'; +import { getDb } from '../migrations-utils/db'; + +export const up = async () => { + try { + const db: Db = await getDb(); + + // Maison du Rhône will become the new type "administration" + await db + .collection('structuretype') + .findOneAndUpdate({ value: 'Maison du Rhône' }, { $set: { value: 'administration' } }); + + // Mapping of old values to new values + const mapping = [ + { value: 'bijPij', newValue: 'sij' }, + { value: 'CAF', newValue: 'administration' }, + { value: 'CARSAT', newValue: 'administration' }, + { value: 'CPAM', newValue: 'administration' }, + { value: 'centreDeGestion', newValue: 'administration' }, + { value: 'prefecture', newValue: 'administration' }, + { value: 'poleEmploi', newValue: 'administration' }, + { value: 'CCAS', newValue: 'mairie' }, + ]; + + for (const map of mapping) { + // Find the old and new _id for the given value + const newStructureType = await db.collection('structuretype').findOne({ value: map.newValue }); + const oldStructureType = await db.collection('structuretype').findOne({ value: map.value }); + // Update the "structures" collection with the new _id for structureType + if (oldStructureType && newStructureType) { + await db + .collection('structures') + .updateMany({ structureType: oldStructureType._id }, { $set: { structureType: newStructureType._id } }); + } + + // Delete the old "structureType" documents + await db.collection('structuretype').deleteMany({ value: map.value }); + } + + // Remove two other obsolete structure types and empty their references in the structure collection + const toDelete = [{ value: 'EPIC' }, { value: 'MaisonFranceService' }]; + for (const del of toDelete) { + // Find the _id + const structureType = await db.collection('structuretype').findOne({ value: del.value }); + // Remove the structureType id from the "structures" collection and delete the obsolete structureType + if (structureType) { + await db + .collection('structures') + .updateMany({ structureType: structureType._id }, { $set: { structureType: null } }); + await db.collection('structuretype').deleteOne({ _id: structureType._id }); + } + } + + // Add full names in database + const nameMapping = [ + { value: 'administration', name: 'Administration' }, + { value: 'formation', name: 'Structure de formation' }, + { value: 'sij', name: 'Structure information jeunesse' }, + { value: 'espaceEmploi', name: 'Espace emploi' }, + { value: 'laPoste', name: 'La Poste' }, + { value: 'mediatheque', name: 'Médiathèque/Bibliothèque' }, + { value: 'logement', name: 'Bailleur social' }, + { value: 'association', name: 'Association' }, + { value: 'insertion', name: "Structure d'insertion" }, + { value: 'centreSocio', name: 'Centre socio-culturel' }, + { value: 'AFPA', name: 'Organisme public de formation' }, + { value: 'mairie', name: 'Mairie' }, + { value: 'mjc', name: 'MJC' }, + { value: 'missionsLocales', name: 'Mission locale' }, + { value: 'Communauté de communes', name: 'Communauté de communes' }, + { value: 'mdm', name: 'Maison de la Métropole de Lyon' }, + { value: 'Université', name: 'Université' }, + { value: 'autre', name: 'Autre' }, + ]; + // Add name field to structure types + for (const nameMap of nameMapping) { + await db.collection('structuretype').updateMany({ value: nameMap.value }, { $set: { name: nameMap.name } }); + } + + // Keep the "value" field because it is useful for elastic search to find a structure type with another search string (ex if value='mdml toto' then 'mdml' or 'toto' = maison de la métropole de lyon) + + // Change value from mdm to mdml so that searches with 'mdm 'and 'mdml' both show structures with structureType name 'Maison de la Métropole de Lyon' + await db.collection('structuretype').updateOne({ value: 'mdm' }, { $set: { value: 'mdml' } }); + + console.log('Updated : "StructureType" collection updated'); + } catch (error) { + console.error('Error updating documents:', error); + } +}; + +export const down = async () => { + try { + const db: Db = await getDb(); + + await db.collection('structuretype').drop(); + + await db.collection('structuretype').insertMany([ + { category: 'Publique', value: 'mairie', selectable: 'true' }, + { category: 'Publique', value: 'CAF', selectable: 'true' }, + { category: 'Publique', value: 'CCAS', selectable: 'true' }, + { category: 'Publique', value: 'CARSAT', selectable: 'true' }, + { category: 'Publique', value: 'poleEmploi', selectable: 'true' }, + { category: 'Publique', value: 'mdml', selectable: 'true' }, + { category: 'Publique', value: 'mediatheque', selectable: 'true' }, + { category: 'Publique', value: 'prefecture', selectable: 'true' }, + { category: 'Publique', value: 'bijPij', selectable: 'true' }, + { category: 'Publique', value: 'logement', selectable: 'true' }, + { category: 'Publique', value: 'MaisonFranceService', selectable: 'true' }, + { category: 'Publique', value: 'autre', selectable: 'false' }, + { category: 'Publique', value: 'laPoste', selectable: 'true' }, + { category: 'Publique', value: 'espaceEmploi', selectable: 'true' }, + { category: 'Publique', value: 'CPAM', selectable: 'true' }, + { category: 'Publique', value: 'AFPA', selectable: 'true' }, + { category: 'Publique', value: 'centreDeGestion', selectable: 'true' }, + { category: 'Publique', value: 'EPIC', selectable: 'true' }, + { category: 'Publique', value: 'Communauté de communes', selectable: 'true' }, + { category: 'Publique', value: 'Maison du Rhône', selectable: 'true' }, + { category: 'Publique', value: 'Université', selectable: 'true' }, + { category: 'Privée à but non lucratif', value: 'association', selectable: 'true' }, + { category: 'Privée à but non lucratif', value: 'centreSocio', selectable: 'true' }, + { category: 'Privée à but non lucratif', value: 'mjc', selectable: 'true' }, + { category: 'Privée à but non lucratif', value: 'sij', selectable: 'true' }, + { category: 'Privée à but non lucratif', value: 'missionsLocales', selectable: 'true' }, + { category: 'Privée à but lucratif', value: 'formation', selectable: 'true' }, + { category: 'Privée à but lucratif', value: 'insertion', selectable: 'true' }, + ]); + + console.log('Downgrade : old structure types have been restored (but not attached to the appropriate structures)'); + } catch (error) { + console.error('Error downgrading documents:', error); + } +}; diff --git a/src/structures/interfaces/structure-search-body.interface.ts b/src/structures/interfaces/structure-search-body.interface.ts index 14857a413f2cf9931baecb307a05fe92857667ee..2541e5bb42c243e76ee73b30303604b78bea12e6 100644 --- a/src/structures/interfaces/structure-search-body.interface.ts +++ b/src/structures/interfaces/structure-search-body.interface.ts @@ -3,7 +3,8 @@ import { Address } from '../schemas/address.schema'; export interface StructureSearchBody { structureId: string; structureName: string; - structureType: string; + structureTypeName: string; + structureTypeValue: string; address: Address; description: string; } diff --git a/src/structures/services/structures-search.service.ts b/src/structures/services/structures-search.service.ts index 2aedde7e642f0d0d5593ddd36fabf8335c415d4c..58011d63ca8089152699cc9f755deef13402bf65 100644 --- a/src/structures/services/structures-search.service.ts +++ b/src/structures/services/structures-search.service.ts @@ -30,7 +30,8 @@ export class StructuresSearchService { private formatIndexBody(structure: StructureDocument): StructureSearchBody { return { structureName: structure.structureName, - structureType: structure.structureType?.value, + structureTypeName: structure.structureType?.name, + structureTypeValue: structure.structureType?.value, structureId: structure._id, address: structure.address, description: structure.description, @@ -111,7 +112,14 @@ export class StructuresSearchService { query: escapeElasticsearchQuery(searchString), fields: fields ? fields - : ['structureName^5', 'structureType^5', 'address.commune^10', 'address.postcode^5', 'description'], + : [ + 'structureName^5', + 'structureTypeName^5', + 'structureTypeValue^5', + 'address.commune^10', + 'address.postcode^5', + 'description', + ], fuzziness: 'AUTO', }, }, diff --git a/src/structures/structure-type/structure-type.schema.ts b/src/structures/structure-type/structure-type.schema.ts index 58564aa993de2735e48705921a2954ecb2185c3c..709af04f53569bc0d34dc3d9098b0d867b3bc04f 100644 --- a/src/structures/structure-type/structure-type.schema.ts +++ b/src/structures/structure-type/structure-type.schema.ts @@ -11,6 +11,9 @@ export class StructureType { @Prop() value: string; + @Prop() + name: string; + // Boolean set to false if user can't select this type during structure creation @Prop() selectable: boolean;