diff --git a/src/api/annuaire/annuaire.routes.js b/src/api/annuaire/annuaire.routes.js new file mode 100644 index 00000000..2bd1b25b --- /dev/null +++ b/src/api/annuaire/annuaire.routes.js @@ -0,0 +1,27 @@ +import express from 'express'; +import { db } from '../../services/mongo.service'; + +const annuaire = db.collection('annuaire'); +const router = new express.Router(); + +router.get('/annuaire', async (req, res) => { + const { relationType, structure, category, mandateTypeGroup, keepInactive, skip = "0", limit = "0" } = req.query; + const filters = { + ...(relationType && { relationType }), + ...(structure && { structureName: structure }), + ...(category && { category }), + ...(mandateTypeGroup && { mandateTypeGroup }), + }; + filters.active = keepInactive === 'true' ? { $in: [true, false] } : true; + console.log(filters); + const data = (parseInt(limit, 10) > 0) + ? await annuaire.find(filters).skip(parseInt(skip, 10)).limit(parseInt(limit, 10)).toArray() + : []; + const relationTypes = await annuaire.distinct('relationType', filters); + const structures = await annuaire.distinct('structureName', filters); + const categories = await annuaire.distinct('category', filters); + const mandateTypeGroups = await annuaire.distinct('mandateTypeGroup', filters); + return res.json({ data, relationTypes, structures, categories, mandateTypeGroups }); +}); + +export default router; \ No newline at end of file diff --git a/src/api/app.js b/src/api/app.js index 2d6c5da4..f34869f5 100644 --- a/src/api/app.js +++ b/src/api/app.js @@ -9,6 +9,7 @@ import YAML from 'yamljs'; import { authenticate } from './commons/middlewares/authenticate.middlewares'; import { handleErrors } from './commons/middlewares/handle-errors.middlewares'; +import annuaireRoutes from './annuaire/annuaire.routes'; import apiKeysRoutes from './apikeys/apikeys.routes'; import assetsRoutes from './assets/assets.routes'; import authRoutes from './auth/auth.routes'; @@ -96,6 +97,7 @@ app.use(requireAuth); app.use(forbidReadersToWrite); // Register api routes +app.use(annuaireRoutes); app.use(apiKeysRoutes); app.use(authRoutes); app.use(assetsRoutes); diff --git a/src/config.js b/src/config.js index 37167db9..f3986cf6 100644 --- a/src/config.js +++ b/src/config.js @@ -2,8 +2,8 @@ const production = { jwtSecret: process.env.JWT_SECRET, defaultAccountConfirmation: false, totpWindow: [20, 0], - accessTokenExpiresIn: '10d', - refreshTokenExpiresIn: '20d', + accessTokenExpiresIn: process.env.ACCESS_TOKEN_EXPRIES_IN || '10d', + refreshTokenExpiresIn: process.env.REFRESH_TOKEN_EXPRIES_IN || '20d', otpHeader: 'x-paysage-otp', otpMethodHeader: 'x-paysage-otp-method', systemName: 'paysage', diff --git a/src/jobs/index.js b/src/jobs/index.js index 6de872ab..069dc141 100644 --- a/src/jobs/index.js +++ b/src/jobs/index.js @@ -18,6 +18,7 @@ import { } from './opendata'; import synchronizeFrEsrReferentielGeographique from './synchronize/fr-esr-referentiel-geographique'; import synchronizeCuriexploreActors from './synchronize/curiexplore-actors'; +import synchronizeAnnuaireCollection from './synchronize/annuaire-collection'; import askForEmailRevalidation from './ask-for-email-validation'; import deletePassedGouvernancePersonnalInformation from './treatments/delete-passed-gouvernance-personal-infos'; @@ -40,6 +41,7 @@ agenda.define('synchronize fr-esr-referentiel-geographique', { shouldSaveResult: agenda.define('synchronize curiexplore actors', { shouldSaveResult: true }, synchronizeCuriexploreActors); agenda.define('ask for email revalidation with otp', { shouldSaveResult: true }, askForEmailRevalidation); agenda.define('delete passed gouvernance personal info', { shouldSaveResult: true }, deletePassedGouvernancePersonnalInformation); +agenda.define('Syncronize governance collection', { shouldSaveResult: true }, synchronizeAnnuaireCollection); agenda .on('ready', () => { logger.info('Agenda connected to mongodb'); }) diff --git a/src/jobs/synchronize/annuaire-collection.js b/src/jobs/synchronize/annuaire-collection.js new file mode 100644 index 00000000..eb0f0f5c --- /dev/null +++ b/src/jobs/synchronize/annuaire-collection.js @@ -0,0 +1,82 @@ +import { db } from '../../services/mongo.service'; +import structuresLightQuery from '../../api/commons/queries/structures.light.query'; +import personLightQuery from '../../api/commons/queries/persons.light.query'; +import relationTypesLightQuery from '../../api/commons/queries/relation-types.light.query'; + +export default async function synchronizeAnnuaireCollection(job) { + await db.collection('relationships') + .aggregate([ + { $match: { relationTag: 'gouvernance' } }, + { + $lookup: { + from: 'persons', + localField: 'relatedObjectId', + foreignField: 'id', + pipeline: personLightQuery, + as: 'persons', + }, + }, + { + $lookup: { + from: 'structures', + localField: 'resourceId', + foreignField: 'id', + pipeline: structuresLightQuery, + as: 'structures', + }, + }, + { $set: { structures: { $arrayElemAt: ['$structures', 0] } } }, + { $set: { persons: { $arrayElemAt: ['$persons', 0] } } }, + { $set: { category: '$structures.category.usualNameFr' } }, + { $set: { structureId: '$structures.id' } }, + { $set: { structureName: '$structures.displayName' } }, + { $set: { person: '$persons.displayName' } }, + { $set: { personId: '$persons.id' } }, + { $set: { gender: '$persons.gender' } }, + { + $lookup: { + from: 'relationtypes', + localField: 'relationTypeId', + foreignField: 'id', + pipeline: relationTypesLightQuery, + as: 'relationType', + }, + }, + { $set: { relationType: { $arrayElemAt: ['$relationType', 0] } } }, + { $set: { mandateTypeGroup: '$relationType.mandateTypeGroup' } }, + { $set: { relationType: '$relationType.name' } }, + { $set: { endDate: { $ifNull: ['$endDate', null] } } }, + { $set: { active: { $ifNull: ['$active', false] } } }, + { $set: { active: { $or: [{ $eq: ['$active', true] }, { $eq: ['$endDate', null] }, { $gte: ['$endDate', new Date().toISOString().split('T')[0]] }] } } }, + { + $project: { + _id: 0, + id: 1, + person: 1, + personId: 1, + structureId: 1, + gender: 1, + category: 1, + structureName: 1, + relationType: 1, + mandateTypeGroup: 1, + startDate: { $ifNull: ['$startDate', null] }, + endDate: { $ifNull: ['$endDate', null] }, + endDatePrevisional: { $ifNull: ['$endDatePrevisional', null] }, + mandatePosition: { $ifNull: ['$mandatePosition', null] }, + mandateReason: { $ifNull: ['$mandateReason', null] }, + mandateEmail: { $ifNull: ['$mandateEmail', null] }, + personalEmail: { $ifNull: ['$personalEmail', null] }, + mandatePhonenumber: { $ifNull: ['$mandatePhonenumber', null] }, + mandateTemporary: { $ifNull: ['$mandateTemporary', null] }, + mandatePrecision: { $ifNull: ['$mandatePrecision', null] }, + active: 1, + }, + }, + { $out: 'annuaire' }, + ]).toArray().catch((e) => { + job.fail(`La synchronisation a échouée: ${e.message}`); + return null; + }); + return { ok: 1 } +}