pounce/README.md
yves.gugger 4cb5f42d90 docs: Complete documentation overhaul for v2.0
README.md - Full rewrite:
- New feature overview (Command Center, Marketplace, Alerts)
- Updated project structure with all new files/directories
- Complete server deployment guide
- Environment variables for all features
- API endpoint documentation for new routes
- UI component reference
- Troubleshooting guide

DATABASE_MIGRATIONS.md - Expanded:
- All 6 new tables with full SQL schemas
- Indexes for performance
- Environment variables (Moz API, Stripe)
- Verification queries
- Rollback instructions
- Scheduler job reference

Tables documented:
1. domain_listings (For Sale marketplace)
2. listing_inquiries (Buyer messages)
3. listing_views (Analytics)
4. sniper_alerts (Personalized alerts)
5. sniper_alert_matches (Matched auctions)
6. domain_seo_data (SEO cache for Tycoon)
2025-12-10 17:07:23 +01:00

483 lines
14 KiB
Markdown

# pounce — Domain Intelligence Platform
A professional full-stack platform for domain hunters, investors, and portfolio managers. Features live auction aggregation, TLD price tracking, domain marketplace, and intelligent monitoring.
---
## 🚀 What's New (v2.0)
### User Command Center
A complete redesign of the authenticated user experience:
| Feature | Description |
|---------|-------------|
| **Dashboard** | Personal overview with quick stats, trending TLDs, and activity |
| **Watchlist** | Monitor domain availability with 4-layer health checks (DNS, HTTP, SSL, WHOIS) |
| **Portfolio** | Track owned domains, valuations, and manage listings |
| **Auctions** | Live aggregated auctions from GoDaddy, Sedo, NameJet, DropCatch |
| **Marketplace** | Browse "For Sale" listings from other users |
| **My Listings** | Manage your own domain listings for sale |
| **TLD Pricing** | Compare prices across 886+ TLDs with trends and alerts |
| **Sniper Alerts** | Personalized auction alerts based on custom criteria |
| **SEO Juice** | Domain authority & backlink analysis (Tycoon only) |
### Public Pages
| Page | Route | Description |
|------|-------|-------------|
| Landing | `/` | Hero, features, pricing preview |
| Auctions | `/auctions` | Public auction browser (blurred Deal Score) |
| TLD Pricing | `/tld-pricing` | TLD overview (preview for non-auth) |
| TLD Detail | `/tld-pricing/[tld]` | Registrar comparison, price chart |
| Marketplace | `/buy` | Browse domains for sale |
| Listing Detail | `/buy/[slug]` | View listing, contact seller |
### Admin Panel (`/admin`)
Dedicated admin interface with its own sidebar:
- User Management (bulk upgrade, export CSV)
- Platform Statistics
- Auction & TLD Stats
- Scheduler Monitoring
- Email Testing
- Activity Logs
### Technical Highlights
- **Performance Optimized**: All pages use `useMemo` and `useCallback` for minimal re-renders
- **Consistent UI Components**: `PremiumTable`, `StatCard`, `SearchInput`, `TabBar`, `ActionButton`
- **Responsive Design**: Mobile-first with collapsible sidebar
- **Keyboard Shortcuts**: ⌘K search, navigation shortcuts
---
## ⚠️ After Fresh Clone / Database Reset
```bash
cd backend
source venv/bin/activate
# 1. Initialize database (creates ALL tables)
python scripts/init_db.py
# 2. Scrape TLD prices (886+ TLDs from Porkbun)
python scripts/seed_tld_prices.py
# 3. Scrape auctions (or let scheduler do it hourly)
python3 -c "
import asyncio
from app.services.auction_scraper import AuctionScraperService
from app.database import AsyncSessionLocal
async def scrape():
scraper = AuctionScraperService()
async with AsyncSessionLocal() as db:
await scraper.scrape_all_platforms(db)
await scraper.close()
asyncio.run(scrape())
"
```
---
## ⚡ Quick Start (Local Development)
**Terminal 1 - Backend:**
```bash
cd backend
source venv/bin/activate
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
```
**Terminal 2 - Frontend:**
```bash
cd frontend
npm run dev
```
**Access:**
- Frontend: http://localhost:3000
- Backend: http://localhost:8000
- API Docs: http://localhost:8000/docs
---
## 📁 Updated Project Structure
```
pounce/
├── backend/
│ ├── app/
│ │ ├── api/
│ │ │ ├── auth.py # Authentication
│ │ │ ├── oauth.py # Google/GitHub OAuth
│ │ │ ├── check.py # Domain availability
│ │ │ ├── domains.py # Watchlist CRUD
│ │ │ ├── portfolio.py # Portfolio management
│ │ │ ├── tld_prices.py # TLD pricing API
│ │ │ ├── auctions.py # Live auction aggregator
│ │ │ ├── listings.py # For Sale marketplace
│ │ │ ├── sniper_alerts.py # Personalized alerts
│ │ │ ├── seo.py # SEO Juice Detector
│ │ │ ├── subscription.py # Stripe payments
│ │ │ └── admin.py # Admin endpoints
│ │ ├── models/
│ │ │ ├── user.py
│ │ │ ├── domain.py
│ │ │ ├── subscription.py
│ │ │ ├── tld_price.py
│ │ │ ├── portfolio.py
│ │ │ ├── auction.py
│ │ │ ├── listing.py # NEW: For Sale listings
│ │ │ ├── sniper_alert.py # NEW: Alert configurations
│ │ │ └── seo_data.py # NEW: SEO cache
│ │ ├── services/
│ │ │ ├── domain_checker.py
│ │ │ ├── domain_health.py # 4-layer health monitoring
│ │ │ ├── auction_scraper.py # Multi-platform scraping
│ │ │ ├── seo_analyzer.py # Moz API / estimation
│ │ │ ├── stripe_service.py
│ │ │ └── email_service.py
│ │ └── scheduler.py # APScheduler cron jobs
│ └── scripts/
│ ├── init_db.py
│ └── seed_tld_prices.py
├── frontend/
│ ├── src/
│ │ ├── app/
│ │ │ ├── page.tsx # Landing page
│ │ │ ├── auctions/ # Public auctions
│ │ │ ├── tld-pricing/ # Public TLD pricing
│ │ │ ├── buy/ # Public marketplace
│ │ │ ├── pricing/ # Subscription plans
│ │ │ ├── login/
│ │ │ ├── register/
│ │ │ ├── command/ # 🆕 User Command Center
│ │ │ │ ├── dashboard/
│ │ │ │ ├── watchlist/
│ │ │ │ ├── portfolio/
│ │ │ │ ├── auctions/
│ │ │ │ ├── marketplace/
│ │ │ │ ├── listings/
│ │ │ │ ├── alerts/
│ │ │ │ ├── pricing/
│ │ │ │ │ └── [tld]/ # TLD detail
│ │ │ │ ├── seo/
│ │ │ │ ├── settings/
│ │ │ │ └── welcome/ # Post-payment onboarding
│ │ │ └── admin/ # Admin panel
│ │ ├── components/
│ │ │ ├── Header.tsx
│ │ │ ├── Footer.tsx
│ │ │ ├── Sidebar.tsx # Command Center nav
│ │ │ ├── AdminLayout.tsx # Admin nav
│ │ │ ├── CommandCenterLayout.tsx
│ │ │ ├── PremiumTable.tsx # Reusable table + UI components
│ │ │ └── DomainChecker.tsx
│ │ └── lib/
│ │ ├── api.ts # API client
│ │ └── store.ts # Zustand state
│ └── tailwind.config.ts
├── DATABASE_MIGRATIONS.md # 🆕 Migration guide
├── DEPLOYMENT.md
└── README.md
```
---
## 🗄️ Database Tables
### Core Tables (Existing)
| Table | Description |
|-------|-------------|
| `users` | User accounts |
| `subscriptions` | Plan tiers (Scout/Trader/Tycoon) |
| `domains` | Watchlist |
| `domain_checks` | Check history |
| `tld_prices` | Price data |
| `tld_info` | TLD metadata |
| `portfolio_domains` | Owned domains |
| `domain_valuations` | Valuation history |
| `domain_auctions` | Scraped auctions |
| `price_alerts` | TLD price alerts |
### NEW Tables (v2.0)
| Table | Description |
|-------|-------------|
| `domain_listings` | For Sale marketplace listings |
| `listing_inquiries` | Buyer contact messages |
| `listing_views` | View analytics |
| `sniper_alerts` | Personalized alert configs |
| `sniper_alert_matches` | Matched auctions |
| `domain_seo_data` | SEO metrics cache |
See `DATABASE_MIGRATIONS.md` for full SQL schemas.
---
## 🔧 Server Deployment Guide
### 1. Clone & Install
```bash
git clone https://git.6bit.ch/yvg/pounce.git
cd pounce
# Backend
cd backend
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
cp env.example .env
# Edit .env with your secrets
# Frontend
cd ../frontend
npm install
echo "NEXT_PUBLIC_API_URL=https://api.pounce.ch" > .env.local
```
### 2. Environment Variables
**Backend `.env`:**
```env
# Core
SECRET_KEY=your-32-char-secret-key
DATABASE_URL=postgresql+asyncpg://user:pass@localhost/pounce
ALLOWED_ORIGINS=https://pounce.ch,https://www.pounce.ch
SITE_URL=https://pounce.ch
# SMTP (Zoho)
SMTP_HOST=smtp.zoho.eu
SMTP_PORT=465
SMTP_USER=hello@pounce.ch
SMTP_PASSWORD=your-password
SMTP_FROM_EMAIL=hello@pounce.ch
SMTP_USE_SSL=true
# Stripe
STRIPE_SECRET_KEY=sk_live_xxx
STRIPE_WEBHOOK_SECRET=whsec_xxx
STRIPE_PRICE_TRADER=price_xxx
STRIPE_PRICE_TYCOON=price_xxx
# OAuth
GOOGLE_CLIENT_ID=xxx
GOOGLE_CLIENT_SECRET=xxx
GOOGLE_REDIRECT_URI=https://api.pounce.ch/api/v1/oauth/google/callback
GITHUB_CLIENT_ID=xxx
GITHUB_CLIENT_SECRET=xxx
GITHUB_REDIRECT_URI=https://api.pounce.ch/api/v1/oauth/github/callback
# SEO (Optional - uses estimation if not set)
MOZ_ACCESS_ID=your-moz-id
MOZ_SECRET_KEY=your-moz-secret
```
**Frontend `.env.local`:**
```env
NEXT_PUBLIC_API_URL=https://api.pounce.ch
```
### 3. Initialize Database
```bash
cd backend
source venv/bin/activate
# Create all tables
python scripts/init_db.py
# Seed TLD prices
python scripts/seed_tld_prices.py
```
### 4. Start Services
**With PM2 (Recommended):**
```bash
# Backend
cd backend && source venv/bin/activate
pm2 start "uvicorn app.main:app --host 0.0.0.0 --port 8000" --name pounce-api
# Frontend
cd frontend
npm run build
pm2 start "npm start" --name pounce-web
# Save & auto-restart
pm2 save
pm2 startup
```
**With Docker:**
```bash
docker-compose up -d --build
```
### 5. Nginx Configuration
```nginx
# API
server {
listen 443 ssl http2;
server_name api.pounce.ch;
ssl_certificate /etc/letsencrypt/live/api.pounce.ch/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.pounce.ch/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
# Frontend
server {
listen 443 ssl http2;
server_name pounce.ch www.pounce.ch;
ssl_certificate /etc/letsencrypt/live/pounce.ch/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/pounce.ch/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
```
### 6. Stripe Webhook
Configure Stripe to send webhooks to:
```
https://api.pounce.ch/api/v1/webhooks/stripe
```
Events to enable:
- `checkout.session.completed`
- `customer.subscription.updated`
- `customer.subscription.deleted`
- `invoice.payment_succeeded`
- `invoice.payment_failed`
---
## 📊 Scheduler Jobs (Automatic)
The backend includes APScheduler that runs automatically:
| Job | Schedule | Description |
|-----|----------|-------------|
| TLD Price Scrape | Daily 03:00 UTC | Scrapes 886+ TLDs from Porkbun |
| Auction Scrape | Hourly :30 | Scrapes from ExpiredDomains |
| Domain Check | Daily 06:00 UTC | Checks all watched domains |
| Price Alerts | Daily 04:00 UTC | Sends email for >5% changes |
| Sniper Alert Match | Every 15 min | Matches auctions to alerts |
---
## 💳 Subscription Tiers
| Feature | Scout (Free) | Trader (€9/mo) | Tycoon (€29/mo) |
|---------|--------------|----------------|-----------------|
| Watchlist Domains | 5 | 50 | 500 |
| Portfolio Domains | — | 25 | Unlimited |
| Marketplace Listings | — | 3 | 25 |
| Sniper Alerts | — | 3 | 25 |
| TLD Pricing | Preview | Full | Full |
| Auction Deal Score | Blurred | Full | Full |
| SEO Juice Detector | — | — | ✓ |
| Health Monitoring | Basic | Advanced | Advanced |
| Notifications | Email | Email + SMS | All + Webhook |
---
## 🔗 API Endpoints (New)
### Listings (For Sale)
| Method | Endpoint | Auth |
|--------|----------|------|
| GET | `/api/v1/listings` | No |
| GET | `/api/v1/listings/{slug}` | No |
| POST | `/api/v1/listings/{slug}/inquire` | No |
| GET | `/api/v1/listings/my` | Yes |
| POST | `/api/v1/listings` | Yes |
| PUT | `/api/v1/listings/{id}` | Yes |
| DELETE | `/api/v1/listings/{id}` | Yes |
| POST | `/api/v1/listings/{id}/verify-dns` | Yes |
### Sniper Alerts
| Method | Endpoint | Auth |
|--------|----------|------|
| GET | `/api/v1/sniper-alerts` | Yes |
| POST | `/api/v1/sniper-alerts` | Yes |
| PUT | `/api/v1/sniper-alerts/{id}` | Yes |
| DELETE | `/api/v1/sniper-alerts/{id}` | Yes |
| POST | `/api/v1/sniper-alerts/{id}/test` | Yes |
| GET | `/api/v1/sniper-alerts/{id}/matches` | Yes |
### SEO Data (Tycoon Only)
| Method | Endpoint | Auth |
|--------|----------|------|
| GET | `/api/v1/seo/{domain}` | Tycoon |
| POST | `/api/v1/seo/batch` | Tycoon |
| GET | `/api/v1/seo/{domain}/quick` | Trader+ |
---
## 🎨 UI Components
The Command Center uses these reusable components from `PremiumTable.tsx`:
| Component | Usage |
|-----------|-------|
| `PremiumTable` | Elegant data tables with sorting |
| `StatCard` | Stats display with icons |
| `PageContainer` | Consistent max-width wrapper |
| `SearchInput` | Search with clear button |
| `TabBar` | Tab navigation with counts |
| `FilterBar` | Row of filter controls |
| `SelectDropdown` | Styled select inputs |
| `ActionButton` | Primary/secondary/ghost buttons |
| `Badge` | Status badges with variants |
| `TableActionButton` | Icon buttons for table rows |
---
## 🐛 Troubleshooting
### Common Console Warnings (Ignore)
| Warning | Explanation |
|---------|-------------|
| `SES Removing unpermitted intrinsics` | MetaMask browser extension |
| `PostHog CORS blocked` | Normal on localhost |
| `-webkit-text-size-adjust` error | Old CSS prefixes |
### Actual Errors
| Error | Solution |
|-------|----------|
| `CORS request did not succeed` to localhost:8000 | **Start the backend!** |
| `500 Internal Server Error` on `/seo/` | Run `init_db.py` to create tables |
| `404` on `/listings/my` | API routes ordered correctly in v2.0 |
---
## 📄 License
MIT License
---
## 📧 Support
For issues and feature requests, please open a GitHub issue or contact support@pounce.ch