Files
MobilityOps/frontend/src/i18n/locales/fr-BE/quality.json
T
NuklearRabbitandClaude Sonnet 5 34df66d28c M8: GUI polish, n8n workflow-3 fixes, RAGcore retrieval root-cause and fix
GUI: dashboard Attention Queue presents a curated severity mix instead of pure
severity-sort (grouped Now/Today/Later headers); Today's Movements seed data
curated so a fresh reset shows a credible day (2+ departures, 2+ returns), with
a new seed-integrity test; About Demo restructured into a compact grid with
progressive disclosure for technical sections; Duplicate Merge shows match/conflict
counts, hides matching fields by default, and previews the final merged record
before confirmation.

Repo hygiene: removed a stray empty `backend;C` directory and an untracked 31MB
zip export; `.gitignore` now excludes future archive exports.

n8n: fixed invalid JSON (a missing `},` between two node objects) in the committed
`fleet-ops-vehicle-return.json` -- the file could not be parsed. Live-validated
workflow 3 (RAGcore Procedure Sync): found and fixed a real defect (three body
parameters had a stray trailing `}}`) and a missing Error Workflow wiring, both
via the safe `n8n import:workflow` CLI path; exported the corrected, still-
inactive workflow as the new source of truth and updated MANIFEST.md/check_drift.py.
Publishing it (starts real daily unattended runs) remains a separate decision.

