feat: PocketVeto v1.0.0 — initial public release
Self-hosted US Congress monitoring platform with AI policy briefs, bill/member/topic follows, ntfy + RSS + email notifications, alignment scoring, collections, and draft-letter generator. Authored by: Jack Levy
This commit is contained in:
271
frontend/lib/types.ts
Normal file
271
frontend/lib/types.ts
Normal file
@@ -0,0 +1,271 @@
|
||||
export interface MemberTerm {
|
||||
congress?: number;
|
||||
chamber?: string;
|
||||
partyName?: string;
|
||||
stateCode?: string;
|
||||
stateName?: string;
|
||||
startYear?: number;
|
||||
endYear?: number;
|
||||
district?: number;
|
||||
}
|
||||
|
||||
export interface MemberLeadership {
|
||||
type?: string;
|
||||
congress?: number;
|
||||
current?: boolean;
|
||||
}
|
||||
|
||||
export interface MemberTrendScore {
|
||||
score_date: string;
|
||||
newsapi_count: number;
|
||||
gnews_count: number;
|
||||
gtrends_score: number;
|
||||
composite_score: number;
|
||||
}
|
||||
|
||||
export interface MemberNewsArticle {
|
||||
id: number;
|
||||
source?: string;
|
||||
headline?: string;
|
||||
url?: string;
|
||||
published_at?: string;
|
||||
relevance_score?: number;
|
||||
}
|
||||
|
||||
export interface Member {
|
||||
bioguide_id: string;
|
||||
name: string;
|
||||
first_name?: string;
|
||||
last_name?: string;
|
||||
party?: string;
|
||||
state?: string;
|
||||
chamber?: string;
|
||||
district?: string;
|
||||
photo_url?: string;
|
||||
official_url?: string;
|
||||
congress_url?: string;
|
||||
birth_year?: string;
|
||||
address?: string;
|
||||
phone?: string;
|
||||
terms_json?: MemberTerm[];
|
||||
leadership_json?: MemberLeadership[];
|
||||
sponsored_count?: number;
|
||||
cosponsored_count?: number;
|
||||
effectiveness_score?: number;
|
||||
effectiveness_percentile?: number;
|
||||
effectiveness_tier?: string;
|
||||
latest_trend?: MemberTrendScore;
|
||||
}
|
||||
|
||||
export interface CitedPoint {
|
||||
text: string;
|
||||
citation: string;
|
||||
quote: string;
|
||||
label?: "cited_fact" | "inference";
|
||||
}
|
||||
|
||||
export interface BriefSchema {
|
||||
id: number;
|
||||
brief_type?: string;
|
||||
summary?: string;
|
||||
key_points?: (string | CitedPoint)[];
|
||||
risks?: (string | CitedPoint)[];
|
||||
deadlines?: { date: string | null; description: string }[];
|
||||
topic_tags?: string[];
|
||||
llm_provider?: string;
|
||||
llm_model?: string;
|
||||
govinfo_url?: string;
|
||||
share_token?: string;
|
||||
created_at?: string;
|
||||
}
|
||||
|
||||
export interface TrendScore {
|
||||
score_date: string;
|
||||
newsapi_count: number;
|
||||
gnews_count: number;
|
||||
gtrends_score: number;
|
||||
composite_score: number;
|
||||
}
|
||||
|
||||
export interface BillAction {
|
||||
id: number;
|
||||
action_date?: string;
|
||||
action_text?: string;
|
||||
action_type?: string;
|
||||
chamber?: string;
|
||||
}
|
||||
|
||||
export interface NewsArticle {
|
||||
id: number;
|
||||
source?: string;
|
||||
headline?: string;
|
||||
url?: string;
|
||||
published_at?: string;
|
||||
relevance_score?: number;
|
||||
}
|
||||
|
||||
export interface Bill {
|
||||
bill_id: string;
|
||||
congress_number: number;
|
||||
bill_type: string;
|
||||
bill_number: number;
|
||||
title?: string;
|
||||
short_title?: string;
|
||||
introduced_date?: string;
|
||||
latest_action_date?: string;
|
||||
latest_action_text?: string;
|
||||
status?: string;
|
||||
chamber?: string;
|
||||
congress_url?: string;
|
||||
sponsor?: Member;
|
||||
latest_brief?: BriefSchema;
|
||||
latest_trend?: TrendScore;
|
||||
updated_at?: string;
|
||||
has_document?: boolean;
|
||||
bill_category?: string;
|
||||
}
|
||||
|
||||
export interface AlignmentScore {
|
||||
bioguide_id: string;
|
||||
name: string;
|
||||
party?: string;
|
||||
state?: string;
|
||||
chamber?: string;
|
||||
photo_url?: string;
|
||||
effectiveness_percentile?: number;
|
||||
aligned: number;
|
||||
opposed: number;
|
||||
total: number;
|
||||
alignment_pct?: number;
|
||||
}
|
||||
|
||||
export interface AlignmentData {
|
||||
members: AlignmentScore[];
|
||||
total_bills_with_stance: number;
|
||||
total_bills_with_votes: number;
|
||||
}
|
||||
|
||||
export interface BillDetail extends Bill {
|
||||
actions: BillAction[];
|
||||
news_articles: NewsArticle[];
|
||||
trend_scores: TrendScore[];
|
||||
briefs: BriefSchema[];
|
||||
has_document: boolean;
|
||||
}
|
||||
|
||||
export interface PaginatedResponse<T> {
|
||||
items: T[];
|
||||
total: number;
|
||||
page: number;
|
||||
per_page: number;
|
||||
pages: number;
|
||||
}
|
||||
|
||||
export interface Follow {
|
||||
id: number;
|
||||
follow_type: "bill" | "member" | "topic";
|
||||
follow_value: string;
|
||||
follow_mode: "neutral" | "pocket_veto" | "pocket_boost";
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface DashboardData {
|
||||
feed: Bill[];
|
||||
trending: Bill[];
|
||||
follows: { bills: number; members: number; topics: number };
|
||||
}
|
||||
|
||||
export interface SettingsData {
|
||||
llm_provider: string;
|
||||
llm_model: string;
|
||||
congress_poll_interval_minutes: number;
|
||||
newsapi_enabled: boolean;
|
||||
pytrends_enabled: boolean;
|
||||
api_keys_configured: Record<string, boolean>;
|
||||
}
|
||||
|
||||
export interface BillNote {
|
||||
id: number;
|
||||
bill_id: string;
|
||||
content: string;
|
||||
pinned: boolean;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface NotificationSettings {
|
||||
ntfy_topic_url: string;
|
||||
ntfy_auth_method: string; // "none" | "token" | "basic"
|
||||
ntfy_token: string;
|
||||
ntfy_username: string;
|
||||
ntfy_password_set: boolean;
|
||||
ntfy_enabled: boolean;
|
||||
rss_enabled: boolean;
|
||||
rss_token: string | null;
|
||||
email_enabled: boolean;
|
||||
email_address: string;
|
||||
digest_enabled: boolean;
|
||||
digest_frequency: "daily" | "weekly";
|
||||
quiet_hours_start: number | null;
|
||||
quiet_hours_end: number | null;
|
||||
timezone: string | null; // IANA name, e.g. "America/New_York"
|
||||
alert_filters: Record<string, Record<string, boolean | string[]>> | null;
|
||||
}
|
||||
|
||||
// Write-only — ntfy_password is accepted on PUT but never returned (use ntfy_password_set to check)
|
||||
export interface NotificationSettingsUpdate extends Omit<Partial<NotificationSettings>, "ntfy_password_set"> {
|
||||
ntfy_password?: string;
|
||||
}
|
||||
|
||||
export interface Collection {
|
||||
id: number;
|
||||
name: string;
|
||||
slug: string;
|
||||
is_public: boolean;
|
||||
share_token: string;
|
||||
bill_count: number;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface CollectionDetail extends Collection {
|
||||
bills: Bill[];
|
||||
}
|
||||
|
||||
export interface MemberVotePosition {
|
||||
bioguide_id?: string;
|
||||
member_name?: string;
|
||||
party?: string;
|
||||
state?: string;
|
||||
position: string;
|
||||
}
|
||||
|
||||
export interface BillVote {
|
||||
id: number;
|
||||
congress: number;
|
||||
chamber: string;
|
||||
session: number;
|
||||
roll_number: number;
|
||||
question?: string;
|
||||
description?: string;
|
||||
vote_date?: string;
|
||||
yeas?: number;
|
||||
nays?: number;
|
||||
not_voting?: number;
|
||||
result?: string;
|
||||
source_url?: string;
|
||||
positions: MemberVotePosition[];
|
||||
}
|
||||
|
||||
export interface NotificationEvent {
|
||||
id: number;
|
||||
bill_id: string;
|
||||
event_type: "new_document" | "new_amendment" | "bill_updated";
|
||||
payload: {
|
||||
bill_title?: string;
|
||||
bill_label?: string;
|
||||
brief_summary?: string;
|
||||
bill_url?: string;
|
||||
} | null;
|
||||
dispatched_at: string | null;
|
||||
created_at: string;
|
||||
}
|
||||
Reference in New Issue
Block a user