"""Bill model - legislation introduced in Congress.""" from __future__ import annotations from datetime import date, datetime from enum import StrEnum from typing import TYPE_CHECKING from sqlalchemy import DateTime, Enum, ForeignKey, Index, UniqueConstraint from sqlalchemy.orm import Mapped, mapped_column, relationship from pipelines.orm.data_science_dev.base import DataScienceDevTableBase if TYPE_CHECKING: from pipelines.orm.data_science_dev.congress.vote import Vote class BillTopicPosition(StrEnum): """Whether a yes vote on a bill is for or against a topic.""" FOR = "for" AGAINST = "against" class Bill(DataScienceDevTableBase): """Legislation with congress number, type, titles, status, and sponsor.""" __tablename__ = "bill" __table_args__ = ( UniqueConstraint( "congress", "bill_type", "number", name="uq_bill_congress_type_number" ), Index("ix_bill_congress", "congress"), ) congress: Mapped[int] bill_type: Mapped[str] number: Mapped[int] title: Mapped[str | None] title_short: Mapped[str | None] official_title: Mapped[str | None] status: Mapped[str | None] status_at: Mapped[date | None] sponsor_bioguide_id: Mapped[str | None] subjects_top_term: Mapped[str | None] score_processed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) votes: Mapped[list[Vote]] = relationship( "Vote", back_populates="bill", ) bill_texts: Mapped[list[BillText]] = relationship( "BillText", back_populates="bill", cascade="all, delete-orphan", ) topics: Mapped[list[BillTopic]] = relationship( "BillTopic", back_populates="bill", cascade="all, delete-orphan", ) class BillText(DataScienceDevTableBase): """Stores different text versions of a bill (introduced, enrolled, etc.).""" __tablename__ = "bill_text" __table_args__ = ( UniqueConstraint( "bill_id", "version_code", name="uq_bill_text_bill_id_version_code" ), ) bill_id: Mapped[int] = mapped_column(ForeignKey("main.bill.id", ondelete="CASCADE")) version_code: Mapped[str] version_name: Mapped[str | None] text_content: Mapped[str | None] summary: Mapped[str | None] summarization_model: Mapped[str | None] summarization_user_prompt_version: Mapped[str | None] summarization_system_prompt_version: Mapped[str | None] date: Mapped[date | None] bill: Mapped[Bill] = relationship("Bill", back_populates="bill_texts") # suport multipu summary prer bill class BillTopic(DataScienceDevTableBase): """One bill stance on one topic used to score roll-call votes.""" __tablename__ = "bill_topic" __table_args__ = ( UniqueConstraint( "bill_id", "topic", "support_position", name="uq_bill_topic_bill_id_topic_support_position", ), Index("ix_bill_topic_topic", "topic"), ) bill_id: Mapped[int] = mapped_column(ForeignKey("main.bill.id", ondelete="CASCADE")) topic: Mapped[str] support_position: Mapped[BillTopicPosition] = mapped_column( Enum( BillTopicPosition, values_callable=lambda enum_cls: [member.value for member in enum_cls], native_enum=False, name="bill_topic_position", ) ) bill: Mapped[Bill] = relationship("Bill", back_populates="topics")