# Project export: Echofix

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: CruzHacks 2026
- Tagline: EchoFix turns real user complaints from Reddit/Twitter into actionable GitHub-ready fixes—summaries, root causes, and patch plans—so startups improve faster.
- Devpost: https://devpost.com/software/echofix
- GitHub: https://github.com/Nayab-23/EchoFix.git
- Video: https://www.youtube.com/embed/h0KzkrMA5nI?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 0 GitHub contributor(s) — 

## Devpost submission (written by the team)

No Devpost description available.

## README (from the GitHub repository)

# EchoFix 🎯

**Reddit-First Feedback-to-Shipping Pipeline for CruzHacks 2026**

EchoFix transforms Reddit feedback into actionable engineering artifacts and automated workflows. Built to showcase the power of **n8n** (orchestration) and **Gemini** (reasoning) with a local insight engine.

## 🚀 What It Does

1. **Collect**: Ingests Reddit threads via Reddit JSON (no OAuth required!) or PRAW
2. **Understand**: Groups feedback into themes with a local insight engine
3. **Reason**: Leverages Gemini to transform insights into structured issue specs with acceptance criteria
4. **Automate**: Orchestrates the entire pipeline with n8n workflows
5. **Ship**: Creates GitHub issues (and optionally PRs) with approval gates

## ✨ Hackathon Mode (No Reddit OAuth!)

**Perfect for hackathons with tight timelines:**
- **JSON-based ingestion**: Paste any Reddit thread URL, no API approval needed
- **Bring-Your-Own-Thread**: Demo with real Reddit content instantly
- **Works offline**: Full demo mode with fixtures if network is down
- **Zero OAuth friction**: Get started in < 5 minutes

## 🏆 CruzHacks Track Alignment

### n8n Track
- **Workflow Orchestration**: End-to-end automation from ingestion to GitHub
- **Scheduled Runs**: Automatic Reddit monitoring on cron
- **Approval Gates**: Human-in-the-loop approval via webhooks
- **GitHub Automation**: Issue/PR creation with labels and assignments

### Gemini Track
- **Structured Outputs**: Strict JSON schemas for issue specs and patch plans
- **Function Calling**: Tool-ready actions (create_issue, request_more_info)
- **Multimodal**: Processes images/screenshots from Reddit for bug reports
- **Reasoning**: Transforms unstructured feedback into engineering artifacts

## 📋 Architecture

```
┌─────────────┐
│   Reddit    │  JSON ingestion (no OAuth!) or PRAW
│   Threads   │  Paste URLs → fetch via JSON
└──────┬──────┘
       │
       ▼
┌─────────────┐
│  Insight    │  Local theme grouping
│  Engine     │
└──────┬──────┘
       │
       ▼
┌─────────────┐
│   Gemini    │  Insight → IssueSpec (structured JSON)
│  (Reasoning)│  Multimodal, function calling, guardrails
└──────┬──────┘
       │
       ▼
┌─────────────┐
│     n8n     │  Orchestrates workflows, approval gates
│(Automation) │  Triggers GitHub actions
└──────┬──────┘
       │
       ▼
┌─────────────┐
│   GitHub    │  Issues created with evidence links
│             │  Optional: PRs with patch plans
└─────────────┘
       │
       ▼
┌─────────────┐
│  Dashboard  │  Review insights, approve actions
│  (Next.js)  │  Reddit evidence, Gemini outputs
└─────────────┘
```

## 🎬 Demo Mode

EchoFix supports **full demo mode** for environments without API keys:
- Uses pre-saved Reddit fixtures (JSON)
- Gemini responses from fixtures
- Full pipeline still runs end-to-end

Set `DEMO_MODE=true` in your `.env` file.

## 🛠️ Quick Start

### Prerequisites
- Python 3.11+
- Node.js 18+
- Docker (for n8n)
- Supabase account (or local instance)

### 1. Backend Setup

```bash
cd backend

# Create virtual environment
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install dependencies
pip install -r requirements.txt

# Setup environment
cp .env.example .env
# Edit .env with your credentials (or use DEMO_MODE=true)

# Run migrations
python migrate.py

# Start backend
python app.py
# Server runs on http://localhost:8000
```

### 2. Frontend Setup

```bash
cd webapp

# Install dependencies
npm install  # or pnpm install

# Setup environment
cp .env.example .env.local
# Edit with your Supabase credentials

# Start dev server
npm run dev
# Dashboard runs on http://localhost:3000
```

