Commit Graph

72 Commits

Author SHA1 Message Date
Jack Levy
91790fd798 Update ARCHITECTURE.md and roadmap to reflect v0.4.0
Architecture doc: add notifications table, v0.4.0 feature history, updated
beat schedule (fetch-actions-active-bills, dispatch-notifications), expanded
admin API table (17 endpoints), new /api/notifications section, BriefPanel
and ActionTimeline component docs, chamberBadgeColor utility, migrations
0010-0011, live LLM model picker endpoint, queue routing corrections.

Roadmap: mark Phase 1 notifications complete, check off LLM model picker,
admin health panel, chamber badges, action history fallback, backfill all
actions, brief regeneration UI; remove completed Phase 1 section.

Authored-By: Jack Levy
2026-03-01 11:45:21 -05:00
Jack Levy
f3a8c1218a Add chamber color badges, action history fallback, and task status polling
- Add chamberBadgeColor util: amber/gold for Senate, slate/silver for House
- Apply chamber badge to BillCard and bill detail header
- ActionTimeline: show latest_action_date/text as fallback when full history
  not yet fetched, with note that full history loads in background
- Manual Controls: poll task status every 5s after triggering, show spinning
  indicator while running, task ID prefix, and completion/failure state

Authored-By: Jack Levy
2026-03-01 11:29:11 -05:00
Jack Levy
5eebc2f196 Add bill action pipeline, admin health panel, and LLM provider fixes
- Fetch bill actions from Congress.gov and populate the action timeline
- Add nightly batch task and beat schedule for active bill actions
- Add admin reprocess endpoint for per-bill debugging
- Add BriefPanel with "What Changed" view and version history
- Add External API Health section with per-source latency testing
- Redesign Manual Controls as health panel with status dots and descriptions
- Add Resume Analysis task for stalled LLM jobs
- Add Backfill Dates & Links task for bills with null metadata
- Fix LLM provider/model DB overrides being ignored (env vars used instead)
- Fix Gemini 404: gemini-1.5-pro deprecated → gemini-2.0-flash
- Fix Anthropic models list: use REST API directly (SDK too old for .models)
- Replace test-LLM full analysis with lightweight ping (max_tokens=20)
- Add has_document field to BillDetail; show "No bill text published" state
- Fix "Introduced: —" showing for bills with null introduced_date
- Add bills_missing_sponsor and bills_missing_metadata to admin stats
- Add GovInfo health check using /collections endpoint (fixes 500 from /packages)

Authored-By: Jack Levy
2026-03-01 11:06:35 -05:00
Jack Levy
defc2c116d fix(admin): LLM provider/model switching now reads DB overrides correctly
- get_llm_provider() now accepts provider + model args so DB overrides
  propagate through to all provider constructors (was always reading
  env vars, ignoring the admin UI selection)
- /test-llm replaced with lightweight ping (max_tokens=20) instead of
  running a full bill analysis; shows model name + reply, no truncation
- /api/settings/llm-models endpoint fetches available models live from
  each provider's API (OpenAI, Anthropic REST, Gemini, Ollama)
- Admin UI model picker dynamically populated from provider API;
  falls back to manual text input on error; Custom model name option kept
- Default Gemini model updated: gemini-1.5-pro → gemini-2.0-flash

Co-Authored-By: Jack Levy
2026-03-01 04:03:51 -05:00
Jack Levy
12a3eac48f fix(news): auto-retry news fetch when backend Celery task is in-flight
When a bill page opens with no stored articles, the backend queues a
fetch_news_for_bill Celery task and returns immediately. Added a retry
loop (up to 3x, 6 s apart) driven off newsArticles state so articles
populate without a manual refresh. Fixed broken useEffect dependency
([billId] → [newsArticles]) that caused the timer to never fire.
News is now fetched via a separate useBillNews query (staleTime: 0)
independent of the cached bill detail response.

