File size: 4,374 Bytes
4e9b744
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
"""Pydantic schemas for interview feedback output."""

from typing import List, Optional
from pydantic import BaseModel, Field


class CandidatFeedback(BaseModel):
    """Feedback section for the candidate."""
    points_forts: List[str] = Field(..., description="Liste des points forts démontrés")
    points_a_ameliorer: List[str] = Field(..., description="Liste des axes d'amélioration identifiés")
    conseils_apprentissage: List[str] = Field(..., description="Ressources ou actions concrètes pour progresser")
    score_global: int = Field(..., description="Note globale sur 100")
    feedback_constructif: str = Field(..., description="Message bienveillant et constructif adressé au candidat")


class MetricsBreakdown(BaseModel):
    """Detailed breakdown of scores."""
    communication: float = Field(..., description="Score 0-10: Orthographe, grammaire, clarté")
    technique: float = Field(..., description="Score 0-10: Compétence technique (SOAR)")
    comportemental: float = Field(..., description="Score 0-10: Soft skills (STAR)")
    fidelite_cv: float = Field(..., description="Score 0-10: Cohérence avec le CV")


class FraudDetectionMetrics(BaseModel):
    """Detailed fraud detection metrics (0-100)."""
    vocab_score: int = Field(..., description="Usage de mots 'GPT' (delve, tapestry...)")
    structure_score: int = Field(..., description="Patterns structurels (listes, longueur...)")
    paste_score: int = Field(..., description="Basé sur l'événement copier-coller")
    pattern_score: int = Field(..., description="Répétitions, questions en retour, proximité CV")

class FraudDetection(BaseModel):
    """Complete fraud analysis."""
    score_global: int = Field(..., description="Probabilité globale d'usage IA (0-100)")
    red_flag: bool = Field(False, description="Vrai si score > 70")
    detected_keywords: List[str] = Field(..., description="Mots suspects identifiés")
    resume: str = Field(..., description="Eplication courte")
    details: FraudDetectionMetrics

class DashboardCompetences(BaseModel):
    """Score de similarité basé sur la triade."""
    technique: float = Field(..., description="Adéquation Hard Skills (0-100)")
    cognitive: float = Field(..., description="Raisonnement et structure (0-100)")
    comportementale: float = Field(..., description="Soft Skills & Culture Fit (0-100)")
    average_score: float = Field(..., description="Moyenne pondérée")

class DecisionStrategique(BaseModel):
    """Pilier décisionnel du rapport."""
    recommendation: str = Field(..., description="RECRUTER, APPROFONDIR ou REJETER")
    action_plan: str = Field(..., description="Recommandation d'action immédiate (ex: Tester sur SQL)")
    so_what: str = Field(..., description="Impact business direct du candidat (Le 'Pourquoi' stratégique)")

class RolsPcdAnalysis(BaseModel):
    """Analyse structurée ROLS et PCD."""
    rols_summary: str = Field(..., description="Résumé ROLS (Résumé, Objectifs, Localisation, Stratégie)")
    pcd_analysis: str = Field(..., description="Analyse PCD (Produits, Clients, Distribution)")

class EntrepriseInsights(BaseModel):
    """Insights section for the recruiter/company."""
    correspondance_profil_offre: str = Field(..., description="Analyse de l'adéquation CV/Poste")
    
    # Dashboard
    dashboard: DashboardCompetences = Field(..., description="Tableau de bord des compétences")
    
    # Qualitative Analysis
    qualitative_analysis: RolsPcdAnalysis = Field(..., description="Analyse structurée ROLS/PCD")
    
    # Strategic Decision
    decision: DecisionStrategique = Field(..., description="Aide à la décision")

    # Fraud & Cheat Detection
    fraud_detection: FraudDetection = Field(..., description="Analyse complète anti-triche")
    
    # Legacy Metrics (kept for backward compatibility if needed, or mapped from dashboard)
    metrics: MetricsBreakdown = Field(..., description="Détail des notes par catégorie")
    
    # Global verification
    red_flag_detected: bool = Field(False, description="True si un comportement inacceptable est détecté")
    red_flag_reason: Optional[str] = Field(None, description="Raison du Veto si applicable")


class FeedbackOutput(BaseModel):
    """Complete feedback output with candidate and company sections."""
    candidat: CandidatFeedback
    entreprise: EntrepriseInsights