### 3. n8n Setup

```bash
cd workflows

# Start n8n with Docker
docker-compose up -d

# Access n8n at http://localhost:5678
# Import workflows from workflows/*.json
```

### 4. Run Demo

```bash
# Option 1: Use seed threads (configured in .env)
# Set REDDIT_SEED_THREAD_URLS in backend/.env, then:
curl -X POST http://localhost:8000/api/reddit/ingest-seed

# Option 2: Ingest a specific Reddit thread (paste any URL!)
curl -X POST http://localhost:8000/api/reddit/ingest-url \
  -H "Content-Type: application/json" \
  -d '{"url": "https://reddit.com/r/webdev/comments/abc123/my_post"}'

# Visit http://localhost:3000 to see results
```

## 📂 Project Structure

```
EchoFix/
├── backend/
│   ├── app.py              # Flask API server
│   ├── models.py           # Pydantic models
│   ├── db.py               # Database operations
│   ├── reddit_client.py    # Reddit PRAW (optional)
│   ├── services/
│   │   ├── reddit_rss.py   # Legacy RSS ingestion
│   │   └── insight_generator.py  # Local insight grouping
│   ├── gemini_client.py    # Gemini integration
│   ├── github_client.py    # GitHub operations
│   ├── sandbox.py          # Code sandbox (optional)
│   ├── requirements.txt
│   ├── .env.example
│   ├── fixtures/           # Demo mode data
│   │   ├── reddit_search.json
│   │   ├── reddit_rss_demo.json
│   └── supabase/
│       └── migrations/     # Database schema
├── webapp/
│   ├── app/                # Next.js app directory
│   ├── components/         # React components
│   ├── lib/                # Utilities
│   ├── package.json
│   └── .env.example
├── workflows/
│   ├── docker-compose.yml  # n8n setup
│   ├── scheduled-ingestion.json
│   ├── approval-workflow.json
│   └── README.md
├── docs/
│   ├── ARCHITECTURE.md
│   ├── API.md
│   └── DEMO.md             # Judge walkthrough
├── MIGRATION.md            # Migration notes from Vector
└── README.md               # This file
```

## 🔐 Environment Variables

### Backend (.env)
```bash
# Core
DEMO_MODE=false

# Reddit Ingestion Mode (hackathon-friendly!)
REDDIT_INGEST_MODE=json  # json (no OAuth!), praw (requires OAuth), rss_url (legacy), or fixtures
# Plan artifacts
ENABLE_PLAN_MD=true
ENABLE_PR_AUTOMATION=false
PLAN_MD_DIR=backend/artifacts/plans
PLAN_MD_PATH_TEMPLATE=docs/echofix_plans/{reddit_entry_id}.md
REDDIT_SEED_THREAD_URLS=https://reddit.com/r/webdev/comments/...,https://reddit.com/r/programming/comments/...

# Reddit JSON (no credentials needed!)
REDDIT_USER_AGENT=EchoFix/1.0 CruzHacks2026

# Score threshold gating
MIN_SCORE=2
SCORE_REFRESH_SECONDS=600

# Reddit API (OPTIONAL - only for PRAW mode)
REDDIT_CLIENT_ID=your_client_id
REDDIT_CLIENT_SECRET=your_secret

# Gemini
GEMINI_API_KEY=your_gemini_key

# GitHub
GITHUB_TOKEN=your_github_token

# Supabase
SUPABASE_URL=your_supabase_url
SUPABASE_SERVICE_ROLE_KEY=your_key
```

### Frontend (.env.local)
```bash
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
NEXT_PUBLIC_API_BASE_URL=http://localhost:8000
```

### n8n (docker-compose.yml)
```bash
N8N_ENCRYPTION_KEY=random_encryption_key
N8N_WEBHOOK_BASE_URL=http://localhost:5678
ECHOFIX_BACKEND_URL=http://host.docker.internal:8000
```

## 📊 API Endpoints

### Reddit Ingestion (JSON Mode - No OAuth!)
- `POST /api/reddit/ingest-url` - Ingest specific Reddit thread URL
- `POST /api/reddit/ingest-seed` - Ingest pre-configured seed threads
- `POST /api/reddit/ingest` - Legacy PRAW ingestion (optional)
- `POST /api/reddit/refresh-scores` - Refresh scores and mark entries READY once `MIN_SCORE` is met
- `GET /api/reddit/entries` - List collected entries
- `POST /api/pipeline/auto-process-ready` - Refresh & process READY entries, returns plan/PR links

