API REST¶
Préfixe : /api/reliability. Toutes les routes utilisateur exigent un JWT
valide (get_current_user). Les routes /dlq/* exigent en plus le rôle admin.
Vue d'ensemble¶
| Méthode | Chemin | Auth | Description |
|---|---|---|---|
| GET | /overview |
utilisateur | Vue agrégée des transcriptions à risque. |
| GET | /transcripts/{transcript_id}/suggestions |
utilisateur + ownership | Liste paginée des suggestions d'une transcription. |
| GET | /transcripts/{transcript_id}/progress |
utilisateur | État de progression du job worker. |
| POST | /suggestions/actions |
utilisateur | Application en lot d'actions utilisateur (idempotent). |
| GET | /ui-config |
publique | Constantes destinées à l'UI. |
| GET | /dlq/list |
admin | Liste paginée des entrées DLQ. |
| GET | /dlq/stats |
admin | Statistiques de la DLQ. |
| POST | /dlq/reprocess |
admin | Réinjecte une entrée DLQ dans le stream principal. |
GET /overview¶
Retourne le score global, les compteurs et la liste des transcriptions à
risque, triée par score croissant puis par nombre de pending décroissant.
Paramètres¶
| Nom | Type | Défaut | Notes |
|---|---|---|---|
project_id |
string | — | Optionnel, filtre par projet. |
page |
int ≥ 1 | 1 | Pagination. |
limit |
int 1..100 | 20 | Taille de page. |
Réponse (200)¶
{
"global_score": 0.83,
"pending_count": 12,
"validated_count": 47,
"ignored_count": 5,
"auto_applied_count": 91,
"at_risk": [
{
"transcript_id": "uuid",
"title": "Réunion ...",
"global_score": 0.61,
"pending_count": 8
}
],
"page": 1,
"limit": 20,
"total": 134
}
global_score vaut null si aucune transcription n'a été analysée.
Codes¶
200 OK404 Not Foundsi le backend Reliability est désactivé
(RELIABILITY_API_V1_ENABLED=false).
GET /transcripts/{transcript_id}/suggestions¶
Suggestions d'une transcription donnée, accompagnées du score le plus récent.
Paramètres¶
| Nom | Type | Défaut | Notes |
|---|---|---|---|
status |
liste | aucun | Filtre pending,validated,ignored,auto_applied. |
type |
liste | aucun | Filtre place,person,acronym,org,typo. |
page |
int ≥ 1 | 1 | |
limit |
int 1..200 | 50 | |
include_evidence |
bool | false |
Si vrai, inclut le champ evidence_json. |
Sécurité¶
L'endpoint vérifie que transcript.user_id == current_user.id (ou que
l'utilisateur a le rôle admin) avant de répondre.
L'endpoint ne filtre pas par analysis_version afin de garantir la
rétro-compatibilité d'affichage avec les suggestions produites par des
versions logiques antérieures.
Réponse (200)¶
{
"transcript_id": "uuid",
"score": {
"transcript_id": "uuid",
"global_score": 0.83,
"score_places": 0.91,
"score_persons": 0.75,
"score_acronyms": null,
"score_orgs": null,
"score_typos": 0.80,
"pending_count": 4,
"validated_count": 7,
"ignored_count": 1,
"auto_applied_count": 12,
"calculation_version": "..."
},
"page": 1,
"limit": 50,
"total": 24,
"suggestions": [
{
"id": "uuid",
"transcript_id": "uuid",
"segment_id": "uuid",
"segment_index": 14,
"suggestion_type": "place",
"original_value": "lyone",
"suggested_value": "Lyon",
"confidence_score": 0.91,
"source": "LLM",
"status": "pending",
"reason_code": null,
"evidence_json": null
}
]
}
score vaut null si la transcription n'a jamais été analysée.
Garantie de non-effet¶
Aucun snapshot n'est créé lors d'un GET ; la lecture est strictement non
mutative.
Codes¶
200 OK403 Forbiddensi l'utilisateur n'est pas propriétaire et n'est pas admin.404 Not Foundsi la transcription n'existe pas.
GET /transcripts/{transcript_id}/progress¶
Retourne le hash Redis de progression.
Réponse (200)¶
{
"transcript_id": "uuid",
"job_status": "running",
"stage": "multi_type_analysis",
"progress": 42,
"started_at": "1716129600"
}
Si aucun job n'est ou n'a été en cours, la réponse renvoie
job_status: "unknown" avec un progress de 0.
POST /suggestions/actions¶
Applique en lot des actions utilisateur. L'endpoint est idempotent sur la
clé (suggestion_id, action_type, idempotency_key).
Body¶
{
"actions": [
{
"suggestion_id": "uuid",
"action_type": "validated",
"idempotency_key": "client-generated-string-6-to-100-chars",
"payload": {
"text_after": "Lyon"
}
}
]
}
action_type ∈ {validated, ignored, auto_applied, reverted}.
Réponse (200)¶
{
"results": [
{
"suggestion_id": "uuid",
"action_type": "validated",
"outcome": "applied",
"score": { "...": "snapshot mis à jour" }
}
]
}
outcome peut prendre les valeurs applied, idempotent_replay,
not_found, forbidden.
Sécurité¶
Pre-check transverse : si la requête contient des suggestions appartenant à
des transcriptions dont l'utilisateur n'est pas propriétaire et qu'il n'est
pas admin, l'endpoint renvoie 403 Forbidden avant toute écriture.
Codes¶
200 OK(y compris pour les replays idempotents).400 Bad Requestsi le body est invalide.403 Forbiddensi ownership KO.
GET /ui-config¶
Constantes nécessaires au frontend (libellés de seuils, plafonds, ordre des
types). Publique, sans authentification.
Endpoints administration /dlq/*¶
GET /dlq/list¶
Liste paginée des entrées dead-letter.
Paramètres :
| Nom | Type | Notes |
|---|---|---|
limit |
int | Taille de page. |
cursor |
string | Identifiant Redis stream pour la pagination. |
Réponse :
{
"entries": [
{
"entry_id": "1716129600000-0",
"transcript_id": "uuid",
"user_id": "uuid",
"retry_count": 3,
"error": "...",
"timestamp": "1716129600"
}
],
"next_cursor": "1716129700000-0"
}
GET /dlq/stats¶
{
"total": 12,
"first_entry_id": "1716100000000-0",
"last_entry_id": "1716129700000-0",
"stream_key": "reliability:events:dlq"
}
POST /dlq/reprocess¶
Réinjecte une entrée dans reliability:events.
Body :
Réponse :
Codes : 200 OK, 403 Forbidden, 404 Not Found si l'entrée DLQ n'existe
plus.