# Project export: Weyes

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: Cal Hacks 12.0
- Tagline: See how the money flows in Washington D.C.
- Devpost: https://devpost.com/software/weyes
- GitHub: https://github.com/MamuzaD/cal-hacks
- Video: https://www.youtube.com/embed/fYRcEpLAYPU?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 5 GitHub contributor(s) — Daniel Mamuza (38 commits), imsqsh (6 commits), Andy Nguyen (4 commits), coderabbitai[bot] (3 commits), Athanasios Tassiadamis (2 commits)

## Devpost submission (written by the team)

### Inspiration

Congressional stock trading is a cornerstone issue in Congress today, with bills being setup as bipartisan issues. Traditional disclosure documents are dense, hard to navigate for casual readers, and incredibly hard to visualize holistically. We decided to create a visual analysis tools which took this dense, messy, and unfriendly data to transform it into a user-friendly graph displaying the flow of money in Congress. This makes it incredibly easy for researchers, journalists, and citizens to follow the money.

### What it does

Our platform visualizes the intricate relationships between: Corporations and their stock holdings Politicians and their financial interests Corporations and their stock holdings Politicians and their financial interests Users can search for any entity (company, politician, organization) and instantly see: A force-directed network graph showing all connections Real-time node selection with detailed relationship breakdowns A force-directed network graph showing all connections Real-time node selection with detailed relationship breakdowns

### How we built it

Frontend: React was used for an awesome UI/UX experience D3.js for graph visualization Backend Architecture: Python and FastAPI for the backend integration and data scraping PostgreSQL to host the database Railway for deployment

### Challenges we ran into

Ideation and brainstorm took almost a full day as we were struggling to find a project that could have real-world impact or was truly engaging with us. Deployment took quite a while because of a lack of documentation as well as a lack of available build tools. Scraping the data was a bottleneck for us as we had multiple sources to comb through and were significantly limited because of the slow Wi-Fi.

### Accomplishments we're proud of

Actually getting a final project out and on time considering our delays just in the very beginning An awesome UI given that only one of us had extensive frontend and React experience prior

### What we learned

D3 + React patterns: Direct DOM manipulation with D3 while React manages the surrounding UI Graph algorithms: Efficient edge deduplication and bidirectional relationship detection Political transparency: Some entities have 50+ connections

### What's next

Add tracking for PAC/Super PAC donations Add a live net worth estimator and visualizer Push notifications to users of notable Congresspeople trading

## README (from the GitHub repository)

# Weyes

<div style="display:flex; align-items:center; flex-wrap:wrap;">
  <img src="https://github.com/user-attachments/assets/9f66c02b-78dd-4390-afe7-e191b2fac435" alt="Screenshot 1" style="height:275px;">
  <img src="https://github.com/user-attachments/assets/aafa8b9d-46a1-46a3-92b1-47d934c2d64c" alt="Screenshot 2" style="height:275px;">
</div>

### Explore the network between politicians, companies, and money

> React + FastAPI app to search entities, visualize connections, and drill into details.

