File size: 4,390 Bytes
7ddb64a
 
9b0ce22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7ddb64a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9b0ce22
7ddb64a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9b0ce22
7ddb64a
 
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
from pydantic import BaseModel
from typing import List, Optional
from datetime import datetime

# ═══════════════════════════════════════════════════════════════════════════════
# AUTH SCHEMAS
# ═══════════════════════════════════════════════════════════════════════════════

class UserRegistration(BaseModel):
    """User registration request"""
    email: str
    password: str
    full_name: Optional[str] = ""
    dob: Optional[str] = ""
    sex: Optional[str] = ""
    medical_history: Optional[str] = ""
    geolocation: Optional[str] = ""

class UserCredentials(BaseModel):
    """User login credentials"""
    email: str
    password: str

class UserProfile(BaseModel):
    """User profile information"""
    user_id: str
    email: str
    full_name: Optional[str] = ""
    dob: Optional[str] = ""
    sex: Optional[str] = ""
    medical_history: Optional[str] = ""
    geolocation: Optional[str] = ""
    created_at: str
    conversation_count: int = 0

class UserProfileUpdate(BaseModel):
    """User profile update request"""
    email: Optional[str] = ""
    full_name: Optional[str] = ""
    dob: Optional[str] = ""
    sex: Optional[str] = ""
    medical_history: Optional[str] = ""
    geolocation: Optional[str] = ""

class PasswordChange(BaseModel):
    """Password change request"""
    old_password: str
    new_password: str

class TokenResponse(BaseModel):
    """JWT token response"""
    access_token: str
    token_type: str = "bearer"
    user: UserProfile

class AuthResponse(BaseModel):
    """Generic auth response"""
    success: bool
    message: str
    data: Optional[dict] = None

class Conversation(BaseModel):
    """Conversation metadata"""
    conversation_id: str
    user_id: str
    title: str
    created_at: str
    last_updated: str
    message_count: int = 0
    has_diagnosis: bool = False
    last_message_preview: str = ""

class ConversationMessage(BaseModel):
    """Individual message in conversation"""
    timestamp: str
    role: str  # "user" or "assistant"
    content: str
    language: Optional[str] = "en"
    symptoms: list[str] = []
    quick_replies: list[str] = []

class ConversationDetail(BaseModel):
    """Full conversation with messages and diagnosis"""
    conversation_id: str
    user_id: str
    title: str
    created_at: str
    messages: list[ConversationMessage] = []
    diagnosis: Optional[dict] = None
    recommendations: Optional[str] = None

# === INPUT ===

class PatientInfo(BaseModel):
    """Reçu depuis le frontend, contient les infos du patient."""
    age: int = 0
    sex: str = "Male"
    medical_history: str = ""
    geolocation: str = ""


class ChatMessage(BaseModel):
    """Message individuel dans l'historique de chat, avec un rôle (user ou assistant) et le contenu textuel."""
    role: str      # "user" or "assistant"
    content: str
    language: Optional[str] = "en"
class ChatRequest(BaseModel):
    """Reçu depuis le frontend, contient l'historique complet du chat et le nouveau message de l'utilisateur."""
    history: list[ChatMessage]   # full conversation so far
    message: str                 # new user message
    patient_info: PatientInfo  # infos du patient, pour contexte additionnel


# === OUTPUT ===


class DiagnosisResultPerDisease(BaseModel):
    """Prediction atomique pour une condition médicale donnée."""
    name: str        # exp. "Malaria"
    probability: float    # exp. 0.87
    level: str        # exp. level_low, level_medium, level_high
    symptoms: List[str]

class DiagnosisResponse(BaseModel):
    """Reponse envoyée au frontend, contient une liste de diagnostics possibles et une recommandation."""
    statistics: List[DiagnosisResultPerDisease]
    recommendation: str


class ChatResponse(BaseModel):
    lang: str
    reply: str
    quick_replies: list[str] = []
    # Quand le LLM a suffisament d'infos pour faire un diagnostic, on peut aussi inclure les résultats:
    symptoms: list[str] = []
    diagnosis: dict = {}   # reponse finale de notre modele
    diseases_info: list[dict] = []
    recommendations: str = ""