Coverage for src/ai_lls_lib/core/models.py: 100%
50 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-08-24 12:44 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-08-24 12:44 +0000
1"""
2Data models for phone verification
3"""
5from datetime import datetime
6from enum import StrEnum
7from typing import NamedTuple
9from pydantic import BaseModel, Field
12class LineType(StrEnum):
13 """Phone line type enumeration"""
15 MOBILE = "mobile"
16 LANDLINE = "landline"
17 VOIP = "voip"
18 UNKNOWN = "unknown"
21class VerificationSource(StrEnum):
22 """Source of verification data"""
24 API = "api"
25 CACHE = "cache"
26 BULK_IMPORT = "bulk_import"
29class JobStatus(StrEnum):
30 """Bulk job status enumeration"""
32 PENDING = "pending"
33 PROCESSING = "processing"
34 COMPLETED = "completed"
35 FAILED = "failed"
38class VerificationResult(NamedTuple):
39 """Raw verification result returned by a provider"""
41 line_type: LineType
42 dnc: bool
43 known_litigator: bool = False
46class PhoneVerification(BaseModel):
47 """Result of phone number verification"""
49 phone_number: str = Field(..., description="E.164 formatted phone number")
50 line_type: LineType = Field(..., description="Type of phone line")
51 dnc: bool = Field(..., description="Whether number is on DNC list")
52 known_litigator: bool = Field(False, description="Whether number belongs to a known litigator")
53 cached: bool = Field(..., description="Whether result came from cache")
54 verified_at: datetime = Field(..., description="When verification occurred")
55 source: VerificationSource = Field(..., description="Source of verification data")
57 class Config:
58 json_encoders = {datetime: lambda v: v.isoformat()}
61class BulkJob(BaseModel):
62 """Bulk processing job metadata"""
64 job_id: str = Field(..., description="Unique job identifier")
65 status: JobStatus = Field(..., description="Current job status")
68class BulkJobStatus(BulkJob):
69 """Extended bulk job status with progress info"""
71 total_rows: int | None = Field(None, description="Total rows to process")
72 processed_rows: int | None = Field(None, description="Rows processed so far")
73 result_url: str | None = Field(None, description="S3 URL of results")
74 created_at: datetime = Field(..., description="Job creation time")
75 completed_at: datetime | None = Field(None, description="Job completion time")
76 error: str | None = Field(None, description="Error message if failed")
79class CacheEntry(BaseModel):
80 """DynamoDB cache entry"""
82 phone_number: str
83 line_type: str # Stored as string in DynamoDB
84 dnc: bool
85 known_litigator: bool = False
86 verified_at: str # ISO format string
87 source: str # Stored as string in DynamoDB
88 ttl: int # Unix timestamp for DynamoDB TTL