""" Tâches de vérification et contrôle qualité """ import logging from typing import Dict, Any from services.worker.celery_app import app logger = logging.getLogger(__name__) @app.task(bind=True, name='verification.verify_document') def verify_document(self, doc_id: str, entities: Dict[str, Any], doc_type: str, context: Dict[str, Any]) -> Dict[str, Any]: """ Vérification et contrôle qualité d'un document Args: doc_id: Identifiant du document entities: Entités extraites doc_type: Type de document context: Contexte de traitement Returns: Résultat des vérifications """ try: logger.info(f"Début des vérifications pour le document {doc_id}") # Mise à jour du statut self.update_state( state='PROGRESS', meta={'current_step': 'verification', 'progress': 0} ) # Vérifications externes avec les APIs verification_results = {} # 1. Vérification des adresses via Cadastre if 'bien' in entities and 'adresse' in entities['bien']: try: from services.worker.utils.external_apis import ExternalAPIManager api_manager = ExternalAPIManager() address_result = await api_manager.verify_address( entities['bien']['adresse'], entities['bien'].get('code_postal'), entities['bien'].get('ville') ) verification_results['cadastre'] = address_result except Exception as e: logger.error(f"Erreur vérification Cadastre: {e}") verification_results['cadastre'] = {'status': 'error', 'error': str(e)} # 2. Vérification des risques géologiques if 'bien' in entities and 'adresse' in entities['bien']: try: from services.worker.utils.external_apis import ExternalAPIManager api_manager = ExternalAPIManager() risks_result = await api_manager.check_geological_risks( entities['bien']['adresse'] ) verification_results['georisques'] = risks_result except Exception as e: logger.error(f"Erreur vérification Géorisques: {e}") verification_results['georisques'] = {'status': 'error', 'error': str(e)} # 3. Vérification des entreprises (si applicable) if 'vendeur' in entities and 'nom' in entities['vendeur']: try: from services.worker.utils.external_apis import ExternalAPIManager api_manager = ExternalAPIManager() company_result = await api_manager.verify_company( entities['vendeur']['nom'] ) verification_results['bodacc'] = company_result except Exception as e: logger.error(f"Erreur vérification BODACC: {e}") verification_results['bodacc'] = {'status': 'error', 'error': str(e)} # 4. Vérification des personnes if 'vendeur' in entities or 'acheteur' in entities: try: from services.worker.utils.external_apis import ExternalAPIManager api_manager = ExternalAPIManager() # Vérification du vendeur if 'vendeur' in entities: person_result = await api_manager.verify_person( entities['vendeur'].get('prenom', ''), entities['vendeur'].get('nom', ''), entities['vendeur'].get('date_naissance') ) verification_results['person_vendeur'] = person_result # Vérification de l'acheteur if 'acheteur' in entities: person_result = await api_manager.verify_person( entities['acheteur'].get('prenom', ''), entities['acheteur'].get('nom', ''), entities['acheteur'].get('date_naissance') ) verification_results['person_acheteur'] = person_result except Exception as e: logger.error(f"Erreur vérification personnes: {e}") verification_results['person_verification'] = {'status': 'error', 'error': str(e)} import time time.sleep(2) # Simulation du traitement # Calcul du score de vraisemblance basé sur les vérifications credibility_score = _calculate_credibility_score(verification_results) result = { 'doc_id': doc_id, 'status': 'completed', 'verifications': verification_results, 'credibility_score': credibility_score, 'manual_review_required': credibility_score < 0.75, 'processing_time': 2.0 } logger.info(f"Vérifications terminées pour le document {doc_id} (score: {credibility_score})") return result except Exception as e: logger.error(f"Erreur lors des vérifications du document {doc_id}: {e}") raise @app.task(name='verification.batch_verify') def batch_verify_documents(doc_ids: list, entities_list: list, doc_types: list) -> Dict[str, Any]: """ Vérification en lot de documents Args: doc_ids: Liste des identifiants de documents entities_list: Liste des entités correspondantes doc_types: Liste des types de documents correspondants Returns: Résultats des vérifications en lot """ if len(doc_ids) != len(entities_list) or len(doc_ids) != len(doc_types): raise ValueError("Le nombre de documents, entités et types doit être identique") logger.info(f"Vérification en lot de {len(doc_ids)} documents") results = [] for doc_id, entities, doc_type in zip(doc_ids, entities_list, doc_types): try: result = verify_document.delay(doc_id, entities, doc_type, {}).get() results.append(result) except Exception as e: logger.error(f"Erreur lors de la vérification en lot pour {doc_id}: {e}") results.append({ 'doc_id': doc_id, 'status': 'failed', 'error': str(e) }) return { 'batch_status': 'completed', 'total_documents': len(doc_ids), 'results': results } @app.task(name='verification.update_external_data') def update_external_data(): """ Mise à jour des données externes (APIs gouvernementales) """ logger.info("Mise à jour des données externes") # TODO: Implémenter la mise à jour des données externes # - Synchronisation avec les APIs gouvernementales # - Mise à jour des caches # - Actualisation des référentiels return { 'status': 'completed', 'updated_sources': ['cadastre', 'georisques', 'bodacc'], 'timestamp': '2025-01-09T10:00:00Z' } def _calculate_credibility_score(verification_results: Dict[str, Any]) -> float: """ Calcul du score de vraisemblance basé sur les vérifications Args: verification_results: Résultats des vérifications Returns: Score de vraisemblance entre 0 et 1 """ total_score = 0.0 total_weight = 0.0 # Poids des différentes vérifications weights = { 'cadastre': 0.3, 'georisques': 0.2, 'bodacc': 0.2, 'person_vendeur': 0.15, 'person_acheteur': 0.15 } for verification_type, result in verification_results.items(): if verification_type in weights: weight = weights[verification_type] total_weight += weight if result.get('status') == 'verified': confidence = result.get('confidence', 0.8) total_score += confidence * weight elif result.get('status') == 'not_found': # Pas trouvé n'est pas forcément négatif total_score += 0.5 * weight elif result.get('status') == 'error': # Erreur réduit le score total_score += 0.2 * weight # Normalisation du score if total_weight > 0: final_score = total_score / total_weight else: final_score = 0.5 # Score par défaut si aucune vérification return min(max(final_score, 0.0), 1.0)