feat: roll-call votes + granular alert filter fix (v0.9.5)

Roll-call votes:
- Migration 0017: bill_votes + member_vote_positions tables
- Fetch vote XML directly from House Clerk / Senate LIS URLs
  embedded in bill actions recordedVotes objects
- GET /api/bills/{id}/votes triggers background fetch on first view
- VotePanel on bill detail: yea/nay bar, result badge, followed
  member positions with Sen./Rep. title, party badge, and state

Alert filter fix:
- _should_dispatch returns True when alert_filters is None so users
  who haven't saved filters still receive all notifications

Authored-By: Jack Levy
This commit is contained in:
Jack Levy
2026-03-02 20:33:32 -05:00
parent 676bf1b78d
commit 91473e6464
13 changed files with 673 additions and 3 deletions

View File

@@ -337,3 +337,34 @@ class CollectionDetailSchema(CollectionSchema):
class BriefShareResponse(BaseModel):
brief: BriefSchema
bill: BillSchema
# ── Votes ──────────────────────────────────────────────────────────────────────
class MemberVotePositionSchema(BaseModel):
bioguide_id: Optional[str] = None
member_name: Optional[str] = None
party: Optional[str] = None
state: Optional[str] = None
position: str
model_config = {"from_attributes": True}
class BillVoteSchema(BaseModel):
id: int
congress: int
chamber: str
session: int
roll_number: int
question: Optional[str] = None
description: Optional[str] = None
vote_date: Optional[date] = None
yeas: Optional[int] = None
nays: Optional[int] = None
not_voting: Optional[int] = None
result: Optional[str] = None
source_url: Optional[str] = None
positions: list[MemberVotePositionSchema] = []
model_config = {"from_attributes": True}