Cahier des charges : l'API RH et ses outils
Le cahier des charges
L'assistant RH doit permettre à un employé, ou à son manager :
- de consulter un solde de congés payés et de RTT ;
- de retrouver un collègue par son nom ;
- de lister ses demandes ;
- de créer une demande de congés (action sensible, confirmée) ;
- d'annuler une demande (action sensible, confirmée).
Contraintes : aucune donnée inventée par le modèle, droits appliqués par l'API, chaque action tracée.
flowchart LR
subgraph Outils["outils_rh.py (vu par le modèle)"]
O1["chercher_employe"]
O2["consulter_solde"]
O3["lister_demandes"]
O4["creer_demande_conges (sensible)"]
O5["annuler_demande (sensible)"]
end
subgraph API["api_rh.py (FastAPI)"]
R1["GET /employes?nom="]
R2["GET /employes/{id}/soldes"]
R3["GET /employes/{id}/demandes"]
R4["POST /demandes"]
R5["POST /demandes/{id}/annulation"]
end
O1 --> R1
O2 --> R2
O3 --> R3
O4 --> R4
O5 --> R5
Lancer l'API
cd files
python -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt
uvicorn api_rh:app --port 8077Ouvrez http://127.0.0.1:8077/docs : FastAPI génère une documentation interactive où l'on peut essayer chaque route. Les données (5 employés fictifs, leurs soldes) sont en mémoire et reviennent à leur état initial à chaque redémarrage.
| Employé | Service | Manager | Congés payés | RTT |
|---|---|---|---|---|
| E001 Camille Martin | Comptabilité | E004 | 18 | 4 |
| E002 Karim Benali | Comptabilité | E004 | 7 | 9 |
| E003 Lucie Moreau | Marketing | E005 | 22 | 2 |
| E004 Sophie Durand | Comptabilité | aucun | 12 | 6 |
| E005 Hugo Lefèvre | Marketing | aucun | 25 | 0 |
Une route de création, côté API
L'API fait son propre travail de validation (Pydantic) et applique les règles métier : jours ouvrés, solde suffisant.
class NouvelleDemande(BaseModel):
employe_id: str = Field(pattern=r"^E\d{3}$")
type_conge: Literal["conges_payes", "rtt"]
date_debut: date
date_fin: date
@app.post("/demandes", status_code=201)
def creer(d: NouvelleDemande, x_utilisateur: str = Header()):
_verifier_acces(x_utilisateur, d.employe_id)
nb = jours_ouvres(d.date_debut, d.date_fin)
if SOLDES[d.employe_id][d.type_conge] < nb:
raise HTTPException(409, f"Solde insuffisant : {nb} jours demandés, ...")
...Essayez une route à la main, en vous faisant passer pour E004 :
curl -s -H "X-Utilisateur: E004" http://127.0.0.1:8077/employes/E002/soldes
curl -s -H "X-Utilisateur: E004" http://127.0.0.1:8077/employes/E003/soldesPourquoi l'outil creer_demande_conges ne prend-il pas de paramètre utilisateur dans son schéma ?
Si le modèle pouvait choisir l'utilisateur, une phrase bien tournée suffirait à agir au nom d'un autre. Le code injecte l'identité de la session dans l'en-tête X-Utilisateur.
Une demande du vendredi 2030-01-04 au mardi 2030-01-08 coûte combien de jours dans l'API ?
Vendredi, lundi et mardi : 3 jours ouvrés. Le samedi et le dimanche ne sont pas décomptés. C'est vérifié par test_api_jours_ouvres_et_solde.
Exercice : ajouter le solde prévisionnel
Ajoutez à l'API une route GET /employes/{id}/soldes/simulation?jours=3&type_conge=rtt qui renvoie le solde restant si la demande était acceptée, sans rien modifier. Quel outil déclareriez-vous, et serait-il sensible ?
Voir la solution
@app.get("/employes/{employe_id}/soldes/simulation")
def simuler(employe_id: str, jours: int, type_conge: Literal["conges_payes", "rtt"],
x_utilisateur: str = Header()):
_verifier_acces(x_utilisateur, employe_id)
reste = SOLDES[employe_id][type_conge] - jours
return {"employe_id": employe_id, "type_conge": type_conge, "reste": reste, "possible": reste >= 0}L'outil simuler_solde(employe_id, type_conge, jours) n'est pas sensible : il ne modifie rien. Il suffit de l'ajouter à DECLARATIONS, OUTILS et à valider() (vérifier 1 <= jours <= 31).
Résultat obtenu
Appels manuels le 2026-10-15, API lancée en local :
$ curl -s -H "X-Utilisateur: E004" http://127.0.0.1:8077/employes/E002/soldes
{"employe_id":"E002","unite":"jours","conges_payes":7,"rtt":9}
$ curl -s -H "X-Utilisateur: E004" http://127.0.0.1:8077/employes/E003/soldes
{"detail":"Accès refusé : vous n'êtes ni l'employé ni son manager"}Je sais faire
- Lancer une API FastAPI locale et explorer
/docs - Faire correspondre chaque outil à une route HTTP
- Expliquer pourquoi la validation existe dans l'outil et dans l'API
- Ajouter une route et l'outil qui l'expose