### Objectifs * Créer un script qui permet de récupérer tous les utilisateurs de la plateforme Ziwig Connect avec le détail de l'utilisateur ainsi que celui du Professionnel qui lui est associé * Le microservice à Utiliser pour les données utilisateur est IAM * Le microservice à utiliser pour les données du professionnel est HRD ### Environnement de Développement * Python 3.12 * Un seul module ### Template * Utiliser le template à partir de EB_Script_Template et bien lire la documentation qui s'y trouve ### Logique du Script Le script s'exécute en deux phases principales séquentielles : **Phase 1 : Traitement par Rôles** 1. Récupérer tous les Rôles de l'IAM (Limit 100, pas de pagination nécessaire). 2. Initialiser un dictionnaire `output` par rôles : * La réponse contient une liste de rôles, chacun avec un tableau d'utilisateurs. * Pour chaque utilisateur trouvé, créer ou mettre à jour une entrée : `user_id: {roles: [{id, name}], user: {}, professional: {}}`. 3. Lancer le traitement multithreadé (voir section Multithreading) sur ces utilisateurs. 4. Sauvegarder le résultat dans `all_users_data.json`. **Phase 2 : Traitement par Applications** 1. Récupérer la liste des applications via `get_applications`. 2. Pour chaque application trouvée : * Afficher une séparation claire dans la console. * Récupérer les profils associés via `get_profiles_by_app_id` (avec `clientId`). * Initialiser un *nouveau* dictionnaire `output` pour cette application : * Pour chaque profil, récupérer les utilisateurs via `get_users_by_profile_id`. * Pour chaque utilisateur trouvé, créer ou mettre à jour une entrée : `user_id: {profiles: [{id, name}], user: {}, professional: {}}`. * *(Note : La clé est `profiles` ici, au lieu de `roles`)*. * Lancer le même traitement multithreadé sur ces utilisateurs. * Sauvegarder le résultat dans un fichier spécifique : `all_users_data_{app_name}.json`. **Phase 3 : Traitement par Centres Endobest** 1. **Configuration** : * Fichier input : `endobest_organizations.json` (Constante). * Fichier output : `professionals_by_endobest_center.json` (Constante). 2. **Logique** : * Charger la liste des organisations depuis le fichier JSON input (champs requis: `id`, `name`, `Center_Name`). * Initialiser une barre de progression basée sur le nombre de centres. * **Itération (Séquentielle, pas de thread pool)** : * Pour chaque centre : * Appeler l'API `get_pros_by_endobest_center`. * Récupérer le tableau de professionnels depuis l'attribut `data`. * **Tri des Pros** : Trier par `properties.nom_exercice`, puis `properties.prenom_exercice`, puis `metadata.id`. * Ajouter ce tableau trié au centre en cours sous l'attribut `pros`. * **Tri des Centres** : Trier la liste finale des centres par `Center_Name`, puis `name`, puis `id`. * Sauvegarder la liste triée dans le fichier output. ### Format de l'Output * **Fichiers générés** : * `all_users_data.json` (Données issues des Rôles). * `all_users_data_{app_name}.json` (Un fichier par Application). * `professionals_by_endobest_center.json` (Données issues des Centres Endobest). * **Structure JSON** : * Array d'objets triés (par `lastname`, `firstname`, `user_id`). * Chaque objet contient : * `user_id` * `user` (Détails IAM) * `professional` (Détails HRD) * `roles` (Uniquement pour le fichier par Rôles) * `profiles` (Uniquement pour les fichiers par Applications) ### Specs des APIs * **Authentication (IAM)**: * `/api/auth/{REALME}/login` [POST] * `/api/auth/refreshToken` [POST] * **Common (All Microservices)**: * `/api/auth/config-token` [POST] * `/api/auth/refreshToken` [POST] * **IAM (User Data)**: * `get_roles`: `/api/profiles/paginate` [POST] * `get_applications`: `/api/applications` [GET] * `get_profiles_by_app_id`: `/api/identity-profiles/paginate` [POST] * `get_users_by_profile_id`: `/api/identity-profiles/{profile_id}/users` [GET] * `get_user_by_id`: `/api/users/find/{user_id}` [GET] * **HRD (Professional Data)**: * `get_professional_by_id`: `/api/entity-manager/meta/{model}/data/nodes/pro/{pro_id}?relationships=2` [GET] * `get_pros_by_endobest_center`: `/api/entity-manager/meta/modele_fr/data/orga/{organization_id}/centers/pros?limit=1000` [GET] * **Note** : `user_id`, `model`, et `professional_id` sont récupérés de la même manière pour tous les traitements. ### Multithreading * Input utilisateur pour le nombre de threads (global). * Le script utilise deux pools de threads persistants (`main` et `subtasks`) réutilisés pour chaque phase (Rôles, App 1, App 2...). * **Traitement Utilisateur (Main Pool)** : * Récupère `get_user_by_id`. * Stocke dans `user`. * Si `hrdProId` existe : soumet une tâche "Professionnel". * Sinon : incrémente la barre de progression "Professionals" (pour ne pas bloquer). * **Traitement Professionnel (Subtasks Pool)** : * Récupère `get_professional_by_id`. * Stocke dans `professional`. * Incrémente la barre de progression "Professionals". ### Progression du Script * Utilisation de `tqdm` pour afficher deux barres (Users et Professionals). * Les barres sont créées, mises à jour, et fermées **indépendamment pour chaque fichier généré** (Rôles, puis chaque Application). * Gestion thread-safe des mises à jour.