### Insight Generation
- `POST /api/insights/generate` - Generate insights from READY entries (score threshold met)
- `GET /api/insights` - List insights

### Auto Pipeline
- `POST /api/pipeline/auto-process` - Refresh scores, generate insights, run Gemini, and create GitHub issues
- `POST /api/pipeline/auto-process-ready` - Ready-focused auto-run that reports issue/PR/plan artifacts

### Gemini Processing
- `POST /api/gemini/analyze` - Analyze insight with Gemini
- `POST /api/gemini/issue-spec` - Generate issue specification
- `POST /api/gemini/patch-plan` - Generate patch plan (optional)

### GitHub Actions
- `POST /api/github/create-iss

[README truncated for size]

## Detected evidence (automated analysis)

Indexed codebase: 248 recognized source files, 980 KB.
- CSS (language) — detected in the code
- Flask (technology) — detected in the code
- JavaScript (language) — detected in the code
- Next.js (technology) — detected in the code
- OpenAI (technology) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code
- SQL (language) — detected in the code
- Supabase (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
- FastAPI (technology) — claimed on Devpost, not found in the code
- Google Gemini (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: config files committed to the repository; commit authorship or trailers

## Codebase structure (from repository index)

### Files (120 of 281)

```
.claude/settings.json
.gitignore
ACCESS.md
AI_FALLBACK_SUMMARY.md
ALL_COMMANDS.md
all_migrations.sql
APPLY_MIGRATION.md
backend/.dockerignore
backend/.env.example
backend/app.py
backend/apply_migration.py
backend/apply_via_update.py
backend/db.py
backend/Dockerfile
backend/fixtures/reddit_rss_demo.json
backend/fixtures/reddit_search.json
backend/gemini_client.py
backend/github_client.py
backend/migration_endpoint.py
backend/models.py
backend/README.md
backend/reddit_client.py
backend/requirements.txt
backend/run_migration.py
backend/scripts/run_one_live.py
backend/services/__init__.py
backend/services/insight_generator.py
backend/services/plan_md.py
backend/services/reddit_json_client.py
backend/services/reddit_rss.py
backend/services/score_threshold.py
backend/supabase/.gitignore
backend/supabase/config.toml
backend/supabase/migrations/00001_create_core_schema.sql
backend/supabase/migrations/00002_add_reddit_entry_status.sql
backend/supabase/migrations/00003_add_plan_and_pr_columns.sql
backend/supabase/migrations/00005_add_community_approval.sql
backend/test_rss.py
backend/tests/test_plan_md.py
backend/tests/test_threshold_processing.py
BRING_UP_DOWN.md
CHEATSHEET.txt
check_repo_config.sh
COMMANDS.txt
copy_migration_sql.sh
CREATE_EXEC_SQL_FUNCTION.sql
delete_wrong_repo.sh
DEMO_QUICKSTART.md
DEMO_READY.md
DEMO_SETUP.md
DEPENDENCY_GRAPH_GUIDE.md
DEPLOY_SUMMARY.md
deploy-frontend.sh
deploy.sh
DEPLOYMENT.md
docker-compose.yml
docs/DEMO.md
FIXED_CODE_GENERATION.md
FRONTEND_DEPLOYMENT.md
frontend/.dockerignore
frontend/.env.local
frontend/app/globals.css
frontend/app/layout.tsx
frontend/app/page.tsx
frontend/components/accordion.tsx
frontend/components/alert-dialog.tsx
frontend/components/alert.tsx
frontend/components/aspect-ratio.tsx
frontend/components/avatar.tsx
frontend/components/badge.tsx
frontend/components/button-group.tsx
frontend/components/button.tsx
frontend/components/calendar.tsx
frontend/components/card.tsx
frontend/components/carousel.tsx
frontend/components/checkbox.tsx
frontend/components/collapsible.tsx
frontend/components/context-menu.tsx
frontend/components/ControlPanel.tsx
frontend/components/DependencyGraph.tsx
frontend/components/dialog.tsx
frontend/components/dropdown-menu.tsx
frontend/components/empty.tsx
frontend/components/field.tsx
frontend/components/Header.tsx
frontend/components/hover-card.tsx
frontend/components/input-group.tsx
frontend/components/input.tsx
frontend/components/InsightsPanel.tsx
frontend/components/item.tsx
frontend/components/kbd.tsx
frontend/components/label.tsx
frontend/components/menubar.tsx
frontend/components/navigation-menu.tsx
frontend/components/pagination.tsx
frontend/components/PipelineStatus.tsx
frontend/components/popover.tsx
frontend/components/progress.tsx
frontend/components/radio-group.tsx
frontend/components/RedditEntriesTable.tsx
frontend/components/scroll-area.tsx
frontend/components/select.tsx
frontend/components/separator.tsx
frontend/components/sheet.tsx
frontend/components/skeleton.tsx
frontend/components/slider.tsx
frontend/components/spinner.tsx
frontend/components/switch.tsx
frontend/components/table.tsx
frontend/components/tabs.tsx
frontend/components/textarea.tsx
frontend/components/toggle-group.tsx
frontend/components/toggle.tsx
frontend/components/tooltip.tsx
frontend/components/ui/accordion.tsx
frontend/components/ui/alert-dialog.tsx
frontend/components/ui/alert.tsx
frontend/components/ui/aspect-ratio.tsx
frontend/components/ui/avatar.tsx
frontend/components/ui/badge.tsx
[161 more files omitted for size]
```

### Dependencies

- backend/requirements.txt: flask@==3.0.0, flask-cors@==4.0.0, google-generativeai@==0.8.3, httpx@==0.27.0, openai@>=1.0.0, praw@==7.7.1, pydantic@>=2.9.0, python-dotenv@==1.0.1, requests@==2.31.0, supabase@==2.9.0
- frontend/package.json: @hookform/resolvers@^5.2.2, @radix-ui/react-accordion@^1.2.12, @radix-ui/react-alert-dialog@^1.1.15, @radix-ui/react-aspect-ratio@^1.1.8, @radix-ui/react-avatar@^1.1.11, @radix-ui/react-checkbox@^1.3.3, @radix-ui/react-collapsible@^1.1.12, @radix-ui/react-context-menu@^2.2.16, @radix-ui/react-dialog@^1.1.15, @radix-ui/react-dropdown-menu@^2.1.16, @radix-ui/react-hover-card@^1.1.15, @radix-ui/react-label@^2.1.8, @radix-ui/react-menubar@^1.1.16, @radix-ui/react-navigation-menu@^1.2.14, @radix-ui/react-popover@^1.1.15, @radix-ui/react-progress@^1.1.8, @radix-ui/react-radio-group@^1.3.8, @radix-ui/react-scroll-area@^1.2.10, @radix-ui/react-select@^2.2.6, @radix-ui/react-separator@^1.1.8, @radix-ui/react-slider@^1.3.6, @radix-ui/react-slot@^1.2.4, @radix-ui/react-switch@^1.2.6, @radix-ui/react-tabs@^1.1.13, @radix-ui/react-toast@^1.2.15, @radix-ui/react-toggle@^1.1.10, @radix-ui/react-toggle-group@^1.1.11, @radix-ui/react-tooltip@^1.2.8, @types/dagre@^0.7.52, @types/node@20.12.12, @types/react@18.3.3, @types/react-dom@18.3.0, autoprefixer@10.4.19, axios@1.7.2, class-variance-authority@^0.7.1, clsx@^2.1.1, cmdk@^1.1.1, dagre@^0.8.5, date-fns@^4.1.0, embla-carousel-react@^8.6.0, input-otp@^1.4.2, lucide-react@^0.562.0, next@14.2.3, postcss@8.4.38, react@18.3.1, react-day-picker@^9.13.0, react-dom@18.3.1, react-hook-form@^7.71.1, react-resizable-panels@^4.4.1, reactflow@^11.11.4, recharts@^3.6.0, sonner@^2.0.7, swr@2.2.5, tailwind-merge@^3.4.0, tailwindcss@3.4.3, typescript@5.4.5, vaul@^1.1.2, zod@^4.3.5
- frosted-glass-ui-crm-dashboard-ui-design/package.json: @hookform/resolvers@^3.10.0, @radix-ui/react-accordion@1.2.2, @radix-ui/react-alert-dialog@1.1.4, @radix-ui/react-aspect-ratio@1.1.1, @radix-ui/react-avatar@1.1.2, @radix-ui/react-checkbox@1.1.3, @radix-ui/react-collapsible@1.1.2, @radix-ui/react-context-menu@2.2.4, @radix-ui/react-dialog@1.1.4, @radix-ui/react-dropdown-menu@2.1.4, @radix-ui/react-hover-card@1.1.4, @radix-ui/react-label@2.1.1, @radix-ui/react-menubar@1.1.4, @radix-ui/react-navigation-menu@1.2.3, @radix-ui/react-popover@1.1.4, @radix-ui/react-progress@1.1.1, @radix-ui/react-radio-group@1.2.2, @radix-ui/react-scroll-area@1.2.2, @radix-ui/react-select@2.1.4, @radix-ui/react-separator@1.1.1, @radix-ui/react-slider@1.2.2, @radix-ui/react-slot@1.1.1, @radix-ui/react-switch@1.1.2, @radix-ui/react-tabs@1.1.2, @radix-ui/react-toast@1.2.4, @radix-ui/react-toggle@1.1.1, @radix-ui/react-toggle-group@1.1.1, @radix-ui/react-tooltip@1.1.6, @tailwindcss/postcss@^4.1.9, @types/node@^22, @types/react@^19, @types/react-dom@^19, @vercel/analytics@1.3.1, autoprefixer@^10.4.20, class-variance-authority@^0.7.1, clsx@^2.1.1, cmdk@1.0.4, date-fns@4.1.0, embla-carousel-react@8.5.1, input-otp@1.4.1, lucide-react@^0.454.0, next@15.2.6, next-themes@^0.4.6, postcss@^8.5, react@^19, react-day-picker@9.8.0, react-dom@^19, react-hook-form@^7.60.0, react-resizable-panels@^2.1.7, recharts@2.15.4, sonner@^1.7.4, tailwind-merge@^2.5.5, tailwindcss@^4.1.9, tailwindcss-animate@^1.0.7, tw-animate-css@1.3.3, typescript@^5, vaul@^1.1.2, zod@3.25.76

### Recent commits (newest first)

- Final project
- New
- Add dependency graph, AI fallback system, and real code generation
- Initial EchoFix workspace

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

### setup_supabase.md

```markdown
# Supabase Setup for EchoFix

