File size: 2,522 Bytes
41fae03
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""ViewerProjection — the rendering truth.

This is the lightweight structure consumed by the front-end viewer.
It is derived from the CanonicalDocument by the projection builder.
It never parses XML.  It never calls providers.
"""

from __future__ import annotations

from typing import Any

from pydantic import BaseModel, ConfigDict, Field

from src.app.domain.models.readiness import ExportEligibility
from src.app.domain.models.status import (
    EvidenceType,
    GeometryStatus,
    OverlayLevel,
    ReadinessLevel,
)


class OverlayItem(BaseModel):
    """A single visual overlay on the page image."""

    model_config = ConfigDict(frozen=True)

    id: str = Field(min_length=1)
    level: OverlayLevel
    bbox: tuple[float, float, float, float] = Field(
        description="(x, y, width, height)"
    )
    polygon: list[tuple[float, float]] | None = None
    label: str | None = None
    text: str | None = None
    confidence: float | None = Field(default=None, ge=0, le=1)
    provenance_type: EvidenceType | None = None
    geometry_status: GeometryStatus | None = None
    click_payload: dict[str, Any] | None = None


class InspectionData(BaseModel):
    """Detailed data for the inspection panel — shown on click."""

    model_config = ConfigDict(frozen=True)

    id: str = Field(min_length=1)
    level: OverlayLevel
    text: str | None = None
    bbox: tuple[float, float, float, float]
    polygon: list[tuple[float, float]] | None = None
    confidence: float | None = None
    lang: str | None = None
    provenance_type: EvidenceType | None = None
    provenance_provider: str | None = None
    geometry_status: GeometryStatus | None = None
    readiness: ReadinessLevel | None = None
    role: str | None = None
    metadata: dict[str, Any] | None = None


class ViewerProjection(BaseModel):
    """Complete projection for the viewer — one per page."""

    model_config = ConfigDict(frozen=True)

    image_ref: str
    image_width: int = Field(gt=0)
    image_height: int = Field(gt=0)

    block_overlays: list[OverlayItem] = Field(default_factory=list)
    line_overlays: list[OverlayItem] = Field(default_factory=list)
    word_overlays: list[OverlayItem] = Field(default_factory=list)
    non_text_overlays: list[OverlayItem] = Field(default_factory=list)

    inspection_index: dict[str, InspectionData] = Field(default_factory=dict)

    validation_flags: list[str] = Field(default_factory=list)
    export_status: ExportEligibility = Field(default_factory=ExportEligibility)