fix: Ensure 100% price consistency across all TLD pages

ROOT CAUSE:
- Overview API prioritized database data (only Porkbun prices)
- Compare API prioritized static data (5+ registrars)
- This caused price mismatches between Overview table and Detail page

SOLUTION:
- Changed Overview API to prioritize static data for TLDs with rich
  multi-registrar pricing (like Compare API does)
- Database data now used only for TLDs NOT in static data
- This ensures all APIs return identical prices for same TLDs

VERIFICATION:
- .com: Overview=$10.75, Compare=$10.75 ✓
- .io: Overview=$32.33, Compare=$32.33 ✓
- .ai: Overview=$71.63, Compare=$71.63 ✓
- .xyz: Overview=$6.86, Compare=$6.86 ✓

DATA FLOW (now consistent):
1. Static TLDs (18): Use rich multi-registrar data
2. DB-only TLDs (869): Use Porkbun scraped data
3. Total: 887 TLDs with consistent pricing
This commit is contained in:
yves.gugger
2025-12-08 12:03:08 +01:00
parent fa3d65acde
commit c2bb48db19

View File

@ -346,40 +346,25 @@ async def get_tld_overview(
):
"""Get overview of TLDs with current pricing, pagination, and search.
Data source priority:
- For TLDs with rich static data (multiple registrars): Use static data for consistency
- For TLDs only in database: Use database data
- This ensures Overview and Compare/Detail pages show identical prices
Args:
limit: Number of results per page (default 25)
offset: Skip N results for pagination
search: Filter TLDs by name (e.g., "com", "io")
sort_by: Sort order - popularity (default), price_asc, price_desc, name
source: Data source - "auto" (DB first, fallback to static), "db" (only DB), "static" (only static)
source: Data source - "auto" (best available), "db" (only DB), "static" (only static)
"""
tld_list = []
data_source = "static"
tld_seen = set()
data_source = "combined"
# Try database first if auto or db
if source in ["auto", "db"]:
db_count = await get_db_price_count(db)
if db_count > 0:
db_prices = await get_db_prices(db)
data_source = "database"
for tld, data in db_prices.items():
prices = data["prices"]
tld_list.append({
"tld": tld,
"type": guess_tld_type(tld),
"description": TLD_DATA.get(tld, {}).get("description", f".{tld} domain"),
"avg_registration_price": round(sum(prices) / len(prices), 2),
"min_registration_price": min(prices),
"max_registration_price": max(prices),
"registrar_count": len(data["registrars"]),
"trend": TLD_DATA.get(tld, {}).get("trend", "stable"),
"popularity_rank": TOP_TLDS_BY_POPULARITY.index(tld) if tld in TOP_TLDS_BY_POPULARITY else 999,
})
# Use static data as fallback or if requested
if not tld_list and source in ["auto", "static"]:
data_source = "static"
# FIRST: Add all static data TLDs (these have rich multi-registrar data)
# This ensures consistency with /compare endpoint which also uses static data first
if source in ["auto", "static"]:
for tld, data in TLD_DATA.items():
tld_list.append({
"tld": tld,
@ -392,6 +377,38 @@ async def get_tld_overview(
"trend": data["trend"],
"popularity_rank": TOP_TLDS_BY_POPULARITY.index(tld) if tld in TOP_TLDS_BY_POPULARITY else 999,
})
tld_seen.add(tld)
# SECOND: Add TLDs from database that are NOT in static data
# This adds the 800+ TLDs scraped from Porkbun
if source in ["auto", "db"]:
db_count = await get_db_price_count(db)
if db_count > 0:
db_prices = await get_db_prices(db)
for tld, data in db_prices.items():
if tld not in tld_seen: # Only add if not already from static
prices = data["prices"]
tld_list.append({
"tld": tld,
"type": guess_tld_type(tld),
"description": f".{tld} domain extension",
"avg_registration_price": round(sum(prices) / len(prices), 2),
"min_registration_price": min(prices),
"max_registration_price": max(prices),
"registrar_count": len(data["registrars"]),
"trend": "stable",
"popularity_rank": TOP_TLDS_BY_POPULARITY.index(tld) if tld in TOP_TLDS_BY_POPULARITY else 999,
})
tld_seen.add(tld)
# Determine source label
if source == "static":
data_source = "static"
elif source == "db":
data_source = "database"
else:
data_source = "combined"
# Apply search filter
if search: