Skip to content

About

A full-stack CRM for restaurant lead generation. It scrapes Google Business Profiles with Playwright and Selenium, enriches and dedupes the results, and tracks every lead through a sales pipeline with analytics, tagging, and automation. FastAPI plus Next.js, Postgres with JSONB storage, SQLAlchemy, and JWT auth.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Restaurant Lead Management System 🍽️

Version 2.0 - Now with 3-5x Performance Improvements!

A production-ready, full-stack application for managing restaurant leads generated from Google Business Profile scraping. Track leads through your sales pipeline with advanced CRM features, analytics, and intelligent automation.

Python FastAPI Next.js License


πŸš€ What's New in v2.0

Performance Optimizations (3-5x Faster!)

  • ⚑ Concurrent Scraping: 3x faster with parallel browser workers
  • πŸ—„οΈ Optimized Queries: 100x faster with 18 new database indexes
  • πŸ“¦ Smart Caching: React Query + config caching for instant responses
  • πŸ”„ Checkpoint/Resume: Never lose scraping progress on failures
  • 🎯 JSONB Storage: 30-50% faster JSON operations in PostgreSQL

See Full Optimization Details | Developer Guide


✨ Features

🎯 Lead Management

  • Complete Sales Pipeline: Track leads from discovery β†’ qualification β†’ conversion
  • Contact History: Record all interactions (calls, emails, meetings)
  • Smart Assignment: Assign leads to team members with priority levels
  • Tagging System: Organize with custom tags and categories
  • Notes & Comments: Collaborative notes on each lead

πŸ“Š Data Collection & Enrichment

  • Automated Scraping: Extract business data from Google Maps/Business
    • Restaurant name, category, rating, reviews
    • Contact info (phone, email, website)
    • Business hours, address, price level
  • Bulk Import: Import from JSON/CSV files
  • Custom Fields: Add custom data fields for your workflow
  • Data Validation: Automatic cleanup and validation

πŸ“ˆ Analytics & Insights

  • Real-time Dashboard: Visual overview of metrics and KPIs
  • Conversion Tracking: Monitor lead progression through your funnel
  • Team Performance: Track individual and team metrics
  • Market Analysis: Analyze categories, ratings, and geographic trends
  • Export Reports: Generate reports in JSON, CSV, Excel

πŸ” Security & Authentication

  • JWT Authentication: Secure token-based auth
  • Role-Based Access: Admin and user roles with permissions
  • Password Hashing: bcrypt + PBKDF2-SHA256
  • Session Management: Secure session handling

🎨 Modern User Experience

  • Responsive Design: Works on desktop, tablet, and mobile
  • Real-time Updates: Instant feedback on changes
  • Dark Mode Ready: Built with Tailwind CSS
  • Fast & Smooth: React Query caching for instant page loads

πŸ—οΈ Technical Architecture

Backend Stack

Frontend Stack

Infrastructure

  • Docker Compose: Local PostgreSQL setup
  • Connection Pooling: Optimized for 50+ concurrent connections
  • Structured Logging: JSON logs for easy parsing
  • Health Checks: Built-in monitoring endpoints

πŸš€ Quick Start

Prerequisites

  • Python 3.8+ (Python 3.10+ recommended)
  • Node.js 16+ (for frontend)
  • PostgreSQL 13+ (recommended) or Docker
  • Git

1. Clone Repository

git clone https://github.com/yourusername/RestroScraper-PY.git
cd RestroScraper-PY

2. Backend Setup

# Run automated setup
chmod +x setup.sh
./setup.sh

# Or manual setup:
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
pip install -r requirements.txt
playwright install chromium

3. Database Setup

Option A: Docker (Recommended)

docker-compose up -d

Option B: Manual PostgreSQL

# Create database
createdb restaurant_leads

# Or use the script
chmod +x setup_postgres.sh
./setup_postgres.sh

Option C: SQLite (Development)

# No setup needed, auto-creates database
export FORCE_DATABASE=sqlite

4. Environment Configuration

# Copy example env file
cp .env.production .env

# Edit configuration (set DATABASE_URL, SECRET_KEY)
nano .env  # or vim, code, etc.

# Generate secure SECRET_KEY
openssl rand -hex 32

5. Initialize Database

source venv/bin/activate
python init_system.py

6. Start Backend

uvicorn api:app --reload --host 0.0.0.0 --port 8000

7. Frontend Setup (Separate Terminal)

cd frontend-dev
npm install
npm run dev  # Starts on port 3000

8. Access Application

9. First-Time Setup

  1. Visit http://localhost:3000/setup
  2. Create admin user (or use defaults)
  3. Login at http://localhost:3000/login
  4. Start scraping at http://localhost:3000/scraping

πŸ“– Usage Examples

Scraping Restaurants

# Via API
curl -X POST http://localhost:8000/scrape \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "location": "New York, NY",
    "search_term": "Italian restaurants",
    "max_results": 50,
    "headless": true,
    "delay": 2.0
  }'

# Via CLI
python main.py --location "New York" --search-term "restaurants" --max-results 50

Managing Leads

