# Project export: ReNOVA

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: ReNOVA is the future of contractor hiring. An AI-powered platform that transforms how homeowners and businesses find licensed building professionals.
- Devpost: https://devpost.com/software/renova-yjvrlq
- GitHub: https://github.com/cjaeey/calhaks12.0
- Team: 2 GitHub contributor(s) — Carlos John Escala (7 commits), Claude (3 commits)

## Devpost submission (written by the team)

### Inspiration

Finding reliable contractors for home improvement projects is frustrating and time-consuming. We wanted to create an AI-powered platform that could understand natural language project descriptions and intelligently match customers with qualified professionals.

### What it does

ReNOVA connects homeowners with verified contractors using multi-agent AI systems. Users describe their project in natural language, and our AI agents analyze requirements, find local contractors, and rank matches with transparent reasoning.

### How we built it

Frontend: Next.js 14 with React 18 and Figma-designed UI Backend: Node.js with Express and Fetch.ai uAgents AI Pipeline: Python agents using uAgents SDK: CoordinatorAgent: Orchestrates the pipeline IntakeAgent: Analyzes project descriptions with Claude AI ScraperAgent: Finds contractors via Yelp API MatcherAgent: Ranks matches using vector similarity + AI reasoning Tech Stack: Anthropic Claude, ChromaDB, Redis, Docker

### Challenges we ran into

When using anthropic the prompts didn't work as intended which caused more issues with debugging.

### Accomplishments we're proud of

We have a functional product, and we're able to speak and understand our idea.

### What we learned

We learned how different technologies learned.

### What's next

Make greater functionality.

## README (from the GitHub repository)

# ReNOVA 2025 🏗️

> AI-powered contractor matching platform built for CalHacks 12.0

ReNOVA connects homeowners and businesses with verified building professionals using multi-agent AI systems powered by Fetch.ai, Anthropic Claude, Bright Data, and ChromaDB.