## Step 1: Get Service Role Key

1. Go to: https://supabase.com/dashboard/project/bkjuzmdzbxffxpeluwsv/settings/api
2. Scroll to **Project API keys**
3. Copy the **`service_role` (secret)** key
4. Update `backend/.env` line 46:
   ```bash
   SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... (paste your key here)
   ```

## Step 2: Run Database Migrations

1. Go to: https://supabase.com/dashboard/project/bkjuzmdzbxffxpeluwsv/editor
2. Click **SQL Editor** (left sidebar)
3. Click **+ New query**
4. Copy and paste the contents of each migration file:

### Migration 1: Core Schema

Copy entire contents of: `backend/supabase/migrations/00001_create_core_schema.sql`
Paste into SQL Editor and click **Run**

### Migration 2: Add Status

Copy entire contents of: `backend/supabase/migrations/00002_add_reddit_entry_status.sql`
Paste into SQL Editor and click **Run**

### Migration 3: Add Plan/PR Columns

Copy entire contents of: `backend/supabase/migrations/00003_add_plan_and_pr_columns.sql`
Paste into SQL Editor and click **Run**

## Step 3: Restart Backend

```bash
./restart.sh
```

## Done!

Your backend should now connect to Supabase successfully.

Test it:
```bash
curl http://localhost:8000/health
```

