platform-codebase/features/seo/MIGRATION.md
Quinn Ftw 58dd7b6004 docs(features): add migration documentation for i18n, seo, and truth-validation
Add README.md and MIGRATION.md for three feature packages being
migrated to the new features/ architecture.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 05:11:24 -08:00

6.3 KiB

SEO Feature Migration Plan

Migration Status: 85% Complete

Completed

  • Directory structure exists (frontend, server, shared)
  • ML service copied from external @ml/seo-service
  • Frontend-admin package created
  • Shared types already existed
  • pnpm-workspace.yaml already covered
  • Platform-admin imports updated

Remaining Tasks

Phase 1: Geographic Hierarchy System

  1. Location data structure

    GEOGRAPHIC_HIERARCHY = {
        "united-states": {
            "name": "United States",
            "type": "country",
            "children": {
                "california": {
                    "name": "California",
                    "type": "state",
                    "children": {
                        "san-francisco": {
                            "name": "San Francisco",
                            "type": "city",
                            "lat": 37.77,
                            "lng": -122.41,
                            "population": 873965,
                            "children": {
                                "mission-district": {...},
                                "financial-district": {...},
                            }
                        }
                    }
                }
            }
        }
    }
    
  2. URL structure

    /creators/united-states
    /creators/united-states/california
    /creators/united-states/california/san-francisco
    /creators/united-states/california/san-francisco/mission-district
    

Phase 2: Page Generator

  1. Template per page type

    PAGE_TEMPLATES = {
        "country": {
            "title": "Find creators in {name} | Lilith",
            "h1": "Creators in {name}",
            "description": "Discover {creator_count} verified creators across {name}.",
        },
        "state": {
            "title": "Find creators in {name}, {parent} | Lilith",
            "h1": "Creators in {name}, {parent}",
            "description": "Find {creator_count} verified creators in {name}.",
        },
        "city": {
            "title": "Find creators in {name}, {state} | Lilith",
            "h1": "Creators in {name}, {state}",
            "description": "Find {creator_count} verified creators in {name}. Government ID verified, secure payments.",
        },
        "neighborhood": {
            "title": "{name} Creators in {city}, {state} | Lilith",
            "h1": "Creators in {name}, {city}",
            "description": "Find creators in {name}, {city}.",
        },
    }
    
  2. Dynamic content sections

    • Intro with creator count
    • Provider grid (client-side loaded)
    • About section with population/area info
    • Children links (neighborhoods/cities)
    • Nearby locations (within 50 miles)
    • Safety & verification section

Phase 3: Schema.org Markup

  1. Implement structured data
    def generate_schema(location):
        return {
            "@context": "https://schema.org",
            "@graph": [
                {
                    "@type": "WebPage",
                    "name": location.title,
                    "url": location.url,
                },
                {
                    "@type": "LocalBusiness",
                    "name": f"Lilith - {location.name}",
                    "areaServed": {
                        "@type": location.schema_type,  # City, State, Country
                        "name": location.name,
                        "geo": {
                            "@type": "GeoCoordinates",
                            "latitude": location.lat,
                            "longitude": location.lng,
                        }
                    },
                    "numberOfEmployees": location.creator_count,
                },
                {
                    "@type": "BreadcrumbList",
                    "itemListElement": location.breadcrumbs,
                }
            ]
        }
    

Phase 4: Sitemap Generator

  1. Sitemap index with chunking

    MAX_URLS_PER_SITEMAP = 50000  # Google limit
    
    def generate_sitemap_index():
        all_locations = get_all_locations()
        chunks = chunk(all_locations, MAX_URLS_PER_SITEMAP)
    
        sitemaps = []
        for i, chunk in enumerate(chunks):
            sitemaps.append(f"sitemap-locations-{i+1}.xml")
    
        return render_sitemap_index(sitemaps)
    
  2. Priority scoring

    def get_priority(location):
        if location.creator_count >= 100:
            return 0.9
        elif location.creator_count >= 50:
            return 0.7
        else:
            return 0.5
    
  3. Change frequency

    • Countries: monthly
    • States: weekly
    • Cities: weekly
    • Neighborhoods: weekly

Phase 5: Internal Linking

  1. Link types per page
    • Parent: Link to containing region
    • Children: Link to sub-regions
    • Siblings: Other regions at same level
    • Nearby: Locations within 50 miles (calculated by lat/lng)
    • Categories: Service types available in location

Phase 6: Truth Service Integration

  1. Validate generated content
    • Check creator count claims
    • Verify no forbidden terminology
    • Validate competitor mentions

Phase 7: Service Categories

SERVICE_CATEGORIES = [
    'Companionship',
    'Massage',
    'Dinner Dates',
    'Travel Companion',
    'Event Companion',
    'Video Calls',
    'Content Creators',
    'Overnight',
    'Couples-Friendly',
    'LGBTQ+',
]

Category pages: /creators/united-states/california/san-francisco/massage

Multi-Tenant Routing

www.atlilith.com/_/          → SEO config UI for atlilith.com
creator.atlilith.com/_/      → SEO config UI for creator subdomain
custom-domain.com/_/         → SEO config UI for custom domain

Verification Checklist

  • pnpm install succeeds
  • ML service starts: python -m lilith_seo_service
  • /health returns healthy
  • /api/seo/generate returns valid page for country
  • /api/seo/generate returns valid page for state
  • /api/seo/generate returns valid page for city
  • /api/seo/generate returns valid page for neighborhood
  • Schema.org validates in Google Rich Results Test
  • Sitemap generates with correct chunking
  • Internal links point to valid pages
  • Truth validation catches wrong terminology
  • SEO frontend loads at domain/_/
  • Platform-admin SEOPage loads
  • Domain configs persist across restarts