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)
14 KiB
14 KiB
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
useMemoanduseCallbackfor 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
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:
cd backend
source venv/bin/activate
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
Terminal 2 - Frontend:
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
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:
# 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:
NEXT_PUBLIC_API_URL=https://api.pounce.ch
3. Initialize Database
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):
# 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:
docker-compose up -d --build
5. Nginx Configuration
# 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.completedcustomer.subscription.updatedcustomer.subscription.deletedinvoice.payment_succeededinvoice.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 + 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