# Update lead status
curl -X PUT http://localhost:8000/businesses/123 \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "lead_status": "contacted",
    "priority": "high",
    "next_contact_date": "2026-01-10"
  }'

# Add note
curl -X POST http://localhost:8000/businesses/123/notes \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"content": "Called owner, interested in demo"}'

Frontend Usage

// In your React components
import { useBusinesses, useUpdateBusiness } from '@/hooks/use-business';

function BusinessList() {
  const { data, isLoading } = useBusinesses({
    lead_status: 'new',
    priority: 'high'
  });

  const { mutate: updateBusiness } = useUpdateBusiness();

  const handleContact = (id) => {
    updateBusiness({
      id,
      data: { lead_status: 'contacted' }
    });
  };

  // Component implementation...
}

πŸ”§ Configuration

Environment Variables (.env)

Database

DATABASE_URL=postgresql://user:password@localhost:5432/restaurant_leads
FORCE_DATABASE=local  # local|supabase|sqlite

Authentication

SECRET_KEY=your-secret-key-here  # Generate with: openssl rand -hex 32
ACCESS_TOKEN_EXPIRE_MINUTES=1440  # 24 hours

Scraper Settings

SCRAPER_MAX_RESULTS=50
SCRAPER_MAX_CONCURRENT=3          # Concurrent scrapers (1-5)
SCRAPER_DELAY=2.0                  # Delay between requests (seconds)
SCRAPER_HEADLESS=true
SCRAPER_TIMEOUT=45000             # Page load timeout (ms)
SCRAPER_MAX_RETRIES=3

Application

DEBUG=false
CORS_ORIGINS=*                     # Comma-separated URLs

See Full Configuration Guide


πŸ“‚ Project Structure

RestroScraper-PY/
β”œβ”€β”€ api.py                     # FastAPI application (USE THIS)
β”œβ”€β”€ app.py                     # Flask application (legacy)
β”œβ”€β”€ main.py                    # CLI scraper
β”œβ”€β”€ requirements.txt           # Python dependencies
β”œβ”€β”€ init_system.py             # Database initialization
β”‚
β”œβ”€β”€ db/                        # Database layer
β”‚   β”œβ”€β”€ database.py           # Connection management (optimized pooling)
β”‚   └── models.py             # ORM models (8 tables, JSONB support)
β”‚
β”œβ”€β”€ services/                  # Business logic
β”‚   β”œβ”€β”€ auth.py               # JWT authentication
β”‚   β”œβ”€β”€ scraper_service.py    # Scraping jobs (checkpoint/resume)
β”‚   └── analytics_service.py  # Analytics calculations
β”‚
β”œβ”€β”€ src/                       # Core scraper
β”‚   β”œβ”€β”€ scraper/
β”‚   β”‚   └── google_scraper.py # Playwright scraper (concurrent)
β”‚   β”œβ”€β”€ models/
β”‚   β”‚   └── business.py       # Business data model
β”‚   β”œβ”€β”€ data/
β”‚   β”‚   └── data_processor.py # Data export (JSON/CSV)
β”‚   └── utils/
β”‚       β”œβ”€β”€ config.py         # Configuration (cached)
β”‚       β”œβ”€β”€ logger.py         # Logging
β”‚       β”œβ”€β”€ structured_logger.py  # NEW: JSON logging
β”‚       └── retry.py          # Retry decorators
β”‚
β”œβ”€β”€ frontend-dev/              # Next.js frontend
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ app/              # Next.js app routes
β”‚   β”‚   β”œβ”€β”€ components/       # React components
β”‚   β”‚   β”œβ”€β”€ hooks/            # React Query hooks (NEW)
β”‚   β”‚   β”œβ”€β”€ lib/
β”‚   β”‚   β”‚   └── api.ts        # NEW: API client
β”‚   β”‚   └── types/            # TypeScript definitions
β”‚   β”œβ”€β”€ package.json
β”‚   └── next.config.js
β”‚
β”œβ”€β”€ static/                    # Legacy static frontend
β”œβ”€β”€ config/                    # YAML config files
β”œβ”€β”€ data/                      # SQLite database (dev)
β”œβ”€β”€ uploads/                   # File uploads
β”œβ”€β”€ logs/                      # Application logs
β”‚
β”œβ”€β”€ README.md                  # This file
β”œβ”€β”€ DEV_README.md             # Developer documentation
β”œβ”€β”€ OPTIMIZATION_SUMMARY.md   # Performance optimizations
β”œβ”€β”€ docker-compose.yml        # PostgreSQL container
└── .env.production           # Example environment config

πŸ“Š Performance Benchmarks

Operation Before v2.0 After v2.0 Improvement
Scrape 50 businesses 8-10 min 2-3 min 3x faster
/businesses API (20 items) 500ms 50ms 10x faster
Filtered database queries 2-5s 20-50ms 100x faster
Config loading 50ms <1ms 50x faster
Frontend page load 2-3s 200-500ms 5x faster

See Full Performance Analysis


πŸ—„οΈ Database Schema