![ReNOVA Architecture](https://img.shields.io/badge/Stack-Next.js%20%7C%20Node.js%20%7C%20Fetch.ai%20%7C%20Claude-blue)
![License](https://img.shields.io/badge/license-MIT-green)

## ✨ Features

- **Multi-Agent AI Pipeline**: Fetch.ai agents orchestrate the entire matching workflow
- **Natural Language Understanding**: Claude AI analyzes project requirements
- **Real-Time Progress**: Server-Sent Events provide live pipeline updates
- **Smart Matching**: Vector similarity search + AI reasoning for optimal contractor matches
- **Beautiful UI**: Figma-designed responsive interface with smooth animations
- **Zero SQL**: All data stored in ChromaDB vector database
- **Usage-Based Billing**: Lava Payments integration with automatic fallback to direct API

## 🎯 How It Works

1. **User submits project** - Describe your need (e.g., "AC unit making noise, needs repair")
2. **IntakeAgent analyzes** - Claude extracts trade, urgency, services, budget hints
3. **ScraperAgent finds pros** - Bright Data searches for local licensed contractors
4. **IndexerAgent stores** - Professionals indexed in ChromaDB with embeddings
5. **MatcherAgent ranks** - Vector search + Claude reasoning generates top matches
6. **Results delivered** - Real-time progress updates, detailed match explanations

## 🚀 Quick Start

### Prerequisites

- **Docker Desktop** installed and running
- **Anthropic API key** (required)
- **At least 4GB RAM** for Docker

### One-Command Setup

```bash
# Clone the repository
git clone https://github.com/cjaeey/calhaks12.0.git
cd calhaks12.0

# Start everything with one command!
./start.sh

# That's it! Open http://localhost:3000
```

The `start.sh` script will:
- ✅ Create `.env` from template
- ✅ Build Docker containers
- ✅ Start all services (frontend, backend, Redis, ChromaDB)
- ✅ Wait for health checks
- ✅ Show you the URLs

### Alternative: Using Make Commands

```bash
# Install dependencies locally
make install

# Start with Docker Compose
make up

# View logs
make logs

# Seed demo data
make seed

# Stop services
make down
```

📖 **Detailed Docker guide:** See [DOCKER_SETUP.md](DOCKER_SETUP.md)

### Local Development (without Docker)

**Terminal 1 - Redis:**
```bash
redis-server
```

**Terminal 2 - Backend:**
```bash
cd backend
npm install
npm run dev
```

**Terminal 3 - Frontend:**
```bash
cd "frontend/Landing Page AI"
npm install
npm run dev
```

## 📁 Project Structure

```
renova/
├── backend/                    # Node.js + Express backend
│   ├── agents/                 # Fetch.ai uAgents
│   │   ├── coordinatorAgent.js
│   │   ├── intakeAgent.js
│   │   ├── scraperAgent.js
│   │   ├── indexerAgent.js
│   │   └── matcherAgent.js
│   ├── services/
│   │   ├── claudeClient.js     # Anthropic Claude integration
│   │   ├── brightDataClient.js # Web scraping
│   │   ├── matchingService.js  # Vector search + business logic
│   │   └── embeddingService.js
│   ├── config/
│   │   ├── chromaClient.js     # ChromaDB setup
│   │   └── redisClient.js      # Redis pub/sub
│   ├── routes/
│   │   ├── jobs.js             # Job API endpoints
│   │   └── pros.js             # Professional listings
│   └── server.js
│
├── frontend/Landing Page AI/   # Next.js 14 frontend
│   ├── src/
│   │   ├── app/
│   │   │   ├── page.tsx        # Landing page
│   │   │   ├── jobs/[jobId]/   # Job results
│   │   │   └── layout.tsx
│   │   ├── components/
│   │   │   ├── Hero.tsx
│   │   │   ├── IntakeForm.tsx
│   │   │   ├── PostProjectModal.tsx
│   │   │   ├── ProgressTracker.tsx
│   │   │   ├── MatchResults.tsx
│   │   │   └── ui/             # shadcn/ui components
│   │   └── lib/
│   │       ├── api.ts          # Backend API client
│   │       └── useSSE.ts       # SSE hook
│   └── package.json
│
├── docker-compose.yml
├── Makefile
├── .env.example
└── README.md
```

## 🧩 Tech Stack

| Layer | Technology |
|-------|-----------|
| **Frontend** | Next.js 14, React 18, Tailwind CSS, Framer Motion, shadcn/ui |
| **Backend** | Node.js, Express, Fetch.ai uAgents |
| **AI/ML** | Anthropic Claude (Sonnet 4.5), ChromaDB (vector DB) |
| **Data** | Bright Data (web scraping), Redis (pub/sub) |
| **Deployment** | Vercel (frontend), Render/Railway (backend) |

## 🔧 Configuration

### Environment Variables

```bash
# Required
ANTHROPIC_API_KEY=sk-ant-...

# Optional (for live scraping)
BRIGHT_DATA_USERNAME=your_username
BRIGHT_DATA_PASSWORD=your_password
BRIGHT_DATA_ZONE=your_zone
BRIGHT_DATA_PROXY=brd.superproxy.io:22225

# Fetch.ai (optional)
UAGENTS_WALLET_MNEMONIC=your_mnemonic
UAGENTS_NETWORK=alpha

# Redis
REDIS_URL=redis://localhost:6379/0

# ChromaDB
CHROMA_PATH=./chroma_data

# App
NODE_ENV=development
PORT=3001
FRONTEND_URL=http://localhost:3000
```

## 📡 API Endpoints

### Jobs

```bash
# Create a new job
POST /api/jobs
{
  "prompt": "Need HVAC repair for noisy AC",
  "city": "San Francisco",
  "state": "CA",
  "zipCode": "94102"
}

# Get job status
GET /api/jobs/:id

# Stream progress (SSE)
GET /api/jobs/:id/events

# Get results
GET /api/jobs/:id/results
```

### Professionals

```bash
# List all professionals
GET /api/pros?trade=HVAC&city=San Francisco&state=CA

# Get professional details
GET /api/pros/:id
```

## 🧪 Testing

```bash
# Seed demo professionals
make seed

# Run end-to-end demo
make demo

# Manual test flow
curl -X POST http://localhost:3001/api/jobs \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "AC not cooling, needs urgent repair",
    "city": "San Francisco",
    "state": "CA"
  }'
```

## 🌋 Lava Payments Integration (Optional)

ReNOVA supports **Lava Payments** for AI usage tracking and billing:

```bash
# Quick setup
./setup-lava.sh

# Or manually set in .env
USE_LAVA=true
LAVA_FORWARD_TOKEN=your_token_here
```

**Features:**
- Real-time usage and cost tracking
- Automatic fallback to direct Anthropic API if credits exhausted
- Zero downtime - transparent switching
- Dashboard analytics at https://www.lavapayments.com/dashboard

**How it works:**
1. Lava acts as a transparent proxy to Anthropic Claude API
2. Tracks every API call with usage metrics
3. If Lava credits run out, automatically falls back to your Anthropic credits
4. Application continues working seamlessly

📖 **Full documentation:** See [LAVA_INTEGRATION.md](LAVA_INTEGRATION.md)

## 🎨 UI Components

The frontend uses a Figma-designed component system:

- **Hero**: Animated landing section with 3D visualization
- **HowItWorks**: Step-by-step process explanation
- **AIShowcase**: Technology stack showcase
- **IntakeForm**: Project submission with validation
- **ProgressTracker**: Real-time SSE progress display
- **MatchResults**: AI-ranked contractor cards with reasoning

## 🚢 Deployment

### Frontend (Vercel)

```bash
cd "frontend/Landing Page AI"
vercel deploy
```

### Backend (Render/Railway)

1. Connect your repo to Render/Railway
2. Set environment variables
3. Deploy from `main` branch
4. Ensure Redis add-on is enabled

## 🤝 Contributing

This is a hackathon project built for CalHacks 12.0. Contributions welcome!

```bash
# Fork the repo
# Create a feature branch
git checkout -b feature/amazing-feature

# Commit changes
git commit -m "Add amazing feature"

# Push and create PR
git push origin feature/amazing-feature
```

## 📝 License

MIT License - see [LICENSE](LICENSE) file for details

## 🙏 Acknowledgments

- **Fetch.ai** - Multi-agent orchestration
- **Anthropic** - Claude AI for natural language understanding
- **Lava Payments** - Usage-based AI billing with automatic fallback
- **Bright Data** - Web scraping infrastructure
- **ChromaDB** - Vector database for embeddings
- **CalHacks 12.0** - Hackathon inspiration and community

## 📧 Contact

Built with ❤️ by the ReNOVA Team for CalHacks 12.0

[README truncated for size]

## Detected evidence (automated analysis)

Indexed codebase: 184 recognized source files, 615 KB.
- Anthropic (technology) — detected in the code
- CSS (language) — detected in the code
- Express (technology) — detected in the code
- Flask (technology) — detected in the code
- HTML (language) — detected in the code
- JavaScript (language) — detected in the code
- Next.js (technology) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code
- Redis (technology) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code
- Docker (technology) — claimed on Devpost, not found in the code
- Node.js (technology) — claimed on Devpost, not found in the code
- AI coding agent: Claude Code — evidence: config files committed to the repository; commit authorship or trailers

## Codebase structure (from repository index)

### Files (120 of 196)

```
.env.example
.gitignore
agents_python/AGENTVERSE_DEPLOYMENT.md
agents_python/AGENTVERSE_REGISTRATION.md
agents_python/api_bridge.py
agents_python/chat_wrapper.py
agents_python/coordinator_agent.py
agents_python/FETCHAI_TRACK_PROOF.md
agents_python/get_agent_info.py
agents_python/intake_agent.py
agents_python/lava_client.py
agents_python/matcher_agent.py
agents_python/models.py
agents_python/README.md
agents_python/READY_FOR_CALHACKS.md
agents_python/register_agentverse.py
agents_python/register_simple.py
agents_python/requirements.txt
agents_python/run_agent_script.py
agents_python/scraper_agent.py
agents_python/setup_and_run.sh
agents_python/start_for_agentverse.sh
backend/.dockerignore
backend/agents/coordinatorAgent.js
backend/agents/indexerAgent.js
backend/agents/intakeAgent.js
backend/agents/matcherAgent.js
backend/agents/scraperAgent.js
backend/config/chromaClient.js
backend/config/env.js
backend/config/redisClient.js
backend/Dockerfile
backend/package.json
backend/public/index.html
backend/public/test.html
backend/routes/jobs.js
backend/routes/pros.js
backend/scripts/demoE2E.js
backend/scripts/seedPros.js
backend/server.js
backend/services/brightDataClient.js
backend/services/claudeClient.js
backend/services/embeddingService.js
backend/services/jobStore.js
backend/services/matchingService.js
backend/services/professionalGenerator.js
backend/services/yelpClient.js
backend/test-claude.js
backend/utils/events.js
backend/utils/logger.js
CLAUDE.md
demo.html
DOCKER_SETUP.md
docker-compose.yml
frontend/Landing Page AI/.dockerignore
frontend/Landing Page AI/App.tsx
frontend/Landing Page AI/Attributions.md
frontend/Landing Page AI/Dockerfile
frontend/Landing Page AI/next-env.d.ts
frontend/Landing Page AI/package.json
frontend/Landing Page AI/postcss.config.mjs
frontend/Landing Page AI/src/app/jobs/[jobId]/page.tsx
frontend/Landing Page AI/src/app/layout.tsx
frontend/Landing Page AI/src/app/page.tsx
frontend/Landing Page AI/src/components/AIShowcase.tsx
frontend/Landing Page AI/src/components/CTASection.tsx
frontend/Landing Page AI/src/components/FeaturedTrades.tsx
frontend/Landing Page AI/src/components/figma/ImageWithFallback.tsx
frontend/Landing Page AI/src/components/Footer.tsx
frontend/Landing Page AI/src/components/Hero.tsx
frontend/Landing Page AI/src/components/HowItWorks.tsx
frontend/Landing Page AI/src/components/IntakeForm.tsx
frontend/Landing Page AI/src/components/MatchResults.tsx
frontend/Landing Page AI/src/components/PostProjectModal.tsx
frontend/Landing Page AI/src/components/ProfessionalProfiles.tsx
frontend/Landing Page AI/src/components/ProgressTracker.tsx
frontend/Landing Page AI/src/components/ui/accordion.tsx
frontend/Landing Page AI/src/components/ui/alert-dialog.tsx
frontend/Landing Page AI/src/components/ui/alert.tsx
frontend/Landing Page AI/src/components/ui/aspect-ratio.tsx
frontend/Landing Page AI/src/components/ui/avatar.tsx
frontend/Landing Page AI/src/components/ui/badge.tsx
frontend/Landing Page AI/src/components/ui/breadcrumb.tsx
frontend/Landing Page AI/src/components/ui/button.tsx
frontend/Landing Page AI/src/components/ui/calendar.tsx
frontend/Landing Page AI/src/components/ui/card.tsx
frontend/Landing Page AI/src/components/ui/carousel.tsx
frontend/Landing Page AI/src/components/ui/chart.tsx
frontend/Landing Page AI/src/components/ui/checkbox.tsx
frontend/Landing Page AI/src/components/ui/collapsible.tsx
frontend/Landing Page AI/src/components/ui/command.tsx
frontend/Landing Page AI/src/components/ui/context-menu.tsx
frontend/Landing Page AI/src/components/ui/dialog.tsx
frontend/Landing Page AI/src/components/ui/drawer.tsx
frontend/Landing Page AI/src/components/ui/dropdown-menu.tsx
frontend/Landing Page AI/src/components/ui/form.tsx
frontend/Landing Page AI/src/components/ui/hover-card.tsx
frontend/Landing Page AI/src/components/ui/input-otp.tsx
frontend/Landing Page AI/src/components/ui/input.tsx
frontend/Landing Page AI/src/components/ui/label.tsx
frontend/Landing Page AI/src/components/ui/menubar.tsx
frontend/Landing Page AI/src/components/ui/navigation-menu.tsx
frontend/Landing Page AI/src/components/ui/pagination.tsx
frontend/Landing Page AI/src/components/ui/popover.tsx
frontend/Landing Page AI/src/components/ui/progress.tsx
frontend/Landing Page AI/src/components/ui/radio-group.tsx
frontend/Landing Page AI/src/components/ui/resizable.tsx
frontend/Landing Page AI/src/components/ui/scroll-area.tsx
frontend/Landing Page AI/src/components/ui/select.tsx
frontend/Landing Page AI/src/components/ui/separator.tsx
frontend/Landing Page AI/src/components/ui/sheet.tsx
frontend/Landing Page AI/src/components/ui/sidebar.tsx
frontend/Landing Page AI/src/components/ui/skeleton.tsx
frontend/Landing Page AI/src/components/ui/slider.tsx
frontend/Landing Page AI/src/components/ui/sonner.tsx
frontend/Landing Page AI/src/components/ui/switch.tsx
frontend/Landing Page AI/src/components/ui/table.tsx
frontend/Landing Page AI/src/components/ui/tabs.tsx
frontend/Landing Page AI/src/components/ui/textarea.tsx
frontend/Landing Page AI/src/components/ui/toggle-group.tsx
[76 more files omitted for size]
```

### Dependencies

- agents_python/requirements.txt: aiohttp@>=3.9.0, anthropic@>=0.17.0, chromadb@>=0.4.0, flask@>=3.0.0, flask-cors@>=4.0.0, python-dotenv@>=1.0.0, redis@>=5.0.0, requests@>=2.31.0, uagents@>=0.12.0
- backend/package.json: @anthropic-ai/sdk@^0.32.1, axios@^1.7.9, chromadb@^1.9.2, chromadb-default-embed@^2.14.0, cors@^2.8.5, dotenv@^16.4.7, express@^4.21.2, ioredis@^5.4.2, nanoid@^5.0.9, nodemon@^3.1.9, pino@^9.5.0, pino-pretty@^13.0.0, zod@^3.24.1
- frontend/Landing Page AI/package.json: @radix-ui/react-dialog@^1.1.2, @radix-ui/react-label@^2.1.1, @radix-ui/react-slot@^1.1.1, @types/node@^22, @types/react@^18, @types/react-dom@^18, autoprefixer@^10.4.20, axios@^1.7.9, class-variance-authority@^0.7.1, clsx@^2.1.1, eslint@^8, eslint-config-next@14.2.21, framer-motion@^11.11.17, lucide-react@^0.460.0, next@^14.2.21, postcss@^8.4.47, react@^18.3.1, react-dom@^18.3.1, tailwind-merge@^2.5.5, tailwindcss@^3.4.1, tailwindcss-animate@^1.0.7, typescript@^5

### Recent commits (newest first)

- Fix ChromaDB health check issues for Docker startup
- Add comprehensive Docker setup with one-command startup
- Add automatic fallback to Anthropic API when Lava credits exhausted
- Add Lava Payments integration for AI billing tracking
- save progress on carlos branch
- transfered from replit
- Initial commit

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

### YELP_SETUP.md

```markdown
# 🔥 Get REAL Professionals from Yelp

Your system now finds **REAL contractors from Yelp** instead of generating fake data!

## How It Works

The system tries this priority order:
1. **Yelp Fusion API** → Get real contractors with ratings, reviews, phone numbers
2. **Fallback** → Generate sample data if Yelp is unavailable

## Setup (5 minutes, FREE)

### Step 1: Get Your FREE Yelp API Key

1. Go to: https://www.yelp.com/developers/v3/manage_app
2. Sign in or create account (free)
3. Click "Create New App"
4. Fill in:
   - **App Name**: "ReNOVA"
   - **Industry**: "Home Services"
   - **Company**: Your name
   - **Website**: http://localhost:3001
   - **Description**: "Contractor matching platform"
5. Accept Terms & Submit
6. Copy your **API Key** (looks like: `abcd1234...xyz`)

### Step 2: Add to Your .env File

```bash
# In /backend/.env
YELP_API_KEY=your_api_key_here
```

### Step 3: Restart Backend

```bash
cd backend
npm run dev
```

## Testing

### Test 1: HVAC Contractors
```bash
curl -X POST http://localhost:3001/api/jobs \
  -H 'Content-Type: application/json' \
  -d '{"prompt":"Need HVAC repair urgently","city":"Oakland","state":"CA"}'
```

### Test 2: Plumbing
```bash
curl -X POST http://localhost:3001/api/jobs \
  -H 'Content-Type: application/json' \
  -d '{"prompt":"Plumbing emergency","city":"San Francisco","state":"CA"}'
```

### Test 3: Electrical
```bash
curl -X POST http://localhost:3001/api/jobs \
  -H 'Content-Type: application/json' \
  -d '{"prompt":"Need electrician","city":"Berkeley","state":"CA"}'
```

## What You'll Get from Yelp

**Real Data**:
- Business names
- Real ratings (1-5 stars)
- Review counts
- Phone numbers
- Actual addresses
- Price levels ($ to $$$$)
- Yelp profile URLs
- Distance from search location

## Limits

- **Free Tier**: 500 API calls/day
- **Rate Limit**: Plenty for development/testing
- **Upgrade**: $0 for more calls if needed

## Example Response (REAL Data)

```json
{
  "matches": [
    {
      "name": "Bay Area Air Conditioning",
      "rating": 4.8,
      "reviewCount": 156,
      "phone": "+15105551234",
      "address": "123 Main St",
      "city": "Oakland",
      "state": "CA",
      "yelpUrl": "https://www.yelp.com/biz/bay-area-air...",
      "priceLevel": "$$",
      "distance": 1245.8  // meters
    }
  ]
}
```

## Troubleshooting

### "Yelp API key not configured"
- Make sure `YELP_API_KEY=...` is in `/backend/.env`
- Restart the backend

### "Yelp API authentication failed"
- Double-check your API key is correct
- No spaces before/after the key

### Still getting generated data?
- Check backend logs: should see "REAL professionals found from Yelp"
- If you see "Generated professionals (Yelp unavailable)", the API key isn't working

## Frontend Usage

Just use the app normally at http://localhost:3005

- Enter any project description
- Enter location (city, state)
- Click "Get Matched Now"
- You'll get REAL contractors from Yelp!

## Why This is Better Than LinkedIn

✅ **Legal**: Y
[truncated — 590 more characters]
```

### CLAUDE.md

```markdown
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

**ReNOVA 2025** is a CalHacks 12.0 AI-powered contractor matching platform that connects homeowners and businesses with licensed building professionals (HVAC, plumbing, electricians, remodelers, etc.) using multi-agent AI systems.

## Tech Stack

### Frontend
- **Framework**: Next.js 14 (App Router)
- **UI**: React 18 with Figma-designed components
- **Styling**: Tailwind CSS with shadcn/ui components
- **Animations**: Framer Motion
- **API Client**: Axios

### Backend
- **Runtime**: Node.js with Express
- **AI Agents**: Fetch.ai uAgents SDK (JavaScript)
- **LLM**: Anthropic Claude API (Sonnet 4.5)
- **Scraping**: Bright Data
- **Database**: ChromaDB (vector database)
- **Queuing**: Redis (pub/sub for real-time updates)

## Architecture

### Multi-Agent Pipeline

The system uses a coordinator pattern with specialized agents:

1. **CoordinatorAgent** (`backend/agents/coordinatorAgent.js`): Orchestrates the entire pipeline
2. **IntakeAgent** (`backend/agents/intakeAgent.js`): Analyzes job requests using Claude
3. **ScraperAgent** (`backend/agents/scraperAgent.js`): Scrapes contractor data via Bright Data
4. **IndexerAgent** (`backend/agents/indexerAgent.js`): Stores professionals in ChromaDB
5. **MatcherAgent** (`backend/agents/matcherAgent.js`): Ranks matches using vector similarity + Claude reasoning

### Data Flow

```
User submits project → IntakeAgent analyzes → ScraperAgent finds pros →
IndexerAgent stores in ChromaDB → MatcherAgent ranks →
Results returned + Real-time SSE progress updates
```

### Key Services

- `backend/services/claudeClient.js`: Claude API integration for job analysis, data normalization, and match ranking
- `backend/services/brightDataClient.js`: Web scraping for contractor data
- `backend/services/matchingService.js`: Vector search and business logic filters
- `backend/config/chromaClient.js`: ChromaDB collections management
- `backend/config/redisClient.js`: Redis pub/sub for progress events

### API Endpoints

```
POST   /api/jobs              - Create new job
GET    /api/jobs/:id          - Get job status
GET    /api/jobs/:id/events   - SSE stream for progress
GET    /api/jobs/:id/results  - Get match results
GET    /api/pros              - List professionals
GET    /api/pros/:id          - Get professional details
```

### Frontend Structure

```
frontend/Landing Page AI/
  src/
    app/
      page.tsx              - Landing page (Figma design)
      jobs/[jobId]/         - Job results with real-time progress
      layout.tsx            - Root layout
    components/
      Hero.tsx              - Hero with animations
      HowItWorks.tsx        - Process explanation
      AIShowcase.tsx        - Technology showcase
      FeaturedTrades.tsx    - Trade categories
      IntakeForm.tsx        - Project submission form
      PostProjectModal.tsx  - Quick project modal
      ProgressTrac
[truncated — 2563 more characters]
```

### docker-compose.yml

```yaml
services:
  redis:
    image: redis:7-alpine
    container_name: renova-redis
    restart: unless-stopped
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    command: redis-server --appendonly yes
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 5
      start_period: 5s
    networks:
      - renova-network

  chromadb:
    image: chromadb/chroma:latest
    container_name: renova-chromadb
    restart: unless-stopped
    ports:
      - "8000:8000"
    volumes:
      - chroma_data:/chroma/chroma
    environment:
      - IS_PERSISTENT=TRUE
      - ANONYMIZED_TELEMETRY=FALSE
      - CHROMA_SERVER_CORS_ALLOW_ORIGINS=["*"]
    networks:
      - renova-network

  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    container_name: renova-backend
    restart: unless-stopped
    ports:
      - "3001:3001"
    environment:
      - NODE_ENV=development
      - REDIS_URL=redis://redis:6379/0
      - CHROMA_HOST=chromadb
      - CHROMA_PORT=8000
      - PORT=3001
    env_file:
      - .env
    volumes:
      - ./backend:/app
      - /app/node_modules
      - chroma_data:/app/chroma_data
    depends_on:
      redis:
        condition: service_healthy
      chromadb:
        condition: service_started
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3001/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    networks:
      - renova-network
    command: npm run dev

  frontend:
    build:
      context: ./frontend/Landing Page AI
      dockerfile: Dockerfile
    container_name: renova-frontend
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=development
      - NEXT_PUBLIC_API_URL=http://localhost:3001
    volumes:
      - ./frontend/Landing Page AI:/app
      - /app/node_modules
      - /app/.next
    depends_on:
      backend:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s
    networks:
      - renova-network
    command: npm run dev

volumes:
  redis_data:
    driver: local
  chroma_data:
    driver: local

networks:
  renova-network:
    driver: bridge

```

### agents_python/requirements.txt

```
# Fetch.ai uAgents SDK
uagents>=0.12.0

# Anthropic Claude API
anthropic>=0.17.0

# HTTP requests
requests>=2.31.0

# Async support
aiohttp>=3.9.0

# Flask API bridge
flask>=3.0.0
flask-cors>=4.0.0

# ChromaDB client (optional, for vector search)
chromadb>=0.4.0

# Redis client (for progress updates)
redis>=5.0.0

# Environment variables
python-dotenv>=1.0.0

```

### backend/Dockerfile

```
FROM node:20-alpine

# Install curl for healthchecks
RUN apk add --no-cache curl

WORKDIR /app

# Copy package files first for better caching
COPY package*.json ./

# Install dependencies
RUN npm install && npm cache clean --force

# Copy application code
COPY . .

# Create chroma_data directory
RUN mkdir -p chroma_data

EXPOSE 3001

# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
  CMD curl -f http://localhost:3001/health || exit 1

CMD ["npm", "run", "dev"]

```

### backend/package.json

```
{
  "name": "renova-backend",
  "version": "1.0.0",
  "description": "ReNOVA 2025 - AI-powered contractor matching backend",
  "main": "server.js",
  "type": "module",
  "scripts": {
    "start": "node server.js",
    "dev": "nodemon server.js",
    "seed": "node scripts/seedPros.js",
    "demo": "node scripts/demoE2E.js",
    "test": "echo \"No tests yet\" && exit 0"
  },
  "keywords": [
    "ai",
    "contractors",
    "matching",
    "fetch.ai",
    "anthropic"
  ],
  "author": "ReNOVA Team",
  "license": "MIT",
  "dependencies": {
    "@anthropic-ai/sdk": "^0.32.1",
    "axios": "^1.7.9",
    "chromadb": "^1.9.2",
    "chromadb-default-embed": "^2.14.0",
    "cors": "^2.8.5",
    "dotenv": "^16.4.7",
    "express": "^4.21.2",
    "ioredis": "^5.4.2",
    "nanoid": "^5.0.9",
    "pino": "^9.5.0",
    "pino-pretty": "^13.0.0",
    "zod": "^3.24.1"
  },
  "devDependencies": {
    "nodemon": "^3.1.9"
  }
}

```

### frontend/Landing Page AI/Dockerfile

```
FROM node:20-alpine

# Install curl for healthchecks
RUN apk add --no-cache curl

WORKDIR /app

# Copy package files first for better caching
COPY package*.json ./

# Install dependencies
RUN npm install && npm cache clean --force

# Copy application code
COPY . .

EXPOSE 3000

# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
  CMD curl -f http://localhost:3000 || exit 1

CMD ["npm", "run", "dev"]

```

### frontend/Landing Page AI/package.json

```
{
  "name": "renova-frontend",
  "version": "1.0.0",
  "description": "ReNOVA 2025 - AI-powered contractor matching frontend",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "next": "^14.2.21",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "axios": "^1.7.9",
    "framer-motion": "^11.11.17",
    "lucide-react": "^0.460.0",
    "class-variance-authority": "^0.7.1",
    "clsx": "^2.1.1",
    "tailwind-merge": "^2.5.5",
    "@radix-ui/react-dialog": "^1.1.2",
    "@radix-ui/react-label": "^2.1.1",
    "@radix-ui/react-slot": "^1.1.1",
    "tailwindcss-animate": "^1.0.7"
  },
  "devDependencies": {
    "@types/node": "^22",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "typescript": "^5",
    "eslint": "^8",
    "eslint-config-next": "14.2.21",
    "tailwindcss": "^3.4.1",
    "autoprefixer": "^10.4.20",
    "postcss": "^8.4.47"
  }
}

```

### Landing Page AI 2/App.tsx

```typescript
import { useState } from "react";
import { Hero } from "./components/Hero";
import { HowItWorks } from "./components/HowItWorks";
import { AIShowcase } from "./components/AIShowcase";
import { FeaturedTrades } from "./components/FeaturedTrades";
import { IntakeForm } from "./components/IntakeForm";
import { CTASection } from "./components/CTASection";
import { Footer } from "./components/Footer";
import { PostProjectModal } from "./components/PostProjectModal";

export default function App() {
  const [isModalOpen, setIsModalOpen] = useState(false);

  const scrollToIntakeForm = () => {
    const element = document.getElementById("intake-form");
    if (element) {
      element.scrollIntoView({ behavior: "smooth", block: "start" });
    }
  };

  const openPostProjectModal = () => {
    setIsModalOpen(true);
  };

  return (
    <div className="min-h-screen">
      <Hero 
        onFindProfessional={scrollToIntakeForm}
        onPostProject={openPostProjectModal}
      />
      <HowItWorks onStartNow={scrollToIntakeForm} />
      <AIShowcase />
      <FeaturedTrades />
      <IntakeForm />
      <CTASection onPostProject={openPostProjectModal} />
      <Footer />
      
      <PostProjectModal 
        open={isModalOpen}
        onOpenChange={setIsModalOpen}
      />
    </div>
  );
}

```

### backend/server.js

```javascript
import express from 'express';
import cors from 'cors';
import config from './config/env.js';
import { initChromaDB } from './config/chromaClient.js';
import { initRedis, closeRedis } from './config/redisClient.js';
import logger from './utils/logger.js';

// Routes
import jobsRouter from './routes/jobs.js';
import prosRouter from './routes/pros.js';

const app = express();

// Middleware
app.use(cors({
  origin: typeof config.CORS_ORIGINS === 'string'
    ? config.CORS_ORIGINS.split(',').map(o => o.trim())
    : config.CORS_ORIGINS,
  credentials: true,
}));

app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true }));
app.use(express.static('public'));