Should show: `"supabase": true`

```

### SUPABASE_MIGRATIONS.md

```markdown
# 🗄️ Run Supabase Migrations (5 minutes)

## Quick Steps

### 1. Open SQL Editor

Go to: https://supabase.com/dashboard/project/bkjuzmdzbxffxpeluwsv/sql/new

### 2. Run Migration 1 - Core Schema

1. Click **"+ New query"**
2. Copy the **entire contents** of this file:
   ```
   backend/supabase/migrations/00001_create_core_schema.sql
   ```
3. Paste into the SQL editor
4. Click **"Run"** (or press Cmd/Ctrl + Enter)
5. ✅ Should show "Success. No rows returned"

### 3. Run Migration 2 - Add Status Column

1. Click **"+ New query"** again
2. Copy contents of:
   ```
   backend/supabase/migrations/00002_add_reddit_entry_status.sql
   ```
3. Paste and click **"Run"**
4. ✅ Success

### 4. Run Migration 3 - Add Plan/PR Columns

1. Click **"+ New query"** again
2. Copy contents of:
   ```
   backend/supabase/migrations/00003_add_plan_and_pr_columns.sql
   ```
3. Paste and click **"Run"**
4. ✅ Success

### 5. Verify Tables Created

In the left sidebar, click **"Table Editor"**

