# Project export: Aperta

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: TreeHacks 2026
- Tagline: Aperta’s signature Agent-Echo networks opportunities. During hackathons and at networking occasions: conferences, fairs and events; across all industries - unlimited.
- Devpost: https://devpost.com/software/aperta-az8gup
- GitHub: https://github.com/ApurvGude2000/Aperta
- Demo: https://frontend-pink-chi-42.vercel.app/dashboard
- Video: https://www.youtube.com/embed/1lnWxnxR04g?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 4 GitHub contributor(s) — Claude Haiku 4.5 (32 commits), harshim1 (30 commits), jjcader (19 commits), apurvgude2000 (9 commits)

## Devpost submission (written by the team)

No Devpost description available.

## README (from the GitHub repository)

# Aperta - AI-Powered Networking Intelligence Platform

Aperta is an advanced AI-powered networking assistant that helps professionals extract actionable insights from conversations, manage relationships intelligently, and optimize their networking strategy using multi-agent orchestration.

## Overview

Aperta uses a sophisticated multi-agent architecture powered by Claude (Anthropic) to analyze conversations, extract entities, protect privacy, and provide strategic networking advice. The system intelligently routes queries to specialized agents and orchestrates their collaboration for comprehensive analysis.

## Architecture

### Multi-Agent System

Aperta employs six specialized AI agents, each focused on a specific aspect of networking intelligence:

1. **Perception Agent** - Extracts entities (people, organizations, locations, dates) and recognizes intents from conversations
2. **Privacy Guardian Agent** - Detects and redacts PII (Personally Identifiable Information) to ensure data privacy
3. **Context Understanding Agent** - Analyzes conversational context, relationships, and emotional tone
4. **Strategic Networking Agent** - Provides actionable networking strategies and relationship insights
5. **Follow-Up Agent** - Generates intelligent follow-up suggestions and action items
6. **Intelligent Router** - Routes queries to the most appropriate agent(s) based on intent analysis

### Orchestrator

The **Agent Orchestrator** coordinates multi-agent workflows, managing:
- Sequential agent execution with dependency management
- Parallel agent execution for independent tasks
- Context sharing between agents
- Result aggregation and synthesis

### Backend Stack

- **Framework**: FastAPI (Python 3.11+)
- **AI/LLM**: Anthropic Claude (claude-opus-4-6)
- **Database**: SQLite with SQLAlchemy (async)
- **Vector Store**: ChromaDB for RAG (Retrieval-Augmented Generation)
- **Logging**: Structured logging with structlog

### Frontend Stack

- **Framework**: React 18 with TypeScript
- **Build Tool**: Vite
- **Styling**: Tailwind CSS
- **Routing**: React Router v6
- **HTTP Client**: Axios

## Project Structure

```
Aperta/
├── README.md                          # This file
├── .gitignore                         # Git ignore rules
│
├── backend/                           # Python FastAPI backend
│   ├── .env.example                   # Environment variables template
│   ├── requirements.txt               # Python dependencies
│   ├── main.py                        # FastAPI application entry point
│   ├── config.py                      # Application configuration
│   │
│   ├── agents/                        # AI Agent implementations
│   │   ├── __init__.py
│   │   ├── base.py                    # Base agent class
│   │   ├── perception.py              # Entity extraction & intent recognition
│   │   ├── privacy_guardian.py        # PII detection & redaction
│   │   ├── context_understanding.py   # Context & relationship analysis
│   │   ├── strategic_networking.py    # Networking strategy advice
│   │   ├── follow_up.py               # Follow-up suggestions
│   │   ├── orchestrator.py            # Multi-agent orchestration
│   │   └── intelligent_router.py      # Query routing logic
│   │
│   ├── tools/                         # Agent tools & utilities
│   │   ├── __init__.py
│   │   ├── entity_extractor.py        # Named entity recognition
│   │   ├── intent_recognizer.py       # Intent classification
│   │   ├── pii_detector.py            # PII detection
│   │   └── redactor.py                # Text redaction
│   │
│   ├── services/                      # Business logic services
│   │   ├── __init__.py
│   │   └── rag_context.py             # RAG context management
│   │
│   ├── utils/                         # Utility modules
│   │   ├── __init__.py
│   │   ├── logger.py                  # Structured logging
│   │   └── console_logger.py          # Console output formatting
│   │
│   ├── db/                            # Database layer
│   │   ├── __init__.py
│   │   ├── database.py                # Database connection
│   │   ├── models.py                  # SQLAlchemy models
│   │   └── session.py                 # Session management
│   │
│   └── api/                           # API routes
│       ├── __init__.py
│       └── routes/
│           ├── __init__.py
│           ├── qa.py                  # Q&A endpoints
│           └── conversations.py       # Conversation CRUD
│
├── frontend/                          # React TypeScript frontend
│   ├── package.json                   # NPM dependencies
│   ├── vite.config.ts                 # Vite configuration
│   ├── tsconfig.json                  # TypeScript configuration
│   ├── index.html                     # HTML entry point
│   │
│   └── src/
│       ├── main.tsx                   # React entry point
│       ├── App.tsx                    # Main app component
│       │
│       ├── pages/                     # Page components
│       │   ├── AskQuestions.tsx       # Q&A interface
│       │   ├── ConversationList.tsx   # List all conversations
│       │   ├── ConversationDetail.tsx # View conversation details
│       │   └── ConversationForm.tsx   # Create/edit conversation
│       │
│       ├── components/                # Reusable components
│       │   ├── ConversationCard.tsx   # Conversation preview card
│       │   └── ExportDialog.tsx       # Export functionality
│       │
│       ├── api/                       # API client
│       │   └── client.ts              # Axios HTTP client
│       │
│       └── types/                     # TypeScript types
│           └── index.ts               # Type definitions
│
└── sample_transcripts/                # Sample data & prompts
    └── custom_prompt.txt              # Custom system prompts
```