RAGcore: root-caused and fixed (live, approved) the "zero retrieval candidates"
bug -- a filesystem permission bug (`embedding_profiles.json` unreadable by the
app's own runtime user) that broke every retrieval call before it reached Qdrant.
Every other suspect (grants, scope resolution, Qdrant filters, embeddings) was
verified healthy first. Found a second, deeper gap: the reranker adapter calls
an Ollama HTTP route that does not exist on the deployed Ollama version, so
`/v1/answers` still returns `not_answerable`. `KNOWLEDGE_PROVIDER` stays `demo`
until that is resolved on the RAGcore side. Evidence-based MCP Hub integration
status (real tool-call audit history, not just a boolean flag) replaces the old
`configured`/`not_configured` guess. Full findings in
`docs/final-integrations/current-state-audit.md`.

Backend: 172 tests passing, ruff clean, mypy clean (50 files). Frontend: tsc
clean, production build clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-05 13:05:02 +02:00

243 lines
14 KiB
JSON

{
"list": {
"eyebrow": "Assurance / Atelier",
"title": "Qualité des données",
"description": "Résolvez les exceptions étayées par des preuves avant qu'elles ne perturbent l'exploitation.",
"runScan": "Lancer le contrôle qualité",
"confirmScanTitle": "Confirmer le contrôle qualité",
"confirmScanBody": "Lancer maintenant le contrôle déterministe sur les cinq types de règles ?",
"scanning": "Analyse en cours…",
"confirmScanYes": "Oui, lancer",
"cancel": "Annuler",
"scanComplete": "Contrôle terminé : {{summary}}",
"scanNoNew": "aucun nouveau problème trouvé (les problèmes ouverts existants ne sont pas recréés).",
"scanFailed": "Impossible d'exécuter le contrôle qualité.",
"statusLabel": "Statut",
"statusAll": "Tous les statuts",
"statusOpen": "Ouvert",
"statusDeferred": "Reporté",
"statusResolved": "Résolu",
"statusRejected": "Rejeté",
"ruleTypeLabel": "Type de règle",
"ruleTypeAll": "Tous les types de règles",
"demoScenariosOnly": "Scénarios de démo uniquement",
"loading": "Chargement de l'atelier qualité…",
"queueClear": "La file est vide",
"noIssuesMatch": "Aucun problème ne correspond aux filtres actuels.",
"noDemoIssuesMatch": "Aucun problème de scénario de démo ne correspond",
"noDemoIssuesMatchDetail": "Décochez « Scénarios de démo uniquement » pour voir la file complète.",
"unavailable": "Les problèmes de qualité des données sont actuellement indisponibles.",
"count": "{{count}} problèmes",
"evidenceBacked": "Détection étayée par des preuves",
"columns": {
"reference": "Référence",
"rule": "Règle",
"entity": "Entité",
"severity": "Gravité",
"status": "Statut"
}
},
"ruleTypes": {
"possible_duplicate_customer": "Client peut-être en double",
"missing_required_field": "Champ obligatoire manquant",
"odometer_regression": "Anomalie de kilométrage",
"booking_overlap": "Chevauchement de réservations",
"vehicle_status_conflict": "Conflit de statut du véhicule"
},
"severities": {
"high": "Critique",
"medium": "Avertissement",
"low": "Info"
},
"detail": {
"backLink": "Atelier qualité",
"eyebrow": "Qualité / {{rule}}",
"title": "Examinez les preuves enregistrées et consignez une résolution auditée.",
"notFound": "Ce problème est introuvable.",
"loading": "Chargement des preuves du problème…",
"managerOnly": "L'atelier qualité est visible uniquement pour les Responsables des opérations.",
"managerOnlyDetail": "Les preuves et résolutions de qualité des données sont visibles uniquement pour les Responsables des opérations.",
"summary": {
"rule": "Règle",
"entity": "Entité",
"evidenceSummary": "Résumé des preuves"
},
"resolved": {
"title": "Problème {{ref}} résolu",
"body": "La modification a été appliquée et enregistrée dans la piste d'audit.",
"viewAudit": "Voir la piste d'audit",
"viewVehicle": "Voir le véhicule",
"continueDemo": "Poursuivre la démo"
},
"deferOrReject": {
"heading": "Reporter ou rejeter",
"description": "Reportez pour un examen ultérieur, ou rejetez si ce n'est pas un véritable problème.",
"defer": "Reporter",
"reject": "Rejeter",
"deferFailed": "Impossible de reporter ce problème.",
"rejectFailed": "Impossible de rejeter ce problème."
},
"explainer": {
"whatIsWrong": "Ce qui ne va pas",
"whyItMatters": "Pourquoi c'est important",
"possible_duplicate_customer": {
"whatIsWrong": "Deux profils clients partagent des données d'identification (e-mail, téléphone ou un nom très similaire) suffisamment fortement pour qu'il s'agisse probablement de la même personne, enregistrée deux fois.",
"whyItMatters": "Les clients en double répartissent l'historique de réservation entre deux fiches, risquent une double facturation et compliquent les échanges avec le support."
},
"missing_required_field": {
"whatIsWrong": "Cette fiche manque d'informations requises pour un fonctionnement normal (par exemple, un client sans e-mail ni numéro de téléphone enregistré).",
"whyItMatters": "Sans ces données, l'entreprise ne peut pas contacter le client, ni identifier de façon fiable le véhicule pour les contrôles de conformité et de remise."
},
"odometer_regression": {
"whatIsWrong": "Un relevé de kilométrage soumis est inférieur au dernier relevé connu (de référence) du véhicule.",
"whyItMatters": "Un kilométrage en baisse signifie généralement une erreur de saisie ou que les relevés ont été enregistrés pour le mauvais véhicule. Laisser passer cela silencieusement corromprait la planification de l'entretien et l'historique kilométrique à la revente."
},
"booking_overlap": {
"whatIsWrong": "Le même véhicule est engagé sur deux réservations dont les périodes se chevauchent.",
"whyItMatters": "Une seule de ces réservations peut réellement être honorée. Non résolu, un client arriverait pour constater que son véhicule est déjà chez quelqu'un d'autre."
},
"vehicle_status_conflict": {
"whatIsWrong": "Le statut opérationnel enregistré de ce véhicule ne correspond pas à ce que son propre historique de réservations et d'inspections implique.",
"whyItMatters": "Un statut incorrect peut faire apparaître un véhicule indisponible comme réservable, ou masquer un véhicule disponible de la flotte."
}
},
"evidence": {
"duplicate.exact_email": "Adresse e-mail identique",
"duplicate.exact_phone": "Numéro de téléphone identique",
"duplicate.same_postal_code": "Même code postal",
"duplicateSimilarName": "Nom fortement similaire (score {{score}})",
"missingField": "Champ manquant : {{field}}",
"overlapReservedBookings": "Réservations qui se chevauchent : {{refs}}",
"odometerRegression": "La réservation {{laterRef}} a enregistré {{laterKm}} km, en dessous des {{earlierKm}} km enregistrés par la réservation antérieure {{earlierRef}}.",
"upcomingBookingMissingInspection": "La réservation {{bookingRef}} commence bientôt mais l'inspection opérationnelle requise est encore manquante.",
"seedPlaceholder": "Donnée de démonstration synthétique sans autre détail."
},
"duplicateCustomer": {
"heading": "Comparer et fusionner",
"description": "Choisissez le client de référence et examinez chaque champ divergent.",
"keepAsSurvivor": "Conserver comme fiche principale",
"differs": "Diffère",
"match": "Identique",
"summaryCounts": "{{matchCount}} champs identiques · {{conflictCount}} champs en conflit",
"showMatchingFields": "Afficher aussi les champs identiques",
"hideMatchingFields": "Masquer les champs identiques",
"previewTitle": "Aperçu de la fiche fusionnée ({{ref}})",
"mergePreview": "{{loser}} deviendra une fiche archivée liée à {{survivor}} ; ses réservations seront transférées.",
"mergeInto": "Fusionner avec {{ref}}",
"confirmMergeTitle": "Confirmer la fusion",
"confirmMergeBody": "Fusionner {{loser}} avec {{survivor}} ? Cette action est irréversible.",
"merging": "Fusion en cours…",
"confirmMergeYes": "Oui, fusionner",
"mergeFailed": "Impossible de fusionner ces clients.",
"bothMissing": "Les deux clients de cette comparaison n'ont pas pu être chargés.",
"fieldColumn": "Champ",
"fields": {
"first_name": "Prénom",
"last_name": "Nom",
"email": "E-mail",
"phone": "Téléphone",
"postal_code": "Code postal",
"city": "Ville"
}
},
"missingField": {
"heading": "Compléter les champs manquants",
"description": "Complétez la fiche pour {{ref}}. Le problème se résout automatiquement dès qu'aucune donnée requise ne manque.",
"atLeastOne": "Au moins un e-mail ou un numéro de téléphone est requis.",
"saveAndRecheck": "Enregistrer et revérifier",
"saving": "Enregistrement…",
"saveFailed": "Impossible d'enregistrer ces champs.",
"fields": {
"first_name": "Prénom",
"last_name": "Nom",
"email": "E-mail",
"phone": "Téléphone",
"registration_number": "Numéro d'immatriculation",
"make": "Marque",
"model": "Modèle",
"location": "Localisation"
}
},
"odometerRegression": {
"heading": "Résoudre l'anomalie de kilométrage",
"description": "Le kilométrage de référence n'est jamais abaissé automatiquement — choisissez comment le régulariser.",
"canonicalOdometer": "Kilométrage de référence",
"decisionLegend": "Décision",
"retainCanonical": "Conserver le relevé de référence",
"retainCanonicalDetail": "Considérer le relevé soumis comme erroné ; rien ne change sur la fiche du véhicule.",
"correctReading": "Corriger le relevé",
"correctReadingDetail": "Mettre à jour à la fois la réservation et le kilométrage de référence avec la valeur correcte.",
"noBookingAttached": "Aucune réservation liée à ce problème, seule l'option « conserver la référence » est donc disponible.",
"booking": "Réservation",
"correctedOdometer": "Kilométrage corrigé (km)",
"note": "Note",
"resolving": "Résolution en cours…",
"resolveIssue": "Résoudre le problème",
"resolveFailed": "Impossible de résoudre ce problème."
},
"bookingOverlap": {
"heading": "Résoudre le chevauchement de réservations",
"description": "Bloquez l'un des deux engagements qui se chevauchent. L'autre conserve son statut actuel.",
"columns": {
"booking": "Réservation",
"window": "Période",
"status": "Statut",
"blockThis": "Bloquer celle-ci"
},
"blockLabel": "Bloquer {{ref}}",
"note": "Note",
"resolving": "Résolution en cours…",
"blockButton": "Bloquer {{ref}}",
"blockButtonFallback": "Bloquer la réservation",
"resolveFailed": "Impossible de résoudre ce chevauchement."
},
"vehicleStatusConflict": {
"heading": "Résoudre le conflit de statut",
"description": "Une règle faisant autorité recommande un statut opérationnel corrigé pour ce véhicule.",
"currentStatus": "Statut actuel",
"reviewRecommendation": "Voir la recommandation",
"loadingRecommendation": "Chargement de la recommandation…",
"recommendationFailed": "Impossible de charger une recommandation.",
"recommendedStatus": "Statut recommandé",
"whyHeading": "Pourquoi",
"evidenceHeading": "Faits",
"consequenceHeading": "Conséquence",
"consequence": {
"statusWillChange": "Le statut du véhicule sera changé en {{status}}.",
"issueWillBeRechecked": "Ce problème de qualité sera à nouveau contrôlé.",
"changeWillBeAudited": "Le changement sera enregistré dans la piste d'audit.",
"bookingsNotDeleted": "Les réservations elles-mêmes ne sont pas supprimées."
},
"changeStatusTo": "Changer le statut vers {{status}}",
"applying": "Application en cours…",
"applied": "Appliqué {{status}} — {{reason}}",
"applyFailed": "Impossible d'appliquer un statut recommandé.",
"staleRecommendation": "La situation a changé depuis l'affichage de cette recommandation. Consultez-la à nouveau avant de l'appliquer.",
"reviewAgain": "Revoir la recommandation",
"manualReview": {
"heading": "Évaluation manuelle requise",
"body": "Les faits concernant ce véhicule se contredisent. Un Responsable des opérations doit évaluer la situation en personne plutôt que d'appliquer un changement de statut automatique.",
"hint": "Utilisez « Reporter » ou « Rejeter » ci-dessous, ou examinez manuellement le véhicule et les réservations concernées."
},
"noConflict": {
"heading": "Aucun changement nécessaire",
"body": "Le statut actuel de ce véhicule correspond déjà aux faits."
},
"evidence": {
"activeBookings": "Réservation(s) active(s) : {{refs}}",
"overlappingBookings": "Réservations qui se chevauchent : {{pairs}}",
"serviceThresholdReached": "Le kilométrage ({{odometer}} km) a atteint le seuil d'entretien ({{threshold}} km).",
"openOverlapIssue": "Problème de chevauchement de réservation ouvert : {{ref}}"
},
"reasonCodes": {
"vehicle.active_rental": "Ce véhicule a une location active mais n'est pas enregistré comme loué. Le statut est corrigé pour refléter la situation réelle.",
"vehicle.service_threshold_reached": "Ce véhicule a atteint son seuil d'entretien. Il est placé en entretien afin qu'il ne soit pas utilisé avant que la révision ait eu lieu.",
"vehicle.booking_conflict": "Ce véhicule a deux réservations qui se chevauchent. Le bloquer évite qu'il soit à nouveau considéré comme disponible avant que le conflit de réservation ne soit résolu.",
"vehicle.rental_ended": "La location de ce véhicule est terminée et il n'y a plus de réservation active. Il est remis en disponible.",
"vehicle.manual_review_required": "Les faits concernant ce véhicule se contredisent (par exemple, une réservation active alors que le véhicule est en entretien, ou un seuil d'entretien atteint en même temps qu'une location active). Cela nécessite une évaluation humaine plutôt qu'un changement de statut automatique.",
"vehicle.no_conflict": "Le statut actuel de ce véhicule correspond déjà aux faits. Aucun changement n'est nécessaire."
}
}
}
}