Co-Authored-By: Jack Levy
2026-03-01 03:17:17 -05:00
Jack Levy
d5711312b8 feat: bill action pipeline, What Changed UI, citation backfill, admin panel
Backend:
- Add fetch_bill_actions task with pagination and idempotent upsert
- Add fetch_actions_for_active_bills nightly batch (4 AM UTC beat schedule)
- Wire fetch_bill_actions into new-bill creation and _update_bill_if_changed
- Add backfill_brief_citations task: detects pre-citation briefs by JSONB
  type check, deletes them, re-queues LLM processing against stored text
  (LLM calls only — zero Congress.gov or GovInfo calls)
- Add admin endpoints: POST /bills/{id}/reprocess, /backfill-citations,
  /trigger-fetch-actions; add uncited_briefs count to /stats

Frontend:
- New BriefPanel component: wraps AIBriefCard, adds amber "What Changed"
  badge for amendment briefs and collapsible version history with
  inline brief expansion
- Swap AIBriefCard for BriefPanel on bill detail page
- Admin panel: Backfill Citations + Fetch Bill Actions buttons; amber
  warning in stats when uncited briefs remain
- Add feature roadmap document with phased plan through Phase 5

Co-Authored-By: Jack Levy
2026-03-01 03:03:29 -05:00
Jack Levy
b57833d4b7 fix(news): robust gnews URL extraction + smarter lazy trigger
- Replace fragile entry.get("link") with _gnews_entry_url() helper that
  checks entry.link attribute then falls back to entry.links[].href,
  fixing cases where feedparser puts the URL in a non-standard location
- Lazy news re-fetch on bill detail now only triggers when the stored
  trend score confirms gnews_count > 0, preventing endless re-queuing
  for bills with genuinely no news coverage

Co-Authored-By: Jack Levy
2026-03-01 00:49:02 -05:00
Jack Levy
50f93468db fix(news): per-bill URL dedup + lazy re-fetch on bill detail load
- Drop global unique constraint on news_articles.url; replace with
  (bill_id, url) so the same article can appear for multiple bills
- news_fetcher dedup now scoped to bill_id instead of global URL
- Bill detail endpoint triggers a background news fetch when no
  articles are stored, so gnews articles surface on next load

Migration 0009.

Co-Authored-By: Jack Levy
2026-03-01 00:43:10 -05:00
Jack Levy
a66b5b4bcb feat(interest): add public interest tracking for members of Congress
Adds Google Trends, NewsAPI, and Google News RSS scoring for members,
mirroring the existing bill interest pipeline. Member profiles now show
a Public Interest chart (with signal breakdown) and a Related News panel.

Key changes:
- New member_trend_scores + member_news_articles tables (migration 0008)
- fetch_gnews_articles() added to news_service for unlimited RSS article storage
- Bill news fetcher now combines NewsAPI + Google News RSS (more coverage)
- New member_interest Celery worker with scheduled news + trend tasks
- GET /members/{id}/trend and /news API endpoints
- TrendChart redesigned with signal breakdown badges and bar+line combo chart
- NewsPanel accepts generic article shape (bills and members)

Co-Authored-By: Jack Levy
2026-03-01 00:36:30 -05:00
Jack Levy
e21eb21acf feat(members): add full member bio, contact info, and service history
Lazy-enriches member profiles on first view via Congress.gov detail API.
Adds office address, phone, official website, congress.gov link, birth
year, terms history, leadership roles, and sponsored/cosponsored counts.
Includes DB migration 0007 for new member columns.

Co-Authored-By: Jack Levy
2026-03-01 00:14:16 -05:00
Jack Levy
37339d6950 feat(ui): add mobile-responsive layout with hamburger drawer
Adds MobileHeader with hamburger button (left-aligned) that opens a
slide-in sidebar drawer on mobile. Desktop layout is unchanged. All
hardcoded multi-column grids updated with responsive Tailwind breakpoints.

Co-Authored-By: Jack Levy
2026-02-28 23:58:28 -05:00
Jack Levy
a8bc20e187 docs: update architecture for v0.2.2 fixes
Documents sponsor linking fix, backfill task, member name search
split_part approach, search spaces fix, and eager loading fix.

Authored-By: Jack Levy
2026-02-28 23:31:35 -05:00
Jack Levy
13e1577968 fix(members): link sponsors to bills and fix member search
- Poller now fetches bill detail on insert to get sponsor (list endpoint
  has no sponsor data)