## Built With
#### Frontend
![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?style=for-the-badge&logo=typescript&logoColor=fff)
![React](https://img.shields.io/badge/react-%2320232a.svg?style=for-the-badge&logo=react&logoColor=%2361DAFB)
![Vite](https://img.shields.io/badge/Vite-646CFF?style=for-the-badge&logo=vite&logoColor=fff)
![TailwindCSS](https://img.shields.io/badge/Tailwind%20CSS-38B2AC?style=for-the-badge&logo=tailwind-css&logoColor=fff)
![shadcn/ui](https://img.shields.io/badge/shadcn%2Fui-000?style=for-the-badge&logo=shadcnui&logoColor=fff)
![D3](https://img.shields.io/badge/d3%20js-F9A03C?style=for-the-badge&logo=d3.js&logoColor=white)

#### Backend
![Python](https://img.shields.io/badge/Python-3776AB?style=for-the-badge&logo=python&logoColor=fff)
![FastAPI](https://img.shields.io/badge/FastAPI-05998B?style=for-the-badge&logo=fastapi&logoColor=fff)
![PostgreSQL](https://img.shields.io/badge/PostgreSQL-4169E1?style=for-the-badge&logo=postgresql&logoColor=fff)
![Anthropic](https://img.shields.io/badge/Claude-D97757?style=for-the-badge&logo=claude&logoColor=white)

## Features
### Smart Search
- AI-assisted classification (Anthropic Claude) of queries into person vs company with confidence and reasoning, with heuristic fallback when AI is unavailable.

### Interactive Graph
- D3-powered visualization shows nodes and edges between politicians and companies.
- Edges encode ownership/holding value; nodes display metadata like ticker, position, state, party, net worth.

### Entity Profiles
- Detail views for people and companies with canonical IDs.

### FastAPI + Typed Schemas
- FastAPI with typed responses, async PostgreSQL pooling via `asyncpg`.
- CORS enabled for local dev and hosted environments.

---
Built at CalHacks.
<img src="https://d112y698adiu2z.cloudfront.net/photos/production/challenge_photos/003/868/395/datas/full_width.png">


## Detected evidence (automated analysis)

Indexed codebase: 74 recognized source files, 362 KB.
- Anthropic (technology) — detected in the code
- CSS (language) — detected in the code
- FastAPI (technology) — detected in the code
- HTML (language) — detected in the code
- JavaScript (language) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code
- SQL (language) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code
- PostgreSQL (technology) — claimed on Devpost, not found in the code
- AI coding agent: Cursor — evidence: config files committed to the repository

## Codebase structure (from repository index)

### Files (87 of 87)

```
.gitignore
backend/env.example
backend/requirements.txt
backend/runtime.txt
backend/scrape_quiver.py
backend/src/core/config.py
backend/src/core/lifespan.py
backend/src/db/pool.py
backend/src/integrations/anthropic_client.py
backend/src/main.py
backend/src/routers/company.py
backend/src/routers/graph.py
backend/src/routers/person.py
backend/src/routers/search.py
backend/src/schemas/common.py
backend/src/schemas/company.py
backend/src/schemas/graph.py
backend/src/schemas/person.py
backend/src/schemas/search.py
backend/src/services/classification_service.py
backend/src/services/company_service.py
backend/src/services/graph_service.py
backend/src/services/person_service.py
backend/src/services/search_service.py
backend/src/utils/nlp_fallbacks.py
dev.sh
frontend/.cta.json
frontend/.cursorrules
frontend/.gitignore
frontend/.prettierignore
frontend/.vscode/settings.json
frontend/components.json
frontend/eslint.config.js
frontend/index.html
frontend/package.json
frontend/prettier.config.js
frontend/public/manifest.json
frontend/public/robots.txt
frontend/README.md
frontend/src/components/landing/cta.tsx
frontend/src/components/landing/features.tsx
frontend/src/components/landing/hero-graph.tsx
frontend/src/components/landing/hero.tsx
frontend/src/components/landing/index.ts
frontend/src/components/layout/footer.tsx
frontend/src/components/layout/header.tsx
frontend/src/components/layout/index.ts
frontend/src/components/layout/layout.tsx
frontend/src/components/ui/button.tsx
frontend/src/components/ui/card.tsx
frontend/src/components/ui/dropdown-menu.tsx
frontend/src/components/ui/input.tsx
frontend/src/components/ui/NetworkGraph.tsx
frontend/src/components/ui/search.tsx
frontend/src/components/ui/theme-toggle.tsx
frontend/src/components/visual/CompanyDetails.tsx
frontend/src/components/visual/ConnectionItem.tsx
frontend/src/components/visual/ConnectionsList.tsx
frontend/src/components/visual/NodeDashboard.tsx
frontend/src/components/visual/NodeHeader.tsx
frontend/src/components/visual/PersonDetails.tsx
frontend/src/constants/brand.ts
frontend/src/constants/index.ts
frontend/src/constants/landing-page.ts
frontend/src/index.css
frontend/src/integrations/tanstack-query/devtools.tsx
frontend/src/integrations/tanstack-query/root-provider.tsx
frontend/src/lib/dark-mode.ts
frontend/src/lib/node-dashboard-hooks.ts
frontend/src/lib/node-dashboard-utils.ts
frontend/src/lib/queries.ts
frontend/src/lib/queryKeys.ts
frontend/src/lib/types.ts
frontend/src/lib/utils.ts
frontend/src/main.tsx
frontend/src/pages/LandingPage.tsx
frontend/src/reportWebVitals.ts
frontend/src/routes/__root.tsx
frontend/src/routes/index.tsx
frontend/src/routes/showcase.tsx
frontend/src/routes/visual.$type.$id.tsx
frontend/src/routeTree.gen.ts
frontend/tsconfig.json
frontend/vite.config.ts
README.md
schema.sql
setup.sh
```

### Dependencies

- backend/requirements.txt: annotated-types@==0.7.0, anthropic@==0.71.0, anyio@==3.7.1, async-timeout@==5.0.1, asyncpg@==0.29.0, certifi@==2025.10.5, click@==8.3.0, distro@==1.9.0, docstring_parser@==0.17.0, fastapi@==0.104.1, h11@==0.16.0, httpcore@==1.0.9, httptools@==0.7.1, httpx@==0.28.1, idna@==3.11, jiter@==0.11.1, pydantic@==2.5.0, pydantic_core@==2.14.1, pydantic-settings@==2.2.1, python-dotenv@==1.0.0, PyYAML@==6.0.3, sniffio@==1.3.1, starlette@==0.27.0, typing_extensions@==4.15.0, uvicorn@==0.24.0, uvloop@==0.22.1, watchfiles@==1.1.1, websockets@==15.0.1
- frontend/package.json: @radix-ui/react-dropdown-menu@^2.1.16, @radix-ui/react-slot@^1.2.3, @tailwindcss/vite@^4.0.6, @tanstack/eslint-config@^0.3.0, @tanstack/react-devtools@^0.7.0, @tanstack/react-query@^5.66.5, @tanstack/react-query-devtools@^5.84.2, @tanstack/react-router@^1.132.0, @tanstack/react-router-devtools@^1.132.0, @tanstack/router-plugin@^1.132.0, @testing-library/dom@^10.4.0, @testing-library/react@^16.2.0, @types/d3@^7.4.3, @types/node@^22.10.2, @types/react@^19.2.0, @types/react-dom@^19.2.0, @vitejs/plugin-react@^5.0.4, class-variance-authority@^0.7.1, clsx@^2.1.1, d3@^7.9.0, jsdom@^27.0.0, lucide-react@^0.544.0, prettier@^3.5.3, react@^19.2.0, react-dom@^19.2.0, tailwind-merge@^3.0.2, tailwindcss@^4.0.6, tw-animate-css@^1.3.6, typescript@^5.7.2, vite@^7.1.7, vitest@^3.0.5, web-vitals@^5.1.0

### Recent commits (newest first)

- remove cta
- add images to readme
- update readme
- add to cors
- fix errors
- Merge pull request #7 from MamuzaD/refactor/backend-routing
- search ui
- reset whenever navigation
- reorganize into separate components
- pr revision
- remove bad console logs smh
- add sidebar selection too
- smart filtering: show top 25, toggle to view all holdings
- wip: nodes
- Merge branch 'main' into refactor/backend-routing
- begin on visual
- Update backend/src/services/graph_service.py
- Merge pull request #8 from MamuzaD/bugfix/d3-text-color
- pr fixes
- fix: dark mode observer

## Key source files (fetched from GitHub, selected and truncated for size)

### backend/requirements.txt

```
annotated-types==0.7.0
anthropic==0.71.0
anyio==3.7.1
async-timeout==5.0.1
asyncpg==0.29.0
certifi==2025.10.5
click==8.3.0
distro==1.9.0
docstring_parser==0.17.0
fastapi==0.104.1
h11==0.16.0
httpcore==1.0.9
httptools==0.7.1
httpx==0.28.1
idna==3.11
jiter==0.11.1
pydantic==2.5.0
pydantic-settings==2.2.1
pydantic_core==2.14.1
python-dotenv==1.0.0
PyYAML==6.0.3
sniffio==1.3.1
starlette==0.27.0
typing_extensions==4.15.0
uvicorn==0.24.0
uvloop==0.22.1
watchfiles==1.1.1
websockets==15.0.1

```

### frontend/package.json

```
{
  "name": "test",
  "private": true,
  "type": "module",
  "scripts": {
    "dev": "vite --port 3000",
    "build": "vite build && tsc",
    "serve": "vite preview",
    "test": "vitest run",
    "lint": "eslint",
    "format": "prettier",
    "check": "prettier --write . && eslint --fix"
  },
  "dependencies": {
    "@radix-ui/react-dropdown-menu": "^2.1.16",
    "@radix-ui/react-slot": "^1.2.3",
    "@tailwindcss/vite": "^4.0.6",
    "@tanstack/react-devtools": "^0.7.0",
    "@tanstack/react-query": "^5.66.5",
    "@tanstack/react-query-devtools": "^5.84.2",
    "@tanstack/react-router": "^1.132.0",
    "@tanstack/react-router-devtools": "^1.132.0",
    "@tanstack/router-plugin": "^1.132.0",
    "class-variance-authority": "^0.7.1",
    "clsx": "^2.1.1",
    "d3": "^7.9.0",
    "lucide-react": "^0.544.0",
    "react": "^19.2.0",
    "react-dom": "^19.2.0",
    "tailwind-merge": "^3.0.2",
    "tailwindcss": "^4.0.6",
    "tw-animate-css": "^1.3.6"
  },
  "devDependencies": {
    "@tanstack/eslint-config": "^0.3.0",
    "@testing-library/dom": "^10.4.0",
    "@testing-library/react": "^16.2.0",
    "@types/d3": "^7.4.3",
    "@types/node": "^22.10.2",
    "@types/react": "^19.2.0",
    "@types/react-dom": "^19.2.0",
    "@vitejs/plugin-react": "^5.0.4",
    "jsdom": "^27.0.0",
    "prettier": "^3.5.3",
    "typescript": "^5.7.2",
    "vite": "^7.1.7",
    "vitest": "^3.0.5",
    "web-vitals": "^5.1.0"
  }
}

```

### backend/src/main.py

```python
"""Main FastAPI application."""
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from src.core.lifespan import lifespan
from src.routers import search, graph, person, company

app = FastAPI(
    title="Web Weyes - Connections API",
    description="API for exploring politician financial holdings and company ownership",
    version="2.0.0",
    lifespan=lifespan,
)

# Configure CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=[
        "http://localhost:3000",
        "http://127.0.0.1:3000",
        "https://weyes.up.railway.app",
    ],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


@app.get("/")
def root():
    """Root endpoint."""
    return {"message": "Welcome to Web Weyes!"}


# Include routers
app.include_router(search.router, prefix="/api/search", tags=["search"])
app.include_router(graph.router, prefix="/api/graph", tags=["graph"])
app.include_router(person.router, prefix="/api/person", tags=["person"])
app.include_router(company.router, prefix="/api/company", tags=["company"])


```

### frontend/src/main.tsx

```typescript
import { StrictMode } from 'react'
import ReactDOM from 'react-dom/client'
import { RouterProvider, createRouter } from '@tanstack/react-router'

import * as TanStackQueryProvider from './integrations/tanstack-query/root-provider.tsx'

// Import the generated route tree
import { routeTree } from './routeTree.gen'

import './index.css'

// Create a new router instance
const TanStackQueryProviderContext = TanStackQueryProvider.getContext()
const router = createRouter({
  routeTree,
  context: {
    ...TanStackQueryProviderContext,
  },
  defaultPreload: 'intent',
  scrollRestoration: true,
  defaultStructuralSharing: true,
  defaultPreloadStaleTime: 0,
})

// Register the router instance for type safety
declare module '@tanstack/react-router' {
  interface Register {
    router: typeof router
  }
}

// Render the app
const rootElement = document.getElementById('app')
if (rootElement && !rootElement.innerHTML) {
  const root = ReactDOM.createRoot(rootElement)
  root.render(
    <StrictMode>
      <TanStackQueryProvider.Provider {...TanStackQueryProviderContext}>
        <RouterProvider router={router} />
      </TanStackQueryProvider.Provider>
    </StrictMode>,
  )
}

```

### frontend/src/constants/index.ts

```typescript
export { brand } from './brand'
export { landingPage } from './landing-page'

```

### frontend/src/routes/index.tsx

```typescript
import { createFileRoute } from '@tanstack/react-router'
import LandingPage from '../pages/LandingPage'

export const Route = createFileRoute('/')({
  component: LandingPage,
})

```

### frontend/src/components/layout/index.ts

```typescript
export { Layout } from './layout'
export { Footer } from './footer'
export { Header } from './header'


```

### frontend/src/components/landing/index.ts

```typescript
export { HeroSection } from './hero'
export { FeaturesSection } from './features'
export { CTASection } from './cta'
export { HeroGraph } from './hero-graph'

```

### setup.sh

```shell
#!/bin/bash

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

echo -e "${GREEN}Setting up Cal-hacks Development Environment${NC}\n"

# Check if Python 3 is installed
if ! command -v python3 &> /dev/null; then
    echo -e "${RED}Error: Python 3 is not installed${NC}"
    echo -e "${YELLOW}Please install Python 3.11 or higher${NC}"
    exit 1
fi

# Setup backend
echo -e "${GREEN}Setting up backend...${NC}"
cd backend

# Create virtual environment
if [ ! -d ".venv" ]; then
    echo "Creating virtual environment..."
    python3 -m venv .venv
    echo -e "${GREEN}✓ Virtual environment created${NC}"
else
    echo -e "${YELLOW}Virtual environment already exists${NC}"
fi

# Activate virtual environment and install dependencies
echo "Installing Python dependencies..."
source .venv/bin/activate
pip install -r requirements.txt
deactivate

echo -e "${GREEN}✓ Backend setup complete${NC}\n"

# Copy .env file if it doesn't exist
if [ ! -f ".env" ]; then
    if [ -f "env.example" ]; then
        cp env.example .env
        echo -e "${GREEN}✓ Created .env file from env.example${NC}"
        echo -e "${YELLOW}Please edit .env and add your actual credentials${NC}"
    else
        echo -e "${YELLOW}No env.example found. You'll need to create .env manually.${NC}"
    fi
else
    echo -e "${YELLOW}.env already exists${NC}"
fi

cd ..

# Setup frontend
echo -e "\n${GREEN}Setting up frontend...${NC}"
cd frontend

# Check if node_modules exists
if [ ! -d "node_modules" ]; then
    echo "Installing Node dependencies..."
    npm install
    echo -e "${GREEN}✓ Frontend setup complete${NC}"
else
    echo -e "${YELLOW}node_modules already exists. Run 'npm install' to update dependencies${NC}"
fi

cd ..

echo -e "\n${GREEN}✓ Setup complete!${NC}"
echo -e "${GREEN}Run './dev.sh' to start development servers${NC}"


```

### dev.sh

```shell
#!/bin/bash

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

echo -e "${GREEN}Starting Cal-hacks Development Environment...${NC}\n"

# Function to cleanup background processes
cleanup() {
    echo -e "\n${YELLOW}Shutting down services...${NC}"
    kill $BACKEND_PID $FRONTEND_PID 2>/dev/null
    wait $BACKEND_PID $FRONTEND_PID 2>/dev/null
    exit 0
}

# Set up signal handlers
trap cleanup SIGINT SIGTERM

# Check if .env file exists in backend
if [ ! -f "backend/.env" ]; then
    echo -e "${YELLOW}Warning: backend/.env file not found${NC}"
    echo -e "${YELLOW}Please create it from backend/env.example${NC}\n"
fi

# Check if virtual environment exists
if [ ! -d "backend/.venv" ] && [ ! -d "backend/venv" ]; then
    echo -e "${YELLOW}Warning: No virtual environment found in backend/${NC}"
    echo -e "${YELLOW}Please run: cd backend && python3 -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt${NC}\n"
fi

# Start FastAPI backend
echo -e "${GREEN}Starting FastAPI backend on http://localhost:8000${NC}"
cd backend

# Activate virtual environment if it exists
if [ -d ".venv" ]; then
    source .venv/bin/activate
elif [ -d "venv" ]; then
    source venv/bin/activate
fi

# Find Python executable
if command -v python3 &> /dev/null; then
    PYTHON_CMD=python3
elif command -v python &> /dev/null; then
    PYTHON_CMD=python
else
    echo -e "${RED}Error: Python not found. Please install Python 3.11+${NC}"
    exit 1
fi

$PYTHON_CMD -m uvicorn src.main:app --reload --host 0.0.0.0 --port 8000 &
BACKEND_PID=$!
cd ..

# Wait a moment for backend to start and check if it's still running
sleep 2
if ! kill -0 $BACKEND_PID 2>/dev/null; then
    echo -e "${RED}Error: Backend failed to start${NC}"
    echo -e "${YELLOW}Make sure you have:${NC}"
    echo -e "  - Virtual environment created in backend/.venv"
    echo -e "  - Dependencies installed: pip install -r requirements.txt"
    echo -e "  - .env file configured with DATABASE_URL and ANTHROPIC_API_KEY"
    exit 1
fi

# Start React frontend
echo -e "${GREEN}Starting React frontend on http://localhost:3000${NC}"
cd frontend
npm run dev &
FRONTEND_PID=$!
cd ..

# Wait for user interrupt
echo -e "\n${GREEN}✓ Both services are running!${NC}"
echo -e "${GREEN}Backend:  http://localhost:8000${NC}"
echo -e "${GREEN}Frontend: http://localhost:3000${NC}"
echo -e "\n${YELLOW}Press Ctrl+C to stop all services${NC}\n"

# Wait for both processes
wait


```

[63 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]