Files
Api-DataSentinel/docs/openapi.json
T
Antho e7b3944436 feat(api): CRUD des référentiels réservé aux administrateurs
L'écran d'administration du front proposait des boutons Modifier et
Désactiver qui n'appelaient rien (console.log côté client), faute
d'endpoints correspondants. Ajoute POST/PUT/DELETE sur /services,
/categories, /contacts et /monitorings, tous protégés par require_admin.

Deux garde-fous métier :
- la suppression d'un service ou d'une catégorie est refusée (409) tant
  que des monitorings ou contacts y sont rattachés, avec le décompte
  dans le message, plutôt que de laisser remonter une violation de clé
  étrangère ;
- un monitoring est désactivé (actif = 0) et jamais supprimé, car
  TABLE_FINAL référence son identifiant et l'historique doit rester
  consultable.

Le rôle utilisateur est désormais typé par l'enum UserRole : Pydantic
le valide seul (422), ce qui supprime les deux contrôles manuels
dupliqués dans create_user et update_user.

Tests : 8 -> 16. Couvre la validation par enum, le refus 409 sur
rattachement, le 403 pour un non-administrateur et la désactivation
logique du monitoring.
2026-08-15 14:28:58 +02:00

1 line
30 KiB
JSON

{"openapi":"3.1.0","info":{"title":"Data Sentinel API","description":"API de monitoring de la qualité des données — XEFI","version":"1.0.0"},"paths":{"/health":{"get":{"tags":["Système"],"summary":"Health Check","description":"Ping API + test connexion SQL Server.","operationId":"health_check_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/login":{"post":{"tags":["Auth"],"summary":"Login","description":"Authentifie un utilisateur et retourne un JWT.","operationId":"login_auth_login_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_login_auth_login_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/me":{"get":{"tags":["Auth"],"summary":"Me","description":"Profil de l'utilisateur connecté.","operationId":"me_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/categories":{"get":{"tags":["Référentiels"],"summary":"Get Categories","description":"Toutes les catégories de monitoring.","operationId":"get_categories_categories_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]},"post":{"tags":["Référentiels"],"summary":"Create Categorie","operationId":"create_categorie_categories_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategorieBody"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/categories/{id_categorie}":{"put":{"tags":["Référentiels"],"summary":"Update Categorie","operationId":"update_categorie_categories__id_categorie__put","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"id_categorie","in":"path","required":true,"schema":{"type":"integer","title":"Id Categorie"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategorieBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Référentiels"],"summary":"Delete Categorie","description":"Supprime une catégorie, sauf si des monitorings s'y rattachent encore :\nla clé étrangère FK_NOM_CATEGORIE l'interdirait, autant renvoyer un\nmessage explicite plutôt que de laisser remonter l'erreur SQL brute.","operationId":"delete_categorie_categories__id_categorie__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"id_categorie","in":"path","required":true,"schema":{"type":"integer","title":"Id Categorie"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/services":{"get":{"tags":["Référentiels"],"summary":"Get Services","description":"Tous les services.","operationId":"get_services_services_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]},"post":{"tags":["Référentiels"],"summary":"Create Service","operationId":"create_service_services_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceBody"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/services/{id_service}":{"put":{"tags":["Référentiels"],"summary":"Update Service","operationId":"update_service_services__id_service__put","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"id_service","in":"path","required":true,"schema":{"type":"integer","title":"Id Service"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Référentiels"],"summary":"Delete Service","description":"Refuse la suppression tant que des monitorings ou contacts y sont rattachés.","operationId":"delete_service_services__id_service__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"id_service","in":"path","required":true,"schema":{"type":"integer","title":"Id Service"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/contacts":{"get":{"tags":["Référentiels"],"summary":"Get Contacts","description":"Contacts, filtrables par service.","operationId":"get_contacts_contacts_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"id_service","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Filtrer par service","title":"Id Service"},"description":"Filtrer par service"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Référentiels"],"summary":"Create Contact","operationId":"create_contact_contacts_post","security":[{"OAuth2PasswordBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactBody"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/contacts/{id_contact}":{"put":{"tags":["Référentiels"],"summary":"Update Contact","operationId":"update_contact_contacts__id_contact__put","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"id_contact","in":"path","required":true,"schema":{"type":"integer","title":"Id Contact"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Référentiels"],"summary":"Delete Contact","description":"Un contact n'est référencé par aucune autre table : suppression directe.","operationId":"delete_contact_contacts__id_contact__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"id_contact","in":"path","required":true,"schema":{"type":"integer","title":"Id Contact"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/monitorings":{"get":{"tags":["Monitorings"],"summary":"Get Monitorings","description":"Liste des monitorings actifs avec table_source et bdd_source.","operationId":"get_monitorings_monitorings_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"id_service","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Filtrer par service","title":"Id Service"},"description":"Filtrer par service"},{"name":"id_categorie","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Filtrer par catégorie","title":"Id Categorie"},"description":"Filtrer par catégorie"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Monitorings"],"summary":"Create Monitoring","description":"Déclare un monitoring dans la nomenclature.\n\nAttention : cela n'ajoute que l'entrée de référentiel. Pour qu'il remonte\ndes données, il faut aussi créer la table MONITO_[NOM] correspondante et\nl'ajouter au mapping MONITO_TABLES — voir l'en-tête de data_sentinel_init.sql.","operationId":"create_monitoring_monitorings_post","security":[{"OAuth2PasswordBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonitoringBody"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/monitorings/{id_monito}":{"put":{"tags":["Monitorings"],"summary":"Update Monitoring","operationId":"update_monitoring_monitorings__id_monito__put","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"id_monito","in":"path","required":true,"schema":{"type":"integer","title":"Id Monito"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonitoringUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Monitorings"],"summary":"Desactiver Monitoring","description":"Désactivation (actif = 0), pas de suppression physique : TABLE_FINAL\nréférence id_monito et l'historique doit rester consultable.","operationId":"desactiver_monitoring_monitorings__id_monito__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"id_monito","in":"path","required":true,"schema":{"type":"integer","title":"Id Monito"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Monitorings"],"summary":"Get Monitoring By Id","description":"Détail d'un monitoring.","operationId":"get_monitoring_by_id_monitorings__id_monito__get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"id_monito","in":"path","required":true,"schema":{"type":"integer","title":"Id Monito"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/monitorings/{id_monito}/details":{"get":{"tags":["Monitorings"],"summary":"Get Monitoring Details","description":"Retourne toutes les lignes en erreur depuis la table MONITO_[NOM] dédiée.\nToutes les colonnes métier sont exposées → utilisable pour export CSV côté frontend.","operationId":"get_monitoring_details_monitorings__id_monito__details_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"id_monito","in":"path","required":true,"schema":{"type":"integer","title":"Id Monito"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Recherche sur colonnes texte (ct_intitule, agence, STE...)","title":"Search"},"description":"Recherche sur colonnes texte (ct_intitule, agence, STE...)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":5000,"minimum":1,"description":"Lignes max — mettre 5000 pour export CSV complet","default":500,"title":"Limit"},"description":"Lignes max — mettre 5000 pour export CSV complet"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Offset pagination","default":0,"title":"Offset"},"description":"Offset pagination"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/monitorings/{id_monito}/count":{"get":{"tags":["Monitorings"],"summary":"Get Monitoring Count","description":"Nombre d'erreurs dans la table dédiée du monitoring.","operationId":"get_monitoring_count_monitorings__id_monito__count_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"id_monito","in":"path","required":true,"schema":{"type":"integer","title":"Id Monito"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/monitorings/{id_monito}/columns":{"get":{"tags":["Monitorings"],"summary":"Get Monitoring Columns","description":"Retourne les colonnes de la table dédiée.\nPermet au frontend de générer dynamiquement les en-têtes du tableau.","operationId":"get_monitoring_columns_monitorings__id_monito__columns_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"id_monito","in":"path","required":true,"schema":{"type":"integer","title":"Id Monito"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/dashboard":{"get":{"tags":["Dashboard"],"summary":"Get Dashboard","description":"Vue consolidée — source principale du dashboard.","operationId":"get_dashboard_dashboard_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"service","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filtrer par service","title":"Service"},"description":"Filtrer par service"},{"name":"categorie","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filtrer par catégorie","title":"Categorie"},"description":"Filtrer par catégorie"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/dashboard/filtres":{"get":{"tags":["Dashboard"],"summary":"Get Dashboard Filtres","description":"Valeurs de filtre réellement présentes dans VUE_CONSO.\n\nLes référentiels SERVICE / CATEGORIE contiennent des entrées auxquelles\naucun monitoring actif n'est rattaché (ex. « Business Intelligence »).\nLes proposer dans les menus déroulants du dashboard mène à un écran vide :\ncet endpoint ne renvoie que les valeurs qui ramènent au moins un monitoring.\n\n`combinaisons` permet au frontend de restreindre les catégories proposées\nau service sélectionné.","operationId":"get_dashboard_filtres_dashboard_filtres_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/dashboard/summary":{"get":{"tags":["Dashboard"],"summary":"Get Dashboard Summary","description":"KPI globaux pour les 4 cartes du dashboard.","operationId":"get_dashboard_summary_dashboard_summary_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/historique":{"get":{"tags":["Historique"],"summary":"Get Historique","description":"Snapshots journaliers (TABLE_FINAL).","operationId":"get_historique_historique_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"id_monito","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id Monito"}},{"name":"date_debut","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"YYYY-MM-DD","title":"Date Debut"},"description":"YYYY-MM-DD"},{"name":"date_fin","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"YYYY-MM-DD","title":"Date Fin"},"description":"YYYY-MM-DD"},{"name":"service","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/historique/comparaison":{"get":{"tags":["Historique"],"summary":"Get Comparaison","description":"Déprécié — utiliser GET /evolution/par-monitoring à la place.\nConservé pour compatibilité ascendante.","operationId":"get_comparaison_historique_comparaison_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"date_debut","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Date Debut"}},{"name":"date_fin","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Date Fin"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/historique/{id_monito}/evolution":{"get":{"tags":["Historique"],"summary":"Get Evolution","description":"Évolution d'un monitoring — format optimisé Recharts.","operationId":"get_evolution_historique__id_monito__evolution_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"id_monito","in":"path","required":true,"schema":{"type":"integer","title":"Id Monito"}},{"name":"date_debut","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Date Debut"}},{"name":"date_fin","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Date Fin"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/evolution/global":{"get":{"tags":["Évolution globale"],"summary":"Get Evolution Global","description":"Courbe globale : total des erreurs tous monitorings confondus, par jour.\nSource : VUE_TABLE_FINAL_CONSO WHERE type_agregat = 'GLOBAL'\nFormat optimisé Recharts → [{date, nb_erreurs}]","operationId":"get_evolution_global_evolution_global_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"date_debut","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"YYYY-MM-DD","title":"Date Debut"},"description":"YYYY-MM-DD"},{"name":"date_fin","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"YYYY-MM-DD","title":"Date Fin"},"description":"YYYY-MM-DD"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/evolution/par-monitoring":{"get":{"tags":["Évolution globale"],"summary":"Get Evolution Par Monitoring","description":"Évolution par monitoring — toutes les courbes individuelles.\nSource : VUE_TABLE_FINAL_CONSO WHERE type_agregat = 'MONITO'\n\nRetourne un format pivot par monitoring :\n{\n \"monitorings\": [{\"id\": 1, \"nom\": \"...\", \"serie\": [{\"date\",\"nb_erreurs\"}]}]\n}\nUtile pour un graphique multi-lignes Recharts (une ligne par monitoring).","operationId":"get_evolution_par_monitoring_evolution_par_monitoring_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"date_debut","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"YYYY-MM-DD","title":"Date Debut"},"description":"YYYY-MM-DD"},{"name":"date_fin","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"YYYY-MM-DD","title":"Date Fin"},"description":"YYYY-MM-DD"},{"name":"id_monito","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Filtrer sur un seul monitoring","title":"Id Monito"},"description":"Filtrer sur un seul monitoring"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/evolution/par-service":{"get":{"tags":["Évolution globale"],"summary":"Get Evolution Par Service","description":"Évolution par service (Contrat / Fournisseur) — 1 courbe par service.\nSource : VUE_TABLE_FINAL_CONSO WHERE type_agregat = 'SERVICE'\n\nRetourne :\n{\n \"services\": [{\"service\": \"Contrat\", \"serie\": [{\"date\",\"nb_erreurs\"}]}]\n}","operationId":"get_evolution_par_service_evolution_par_service_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"date_debut","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"YYYY-MM-DD","title":"Date Debut"},"description":"YYYY-MM-DD"},{"name":"date_fin","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"YYYY-MM-DD","title":"Date Fin"},"description":"YYYY-MM-DD"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/users":{"get":{"tags":["Admin"],"summary":"List Users","operationId":"list_users_admin_users_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]},"post":{"tags":["Admin"],"summary":"Create User","operationId":"create_user_admin_users_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/admin/users/{id_user}":{"put":{"tags":["Admin"],"summary":"Update User","operationId":"update_user_admin_users__id_user__put","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"id_user","in":"path","required":true,"schema":{"type":"integer","title":"Id User"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Admin"],"summary":"Delete User","description":"Suppression douce (actif = 0).","operationId":"delete_user_admin_users__id_user__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"id_user","in":"path","required":true,"schema":{"type":"integer","title":"Id User"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/users/{id_user}/reset-password":{"post":{"tags":["Admin"],"summary":"Reset Password","operationId":"reset_password_admin_users__id_user__reset_password_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"id_user","in":"path","required":true,"schema":{"type":"integer","title":"Id User"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordReset"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/journal":{"get":{"tags":["Admin"],"summary":"Get Journal","operationId":"get_journal_admin_journal_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":200,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/me/data-export":{"get":{"tags":["RGPD"],"summary":"Export My Data","description":"Droit à la portabilité (art. 20) : export des données de l'utilisateur.","operationId":"export_my_data_me_data_export_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}},"/me":{"delete":{"tags":["RGPD"],"summary":"Delete My Account","description":"Droit à l'oubli (art. 17) : désactivation + anonymisation.","operationId":"delete_my_account_me_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]}]}}},"components":{"schemas":{"Body_login_auth_login_post":{"properties":{"grant_type":{"anyOf":[{"type":"string","pattern":"^password$"},{"type":"null"}],"title":"Grant Type"},"username":{"type":"string","title":"Username"},"password":{"type":"string","format":"password","title":"Password"},"scope":{"type":"string","title":"Scope","default":""},"client_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Id"},"client_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"format":"password","title":"Client Secret"}},"type":"object","required":["username","password"],"title":"Body_login_auth_login_post"},"CategorieBody":{"properties":{"intitule_categorie":{"type":"string","maxLength":100,"minLength":1,"title":"Intitule Categorie"}},"type":"object","required":["intitule_categorie"],"title":"CategorieBody"},"ContactBody":{"properties":{"id_service":{"type":"integer","title":"Id Service"},"intitule_contact":{"type":"string","maxLength":100,"minLength":1,"title":"Intitule Contact"},"nom":{"type":"string","maxLength":100,"minLength":1,"title":"Nom"},"prenom":{"type":"string","maxLength":100,"minLength":1,"title":"Prenom"},"mail":{"type":"string","maxLength":200,"minLength":1,"title":"Mail"}},"type":"object","required":["id_service","intitule_contact","nom","prenom","mail"],"title":"ContactBody"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"MonitoringBody":{"properties":{"monito_intitule":{"type":"string","maxLength":200,"minLength":1,"title":"Monito Intitule"},"id_service":{"type":"integer","title":"Id Service"},"id_categorie":{"type":"integer","title":"Id Categorie"},"table_source":{"type":"string","maxLength":100,"minLength":1,"title":"Table Source"},"bdd_source":{"type":"string","maxLength":50,"minLength":1,"title":"Bdd Source"}},"type":"object","required":["monito_intitule","id_service","id_categorie","table_source","bdd_source"],"title":"MonitoringBody"},"MonitoringUpdate":{"properties":{"monito_intitule":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Monito Intitule"},"id_service":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id Service"},"id_categorie":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id Categorie"},"table_source":{"anyOf":[{"type":"string","maxLength":100,"minLength":1},{"type":"null"}],"title":"Table Source"},"bdd_source":{"anyOf":[{"type":"string","maxLength":50,"minLength":1},{"type":"null"}],"title":"Bdd Source"},"actif":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Actif"}},"type":"object","title":"MonitoringUpdate"},"PasswordReset":{"properties":{"password":{"type":"string","title":"Password"}},"type":"object","required":["password"],"title":"PasswordReset"},"ServiceBody":{"properties":{"nom_service":{"type":"string","maxLength":100,"minLength":1,"title":"Nom Service"}},"type":"object","required":["nom_service"],"title":"ServiceBody"},"UserCreate":{"properties":{"username":{"type":"string","title":"Username"},"email":{"type":"string","title":"Email"},"password":{"type":"string","title":"Password"},"role":{"$ref":"#/components/schemas/UserRole"}},"type":"object","required":["username","email","password","role"],"title":"UserCreate"},"UserRole":{"type":"string","enum":["Admin","Superviseur","Consultant"],"title":"UserRole","description":"Rôles applicatifs — miroir de la contrainte CK_USER_ROLE en base."},"UserUpdate":{"properties":{"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"role":{"anyOf":[{"$ref":"#/components/schemas/UserRole"},{"type":"null"}]},"actif":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Actif"}},"type":"object","title":"UserUpdate"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"OAuth2PasswordBearer":{"type":"oauth2","flows":{"password":{"scopes":{},"tokenUrl":"auth/login"}}}}}}