claimflow-api / app /models /records.py
Minifigures's picture
feat: ClaimFlow API demo backend
ceea9e1 verified
Raw
History Blame Contribute Delete
3.83 kB
from datetime import date, datetime
from sqlalchemy import Date, DateTime, Float, ForeignKey, Integer, String, Text
from sqlalchemy.orm import Mapped, mapped_column
from app.db import Base
from app.models.entities import utcnow
from app.models.enums import ClaimAction, ClaimState, NotificationStatus, db_enum
class Decision(Base):
"""One row per human/system workflow action — drives the claimant timeline UI."""
__tablename__ = "decisions"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
claim_id: Mapped[int] = mapped_column(ForeignKey("claims.id"), index=True)
actor_id: Mapped[int | None] = mapped_column(ForeignKey("users.id"), default=None)
actor_role: Mapped[str] = mapped_column(String(32)) # Role value or "system"
action: Mapped[ClaimAction] = mapped_column(db_enum(ClaimAction, 32))
from_state: Mapped[ClaimState | None] = mapped_column(
db_enum(ClaimState, 32), default=None
)
to_state: Mapped[ClaimState] = mapped_column(db_enum(ClaimState, 32))
note: Mapped[str | None] = mapped_column(Text, default=None)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utcnow)
class Notification(Base):
__tablename__ = "notifications"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
claim_id: Mapped[int] = mapped_column(ForeignKey("claims.id"), index=True)
recipient_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
channel: Mapped[str] = mapped_column(String(16), default="email")
subject: Mapped[str] = mapped_column(String(255))
body_text: Mapped[str] = mapped_column(Text)
body_html: Mapped[str | None] = mapped_column(Text, default=None)
provider: Mapped[str] = mapped_column(String(32), default="console")
status: Mapped[NotificationStatus] = mapped_column(
db_enum(NotificationStatus, 16), default=NotificationStatus.LOGGED
)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utcnow)
sent_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), default=None)
class ClaimHistory(Base):
"""PII-free historical claims per member (seeded; queried by stage 3)."""
__tablename__ = "claim_history"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
member_id: Mapped[str] = mapped_column(String(32), index=True)
claim_type: Mapped[str] = mapped_column(String(64))
procedure_code: Mapped[str] = mapped_column(String(16))
diagnosis_code: Mapped[str] = mapped_column(String(16))
modality: Mapped[str | None] = mapped_column(String(16), default=None)
billed_amount: Mapped[float] = mapped_column(Float)
outcome: Mapped[str] = mapped_column(String(16)) # approved | rejected
date_of_service: Mapped[date | None] = mapped_column(Date, default=None)
decided_at: Mapped[date | None] = mapped_column(Date, default=None)
notes: Mapped[str | None] = mapped_column(Text, default=None)
class AuditEvent(Base):
"""Hash-chained, actor-aware audit log (pattern vendored from the ClaimGuard POC,
extended: actor fields are part of the record hash)."""
__tablename__ = "audit_events"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
event_type: Mapped[str] = mapped_column(String(48), index=True)
claim_id: Mapped[int | None] = mapped_column(Integer, index=True, default=None)
actor_user_id: Mapped[int | None] = mapped_column(Integer, default=None)
actor_role: Mapped[str | None] = mapped_column(String(32), default=None)
payload_json: Mapped[str] = mapped_column(Text, default="{}")
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utcnow)
prev_hash: Mapped[str] = mapped_column(String(64))
record_hash: Mapped[str] = mapped_column(String(64), unique=True)