Files
Anonyme/app/components/AnonymizationLogic.tsx
2025-07-28 21:15:41 +02:00

176 lines
5.2 KiB
TypeScript

import { useState } from "react";
interface EntityMapping {
originalValue: string;
anonymizedValue: string;
entityType: string;
startIndex: number;
endIndex: number;
}
// Nouvelle interface pour les résultats de Presidio Analyzer
interface PresidioAnalyzerResult {
entity_type: string;
start: number;
end: number;
score: number;
analysis_explanation?: {
recognizer: string;
pattern_name?: string;
pattern?: string;
validation_result?: boolean;
};
}
// Interface pour la réponse de l'API
interface ProcessDocumentResponse {
text?: string;
anonymizedText?: string;
piiCount?: number;
analyzerResults?: PresidioAnalyzerResult[];
error?: string;
}
interface AnonymizationLogicProps {
sourceText: string;
fileContent: string;
uploadedFile: File | null;
setOutputText: (text: string) => void;
setError: (error: string | null) => void;
setEntityMappings: (mappings: EntityMapping[]) => void;
}
export const useAnonymization = ({
sourceText,
fileContent,
uploadedFile,
setOutputText,
setError,
setEntityMappings,
}: AnonymizationLogicProps) => {
const [isProcessing, setIsProcessing] = useState(false);
const anonymizeData = async () => {
const textToProcess = sourceText || fileContent || "";
if (!textToProcess.trim()) {
setError(
"Veuillez saisir du texte à anonymiser ou télécharger un fichier"
);
return;
}
setIsProcessing(true);
setError(null);
setOutputText("");
setEntityMappings([]);
try {
console.log("🚀 Début anonymisation avec Presidio");
const formData = new FormData();
if (uploadedFile) {
console.log("📁 Traitement fichier:", {
name: uploadedFile.name,
type: uploadedFile.type,
size: uploadedFile.size
});
formData.append("file", uploadedFile);
} else {
console.log("📝 Traitement texte saisi");
const textBlob = new Blob([textToProcess], { type: "text/plain" });
const textFile = new File([textBlob], "input.txt", { type: "text/plain" });
formData.append("file", textFile);
}
console.log("🔍 Appel à /api/process-document avec Presidio...");
console.log("📦 FormData préparée:", Array.from(formData.entries()));
const response = await fetch("/api/process-document", {
method: "POST",
body: formData,
});
console.log("📡 Réponse reçue:", {
ok: response.ok,
status: response.status,
statusText: response.statusText,
headers: Object.fromEntries(response.headers.entries())
});
if (!response.ok) {
let errorMessage = `Erreur HTTP: ${response.status}`;
try {
const responseText = await response.text();
console.log("📄 Contenu de l'erreur:", responseText);
if (responseText.trim()) {
try {
const errorData = JSON.parse(responseText);
if (errorData.error) {
errorMessage = errorData.error;
console.log("✅ Message détaillé récupéré:", errorMessage);
}
} catch (jsonError) {
console.error("❌ Erreur parsing JSON:", jsonError); // ✅ Utiliser la variable
console.error("❌ Réponse non-JSON:", responseText);
errorMessage = `Erreur ${response.status}: Réponse invalide du serveur`;
}
}
} catch (readError) {
console.error("❌ Impossible de lire la réponse:", readError);
}
throw new Error(errorMessage);
}
const data: ProcessDocumentResponse = await response.json();
console.log("📊 Réponse API:", data);
if (data.error) {
throw new Error(data.error);
}
if (data.anonymizedText) {
console.log("✅ Anonymisation réussie avec Presidio");
setOutputText(data.anonymizedText);
// Extraire les mappings depuis les résultats Presidio (plus d'erreur 'any')
if (data.analyzerResults && data.text) {
const mappings: EntityMapping[] = data.analyzerResults.map(
(entity: PresidioAnalyzerResult, index: number) => ({
originalValue: data.text!.substring(entity.start, entity.end),
anonymizedValue: `[${entity.entity_type}${index + 1}]`,
entityType: entity.entity_type,
startIndex: entity.start,
endIndex: entity.end,
})
);
setEntityMappings(mappings);
console.log("📋 Entités détectées:", mappings.length);
console.log("🔍 Détails des entités:", mappings);
}
} else if (data.text) {
console.log(
"⚠️ Fallback: Presidio non disponible, texte original retourné"
);
setOutputText(data.text);
setError("Presidio temporairement indisponible. Texte non anonymisé.");
}
} catch (error) {
console.error("❌ Erreur anonymisation complète:", error);
setError(
error instanceof Error
? error.message
: "Erreur lors de l'anonymisation avec Presidio"
);
} finally {
setIsProcessing(false);
}
};
return { anonymizeData, isProcessing };
};