- Add backfill_sponsor_ids task + admin endpoint + UI button to fix the
  1,616 existing bills with NULL sponsor_id
- Member name search now matches both "Last, First" and "First Last"
  using split_part() on the stored name column; same fix applied to
  global search
- Load Bill.sponsor relationship eagerly in get_member_bills to prevent
  MissingGreenlet error during Pydantic serialization
- Remove .trim() on search onChange so spaces can be typed

Authored-By: Jack Levy
2026-02-28 23:29:58 -05:00
Jack Levy
795385dcba docs: add comprehensive architecture documentation
Covers full stack, database schema, API endpoints, Celery pipeline,
LLM service design, frontend structure, auth, deployment, and feature
history through v0.2.0.

Authored-By: Jack Levy
2026-02-28 23:07:43 -05:00
Jack Levy
a111731cb4 fix(tailwind): add lib/ to content scan so utils.ts classes aren't purged
Party badge colors defined in lib/utils.ts were being stripped from the
production CSS bundle because the lib/ directory was missing from the
Tailwind content glob.

Authored-By: Jack Levy
2026-02-28 22:59:36 -05:00
Jack Levy
5cc6d13b3b fix(ui): use solid party badge colors readable in light and dark mode
Replaces light/dark variant classes (which produced unreadable pale pink
in dark mode) with solid saturated colors: red-600 for Republicans,
blue-600 for Democrats, slate-500 for Independents — all with white text.

Authored-By: Jack Levy
2026-02-28 22:57:10 -05:00
Jack Levy
e91e202eb4 fix(nginx): add Docker DNS resolver to prevent stale upstream IPs
Without resolver 127.0.0.11, nginx caches upstream IPs at startup and
returns 502 after container restarts until manually reloaded.

Authored-By: Jack Levy
2026-02-28 22:51:46 -05:00
Jack Levy
8d6a55905c feat(citations): add per-claim citations to AI briefs
LLM prompts updated to output {text, citation, quote} objects for every
key_point and risk. govinfo_url stored on BillBrief (migration 0006) so
the frontend can link directly to the source document without an extra
query. AIBriefCard renders § citation chips that expand inline to show
the verbatim quote and a View source → GovInfo link. Old plain-string
briefs continue to render unchanged.

Authored-By: Jack Levy
2026-02-28 22:48:58 -05:00
Jack Levy
6a1b387dd2 Add analysis status panel to admin page
- GET /api/admin/stats returns total bills, docs fetched, briefs generated
  (full + amendment), and remaining count
- Admin page shows stat cards + progress bar, auto-refreshes every 30s

Authored-By: Jack Levy
2026-02-28 22:25:49 -05:00
Jack Levy
c48241fe2f Limit bills to last 2 months + filter out procedural resolutions
- Drop hres/sres/hconres/sconres (simple/concurrent resolutions) from poller;
  only track hr, s, hjres, sjres (legislation that can become law)
- On first run, seed from 60 days back instead of full congress history,
  keeping the bill count to ~1,600 instead of 13,000+

Authored-By: Jack Levy
2026-02-28 22:21:34 -05:00
Jack Levy
5b73b60d9e Add multi-user auth system and admin panel
- User model with email/hashed_password/is_admin/notification_prefs
- JWT auth: POST /api/auth/register, /login, /me
- First registered user auto-promoted to admin
- Migration 0005: users table + user_id FK on follows (clears global follows)
- Follows, dashboard, settings, admin endpoints all require authentication
- Admin endpoints (settings writes, celery triggers) require is_admin
- Frontend: login/register pages, Zustand auth store (localStorage persist)
- AuthGuard component gates all app routes, shows app shell only when authed
- Sidebar shows user email + logout; Admin nav link visible to admins only
- Admin panel (/settings): user list with delete + promote/demote, LLM config,
  data source settings, and manual celery controls

Authored-By: Jack Levy
2026-02-28 21:44:34 -05:00
Jack Levy
e418dd9ae0 Initial commit 2026-02-28 21:08:19 -05:00