Coverage for polar/models/organization_review.py: 92%
37 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-12-05 16:17 +0000
« prev ^ index » next coverage.py v7.10.6, created at 2025-12-05 16:17 +0000
1from datetime import datetime 1ab
2from enum import StrEnum 1ab
3from typing import TYPE_CHECKING, Any 1ab
4from uuid import UUID 1ab
6from sqlalchemy import TIMESTAMP, ForeignKey, String, Text, Uuid 1ab
7from sqlalchemy.dialects.postgresql import JSONB 1ab
8from sqlalchemy.orm import Mapped, declared_attr, mapped_column, relationship 1ab
10from polar.kit.db.models import RecordModel 1ab
12if TYPE_CHECKING: 12 ↛ 13line 12 didn't jump to line 13 because the condition on line 12 was never true1ab
13 from polar.models.organization import Organization
16class OrganizationReview(RecordModel): 1ab
17 """Model to store AI validation responses for organizations."""
19 class Verdict(StrEnum): 1ab
20 PASS = "PASS" 1ab
21 FAIL = "FAIL" 1ab
22 UNCERTAIN = "UNCERTAIN" 1ab
24 class AppealDecision(StrEnum): 1ab
25 APPROVED = "approved" 1ab
26 REJECTED = "rejected" 1ab
28 __tablename__ = "organization_reviews" 1ab
30 organization_id: Mapped[UUID] = mapped_column( 1ab
31 Uuid,
32 ForeignKey("organizations.id", ondelete="cascade"),
33 nullable=False,
34 unique=True,
35 index=True,
36 )
38 verdict: Mapped[Verdict] = mapped_column(String, nullable=False) 1ab
39 risk_score: Mapped[float] = mapped_column(nullable=False) 1ab
40 violated_sections: Mapped[list[str]] = mapped_column( 1ab
41 JSONB, nullable=False, default=list
42 )
43 reason: Mapped[str] = mapped_column(Text, nullable=False) 1ab
45 timed_out: Mapped[bool] = mapped_column(nullable=False, default=False) 1ab
46 model_used: Mapped[str] = mapped_column(String, nullable=False) 1ab
48 organization_details_snapshot: Mapped[dict[str, Any]] = mapped_column( 1ab
49 JSONB, nullable=False, default=dict
50 )
52 validated_at: Mapped[datetime] = mapped_column( 1ab
53 TIMESTAMP(timezone=True), nullable=False, default=lambda: datetime.now()
54 )
56 # Appeal fields
57 appeal_submitted_at: Mapped[datetime | None] = mapped_column( 1ab
58 TIMESTAMP(timezone=True), nullable=True, default=None
59 )
60 appeal_reason: Mapped[str | None] = mapped_column(Text, nullable=True, default=None) 1ab
61 appeal_reviewed_at: Mapped[datetime | None] = mapped_column( 1ab
62 TIMESTAMP(timezone=True), nullable=True, default=None
63 )
64 appeal_decision: Mapped[AppealDecision | None] = mapped_column( 1ab
65 String, nullable=True, default=None
66 )
68 @declared_attr 1ab
69 def organization(cls) -> Mapped["Organization"]: 1ab
70 return relationship("Organization", lazy="raise", back_populates="review") 1ab
72 def __repr__(self) -> str: 1ab
73 return f"OrganizationReview(id={self.id}, organization_id={self.organization_id}, verdict={self.verdict})"