diff --git a/database.py b/database.py index 2c80e21..b569f4e 100644 --- a/database.py +++ b/database.py @@ -13,10 +13,11 @@ Models: - CompanyDigitalMaturity: Digital maturity scores and benchmarking - CompanyWebsiteAnalysis: Website analysis and SEO metrics - MaturityAssessment: Historical tracking of maturity scores +- GBPAudit: Google Business Profile audit results Author: Norda Biznes Development Team Created: 2025-11-23 -Updated: 2025-11-26 (Digital Maturity Platform - ETAP 1) +Updated: 2026-01-08 (GBP Audit Tool) """ import os @@ -1129,6 +1130,89 @@ class UserNotification(Base): self.read_at = datetime.now() +# ============================================================ +# GOOGLE BUSINESS PROFILE AUDIT +# ============================================================ + +class GBPAudit(Base): + """ + Google Business Profile audit results for companies. + Tracks completeness scores and provides improvement recommendations. + """ + __tablename__ = 'gbp_audits' + + id = Column(Integer, primary_key=True) + company_id = Column(Integer, ForeignKey('companies.id', ondelete='CASCADE'), nullable=False, index=True) + + # Audit timestamp + audit_date = Column(DateTime, default=datetime.now, nullable=False, index=True) + + # Completeness scoring (0-100) + completeness_score = Column(Integer) + + # Field-by-field status tracking + # Example: {"name": {"status": "complete", "value": "Company Name"}, "phone": {"status": "missing"}, ...} + fields_status = Column(JSONB) + + # AI-generated recommendations + # Example: [{"priority": "high", "field": "description", "recommendation": "Add a detailed business description..."}, ...] + recommendations = Column(JSONB) + + # Individual field scores (for detailed breakdown) + has_name = Column(Boolean, default=False) + has_address = Column(Boolean, default=False) + has_phone = Column(Boolean, default=False) + has_website = Column(Boolean, default=False) + has_hours = Column(Boolean, default=False) + has_categories = Column(Boolean, default=False) + has_photos = Column(Boolean, default=False) + has_description = Column(Boolean, default=False) + has_services = Column(Boolean, default=False) + has_reviews = Column(Boolean, default=False) + + # Photo counts + photo_count = Column(Integer, default=0) + logo_present = Column(Boolean, default=False) + cover_photo_present = Column(Boolean, default=False) + + # Review metrics + review_count = Column(Integer, default=0) + average_rating = Column(Numeric(2, 1)) + + # Google Place data + google_place_id = Column(String(100)) + google_maps_url = Column(String(500)) + + # Audit metadata + audit_source = Column(String(50), default='manual') # manual, automated, api + audit_version = Column(String(20), default='1.0') + audit_errors = Column(Text) + + # Timestamps + created_at = Column(DateTime, default=datetime.now) + updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now) + + # Relationship + company = relationship('Company', backref='gbp_audits') + + def __repr__(self): + return f'' + + @property + def score_category(self): + """Return score category: excellent, good, needs_work, poor""" + if self.completeness_score is None: + return 'unknown' + if self.completeness_score >= 90: + return 'excellent' + elif self.completeness_score >= 70: + return 'good' + elif self.completeness_score >= 50: + return 'needs_work' + else: + return 'poor' + + # ============================================================ # MEMBERSHIP FEES # ============================================================