"""
Mock data for Absher Voice Assistant MCP Server
All data keyed by national_id (Saudi National ID)
"""
from typing import Dict, List, Any, Optional
from dataclasses import dataclass
# ============================================================================
# Data Models
# ============================================================================
@dataclass
class SecurityQuestion:
"""Security question and answer for user verification"""
question_id: str
question: str
answer: str
@dataclass
class PersonalData:
"""User's personal information"""
first_name: str
last_name: str
date_of_birth: str
phone: str
email: str
address: str
passport_number: str
passport_issue_date: str
passport_expiry: str
@dataclass
class User:
"""Complete user profile"""
national_id: str
security_questions: List[SecurityQuestion]
personal_data: PersonalData
# ============================================================================
# Mock Users Database (keyed by national_id)
# ============================================================================
MOCK_USERS: Dict[str, User] = {
"1234567890": User(
national_id="1234567890",
security_questions=[
SecurityQuestion(
question_id="q1",
question="ما هو اسم مدينة ميلادك؟",
answer="الرياض"
),
SecurityQuestion(
question_id="q2",
question="ما هو اسم أول مدرسة؟",
answer="النور"
),
SecurityQuestion(
question_id="q3",
question="ما هو اسم والدتك؟",
answer="فاطمة"
)
],
personal_data=PersonalData(
first_name="أحمد",
last_name="محمد",
date_of_birth="1990-01-15",
phone="+966501234567",
email="ahmed.mohamed@example.com",
address="شارع الملك فهد، الرياض",
passport_number="A12345678",
passport_issue_date="2020-01-15",
passport_expiry="2025-01-15"
)
),
"0987654321": User(
national_id="0987654321",
security_questions=[
SecurityQuestion(
question_id="q1",
question="ما هو اسم مدينة ميلادك؟",
answer="جدة"
),
SecurityQuestion(
question_id="q2",
question="ما هو اسم أول مدرسة؟",
answer="الأمل"
),
SecurityQuestion(
question_id="q3",
question="ما هو اسم والدك؟",
answer="علي"
)
],
personal_data=PersonalData(
first_name="فاطمة",
last_name="أحمد",
date_of_birth="1985-06-15",
phone="+966509876543",
email="fatima.ahmed@example.com",
address="شارع المدينة، جدة",
passport_number="B98765432",
passport_issue_date="2019-03-20",
passport_expiry="2026-03-20"
)
),
"1122334455": User(
national_id="1122334455",
security_questions=[
SecurityQuestion(
question_id="q1",
question="ما هو اسم مدينة ميلادك؟",
answer="الدمام"
),
SecurityQuestion(
question_id="q2",
question="ما هو اسم أول مدرسة؟",
answer="الفيصل"
),
SecurityQuestion(
question_id="q3",
question="ما هو اسم والدتك؟",
answer="مريم"
)
],
personal_data=PersonalData(
first_name="خالد",
last_name="عبدالله",
date_of_birth="1992-11-20",
phone="+966505556666",
email="khalid.abdullah@example.com",
address="شارع الخليج، الدمام",
passport_number="C11223344",
passport_issue_date="2021-05-10",
passport_expiry="2028-05-10"
)
)
}
# ============================================================================
# Mock Traffic Fines Database (keyed by national_id)
# ============================================================================
MOCK_FINES: Dict[str, List[Dict[str, Any]]] = {
"1234567890": [
{
"fine_id": "F001",
"date": "2024-11-15",
"violation": "تجاوز السرعة",
"location": "طريق الملك فهد، الرياض",
"amount": 500,
"status": "غير مدفوعة"
},
{
"fine_id": "F002",
"date": "2024-10-20",
"violation": "إيقاف غير قانوني",
"location": "شارع التحلية، الرياض",
"amount": 150,
"status": "غير مدفوعة"
}
],
"0987654321": [
{
"fine_id": "F003",
"date": "2024-11-01",
"violation": "استخدام الهاتف أثناء القيادة",
"location": "طريق الدمام السريع",
"amount": 900,
"status": "مدفوعة"
}
],
"1122334455": [] # No fines
}
# ============================================================================
# Mock Appointment Slots Database
# ============================================================================
AVAILABLE_APPOINTMENT_SLOTS = {
"passports": {
"الرياض": ["2024-12-15 09:00", "2024-12-15 11:00", "2024-12-16 10:00"],
"جدة": ["2024-12-15 10:00", "2024-12-17 09:00"],
"الدمام": ["2024-12-16 09:00", "2024-12-17 11:00"]
},
"civil_affairs": {
"الرياض": ["2024-12-14 09:00", "2024-12-15 14:00"],
"جدة": ["2024-12-16 10:00", "2024-12-17 09:00"],
"الدمام": ["2024-12-15 11:00", "2024-12-18 10:00"]
},
"traffic": {
"الرياض": ["2024-12-15 08:00", "2024-12-16 13:00"],
"جدة": ["2024-12-17 09:00", "2024-12-18 10:00"],
"الدمام": ["2024-12-16 14:00", "2024-12-19 09:00"]
}
}
# ============================================================================
# Service Requirements Configuration
# ============================================================================
SERVICE_REQUIREMENTS = {
"passport_renewal": {
"service_name_ar": "تجديد جواز السفر",
"required_fields": [
{
"field_name": "national_id",
"field_name_ar": "رقم الهوية الوطنية",
"source": "user_data",
"description": "يتم جلبه من بيانات المستخدم"
},
{
"field_name": "first_name",
"field_name_ar": "الاسم الأول",
"source": "user_data",
"description": "يتم جلبه من بيانات المستخدم"
},
{
"field_name": "last_name",
"field_name_ar": "اسم العائلة",
"source": "user_data",
"description": "يتم جلبه من بيانات المستخدم"
},
{
"field_name": "phone",
"field_name_ar": "رقم الهاتف",
"source": "user_data",
"description": "يتم جلبه من بيانات المستخدم"
},
{
"field_name": "passport_number",
"field_name_ar": "رقم الجواز الحالي",
"source": "user_data",
"description": "يتم جلبه من بيانات المستخدم"
},
{
"field_name": "renewal_reason",
"field_name_ar": "سبب التجديد",
"source": "user_input",
"description": "يجب سؤال المستخدم",
"options": ["انتهاء الصلاحية", "تلف", "ضياع", "امتلاء الصفحات"]
},
{
"field_name": "delivery_method",
"field_name_ar": "طريقة الاستلام",
"source": "user_input",
"description": "يجب سؤال المستخدم",
"options": ["استلام من المكتب", "توصيل بالبريد"]
}
]
},
"traffic_fines": {
"service_name_ar": "الاستعلام عن المخالفات المرورية",
"required_fields": [
{
"field_name": "national_id",
"field_name_ar": "رقم الهوية الوطنية",
"source": "user_data",
"description": "يتم جلبه من بيانات المستخدم"
}
]
},
"book_appointment": {
"service_name_ar": "حجز موعد حكومي",
"required_fields": [
{
"field_name": "national_id",
"field_name_ar": "رقم الهوية الوطنية",
"source": "user_data",
"description": "يتم جلبه من بيانات المستخدم"
},
{
"field_name": "service_type",
"field_name_ar": "نوع الخدمة",
"source": "user_input",
"description": "يجب سؤال المستخدم",
"options": ["الجوازات", "الأحوال المدنية", "المرور"]
},
{
"field_name": "location",
"field_name_ar": "الموقع",
"source": "user_input",
"description": "يجب سؤال المستخدم",
"options": ["الرياض", "جدة", "الدمام"]
},
{
"field_name": "preferred_date",
"field_name_ar": "التاريخ المفضل",
"source": "user_input",
"description": "يجب سؤال المستخدم (صيغة: YYYY-MM-DD)"
}
]
}
}
# ============================================================================
# Helper Functions
# ============================================================================
def get_user_by_national_id(national_id: str) -> Optional[User]:
"""Get user by national ID"""
return MOCK_USERS.get(national_id)
def verify_national_id(national_id: str) -> bool:
"""Check if national ID exists in system"""
return national_id in MOCK_USERS
def get_security_questions(national_id: str) -> Optional[List[SecurityQuestion]]:
"""Get security questions for a user"""
user = get_user_by_national_id(national_id)
return user.security_questions if user else None
def verify_security_answers(national_id: str, answers: List[Dict[str, str]]) -> bool:
"""
Verify user's security answers
Args:
national_id: User's national ID
answers: List of {question_id: str, answer: str}
Returns:
True if all answers are correct
"""
user = get_user_by_national_id(national_id)
if not user:
return False
# Create lookup dict of correct answers
correct_answers = {
q.question_id: q.answer.strip().lower()
for q in user.security_questions
}
# Verify each answer
for answer_obj in answers:
question_id = answer_obj.get("question_id")
user_answer = answer_obj.get("answer", "").strip().lower()
if question_id not in correct_answers:
return False
if correct_answers[question_id] != user_answer:
return False
return True
def get_traffic_fines(national_id: str) -> List[Dict[str, Any]]:
"""Get traffic fines for a user"""
return MOCK_FINES.get(national_id, [])
def get_unpaid_fines(national_id: str) -> List[Dict[str, Any]]:
"""Get only unpaid fines"""
fines = get_traffic_fines(national_id)
return [fine for fine in fines if fine["status"] == "غير مدفوعة"]
def get_total_unpaid_amount(national_id: str) -> float:
"""Calculate total unpaid fines amount"""
unpaid = get_unpaid_fines(national_id)
return sum(fine["amount"] for fine in unpaid)
def get_service_requirements(service_name: str) -> Optional[Dict[str, Any]]:
"""Get required fields for a service"""
return SERVICE_REQUIREMENTS.get(service_name)