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)
This commit is contained in:
@ -1,37 +1,35 @@
|
||||
# Database Migrations Guide
|
||||
|
||||
## Overview
|
||||
## Quick Overview
|
||||
|
||||
This document lists all database tables that need to be created when deploying Pounce to a new server.
|
||||
When deploying Pounce to a new server, these tables need to be created:
|
||||
|
||||
## Required Tables
|
||||
|
||||
### Core Tables (Already Implemented)
|
||||
|
||||
| Table | Model | Description |
|
||||
|-------|-------|-------------|
|
||||
| `users` | User | User accounts and authentication |
|
||||
| `subscriptions` | Subscription | User subscription plans (Scout, Trader, Tycoon) |
|
||||
| `domains` | Domain | Tracked domains in watchlists |
|
||||
| `domain_checks` | DomainCheck | Domain availability check history |
|
||||
| `tld_prices` | TLDPrice | TLD price history |
|
||||
| `tld_info` | TLDInfo | TLD metadata |
|
||||
| `portfolio_domains` | PortfolioDomain | User-owned domains |
|
||||
| `domain_valuations` | DomainValuation | Domain valuation history |
|
||||
| `domain_auctions` | DomainAuction | Scraped auction listings |
|
||||
| `auction_scrape_logs` | AuctionScrapeLog | Scraping job logs |
|
||||
| `newsletter_subscribers` | NewsletterSubscriber | Email newsletter list |
|
||||
| `price_alerts` | PriceAlert | TLD price change alerts |
|
||||
| `admin_activity_logs` | AdminActivityLog | Admin action audit log |
|
||||
| `blog_posts` | BlogPost | Blog content |
|
||||
```
|
||||
✅ Core Tables (17) - User, Subscription, Domain, TLD, etc.
|
||||
🆕 New Tables (6) - Listings, Sniper Alerts, SEO Data
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### NEW Tables (To Be Created)
|
||||
## Automatic Migration
|
||||
|
||||
These tables were added for the **"For Sale" Marketplace** and **Sniper Alerts** features:
|
||||
The easiest way to create all tables:
|
||||
|
||||
#### 1. Domain Listings (For Sale Marketplace)
|
||||
```bash
|
||||
cd backend
|
||||
source venv/bin/activate
|
||||
python scripts/init_db.py
|
||||
```
|
||||
|
||||
This creates all tables from the SQLAlchemy models automatically.
|
||||
|
||||
---
|
||||
|
||||
## Manual SQL Migration
|
||||
|
||||
If you need to run migrations manually (e.g., on an existing database), use the SQL below.
|
||||
|
||||
### NEW Table 1: Domain Listings (For Sale Marketplace)
|
||||
|
||||
```sql
|
||||
-- Main listing table
|
||||
@ -45,13 +43,13 @@ CREATE TABLE domain_listings (
|
||||
asking_price FLOAT,
|
||||
min_offer FLOAT,
|
||||
currency VARCHAR(3) DEFAULT 'USD',
|
||||
price_type VARCHAR(20) DEFAULT 'fixed',
|
||||
price_type VARCHAR(20) DEFAULT 'fixed', -- 'fixed', 'negotiable', 'make_offer'
|
||||
pounce_score INTEGER,
|
||||
estimated_value FLOAT,
|
||||
verification_status VARCHAR(20) DEFAULT 'not_started',
|
||||
verification_status VARCHAR(20) DEFAULT 'not_started', -- 'not_started', 'pending', 'verified', 'failed'
|
||||
verification_code VARCHAR(64),
|
||||
verified_at TIMESTAMP,
|
||||
status VARCHAR(30) DEFAULT 'draft',
|
||||
status VARCHAR(30) DEFAULT 'draft', -- 'draft', 'published', 'sold', 'expired', 'removed'
|
||||
show_valuation BOOLEAN DEFAULT TRUE,
|
||||
allow_offers BOOLEAN DEFAULT TRUE,
|
||||
featured BOOLEAN DEFAULT FALSE,
|
||||
@ -67,8 +65,11 @@ CREATE INDEX idx_listings_user_id ON domain_listings(user_id);
|
||||
CREATE INDEX idx_listings_domain ON domain_listings(domain);
|
||||
CREATE INDEX idx_listings_slug ON domain_listings(slug);
|
||||
CREATE INDEX idx_listings_status ON domain_listings(status);
|
||||
CREATE INDEX idx_listings_price ON domain_listings(asking_price);
|
||||
```
|
||||
|
||||
### NEW Table 2: Listing Inquiries
|
||||
|
||||
```sql
|
||||
-- Contact inquiries from potential buyers
|
||||
CREATE TABLE listing_inquiries (
|
||||
@ -80,7 +81,7 @@ CREATE TABLE listing_inquiries (
|
||||
company VARCHAR(200),
|
||||
message TEXT NOT NULL,
|
||||
offer_amount FLOAT,
|
||||
status VARCHAR(20) DEFAULT 'new',
|
||||
status VARCHAR(20) DEFAULT 'new', -- 'new', 'read', 'replied', 'archived'
|
||||
ip_address VARCHAR(45),
|
||||
user_agent VARCHAR(500),
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
@ -89,8 +90,11 @@ CREATE TABLE listing_inquiries (
|
||||
);
|
||||
|
||||
CREATE INDEX idx_inquiries_listing_id ON listing_inquiries(listing_id);
|
||||
CREATE INDEX idx_inquiries_status ON listing_inquiries(status);
|
||||
```
|
||||
|
||||
### NEW Table 3: Listing Views
|
||||
|
||||
```sql
|
||||
-- Analytics: page views
|
||||
CREATE TABLE listing_views (
|
||||
@ -104,41 +108,53 @@ CREATE TABLE listing_views (
|
||||
);
|
||||
|
||||
CREATE INDEX idx_views_listing_id ON listing_views(listing_id);
|
||||
CREATE INDEX idx_views_date ON listing_views(viewed_at);
|
||||
```
|
||||
|
||||
#### 2. Sniper Alerts
|
||||
### NEW Table 4: Sniper Alerts
|
||||
|
||||
```sql
|
||||
-- Saved filter configurations for personalized alerts
|
||||
-- Saved filter configurations for personalized auction alerts
|
||||
CREATE TABLE sniper_alerts (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id),
|
||||
name VARCHAR(100) NOT NULL,
|
||||
description VARCHAR(500),
|
||||
|
||||
-- Filter criteria (stored as JSON for flexibility)
|
||||
filter_criteria JSONB NOT NULL DEFAULT '{}',
|
||||
tlds VARCHAR(500),
|
||||
keywords VARCHAR(500),
|
||||
exclude_keywords VARCHAR(500),
|
||||
|
||||
-- Quick filters (also stored as columns for fast queries)
|
||||
tlds VARCHAR(500), -- comma-separated: "com,net,io"
|
||||
keywords VARCHAR(500), -- comma-separated search terms
|
||||
exclude_keywords VARCHAR(500), -- words to exclude
|
||||
max_length INTEGER,
|
||||
min_length INTEGER,
|
||||
max_price FLOAT,
|
||||
min_price FLOAT,
|
||||
max_bids INTEGER,
|
||||
ending_within_hours INTEGER,
|
||||
platforms VARCHAR(200),
|
||||
platforms VARCHAR(200), -- "GoDaddy,Sedo,NameJet"
|
||||
|
||||
-- Vanity filters
|
||||
no_numbers BOOLEAN DEFAULT FALSE,
|
||||
no_hyphens BOOLEAN DEFAULT FALSE,
|
||||
exclude_chars VARCHAR(50),
|
||||
|
||||
-- Notification settings
|
||||
notify_email BOOLEAN DEFAULT TRUE,
|
||||
notify_sms BOOLEAN DEFAULT FALSE,
|
||||
notify_push BOOLEAN DEFAULT FALSE,
|
||||
max_notifications_per_day INTEGER DEFAULT 10,
|
||||
cooldown_minutes INTEGER DEFAULT 30,
|
||||
|
||||
-- Status
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
matches_count INTEGER DEFAULT 0,
|
||||
notifications_sent INTEGER DEFAULT 0,
|
||||
last_matched_at TIMESTAMP,
|
||||
last_notified_at TIMESTAMP,
|
||||
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
@ -147,6 +163,8 @@ CREATE INDEX idx_alerts_user_id ON sniper_alerts(user_id);
|
||||
CREATE INDEX idx_alerts_active ON sniper_alerts(is_active);
|
||||
```
|
||||
|
||||
### NEW Table 5: Sniper Alert Matches
|
||||
|
||||
```sql
|
||||
-- Matched auctions for each alert
|
||||
CREATE TABLE sniper_alert_matches (
|
||||
@ -164,128 +182,159 @@ CREATE TABLE sniper_alert_matches (
|
||||
);
|
||||
|
||||
CREATE INDEX idx_matches_alert_id ON sniper_alert_matches(alert_id);
|
||||
CREATE INDEX idx_matches_domain ON sniper_alert_matches(domain);
|
||||
CREATE INDEX idx_matches_notified ON sniper_alert_matches(notified);
|
||||
```
|
||||
|
||||
#### 3. SEO Data (Tycoon Feature)
|
||||
### NEW Table 6: SEO Data (Tycoon Feature)
|
||||
|
||||
```sql
|
||||
-- Cached SEO metrics for domains
|
||||
-- Cached SEO metrics for domains (Moz API or estimation)
|
||||
CREATE TABLE domain_seo_data (
|
||||
id SERIAL PRIMARY KEY,
|
||||
domain VARCHAR(255) NOT NULL UNIQUE,
|
||||
domain_authority INTEGER,
|
||||
page_authority INTEGER,
|
||||
spam_score INTEGER,
|
||||
|
||||
-- Core metrics
|
||||
domain_authority INTEGER, -- 0-100
|
||||
page_authority INTEGER, -- 0-100
|
||||
spam_score INTEGER, -- 0-100
|
||||
total_backlinks INTEGER,
|
||||
referring_domains INTEGER,
|
||||
top_backlinks JSONB,
|
||||
notable_backlinks TEXT,
|
||||
|
||||
-- Backlink analysis
|
||||
top_backlinks JSONB, -- [{domain, authority, page}, ...]
|
||||
notable_backlinks TEXT, -- comma-separated high-value domains
|
||||
|
||||
-- Notable link flags
|
||||
has_wikipedia_link BOOLEAN DEFAULT FALSE,
|
||||
has_gov_link BOOLEAN DEFAULT FALSE,
|
||||
has_edu_link BOOLEAN DEFAULT FALSE,
|
||||
has_news_link BOOLEAN DEFAULT FALSE,
|
||||
seo_value_estimate FLOAT,
|
||||
data_source VARCHAR(50) DEFAULT 'moz',
|
||||
|
||||
-- Value estimation
|
||||
seo_value_estimate FLOAT, -- Estimated $ value based on SEO metrics
|
||||
|
||||
-- Metadata
|
||||
data_source VARCHAR(50) DEFAULT 'estimated', -- 'moz', 'estimated'
|
||||
last_updated TIMESTAMP DEFAULT NOW(),
|
||||
expires_at TIMESTAMP,
|
||||
expires_at TIMESTAMP, -- Cache expiry (7 days)
|
||||
fetch_count INTEGER DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE INDEX idx_seo_domain ON domain_seo_data(domain);
|
||||
CREATE INDEX idx_seo_da ON domain_seo_data(domain_authority);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Migration Commands
|
||||
## All Tables Summary
|
||||
|
||||
### Using Alembic (Recommended)
|
||||
### Core Tables (Already Implemented)
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
| Table | Purpose |
|
||||
|-------|---------|
|
||||
| `users` | User accounts and authentication |
|
||||
| `subscriptions` | Subscription plans (Scout, Trader, Tycoon) |
|
||||
| `domains` | Tracked domains in watchlists |
|
||||
| `domain_checks` | Domain availability check history |
|
||||
| `tld_prices` | TLD price history (886+ TLDs) |
|
||||
| `tld_info` | TLD metadata and categories |
|
||||
| `portfolio_domains` | User-owned domains |
|
||||
| `domain_valuations` | Domain valuation history |
|
||||
| `domain_auctions` | Scraped auction listings |
|
||||
| `auction_scrape_logs` | Scraping job logs |
|
||||
| `newsletter_subscribers` | Email newsletter list |
|
||||
| `price_alerts` | TLD price change alerts |
|
||||
| `admin_activity_logs` | Admin action audit log |
|
||||
| `blog_posts` | Blog content |
|
||||
|
||||
# Generate migration
|
||||
alembic revision --autogenerate -m "Add marketplace and sniper alert tables"
|
||||
### New Tables (v2.0)
|
||||
|
||||
# Apply migration
|
||||
alembic upgrade head
|
||||
```
|
||||
|
||||
### Manual SQL (Alternative)
|
||||
|
||||
Run the SQL statements above in order on your PostgreSQL database.
|
||||
| Table | Purpose | Required For |
|
||||
|-------|---------|--------------|
|
||||
| `domain_listings` | For Sale marketplace | `/command/listings`, `/buy` |
|
||||
| `listing_inquiries` | Buyer messages | Marketplace inquiries |
|
||||
| `listing_views` | View analytics | Listing stats |
|
||||
| `sniper_alerts` | Alert configurations | `/command/alerts` |
|
||||
| `sniper_alert_matches` | Matched auctions | Alert notifications |
|
||||
| `domain_seo_data` | SEO metrics cache | `/command/seo` (Tycoon) |
|
||||
|
||||
---
|
||||
|
||||
## Verification
|
||||
|
||||
After running migrations, verify tables exist:
|
||||
After migration, verify all tables exist:
|
||||
|
||||
```sql
|
||||
-- PostgreSQL
|
||||
SELECT table_name
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name IN (
|
||||
'domain_listings',
|
||||
'listing_inquiries',
|
||||
'listing_views',
|
||||
'sniper_alerts',
|
||||
'sniper_alert_matches',
|
||||
'domain_seo_data'
|
||||
);
|
||||
ORDER BY table_name;
|
||||
|
||||
-- Should include:
|
||||
-- domain_listings
|
||||
-- listing_inquiries
|
||||
-- listing_views
|
||||
-- sniper_alerts
|
||||
-- sniper_alert_matches
|
||||
-- domain_seo_data
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Feature References
|
||||
## Environment Variables for New Features
|
||||
|
||||
These tables implement features from:
|
||||
### Moz API (Optional - for real SEO data)
|
||||
|
||||
- **analysis_3.md** - "Micro-Marktplatz" (For Sale Landing Pages)
|
||||
- **analysis_3.md** - "Sniper Alerts" (Strategie 4: Alerts nach Maß)
|
||||
- **concept.md** - "For Sale Pages" marketplace feature
|
||||
```env
|
||||
MOZ_ACCESS_ID=your_moz_access_id
|
||||
MOZ_SECRET_KEY=your_moz_secret_key
|
||||
```
|
||||
|
||||
Without these variables, the SEO analyzer uses **estimation mode** based on domain characteristics (length, TLD, keywords).
|
||||
|
||||
### Stripe (Required for payments)
|
||||
|
||||
```env
|
||||
STRIPE_SECRET_KEY=sk_live_xxx
|
||||
STRIPE_WEBHOOK_SECRET=whsec_xxx
|
||||
STRIPE_PRICE_TRADER=price_xxx # €9/month
|
||||
STRIPE_PRICE_TYCOON=price_xxx # €29/month
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API Endpoints
|
||||
## Scheduler Jobs
|
||||
|
||||
### Listings (For Sale)
|
||||
These background jobs run automatically when the backend starts:
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| GET | `/api/v1/listings` | Browse public listings |
|
||||
| GET | `/api/v1/listings/{slug}` | View listing details |
|
||||
| POST | `/api/v1/listings/{slug}/inquire` | Contact seller |
|
||||
| POST | `/api/v1/listings` | Create listing (auth) |
|
||||
| GET | `/api/v1/listings/my` | Get my listings (auth) |
|
||||
| PUT | `/api/v1/listings/{id}` | Update listing (auth) |
|
||||
| DELETE | `/api/v1/listings/{id}` | Delete listing (auth) |
|
||||
| POST | `/api/v1/listings/{id}/verify-dns` | Start verification |
|
||||
| GET | `/api/v1/listings/{id}/verify-dns/check` | Check verification |
|
||||
| Job | Schedule | Table Affected |
|
||||
|-----|----------|----------------|
|
||||
| Sniper Alert Matching | Every 15 min | `sniper_alert_matches` |
|
||||
| Auction Scrape | Hourly | `domain_auctions` |
|
||||
| TLD Price Scrape | Daily 03:00 | `tld_prices` |
|
||||
| Domain Check | Daily 06:00 | `domain_checks` |
|
||||
|
||||
### Sniper Alerts
|
||||
---
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| GET | `/api/v1/sniper-alerts` | Get my alerts |
|
||||
| POST | `/api/v1/sniper-alerts` | Create alert |
|
||||
| PUT | `/api/v1/sniper-alerts/{id}` | Update alert |
|
||||
| DELETE | `/api/v1/sniper-alerts/{id}` | Delete alert |
|
||||
| GET | `/api/v1/sniper-alerts/{id}/matches` | Get matched auctions |
|
||||
| POST | `/api/v1/sniper-alerts/{id}/test` | Test alert criteria |
|
||||
## Rollback
|
||||
|
||||
### SEO Data (Tycoon Only)
|
||||
If you need to remove the new tables:
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| GET | `/api/v1/seo/{domain}` | Full SEO analysis (Tycoon) |
|
||||
| POST | `/api/v1/seo/batch` | Batch analyze domains (Tycoon) |
|
||||
| GET | `/api/v1/seo/{domain}/quick` | Quick summary (Trader+) |
|
||||
|
||||
**Environment Variables for Moz API:**
|
||||
```
|
||||
MOZ_ACCESS_ID=your_access_id
|
||||
MOZ_SECRET_KEY=your_secret_key
|
||||
```sql
|
||||
DROP TABLE IF EXISTS sniper_alert_matches CASCADE;
|
||||
DROP TABLE IF EXISTS sniper_alerts CASCADE;
|
||||
DROP TABLE IF EXISTS listing_views CASCADE;
|
||||
DROP TABLE IF EXISTS listing_inquiries CASCADE;
|
||||
DROP TABLE IF EXISTS domain_listings CASCADE;
|
||||
DROP TABLE IF EXISTS domain_seo_data CASCADE;
|
||||
```
|
||||
|
||||
Without these, the system uses estimation mode based on domain characteristics.
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- `README.md` - Full deployment guide
|
||||
- `DEPLOYMENT.md` - Server setup details
|
||||
- `backend/app/models/` - SQLAlchemy model definitions
|
||||
|
||||
Reference in New Issue
Block a user