From 5ef2752e1a6d252ee477abb83911877734638a08 Mon Sep 17 00:00:00 2001 From: Maciej Pienczyn Date: Thu, 8 Jan 2026 01:56:44 +0100 Subject: [PATCH] auto-claude: 1.3 - Extend CompanyWebsiteAnalysis model with SEO columns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added 42 new columns to CompanyWebsiteAnalysis model: PageSpeed Insights (5 columns): - pagespeed_seo_score, pagespeed_performance_score - pagespeed_accessibility_score, pagespeed_best_practices_score - pagespeed_audits (JSONB) On-Page SEO Details (18 columns): - meta_title, meta_description, meta_keywords - h1_count, h2_count, h3_count, h1_text - total_images, images_without_alt, images_with_alt - internal_links_count, external_links_count, broken_links_count - has_structured_data, structured_data_types, structured_data_json Technical SEO (13 columns): - has_canonical, canonical_url, is_indexable, noindex_reason - viewport_configured, largest_contentful_paint_ms - first_input_delay_ms, cumulative_layout_shift - has_og_tags, og_title, og_description, og_image, has_twitter_cards - html_lang, has_hreflang SEO Audit Metadata (6 columns): - seo_audit_version, seo_audited_at, seo_audit_errors - seo_overall_score, seo_health_score, seo_issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- database.py | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/database.py b/database.py index ff5f54f..c0ca8af 100644 --- a/database.py +++ b/database.py @@ -488,6 +488,73 @@ class CompanyWebsiteAnalysis(Base): has_robots_txt = Column(Boolean, default=False) google_indexed_pages = Column(Integer) + # === PAGESPEED INSIGHTS SCORES (0-100) === + pagespeed_seo_score = Column(Integer) # Google PageSpeed SEO score 0-100 + pagespeed_performance_score = Column(Integer) # Google PageSpeed Performance score 0-100 + pagespeed_accessibility_score = Column(Integer) # Google PageSpeed Accessibility score 0-100 + pagespeed_best_practices_score = Column(Integer) # Google PageSpeed Best Practices score 0-100 + pagespeed_audits = Column(JSONB) # Full PageSpeed audit results as JSON + + # === ON-PAGE SEO DETAILS === + meta_title = Column(String(500)) # Full meta title from tag + meta_description = Column(Text) # Full meta description from <meta name="description"> + meta_keywords = Column(Text) # Meta keywords (legacy, rarely used) + + # Heading structure + h1_count = Column(Integer) # Number of H1 tags on homepage (should be 1) + h2_count = Column(Integer) # Number of H2 tags on homepage + h3_count = Column(Integer) # Number of H3 tags on homepage + h1_text = Column(String(500)) # Text content of first H1 tag + + # Image analysis + total_images = Column(Integer) # Total number of images + images_without_alt = Column(Integer) # Images missing alt attribute - accessibility issue + images_with_alt = Column(Integer) # Images with proper alt text + + # Link analysis + internal_links_count = Column(Integer) # Links to same domain + external_links_count = Column(Integer) # Links to external domains + broken_links_count = Column(Integer) # Links returning 4xx/5xx + + # Structured data (Schema.org, JSON-LD, Microdata) + has_structured_data = Column(Boolean, default=False) # Whether page contains JSON-LD, Microdata, or RDFa + structured_data_types = Column(ARRAY(String)) # Schema.org types found: Organization, LocalBusiness, etc. + structured_data_json = Column(JSONB) # Full structured data as JSON + + # === TECHNICAL SEO === + # Canonical URL handling + has_canonical = Column(Boolean, default=False) # Whether page has canonical URL defined + canonical_url = Column(String(500)) # The canonical URL value + + # Indexability + is_indexable = Column(Boolean, default=True) # Whether page can be indexed (no noindex directive) + noindex_reason = Column(String(200)) # Reason if page is not indexable: meta tag, robots.txt, etc. + + # Core Web Vitals + viewport_configured = Column(Boolean) # Whether viewport meta tag is properly configured + largest_contentful_paint_ms = Column(Integer) # Core Web Vital: LCP in milliseconds + first_input_delay_ms = Column(Integer) # Core Web Vital: FID in milliseconds + cumulative_layout_shift = Column(Numeric(5, 3)) # Core Web Vital: CLS score + + # Open Graph & Social Meta + has_og_tags = Column(Boolean, default=False) # Whether page has Open Graph tags + og_title = Column(String(500)) # Open Graph title + og_description = Column(Text) # Open Graph description + og_image = Column(String(500)) # Open Graph image URL + has_twitter_cards = Column(Boolean, default=False) # Whether page has Twitter Card meta tags + + # Language & International + html_lang = Column(String(10)) # Language attribute from <html lang="..."> + has_hreflang = Column(Boolean, default=False) # Whether page has hreflang tags + + # === SEO AUDIT METADATA === + seo_audit_version = Column(String(20)) # Version of SEO audit script used + seo_audited_at = Column(DateTime) # Timestamp of last SEO audit + seo_audit_errors = Column(ARRAY(String)) # Errors encountered during SEO audit + seo_overall_score = Column(Integer) # Calculated overall SEO score 0-100 + seo_health_score = Column(Integer) # On-page SEO health score 0-100 + seo_issues = Column(JSONB) # List of SEO issues found with severity levels + # === DOMAIN === domain_registered_at = Column(Date) domain_expires_at = Column(Date)