You should see these tables:
- ✅ repo_configs
- ✅ reddit_entries
- ✅ insights

## After Migrations Complete

Restart the backend to connect to Supabase:

```bash
./restart.sh
```

Test the connection:

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

Should show:
```json
{
  "status": "healthy",
  "services": {
    "supabase": true
  }
}
```

## Done! 🎉

Your database is now set up and EchoFix can store Reddit entries!

Try ingesting data:

```bash
curl -X POST http://localhost:8000/api/reddit/ingest-seed
```

Check the dashboard:

```bash
open http://localhost:3000
```

```

### docker-compose.yml

```yaml
services:
  # EchoFix Backend API
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    container_name: echofix-backend
    ports:
      - "8000:8000"
    # Environment is provided by backend/.env (mount or env_file below)
    env_file:
      - ./backend/.env
    volumes:
      # Mount fixtures for demo mode
      - ./backend/fixtures:/app/fixtures:ro
    healthcheck:
      test: ["CMD", "python", "-c", "import requests; requests.get('http://localhost:8000/health', timeout=5)"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    restart: unless-stopped
    networks:
      - echofix-network

  # EchoFix Frontend Dashboard
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    container_name: echofix-frontend
    ports:
      - "3000:3000"
    environment:
      - NEXT_PUBLIC_API_URL=http://localhost:8000
    depends_on:
      backend:
        condition: service_healthy
    restart: unless-stopped
    networks:
      - echofix-network

  # n8n Workflow Automation (from existing docker-compose.yml)
  n8n:
    image: n8nio/n8n:latest
    container_name: echofix-n8n
    ports:
      - "5678:5678"
    environment:
      # Use owner-based auth (modern n8n approach)
      - N8N_HOST=localhost
      - N8N_PORT=5678
      - N8N_PROTOCOL=http
      - WEBHOOK_URL=http://localhost:5678
      - GENERIC_TIMEZONE=America/Los_Angeles
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY:-409f6ce4a758126067eb74c4bf926fe06d0da080feb4aaff06a83703bcf1e648}
      # Backend API endpoint for n8n workflows
      - ECHOFIX_API_URL=http://backend:8000
      # Disable instance customization survey
      - N8N_PERSONALIZATION_ENABLED=false
      # Keep user sessions longer
      - N8N_USER_MANAGEMENT_JWT_DURATION_HOURS=168
    volumes:
      - n8n_data:/home/node/.n8n
      - ./workflows:/workflows:ro
    depends_on:
      backend:
        condition: service_healthy
    restart: unless-stopped
    networks:
      - echofix-network

networks:
  echofix-network:
    driver: bridge

volumes:
  n8n_data:
    driver: local

```

### backend/requirements.txt

```
# Web Framework
flask==3.0.0
flask-cors==4.0.0

# Database
supabase==2.9.0
httpx==0.27.0

# Reddit API (optional for post-hackathon PRAW mode)
praw==7.7.1

# AI APIs
google-generativeai==0.8.3
openai>=1.0.0

# Data validation
pydantic>=2.9.0

# Environment
python-dotenv==1.0.1

# Utilities
requests==2.31.0

```

### workflows/docker-compose.yml

```yaml
services:
  n8n:
    image: n8nio/n8n:latest
    container_name: echofix-n8n
    ports:
      - "5678:5678"
    environment:
      - N8N_BASIC_AUTH_ACTIVE=false
      - N8N_HOST=localhost
      - N8N_PORT=5678
      - N8N_PROTOCOL=http
      - WEBHOOK_URL=http://localhost:5678
      - GENERIC_TIMEZONE=America/Los_Angeles
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY:-change-this-to-random-string}
    volumes:
      - n8n_data:/home/node/.n8n
      - ./workflows:/workflows:ro
    restart: unless-stopped
    networks:
      - echofix-network

networks:
  echofix-network:
    driver: bridge

volumes:
  n8n_data:
    driver: local

```

### frontend/Dockerfile

```
# Frontend Dockerfile for EchoFix Dashboard
FROM node:20-alpine AS base

