"""Data models for Bible verses and translation context.""" from __future__ import annotations from datetime import datetime from typing import TYPE_CHECKING from pydantic import BaseModel, Field # Import enhanced glossary for backward compatibility from src.models.glossary import EnhancedGlossaryTerm, GlossaryTerm, TheologicalDomain if TYPE_CHECKING: pass # Re-export for backward compatibility __all__ = [ "VerseReference", "Verse", "GlossaryTerm", "EnhancedGlossaryTerm", "TheologicalDomain", "BookMetadata", "ChapterSummary", "TranslationContext", "TranslationOutput", ] class VerseReference(BaseModel): """Reference to a specific Bible verse.""" book: str = Field(..., description="Book name (e.g., 'john', 'genesis')") chapter: int = Field(..., ge=1, description="Chapter number") verse: int = Field(..., ge=1, description="Verse number") def __str__(self) -> str: return f"{self.book}:{self.chapter}:{self.verse}" @classmethod def from_string(cls, ref: str) -> VerseReference: """Parse a verse reference string like 'john:1:1'.""" parts = ref.lower().split(":") if len(parts) != 3: msg = f"Invalid verse reference: {ref}. Expected format: 'book:chapter:verse'" raise ValueError(msg) return cls(book=parts[0], chapter=int(parts[1]), verse=int(parts[2])) class Verse(BaseModel): """A Bible verse with source texts from multiple translations.""" reference: VerseReference greek_text: str | None = Field(None, description="Greek source text (NT only)") greek_translit: str | None = Field(None, description="Greek transliteration") hebrew_text: str | None = Field(None, description="Hebrew source text (OT only)") hebrew_translit: str | None = Field(None, description="Hebrew transliteration") japanese_meiji: str | None = Field(None, description="Meiji translation (1887)") japanese_taisho: str | None = Field(None, description="Taisho translation (1917)") japanese_kougo: str | None = Field(None, description="Kougo translation (1955)") greek_words: list[dict] | None = Field(None, description="MorphGNT word entries") hebrew_words: list[dict] | None = Field(None, description="OSHB word entries") english_kjv: str | None = Field(None, description="King James Version") english_asv: str | None = Field(None, description="American Standard Version") def has_source_text(self) -> bool: """Check if the verse has at least one source text.""" return bool(self.greek_text or self.hebrew_text) class BookMetadata(BaseModel): """Metadata about a Bible book.""" book: str = Field(..., description="Book name (e.g., 'john')") name_japanese: str = Field(..., description="Japanese book name") name_english: str = Field(..., description="English book name") testament: str = Field(..., description="'OT' or 'NT'") author: str = Field(..., description="Traditional author attribution") themes: list[str] = Field(default_factory=list, description="Key themes") description: str = Field(..., description="Brief description of the book") chapter_count: int = Field(..., ge=1, description="Total number of chapters") verse_count: int = Field(..., ge=1, description="Total number of verses") class ChapterSummary(BaseModel): """Summary of a Bible chapter for context.""" book: str chapter: int summary: str = Field(..., description="Brief chapter summary") key_events: list[str] = Field(default_factory=list) key_characters: list[str] = Field(default_factory=list) key_themes: list[str] = Field(default_factory=list) class TranslationContext(BaseModel): """Full context for translating a verse.""" target_verse: Verse preceding_verses: list[Verse] = Field(default_factory=list) following_verses: list[Verse] = Field(default_factory=list) chapter_summary: ChapterSummary | None = None book_metadata: BookMetadata | None = None glossary_terms: list[GlossaryTerm] = Field(default_factory=list) class TranslationOutput(BaseModel): """Output from a translation operation.""" reference: VerseReference text: str = Field(..., description="Plain Japanese text (furigana stripped)") text_with_furigana: str = Field( default="", description="Text with inline furigana notation" ) furigana_annotations: list[dict] = Field( default_factory=list, description="Serialized FuriganaAnnotation list" ) model: str = Field(..., description="Model used for translation") timestamp: datetime = Field(default_factory=datetime.utcnow) prompt_version: str = Field(default="v1.0") sources_used: list[str] = Field( default_factory=list, description="Source texts used" ) glossary_terms_applied: list[str] = Field( default_factory=list, description="Glossary terms applied" )