// Request logging
app.use((req, res, next) => {
  logger.info({ method: req.method, path: req.path }, 'Incoming request');
  next();
});

// Health check
app.get('/health', (req, res) => {
  res.json({
    status: 'ok',
    timestamp: new Date().toISOString(),
    environment: config.NODE_ENV,
  });
});

// API Routes
app.use('/api/jobs', jobsRouter);
app.use('/api/pros', prosRouter);

// 404 handler
app.use((req, res) => {
  res.status(404).json({ error: 'Not found' });
});

// Error handler
app.use((err, req, res, next) => {
  logger.error({ error: err }, 'Unhandled error');
  res.status(500).json({
    error: 'Internal server error',
    message: config.isDevelopment ? err.message : undefined,
  });
});

/**
 * Initialize services and start server
 */
async function start() {
  try {
    logger.info('Starting ReNOVA backend...');

    // Initialize ChromaDB
    await initChromaDB();
    logger.info('ChromaDB initialized');

    // Initialize Redis
    initRedis();
    logger.info('Redis initialized');

    // Start server
    app.listen(config.PORT, () => {
      logger.info(
        {
          port: config.PORT,
          environment: config.NODE_ENV,
        },
        'Server listening'
      );
      console.log(`\n✅ ReNOVA backend running on http://localhost:${config.PORT}`);
      console.log(`📚 API endpoints:`);
      console.log(`   POST   /api/jobs`);
      console.log(`   GET    /api/jobs/:id`);
      console.log(`   GET    /api/jobs/:id/events (SSE)`);
      console.log(`   GET    /api/jobs/:id/results`);
      console.log(`   GET    /api/pros`);
      console.log(`   GET    /api/pros/:id\n`);
    });
  } catch (error) {
    logger.error({ error }, 'Failed to start server');
    process.exit(1);
  }
}

/**
 * Graceful shutdown
 */
async function shutdown() {
  logger.info('Shutting down...');
  await closeRedis();
  process.exit(0);
}

process.on('SIGTERM', shutdown);
process.on('SIGINT', shutdown);

// Start the server
start();

```

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