# Install dependencies only when needed
FROM base AS deps
WORKDIR /app

# Copy package files
COPY package.json package-lock.json* ./
RUN npm ci

# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

# Set environment variables
ENV NEXT_TELEMETRY_DISABLED 1
ENV NODE_ENV production

# Build Next.js app
RUN npm run build

# Production image
FROM base AS runner
WORKDIR /app

ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

# Copy built files
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
COPY --from=builder --chown=nextjs:nodejs /app/public ./public

USER nextjs

EXPOSE 3000

ENV PORT 3000
ENV HOSTNAME "0.0.0.0"

CMD ["node", "server.js"]

```

### backend/Dockerfile

```
# Production-ready Dockerfile for EchoFix Backend
FROM python:3.11-slim

# Create non-root user
RUN useradd -m -u 1000 echofix && \
    mkdir -p /app && \
    chown -R echofix:echofix /app

# Set working directory
WORKDIR /app

# Install system dependencies including GitHub CLI
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
    gcc \
    curl \
    git \
    && curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
    && chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
    && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
    && apt-get update \
    && apt-get install -y gh \
    && rm -rf /var/lib/apt/lists/*

# Copy requirements first for better caching
COPY --chown=echofix:echofix requirements.txt .

# Install Python dependencies
RUN pip install --no-cache-dir -r requirements.txt && \
    pip install --no-cache-dir gunicorn==21.2.0

# Copy application code
COPY --chown=echofix:echofix . .

# Ensure fixtures directory is included
RUN test -d fixtures || mkdir -p fixtures

# Switch to non-root user
USER echofix

# Expose port
EXPOSE 8000

# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
    CMD python -c "import requests; requests.get('http://localhost:8000/health', timeout=5)" || exit 1

# Run with gunicorn (authenticate gh CLI first)
CMD sh -c 'echo "$GITHUB_TOKEN" | gh auth login --with-token 2>/dev/null || true && gunicorn --bind 0.0.0.0:8000 --workers 2 --threads 4 --timeout 120 --access-logfile - --error-logfile - app:app'

```

### frosted-glass-ui-crm-dashboard-ui-design/package.json

```
{
  "name": "my-v0-project",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "build": "next build",
    "dev": "next dev",
    "lint": "eslint .",
    "start": "next start"
  },
  "dependencies": {
    "@hookform/resolvers": "^3.10.0",
    "@radix-ui/react-accordion": "1.2.2",
    "@radix-ui/react-alert-dialog": "1.1.4",
    "@radix-ui/react-aspect-ratio": "1.1.1",
    "@radix-ui/react-avatar": "1.1.2",
    "@radix-ui/react-checkbox": "1.1.3",
    "@radix-ui/react-collapsible": "1.1.2",
    "@radix-ui/react-context-menu": "2.2.4",
    "@radix-ui/react-dialog": "1.1.4",
    "@radix-ui/react-dropdown-menu": "2.1.4",
    "@radix-ui/react-hover-card": "1.1.4",
    "@radix-ui/react-label": "2.1.1",
    "@radix-ui/react-menubar": "1.1.4",
    "@radix-ui/react-navigation-menu": "1.2.3",
    "@radix-ui/react-popover": "1.1.4",
    "@radix-ui/react-progress": "1.1.1",
    "@radix-ui/react-radio-group": "1.2.2",
    "@radix-ui/react-scroll-area": "1.2.2",
    "@radix-ui/react-select": "2.1.4",
    "@radix-ui/react-separator": "1.1.1",
    "@radix-ui/react-slider": "1.2.2",
    "@radix-ui/react-slot": "1.1.1",
    "@radix-ui/react-switch": "1.1.2",
    "@radix-ui/react-tabs": "1.1.2",
    "@radix-ui/react-toast": "1.2.4",
    "@radix-ui/react-toggle": "1.1.1",
    "@radix-ui/react-toggle-group": "1.1.1",
    "@radix-ui/react-tooltip": "1.1.6",
    "@vercel/analytics": "1.3.1",
    "autoprefixer": "^10.4.20",
    "class-variance-authority": "^0.7.1",
    "clsx": "^2.1.1",
    "cmdk": "1.0.4",
    "date-fns": "4.1.0",
    "embla-carousel-react": "8.5.1",
    "input-otp": "1.4.1",
    "lucide-react": "^0.454.0",
    "next": "15.2.6",
    "next-themes": "^0.4.6",
    "react": "^19",
    "react-day-picker": "9.8.0",
    "react-dom": "^19",
    "react-hook-form": "^7.60.0",
    "react-resizable-panels": "^2.1.7",
    "recharts": "2.15.4",
    "sonner": "^1.7.4",
    "tailwind-merge": "^2.5.5",
    "tailwindcss-animate": "^1.0.7",
    "vaul": "^1.1.2",
    "zod": "3.25.76"
  },
  "devDependencies": {
    "@tailwindcss/postcss": "^4.1.9",
    "@types/node": "^22",
    "@types/react": "^19",
    "@types/react-dom": "^19",
    "postcss": "^8.5",
    "tailwindcss": "^4.1.9",
    "tw-animate-css": "1.3.3",
    "typescript": "^5"
  }
}
```

### frontend/package.json

```
{
  "name": "echofix-dashboard",
  "version": "1.0.0",
  "description": "EchoFix - Reddit to Engineering Pipeline Dashboard",
  "scripts": {
    "dev": "next dev -p 3000",
    "build": "next build",
    "start": "next start -p 3000",
    "lint": "next lint"
  },
  "dependencies": {
    "@hookform/resolvers": "^5.2.2",
    "@radix-ui/react-accordion": "^1.2.12",
    "@radix-ui/react-alert-dialog": "^1.1.15",
    "@radix-ui/react-aspect-ratio": "^1.1.8",
    "@radix-ui/react-avatar": "^1.1.11",
    "@radix-ui/react-checkbox": "^1.3.3",
    "@radix-ui/react-collapsible": "^1.1.12",
    "@radix-ui/react-context-menu": "^2.2.16",
    "@radix-ui/react-dialog": "^1.1.15",
    "@radix-ui/react-dropdown-menu": "^2.1.16",
    "@radix-ui/react-hover-card": "^1.1.15",
    "@radix-ui/react-label": "^2.1.8",
    "@radix-ui/react-menubar": "^1.1.16",
    "@radix-ui/react-navigation-menu": "^1.2.14",
    "@radix-ui/react-popover": "^1.1.15",
    "@radix-ui/react-progress": "^1.1.8",
    "@radix-ui/react-radio-group": "^1.3.8",
    "@radix-ui/react-scroll-area": "^1.2.10",
    "@radix-ui/react-select": "^2.2.6",
    "@radix-ui/react-separator": "^1.1.8",
    "@radix-ui/react-slider": "^1.3.6",
    "@radix-ui/react-slot": "^1.2.4",
    "@radix-ui/react-switch": "^1.2.6",
    "@radix-ui/react-tabs": "^1.1.13",
    "@radix-ui/react-toast": "^1.2.15",
    "@radix-ui/react-toggle": "^1.1.10",
    "@radix-ui/react-toggle-group": "^1.1.11",
    "@radix-ui/react-tooltip": "^1.2.8",
    "axios": "1.7.2",
    "class-variance-authority": "^0.7.1",
    "clsx": "^2.1.1",
    "cmdk": "^1.1.1",
    "dagre": "^0.8.5",
    "date-fns": "^4.1.0",
    "embla-carousel-react": "^8.6.0",
    "input-otp": "^1.4.2",
    "lucide-react": "^0.562.0",
    "next": "14.2.3",
    "react": "18.3.1",
    "react-day-picker": "^9.13.0",
    "react-dom": "18.3.1",
    "react-hook-form": "^7.71.1",
    "react-resizable-panels": "^4.4.1",
    "reactflow": "^11.11.4",
    "recharts": "^3.6.0",
    "sonner": "^2.0.7",
    "swr": "2.2.5",
    "tailwind-merge": "^3.4.0",
    "vaul": "^1.1.2",
    "zod": "^4.3.5"
  },
  "devDependencies": {
    "@types/dagre": "^0.7.52",
    "@types/node": "20.12.12",
    "@types/react": "18.3.3",
    "@types/react-dom": "18.3.0",
    "autoprefixer": "10.4.19",
    "postcss": "8.4.38",
    "tailwindcss": "3.4.3",
    "typescript": "5.4.5"
  }
}

```

### frosted-glass-ui-crm-dashboard-ui-design/app/page.tsx

```typescript
import { CRMDashboard } from "@/components/crm-dashboard"

export default function Home() {
  return <CRMDashboard />
}

```

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