SanadLLM / app /db /models.py
Hydra-Bolt
added
8de5b21
from typing import List, Optional, Dict, Any
from pydantic import BaseModel, Field
from datetime import datetime
from enum import Enum
# Authentication Models
class UserRole(str, Enum):
"""User roles enum."""
USER = "user"
ADMIN = "admin"
RESEARCHER = "researcher"
class User(BaseModel):
"""User model for authentication."""
id: Optional[str] = Field(default=None, description="User ID from Supabase")
email: str = Field(description="User email address")
username: Optional[str] = Field(default=None, description="Username")
full_name: Optional[str] = Field(default=None, description="Full name")
role: UserRole = Field(default=UserRole.USER, description="User role")
is_active: bool = Field(default=True, description="Whether user is active")
created_at: Optional[datetime] = Field(default=None, description="Account creation timestamp")
last_login: Optional[datetime] = Field(default=None, description="Last login timestamp")
class UserSession(BaseModel):
"""User session model."""
id: Optional[str] = Field(default=None, description="Session ID")
user_id: str = Field(description="User ID")
access_token: str = Field(description="JWT access token")
refresh_token: Optional[str] = Field(default=None, description="JWT refresh token")
expires_at: datetime = Field(description="Token expiration time")
created_at: Optional[datetime] = Field(default=None, description="Session creation time")
last_used: Optional[datetime] = Field(default=None, description="Last used timestamp")
user_agent: Optional[str] = Field(default=None, description="User agent string")
ip_address: Optional[str] = Field(default=None, description="Client IP address")
class LoginRequest(BaseModel):
"""Login request model."""
email: str = Field(description="User email")
password: str = Field(description="User password", min_length=6)
class RegisterRequest(BaseModel):
"""Registration request model."""
email: str = Field(description="User email")
password: str = Field(description="User password", min_length=6)
username: Optional[str] = Field(default=None, description="Username")
full_name: Optional[str] = Field(default=None, description="Full name")
class AuthResponse(BaseModel):
"""Authentication response model."""
access_token: str = Field(description="JWT access token")
refresh_token: Optional[str] = Field(default=None, description="JWT refresh token")
token_type: str = Field(default="bearer", description="Token type")
expires_in: int = Field(description="Token expiration time in seconds")
user: User = Field(description="User information")
class TokenRefreshRequest(BaseModel):
"""Token refresh request model."""
refresh_token: str = Field(description="Refresh token")
# Database Storage Models
class NarratorExtractionRecord(BaseModel):
"""Database record for narrator extraction."""
id: Optional[str] = Field(default=None, description="Record ID")
user_id: str = Field(description="User who made the request")
hadith_text: str = Field(description="Original hadith text")
extracted_narrators: List[str] = Field(description="Extracted narrator names")
sanad_chain: str = Field(description="Extracted sanad chain")
success: bool = Field(description="Whether extraction was successful")
error_message: Optional[str] = Field(default=None, description="Error message if failed")
processing_time_ms: Optional[int] = Field(default=None, description="Processing time in milliseconds")
created_at: Optional[datetime] = Field(default=None, description="Creation timestamp")
session_id: Optional[str] = Field(default=None, description="Session ID")
ip_address: Optional[str] = Field(default=None, description="Client IP address")
class NarratorAnalysisRecord(BaseModel):
"""Database record for narrator analysis."""
id: Optional[str] = Field(default=None, description="Record ID")
user_id: str = Field(description="User who made the request")
extraction_id: Optional[str] = Field(default=None, description="Related extraction record ID")
narrator_name: str = Field(description="Analyzed narrator name")
reliability_grade: str = Field(description="Assigned reliability grade")
confidence_level: str = Field(description="Confidence level")
reasoning: str = Field(description="Analysis reasoning")
scholarly_consensus: str = Field(description="Scholarly consensus analysis")
known_issues: Optional[str] = Field(default=None, description="Known issues")
biographical_info: str = Field(description="Biographical information")
recommendation: str = Field(description="Usage recommendation")
success: bool = Field(description="Whether analysis was successful")
error_message: Optional[str] = Field(default=None, description="Error message if failed")
processing_time_ms: Optional[int] = Field(default=None, description="Processing time in milliseconds")
created_at: Optional[datetime] = Field(default=None, description="Creation timestamp")
# Existing Models (keeping them for compatibility)
class NarratorGrade(BaseModel):
"""Grade for individual narrator in the chain."""
name: str = Field(description="Name of the narrator")
reliability_grade: str = Field(description="Reliability grade: Thiqah (Trustworthy), Saduq (Truthful), Da'if (Weak), Matruk (Abandoned), or Majhul (Unknown)")
reasoning: str = Field(description="Brief explanation for the narrator's grade")
known_issues: Optional[str] = Field(default=None, description="Any known issues with this narrator")
class HadithAnalysis(BaseModel):
"""Comprehensive hadith analysis with structured output."""
overall_grade: str = Field(description="Overall hadith grade: Sahih, Hasan, Da'if, or Mawdu'")
confidence_level: str = Field(description="Confidence in the grading: High, Medium, or Low")
# Sanad Analysis
sanad_grade: str = Field(description="Grade of the chain of narration")
narrator_grades: List[NarratorGrade] = Field(description="Individual grades for each narrator in the chain")
chain_continuity: str = Field(description="Assessment of chain continuity: Connected, Broken, or Unclear")
# Matn Analysis
matn_grade: str = Field(description="Grade of the hadith text content")
content_consistency: str = Field(description="Consistency with Quran and other authentic hadiths")
language_authenticity: str = Field(description="Authenticity of the prophetic speech style")
# Supporting Information
primary_sources: List[str] = Field(description="Classical hadith collections where this hadith appears")
scholarly_opinions: List[str] = Field(description="Opinions of classical and contemporary scholars")
# Final Assessment
detailed_reasoning: str = Field(description="Comprehensive explanation of the grading decision")
practical_guidance: str = Field(description="Guidance for Muslims regarding acting upon this hadith")
academic_notes: Optional[str] = Field(default=None, description="Additional scholarly observations")
class HadithTextRequest(BaseModel):
"""Request model for hadith text analysis."""
hadith_text: str = Field(description="The complete hadith text in Arabic", min_length=1)
class NarratorExtractionResponse(BaseModel):
"""Response model for narrator extraction."""
narrators: List[str] = Field(description="List of narrator names extracted from the hadith")
sanad_chain: str = Field(description="The complete chain of narration (sanad)")
success: bool = Field(description="Whether the extraction was successful")
message: str = Field(description="Status message or error description")
class ScholarlyOpinion(BaseModel):
"""Model for scholarly opinion on a narrator."""
scholar_name: str = Field(description="Name of the scholar")
opinion: str = Field(description="The scholar's opinion or assessment")
source: Optional[str] = Field(default=None, description="Source of the opinion")
reliability_assessment: Optional[str] = Field(default=None, description="Reliability grade given by this scholar")
class NarratorAnalysisRequest(BaseModel):
"""Request model for narrator analysis."""
narrator_name: str = Field(description="Name of the narrator to analyze", min_length=1)
class NarratorAnalysisResponse(BaseModel):
"""Response model for narrator analysis."""
narrator_name: str = Field(description="Name of the analyzed narrator")
reliability_grade: str = Field(description="Final reliability grade: Thiqah (Trustworthy), Saduq (Truthful), Da'if (Weak), Matruk (Abandoned), or Majhul (Unknown)")
confidence_level: str = Field(description="Confidence in the assessment: High, Medium, Low")
reasoning: str = Field(description="Detailed reasoning for the grade")
scholarly_consensus: str = Field(description="Analysis of what scholars have said about this narrator")
known_issues: Optional[str] = Field(default=None, description="Any known issues or criticisms of this narrator")
biographical_info: str = Field(description="Basic biographical information about the narrator")
recommendation: str = Field(description="Recommendation for using this narrator's narrations")
success: bool = Field(description="Whether the analysis was successful")
message: str = Field(description="Status message or error description")
class IndividualNarratorAnalysis(BaseModel):
"""Individual narrator analysis within a chain."""
narrator_name: str = Field(description="Name of the analyzed narrator")
reliability_grade: str = Field(description="Final reliability grade")
confidence_level: str = Field(description="Confidence in the assessment: High, Medium, Low")
reasoning: str = Field(description="Detailed reasoning for the grade")
scholarly_consensus: str = Field(description="Analysis of scholarly opinions")
known_issues: Optional[str] = Field(default=None, description="Any known issues or criticisms")
biographical_info: str = Field(description="Basic biographical information")
recommendation: str = Field(description="Recommendation for using this narrator's narrations")
success: bool = Field(description="Whether the analysis was successful")
message: str = Field(description="Status message or error description")
class ChainAnalysisMetadata(BaseModel):
"""Metadata for chain analysis."""
total_narrators: int = Field(description="Total number of narrators in the chain")
successful_analyses: int = Field(description="Number of successfully analyzed narrators")
analysis_method: str = Field(description="Method used for analysis")
class NarratorChainAnalysisResponse(BaseModel):
"""Response model for narrator chain analysis."""
chain: List[str] = Field(description="List of narrator names in the chain")
individual_analyses: Dict[str, IndividualNarratorAnalysis] = Field(description="Individual analysis for each narrator")
chain_synthesis: Dict[str, Any] = Field(description="Synthesized analysis of the complete chain")
metadata: ChainAnalysisMetadata = Field(description="Analysis metadata")
class ExtractionResult(BaseModel):
"""Extraction result sub-model."""
narrators: List[str] = Field(description="List of extracted narrator names")
sanad_chain: str = Field(description="The complete chain of narration")
success: bool = Field(description="Whether extraction was successful")
message: str = Field(description="Status message or error description")
class ChainAnalysisResult(BaseModel):
"""Chain analysis result sub-model."""
individual_analyses: Dict[str, IndividualNarratorAnalysis] = Field(description="Individual narrator analyses")
synthesis: Dict[str, Any] = Field(description="Synthesized chain analysis")
class ExtractAndAnalyzeMetadata(BaseModel):
"""Metadata for extract and analyze workflow."""
hadith_text_length: int = Field(description="Length of the input hadith text")
extracted_narrators_count: int = Field(description="Number of extracted narrators")
successful_analyses: int = Field(description="Number of successfully analyzed narrators")
analysis_method: str = Field(description="Method used for analysis")
class ExtractAndAnalyzeResponse(BaseModel):
"""Response model for extract and analyze workflow."""
extraction: ExtractionResult = Field(description="Results of narrator extraction")
chain_analysis: Optional[ChainAnalysisResult] = Field(default=None, description="Results of chain analysis")
metadata: ExtractAndAnalyzeMetadata = Field(description="Analysis metadata")
error: Optional[str] = Field(default=None, description="Error message if analysis failed")