## Setup Instructions

### Prerequisites

- Python 3.11 or higher
- Node.js 18+ and npm
- Anthropic API key (get from https://console.anthropic.com/)

### Backend Setup

1. **Navigate to backend directory**
   ```bash
   cd backend
   ```

2. **Create virtual environment**
   ```bash
   python -m venv venv
   source venv/bin/activate  # On Windows: venv\Scripts\activate
   ```

3. **Install dependencies**
   ```bash
   pip install -r requirements.txt
   ```

4. **Configure environment variables**
   ```bash
   cp .env.example .env
   # Edit .env and add your ANTHROPIC_API_KEY
   ```

5. **Initialize database**
   ```bash
   # Database will be created automatically on first run
   # For migrations (if using Alembic):
   alembic upgrade head
   ```

6. **Run the backend server**
   ```bash
   python main.py
   # Or with uvicorn directly:
   uvicorn main:app --reload --host 0.0.0.0 --port 8000
   ```

   Backend will be available at: `http://localhost:8000`
   API Documentation: `http://localhost:8000/docs`

### Frontend Setup

1. **Navigate to frontend directory**
   ```bash
   cd frontend
   ```

2. **Install dependencies**
   ```bash
   npm install
   ```

3. **Run the development server**
   ```bash
   npm run dev
   ```

   Frontend will be available at: `http://localhost:5173`

4. **Build for production**
   ```bash
   npm run build
   ```

## API Documentation

### Base URL
```
http://localhost:8000
```

### Endpoints

#### 1. Root Information
```http
GET /
```
Returns API information and available endpoints.

#### 2. Health Check
```http
GET /health
```
Returns application health status.

#### 3. Ask Question (Q&A)
```http
POST /qa/ask
Content-Type: application/json

{
  "question": "What networking strategies were discussed?",
  "conversation_id": 123,
  "use_rag": true
}
```

Routes the question to appropriate agent(s) and returns analysis.

**Response:**
```json
{
  "answer": "Based on the conversation...",
  "routing_decision": {
    "selected_agents": ["PerceptionAgent", "StrategicNetworkingAgent"],
    "execution_mode": "sequential",
    "reasoning": "..."
  },
  "conversation_id": 123,
  "timestamp": "2024-02-14T16:00:00Z"
}
```

#### 4. Create Conversati

[README truncated for size]

## Detected evidence (automated analysis)

Indexed codebase: 124 recognized source files, 800 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
- Python (language) — detected in the code
- React (technology) — detected in the code
- Swift (language) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code
- JavaScript (language) — claimed on Devpost, not found in the code
- Node.js (technology) — claimed on Devpost, not found in the code
- Vercel (technology) — claimed on Devpost, not found in the code
- AI coding agent: Claude Code — evidence: commit authorship or trailers

## Codebase structure (from repository index)

### Files (120 of 161)

```
.gitignore
ApertaMobile/Aperta.xcodeproj/project.pbxproj
ApertaMobile/Aperta.xcodeproj/project.xcworkspace/contents.xcworkspacedata
ApertaMobile/Aperta.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
ApertaMobile/Aperta.xcodeproj/project.xcworkspace/xcuserdata/jedrzejcader.xcuserdatad/UserInterfaceState.xcuserstate
ApertaMobile/Aperta.xcodeproj/xcuserdata/jedrzejcader.xcuserdatad/xcschemes/xcschememanagement.plist
ApertaMobile/Aperta/Agents/Agent.swift
ApertaMobile/Aperta/Agents/LLM_SETUP.md
ApertaMobile/Aperta/Agents/LLMModelManager.swift
ApertaMobile/Aperta/Agents/PIIDetectionTools.swift
ApertaMobile/Aperta/Agents/PIIGuardianAgent.swift
ApertaMobile/Aperta/Agents/PIIGuardianIntegration.swift
ApertaMobile/Aperta/Agents/PIIGuardianTests.swift
ApertaMobile/Aperta/Agents/QUICKSTART.md
ApertaMobile/Aperta/Agents/README.md
ApertaMobile/Aperta/ApertaApp.swift
ApertaMobile/Aperta/Assets.xcassets/AccentColor.colorset/Contents.json
ApertaMobile/Aperta/Assets.xcassets/aperta-logo.imageset/Contents.json
ApertaMobile/Aperta/Assets.xcassets/AppIcon.appiconset/Contents.json
ApertaMobile/Aperta/Assets.xcassets/Contents.json
ApertaMobile/Aperta/AudioLevelMeter.swift
ApertaMobile/Aperta/AudioUploadService.swift
ApertaMobile/Aperta/AudioUploadView.swift
ApertaMobile/Aperta/ContentView.swift
ApertaMobile/Aperta/EventCreationView.swift
ApertaMobile/Aperta/EventModels.swift
ApertaMobile/Aperta/EventStorageManager.swift
ApertaMobile/Aperta/FileTranscriber.swift
ApertaMobile/Aperta/LoadingView.swift
ApertaMobile/Aperta/PastEventsView.swift
ApertaMobile/Aperta/PulsingRecordIndicator.swift
ApertaMobile/Aperta/RecordingTimerView.swift
ApertaMobile/Aperta/RecordingView.swift
ApertaMobile/Aperta/SettingsView.swift
ApertaMobile/Aperta/SimpleWhisperRecorder.swift
ApertaMobile/Aperta/WaveformView.swift
ApertaMobile/Aperta/WhisperManager.swift
backend/__init__.py
backend/.dockerignore
backend/.gitignore
backend/.vercelignore
backend/agents/__init__.py
backend/agents/AGENT_SYSTEM_GUIDE.md
backend/agents/base.py
backend/agents/context_understanding.py
backend/agents/conversation_retrieval.py
backend/agents/cross_pollination.py
backend/agents/follow_up.py
backend/agents/insight.py
backend/agents/intelligent_router.py
backend/agents/orchestrator.py
backend/agents/perception.py
backend/agents/privacy_guardian.py
backend/agents/qa_orchestrator.py
backend/agents/query_router.py
backend/agents/recommendation.py
backend/agents/response_composer.py
backend/agents/strategic_networking.py
backend/api/__init__.py
backend/api/index.py
backend/api/routes/__init__.py
backend/api/routes/audio.py
backend/api/routes/auth.py
backend/api/routes/conversations.py
backend/api/routes/dashboard.py
backend/api/routes/qa.py
backend/api/routes/search.py
backend/auth/__init__.py
backend/auth/dependencies.py
backend/auth/google_oauth.py
backend/auth/utils.py
backend/config.py
backend/db/__init__.py
backend/db/models_auth.py
backend/db/models.py
backend/db/session.py
backend/deploy.sh
backend/deploy/deploy.sh
backend/deploy/docker-compose.prod.yml
backend/docker-compose.dev.yml
backend/Dockerfile
backend/examples/audio_processing_example.py
backend/main.py
backend/Procfile
backend/requirements.txt
backend/run_elasticsearch.sh
backend/scripts/migrate_to_gcp.py
backend/scripts/update_db_from_gcs.py
backend/SEARCH_SETUP_GUIDE.md
backend/services/__init__.py
backend/services/audio_processor.py
backend/services/conversation_storage.py
backend/services/elasticsearch_service.py
backend/services/embeddings.py
backend/services/rag_context.py
backend/services/storage.py
backend/services/transcript_storage.py
backend/test_full_flow.py
backend/test_gcs_upload.py
backend/tools/__init__.py
backend/tools/entity_extractor.py
backend/tools/intent_recognizer.py
backend/tools/pii_detector.py
backend/tools/redactor.py
backend/uploads/conv_4bd68384cd1e/2026/02/15/conv_4bd68384cd1e_transcript.txt
backend/uploads/conv_4bd68384cd1e/2026/02/15/test_audio_metadata.json
backend/uploads/conv_525931263216/2026/02/15/conv_525931263216_transcript.txt
backend/uploads/conv_525931263216/2026/02/15/test_audio_metadata.json
backend/uploads/conv_8de1493978af/2026/02/15/conv_8de1493978af_transcript.txt
backend/uploads/conv_8de1493978af/2026/02/15/test_audio_metadata.json
backend/uploads/conv_9c4d34eb7f4a/2026/02/15/conv_9c4d34eb7f4a_transcript.txt
backend/uploads/conv_9c4d34eb7f4a/2026/02/15/test_audio_metadata.json
backend/uploads/conv_a02fbac80991/2026/02/15/conv_a02fbac80991_transcript.txt
backend/uploads/conv_a02fbac80991/2026/02/15/test_audio_metadata.json
backend/uploads/conv_d85a0811a02e/2026/02/15/conv_d85a0811a02e_transcript.txt
backend/uploads/conv_d85a0811a02e/2026/02/15/test_audio_metadata.json
backend/uploads/conv_ded364dc409f/2026/02/15/conv_ded364dc409f_transcript.txt
backend/uploads/conv_ded364dc409f/2026/02/15/test_audio_metadata.json
backend/utils/__init__.py
backend/utils/cloud_sql.py
[41 more files omitted for size]
```

### Dependencies

- backend/requirements.txt: aiosqlite@==0.20.0, alembic@==1.13.1, anthropic@==0.40.0, bcrypt@==4.1.2, colorama@==0.4.6, elasticsearch[async]@==8.12.0, email-validator@==2.1.0, fastapi@==0.115.0, google-auth@>=2.25.0, google-cloud-storage@==2.14.0, httpx@==0.27.0, passlib[bcrypt]@==1.7.4, pydantic@==2.10.5, pydantic-settings@==2.7.0, PyJWT@==2.11.0, python-dateutil@==2.8.2, python-dotenv@==1.0.1, python-jose[cryptography]@==3.3.0, python-multipart@==0.0.20, sqlalchemy@==2.0.36, structlog@==24.4.0, uvicorn[standard]@==0.32.1
- frontend/package.json: @tailwindcss/postcss@^4.1.18, @types/react@^18.2.48, @types/react-dom@^18.2.18, @vitejs/plugin-react@^4.2.1, autoprefixer@^10.4.24, axios@^1.6.5, postcss@^8.5.6, react@^18.2.0, react-dom@^18.2.0, react-router-dom@^6.21.0, tailwindcss@^4.1.18, typescript@^5.3.3, vite@^5.0.11

### Recent commits (newest first)

- Deployment
- abcd
- Updating agents
- Merge branch 'iosfinal'
- ios final
- Webapp improvements
- Cleaning up
- fix: Use Mac IP instead of localhost for device testing
- fix: Add error handling for PII redaction
- PII before upload, gcp fix
- feat: Remove audio file saving and add transcript-only endpoint
- feat: Implement auto-upload for mobile recordings
- Merge branches
- feat: Replace S3 with GCP storage and implement transcript appending
- Merge pull request #5 from ApurvGude2000/audio-database-transcribe
- Webapp stuff
- can now upload audio as files
- fix: Calculate actual audio duration for uploaded files
- feat: Add audio file upload with automatic transcription
- feat: Implement PII Guardian for automatic privacy protection

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

### backend/SEARCH_SETUP_GUIDE.md

```markdown
## 🔍 Semantic Search Setup Guide

Complete guide for setting up Elasticsearch + JINA AI embeddings for semantic conversation search.

---

## 📋 Prerequisites

1. **Elasticsearch 8.x** installed and running
2. **JINA AI API key** for embeddings
3. **Python 3.12** with backend dependencies

---

## 🚀 Quick Start

### Step 1: Install Elasticsearch

#### macOS (Homebrew):
```bash
brew tap elastic/tap
brew install elastic/tap/elasticsearch-full

# Start Elasticsearch
brew services start elastic/tap/elasticsearch-full
```

#### Docker:
```bash
docker run -d \
  --name elasticsearch \
  -p 9200:9200 \
  -e "discovery.type=single-node" \
  -e "xpack.security.enabled=false" \
  docker.elastic.co/elasticsearch/elasticsearch:8.12.0
```

#### Linux (apt):
```bash
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
echo "deb https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
sudo apt-get update && sudo apt-get install elasticsearch
sudo systemctl start elasticsearch
```

### Step 2: Get JINA AI API Key

1. Go to https://jina.ai/embeddings/
2. Sign up or log in
3. Create a new API key
4. Copy the key (starts with `jina_...`)

### Step 3: Configure Environment

Update `backend/.env`:

```bash
# JINA AI Configuration
JINA_API_KEY=jina_your_actual_key_here

# Elasticsearch Configuration
ELASTICSEARCH_HOST=http://localhost:9200
ELASTICSEARCH_USER=elastic
ELASTICSEARCH_PASSWORD=  # Leave empty for local dev
```

### Step 4: Install Python Dependencies

```bash
cd backend
source venv/bin/activate
pip install elasticsearch[async]==8.12.0
```

### Step 5: Initialize Search Index

```bash
# Start the backend
python main.py

# In another terminal, initialize the index
curl -X POST http://localhost:8000/api/search/initialize
```

Or via Python:
```python
import httpx
import asyncio

async def init():
    async with httpx.AsyncClient() as client:
        response = await client.post("http://localhost:8000/api/search/initialize")
        print(response.json())

asyncio.run(init())
```

---

## 🧪 Testing

### Test 1: Health Check

```bash
curl http://localhost:8000/api/search/health
```

Expected output:
```json
{
  "elasticsearch": {
    "status": "connected",
    "cluster_name": "elasticsearch",
    "version": "8.12.0"
  },
  "embedding_service": {
    "status": "configured",
    "model": "jina-embeddings-v2-base-en",
    "dimensions": 768
  },
  "overall_status": "healthy"
}
```

### Test 2: Index a Conversation

```bash
curl -X POST http://localhost:8000/api/search/index \
  -H "Content-Type: application/json" \
  -d '{
    "conversation_id": "test_conv_1",
    "user_id": "user_123",
    "transcript": "I met Alice Chen who is a Partner at Acme Ventures. We discussed AI safety in healthcare and she is interested in funding early-stage healthcare AI startups. She asked me to send over our pitch deck.",
    "metadata": {
      "title": "Meeting with Alice Chen",
      "people": [
[truncated — 5553 more characters]
```

### backend/agents/AGENT_SYSTEM_GUIDE.md

```markdown
# Aperta Agent System Guide

## 🎯 System Overview

The Aperta agent system follows a three-phase architecture:

### 1. **Data Capture Phase**
- **Privacy Guardian Agent**: Redacts PII before database storage
  - Runs on every transcript chunk (every 3 seconds)
  - Output: Plain text with [PHONE], [EMAIL], etc. redactions

### 2. **Post-Event Processing**
- **Context Understanding Agent**: Extracts structured entities and insights
  - Runs once per conversation after event ends
  - Output: JSON with people, topics, action items, sentiment, etc.

- **Follow-Up Agent**: Generates personalized messages
  - Runs once per person met
  - Output: 3 message variants (Professional, Friendly, Value-First)

- **Cross-Pollination Agent**: Finds introduction opportunities
  - Runs once per event (if 3+ people)
  - Uses Perplexity API for enrichment
  - Output: JSON with introduction suggestions

### 3. **Question-Answering Phase**
- **Query Router**: Decides which agents to call
- **Conversation Retrieval**: Searches conversations
- **Insight Agent**: Analyzes patterns and trends
- **Recommendation Agent**: Suggests next actions
- **Response Composer**: Synthesizes final answer

## 📋 Agent Specifications

### Privacy Guardian Agent
```python
from agents import PrivacyGuardianAgent, redact_pii

agent = PrivacyGuardianAgent()
redacted_text = await agent.redact_transcript("Hi, my email is alice@example.com")
# Output: "Hi, my email is [EMAIL]"

# Or use convenience function
redacted = await redact_pii("Call me at 415-555-1234")
# Output: "Call me at [PHONE]"
```

### Context Understanding Agent
```python
from agents import ContextUnderstandingAgent

agent = ContextUnderstandingAgent()
result = await agent.analyze_conversation({
    "conversation_id": "conv_123",
    "full_transcript": "Speaker 1: Hi I'm Alice...",
    "speaker_labels": ["Speaker 1", "Speaker 2"],
    "duration_minutes": 8,
    "user_goals": ["Find investors"],
    "event_context": {
        "event_name": "TechCrunch Disrupt",
        "event_date": "2026-03-15"
    }
})

# result contains: people, topics, action_items, sentiment, goal_alignment
```

### Follow-Up Agent
```python
from agents import FollowUpAgent

agent = FollowUpAgent()
messages = await agent.generate_messages(
    person_data={
        "name": "Alice Chen",
        "role": "Partner",
        "company": "Acme Ventures"
    },
    context_data={
        "conversation_summary": "Alice is healthcare AI investor...",
        "topics_discussed": ["AI safety", "Series A"],
        "action_items": [{"action": "Send pitch deck", "priority": "high"}],
        "key_interests": ["Healthcare AI"]
    },
    user_context={
        "name": "John Doe",
        "company": "HealthAI Inc",
        "role": "Founder",
        "event": "TechCrunch Disrupt"
    }
)

# messages["variants"] contains 3 message variants
```

### Cross-Pollination Agent
```python
from agents import CrossPollinationAgent

agent = CrossPollinationAgent()
connections = await 
[truncated — 5531 more characters]
```

### frontend/package.json

```
{
  "name": "networking-app-web",
  "private": true,
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "axios": "^1.6.5",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.21.0"
  },
  "devDependencies": {
    "@tailwindcss/postcss": "^4.1.18",
    "@types/react": "^18.2.48",
    "@types/react-dom": "^18.2.18",
    "@vitejs/plugin-react": "^4.2.1",
    "autoprefixer": "^10.4.24",
    "postcss": "^8.5.6",
    "tailwindcss": "^4.1.18",
    "typescript": "^5.3.3",
    "vite": "^5.0.11"
  }
}

```

### backend/requirements.txt

```
# ABOUTME: Python dependencies for Aperta backend (webapp only)
# ABOUTME: FastAPI-based AI networking assistant with multi-agent orchestration
# NOTE: Audio processing (whisper, pyannote, torch) is handled by iOS app, not here

# Core Framework
fastapi==0.115.0
uvicorn[standard]==0.32.1
pydantic==2.10.5
pydantic-settings==2.7.0
python-multipart==0.0.20
python-dotenv==1.0.1

# AI & LLM
anthropic==0.40.0

# Database
sqlalchemy==2.0.36
aiosqlite==0.20.0  # For SQLite (local development)
alembic==1.13.1

# Google Cloud
google-cloud-storage==2.14.0
google-auth>=2.25.0

# Logging & Monitoring
structlog==24.4.0
colorama==0.4.6

# Utilities
httpx==0.27.0
python-jose[cryptography]==3.3.0
passlib[bcrypt]==1.7.4
PyJWT==2.11.0
bcrypt==4.1.2
python-dateutil==2.8.2
email-validator==2.1.0

# Search & Embeddings
elasticsearch[async]==8.12.0

```

### backend/Dockerfile

```
# Multi-stage build for Aperta backend
FROM python:3.12-slim as builder

WORKDIR /app

# Install system dependencies
RUN apt-get update && apt-get install -y \
    gcc \
    g++ \
    && rm -rf /var/lib/apt/lists/*

# Copy requirements and install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Final stage
FROM python:3.12-slim

WORKDIR /app

# Install runtime dependencies
RUN apt-get update && apt-get install -y \
    curl \
    && rm -rf /var/lib/apt/lists/*

# Copy installed packages from builder
COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
COPY --from=builder /usr/local/bin /usr/local/bin

# Copy application code
COPY . .

# Create data directory for SQLite
RUN mkdir -p /app/data

# Expose port
EXPOSE 8000

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

# Run the application (use PORT env var for Cloud Run)
CMD ["sh", "-c", "uvicorn main:app --host 0.0.0.0 --port ${PORT:-8080}"]

```

### backend/main.py

```python
# ABOUTME: FastAPI backend for NetworkingApp web interface with full agent integration.
# ABOUTME: Provides API endpoints for Q&A, conversation management, and AI analysis.

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from contextlib import asynccontextmanager

from config import settings
from db.session import init_db, close_db
from utils.logger import setup_logger
import utils.console_logger as console_logger

# Import agents
from agents import (
    qa_orchestrator,
    orchestrator,
    ContextUnderstandingAgent,
    PrivacyGuardianAgent,
    FollowUpAgent,
    CrossPollinationAgent
)

# Import services
from services.rag_context import RAGContextManager

# Import routers
from api.routes import qa, conversations, search, auth, dashboard

logger = setup_logger(__name__)


# Lifespan context manager for startup/shutdown
@asynccontextmanager
async def lifespan(app: FastAPI):
    """
    Lifespan context manager for FastAPI application.
    Handles startup and shutdown events.
    """
    # Startup
    logger.info("Starting NetworkAI backend...")
    console_logger.log_section("NetworkAI Backend Startup")

    # Initialize database (with graceful fallback)
    try:
        await init_db()
        logger.info("Database initialized")
        console_logger.log_info("Database initialized", "Startup")
    except Exception as e:
        logger.warning(f"Database initialization failed: {e}")
        logger.warning("Server will run without database (audio processing still works)")
        console_logger.log_info(f"Database unavailable - running in offline mode", "Startup")
    
    # Initialize RAG context manager
    try:
        rag_manager = RAGContextManager()
        logger.info("RAG context manager initialized")
        console_logger.log_info("RAG context manager initialized", "Startup")
    except Exception as e:
        logger.warning(f"RAG context manager failed: {e}")
        rag_manager = None

    # Initialize agents (with graceful fallback)
    try:
        context_agent = ContextUnderstandingAgent()
        privacy_agent = PrivacyGuardianAgent()
        followup_agent = FollowUpAgent()
        crosspoll_agent = CrossPollinationAgent()

        logger.info("All agents initialized")
        console_logger.log_info("All 4 core agents initialized", "Startup")

        # Register agents with orchestrator (using global instance)
        orchestrator.register_agent(context_agent)
        orchestrator.register_agent(privacy_agent)
        orchestrator.register_agent(followup_agent)
        orchestrator.register_agent(crosspoll_agent)
        logger.info("Orchestrator initialized with agents")
        console_logger.log_info("Orchestrator initialized with agents", "Startup")
    except Exception as e:
        logger.warning(f"Agent initialization failed: {e}")

    # Q&A Orchestrator is already initialized globally
    try:
        logger.info("Q&A orchestrator ready")
        console_logger.log_info("Q&A orchestrator ready", "Startup")
    except Exception as e:
        logger.warning(f"Q&A orchestrator setup failed: {e}")

    # Set components in route modules
    try:
        if orchestrator and rag_manager:
            qa.set_qa_components(qa_orchestrator, orchestrator, rag_manager)
        if orchestrator:
            conversations.set_conversation_orchestrator(orchestrator)
        logger.info("Route components configured")
        console_logger.log_info("Route components configured", "Startup")
    except Exception as e:
        logger.warning(f"Route configuration failed: {e}")

    # Sync data to GCS if enabled
    if settings.use_gcs_for_chroma and settings.gcp_bucket_name:
        try:
            from utils.gcs_storage import get_gcs_storage
            import os
            gcs = get_gcs_storage()
            if gcs:
                # Auto-restore database from GCS if missing locally
                db_file = "aperta.db"
                if not os.path.exists(db_file):
                    logger.info("Database not found locally, restoring from GCS...")
                    console_logger.log_info("Restoring database from GCS backup", "Startup")
                    try:
                        from google.cloud import storage
                        bucket = gcs.bucket
                        blob = bucket.blob(f'backups/{db_file}')
                        if blob.exists():
                            blob.download_to_filename(db_file)
                            logger.info("✓ Database restored from GCS")
                            console_logger.log_info("✓ Database restored from GCS", "Startup")
                        else:
                            logger.warning("No database backup found in GCS, will create new DB")
                    except Exception as e:
                        logger.error(f"Failed to restore database from GCS: {e}")
                # Sync ChromaDB
                if os.path.exists(settings.chroma_persist_dir):
                    logger.info("Syncing ChromaDB to GCS...")
                    console_logger.log_info("Syncing ChromaDB to GCS bucket", "Startup")
                    success = gcs.sync_to_gcs(settings.chroma_persist_dir, "chroma_db/")
                    if success:
                        logger.info("✓ ChromaDB synced to GCS")
                        console_logger.log_info("✓ ChromaDB synced to GCS", "Startup")

                # Backup SQLite database
                db_file = "aperta.db"
                if os.path.exists(db_file):
                    logger.info("Backing up database to GCS...")
                    console_logger.log_info("Backing up database to GCS", "Startup")
                    success = gcs.backup_database_file(db_file, f"backups/{db_file}")
                    if success:
                        logger.info("✓ Database backed up to GCS")
                        console_logger.log_info("✓ Database backed up to GCS", "Startup")
        except Exception as e:
            logger.
[truncated — 1730 more characters]
```

### frontend/src/main.tsx

```typescript
import React from 'react';
import ReactDOM from 'react-dom/client';
import { App } from './App';
import './index.css';

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

```

### backend/api/index.py

```python
"""
Vercel serverless entry point for Aperta backend.
"""
import sys
from pathlib import Path

# Add parent directory to path
backend_dir = Path(__file__).parent.parent
sys.path.insert(0, str(backend_dir))

from main import app

# Export app for Vercel
handler = app

```

### frontend/src/App.tsx

```typescript
// ABOUTME: Main app component with routing
// ABOUTME: Sets up React Router for navigation between pages

import { BrowserRouter, Routes, Route, Link, useLocation } from 'react-router-dom';
import { Landing } from './pages/Landing';
import { Login } from './pages/Login';
import { Register } from './pages/Register';
import { Dashboard } from './pages/Dashboard';
import { Events } from './pages/Events';
import { EventDetailNew } from './pages/EventDetailNew';
import { KnowledgeGraph } from './pages/KnowledgeGraph';
import { ConversationList } from './pages/ConversationList';
import { ConversationDetail } from './pages/ConversationDetail';
import { ConversationForm } from './pages/ConversationForm';
import { AskQuestions } from './pages/AskQuestions';
import { Settings } from './pages/Settings';

function Navigation() {
  const location = useLocation();

  const isActive = (path: string) => {
    return location.pathname === path || location.pathname.startsWith(path);
  };

  return (
    <nav className="bg-white shadow-sm border-b border-gray-200">
      <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
        <div className="flex justify-between h-16">
          <div className="flex space-x-8">
            <Link
              to="/"
              className="inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium"
              style={{
                borderBottomColor: isActive('/') && !location.pathname.includes('conversation') ? '#3b82f6' : 'transparent',
                color: isActive('/') && !location.pathname.includes('conversation') ? '#3b82f6' : '#6b7280',
              }}
            >
              Conversations
            </Link>
            <Link
              to="/ask"
              className="inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium"
              style={{
                borderBottomColor: isActive('/ask') ? '#3b82f6' : 'transparent',
                color: isActive('/ask') ? '#3b82f6' : '#6b7280',
              }}
            >
              Ask Questions
            </Link>
          </div>
          <div className="flex items-center">
            <Link
              to="/conversations/new"
              className="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700"
            >
              New Conversation
            </Link>
          </div>
        </div>
      </div>
    </nav>
  );
}

export function App() {
  return (
    <BrowserRouter>
      <Routes>
        {/* New UI/UX Prototypes */}
        <Route path="/" element={<Landing />} />
        <Route path="/login" element={<Login />} />
        <Route path="/register" element={<Register />} />
        <Route path="/dashboard" element={<Dashboard />} />
        <Route path="/events" element={<Events />} />
        <Route path="/events/:id" element={<EventDetailNew />} />
        <Route path="/knowledge-graph" element={<KnowledgeGraph />} />
        <Route path="/settings" element={<Settings />} />

        {/* Existing Features */}
        <Route path="/old" element={<ConversationList />} />
        <Route path="/conversations/new" element={<ConversationForm />} />
        <Route path="/conversations/:id" element={<ConversationDetail />} />
        <Route path="/conversations/:id/edit" element={<ConversationForm />} />
        <Route path="/ask" element={<AskQuestions />} />
      </Routes>
    </BrowserRouter>
  );
}

```

### frontend/src/types/index.ts

```typescript
// ABOUTME: TypeScript type definitions for the Aperta web app
// ABOUTME: Matches the Pydantic models from the FastAPI backend

// Conversation types
export interface ConversationCreate {
  title?: string;
  transcript: string;
  status?: string;
  recording_url?: string;
  location?: string;
  event_name?: string;
  started_at?: string;
  ended_at?: string;
}

export interface ConversationUpdate {
  title?: string;
  transcript?: string;
  status?: string;
  recording_url?: string;
  location?: string;
  event_name?: string;
  ended_at?: string;
}

export interface ParticipantResponse {
  id: string;
  name?: string;
  email?: string;
  company?: string;
  title?: string;
  linkedin_url?: string;
  phone?: string;
  consent_status: string;
  lead_priority?: string;
  lead_score: number;
}

export interface EntityResponse {
  id: string;
  entity_type: string;
  entity_value: string;
  confidence: number;
  context?: string;
}

export interface ActionItemResponse {
  id: string;
  description: string;
  responsible_party?: string;
  due_date?: string;
  completed: boolean;
}

export interface ConversationResponse {
  id: string;
  user_id: string;
  title?: string;
  status: string;
  transcript?: string;
  recording_url?: string;
  location?: string;
  event_name?: string;
  started_at: string;
  ended_at?: string;
  created_at: string;
  updated_at: string;
  participants: ParticipantResponse[];
  entities: EntityResponse[];
  action_items: ActionItemResponse[];
}

export interface ConversationListItem {
  id: string;
  title?: string;
  status: string;
  location?: string;
  event_name?: string;
  started_at: string;
  created_at: string;
  participant_count: number;
}

export interface AnalysisResult {
  participants: ParticipantResponse[];
  entities: EntityResponse[];
  action_items: ActionItemResponse[];
  context_summary?: string;
  sentiment?: string;
  privacy_warnings: string[];
}

// Q&A types
export interface AskQuestionRequest {
  question: string;
  conversation_id?: string;
  use_rag?: boolean;
}

export interface AskQuestionResponse {
  session_id: string;
  interaction_id: string;
  question: string;
  final_answer: string;
  routed_agents: string[];
  execution_time: number;
  timestamp: string;
  agent_trace?: {
    routing?: {
      agents_needed?: string[];
      execution_mode?: string;
      question_type?: string;
      reasoning?: string;
    };
    agent_results?: Record<string, any>;
  };
}

export interface QASessionSummary {
  id: string;
  conversation_id?: string;
  created_at: string;
  interaction_count: number;
}

export interface QAInteractionDetail {
  id: string;
  question: string;
  final_answer?: string;
  routed_agents: string[];
  responses: Record<string, any>;
  execution_time?: number;
  timestamp: string;
}

export interface QASessionDetail {
  id: string;
  conversation_id?: string;
  created_at: string;
  interactions: QAInteractionDetail[];
}

// Export format
export type ExportFormat = 'json' | 'txt' | 'markdown';

```

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