Core Tables

  • users: Team members and authentication
  • businesses: Restaurant leads (30+ fields)
  • scraping_sessions: Track scraping jobs
  • notes: Business notes and comments
  • contact_attempts: Contact history
  • tags: Business categorization
  • business_tags: Many-to-many relationship

Lead Pipeline (11 States)

NEW β†’ CONTACTED β†’ RESPONDED β†’ QUALIFIED β†’
PROPOSAL_SENT β†’ NEGOTIATING β†’ WON β†’ LOST β†’
NOT_INTERESTED β†’ FOLLOW_UP β†’ ON_HOLD

Priority Levels

LOW, MEDIUM, HIGH, URGENT

See Full Schema Documentation


πŸ”Œ API Endpoints

Authentication

  • POST /token - Login (get JWT)
  • POST /setup/admin - Create admin (first-time)
  • GET /setup/status - Check setup status

Businesses

  • GET /businesses - List with filters
  • GET /businesses/{id} - Get details
  • PUT /businesses/{id} - Update business
  • POST /businesses/{id}/notes - Add note

Scraping

  • POST /scrape - Start scraping job
  • GET /scrape/sessions - List sessions
  • GET /scrape/sessions/{id} - Session details

Analytics

  • GET /analytics/overview - Dashboard metrics
  • GET /public/analytics - Public analytics

See Full API Documentation


πŸ§ͺ Testing

Run Backend Tests

source venv/bin/activate
pytest tests/

Run Frontend Tests

cd frontend-dev
npm test

Manual Testing

# Health check
curl http://localhost:8000/health

# Test scraping (requires auth)
curl -X POST http://localhost:8000/scrape \
  -H "Authorization: Bearer TOKEN" \
  -d '{"location":"NYC","search_term":"pizza"}'

🚒 Deployment

Production Checklist

  • Use PostgreSQL (not SQLite)
  • Generate secure SECRET_KEY
  • Change default admin credentials
  • Set CORS_ORIGINS to your domain
  • Enable HTTPS (reverse proxy)
  • Set up database backups
  • Configure monitoring (logs, health checks)
  • Use environment variables for secrets
  • Set DEBUG=false
  • Apply database migrations (python init_system.py)

Deployment Options

Docker:

# Build and run
docker build -t restroscraper .
docker run -p 8000:8000 restroscraper

Production Server:

# Use production ASGI server
uvicorn api:app --host 0.0.0.0 --port 8000 --workers 4

Reverse Proxy (Nginx):

server {
    listen 80;
    server_name yourdomain.com;

    location / {
        proxy_pass http://localhost:3000;  # Frontend
    }

    location /api {
        proxy_pass http://localhost:8000;  # Backend
    }
}

πŸ› Troubleshooting

Common Issues

"Database connection failed"

# Check PostgreSQL is running
docker ps | grep postgres

# Test connection
psql -U postgres -h localhost -d restaurant_leads

# Or force SQLite
export FORCE_DATABASE=sqlite

"Scraping job stuck"

# Check background processes
ps aux | grep playwright

# Kill zombie browsers
pkill -9 chromium

# Enable visible browser for debugging
export SCRAPER_HEADLESS=false

"Frontend can't connect to API"

# Check CORS settings in api.py
# Verify API is running
curl http://localhost:8000/health

# Check API URL in frontend
# Edit: frontend-dev/src/lib/api.ts

See Full Troubleshooting Guide


🀝 Contributing

We welcome contributions! Please follow these guidelines:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Code Style

  • Python: Follow PEP 8, use black formatter
  • TypeScript: Follow project's ESLint config
  • Commits: Use conventional commits (feat:, fix:, docs:)

πŸ“ License

This project is licensed under the MIT License - see the LICENSE file for details.


πŸ™ Acknowledgments

  • FastAPI - Modern Python web framework
  • Playwright - Reliable browser automation
  • Next.js - React framework for production
  • TanStack Query - Powerful data synchronization
  • Tailwind CSS - Utility-first CSS framework

πŸ“ž Support


πŸ—ΊοΈ Roadmap

v2.1 (Planned)

  • Rate limiting for API
  • IP rotation for scraping
  • Webhook notifications
  • Excel export format
  • Email templates for outreach

v3.0 (Future)

  • Celery/RQ for background jobs
  • Redis caching layer
  • Read replicas for analytics
  • Multi-tenant support
  • Mobile app

πŸ“ˆ Stats

  • Codebase: ~7,200 lines of Python + frontend
  • Database Models: 8 tables with relationships
  • API Endpoints: 20+ routes
  • Performance: 3-5x faster than v1.0
  • Scraperaccuracy: 90%+ data extraction success

Made with ❀️ by developers, for developers

Version: 2.0.0 Last Updated: 2026-01-03 Status: βœ… Production Ready

About

A full-stack CRM for restaurant lead generation. It scrapes Google Business Profiles with Playwright and Selenium, enriches and dedupes the results, and tracks every lead through a sales pipeline with analytics, tagging, and automation. FastAPI plus Next.js, Postgres with JSONB storage, SQLAlchemy, and JWT auth.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages