Aller au contenu

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 OK
  • 404 Not Found si 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 OK
  • 403 Forbidden si l'utilisateur n'est pas propriétaire et n'est pas admin.
  • 404 Not Found si 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 Request si le body est invalide.
  • 403 Forbidden si 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 :

{
  "entry_id": "1716129600000-0"
}

Réponse :

{
  "outcome": "republished",
  "transcript_id": "uuid",
  "new_message_id": "1716130000000-0"
}

Codes : 200 OK, 403 Forbidden, 404 Not Found si l'entrée DLQ n'existe
plus.