import os from dotenv import load_dotenv from sqlalchemy import create_engine, Column, BigInteger, Text, DateTime, ForeignKey, func, Boolean, JSON from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker, relationship load_dotenv() DATABASE_URL = f"postgresql://{os.getenv('SUPABASE_DB_USER')}:{os.getenv('SUPABASE_DB_PASSWORD')}@{os.getenv('SUPABASE_DB_HOST')}:{os.getenv('SUPABASE_DB_PORT')}/{os.getenv('SUPABASE_DB_NAME')}" engine = create_engine(DATABASE_URL) SessionLocal = sessionmaker(bind=engine) Base = declarative_base() class Project(Base): __tablename__ = 'projects' id = Column(BigInteger, primary_key=True) project_name = Column(Text, default="Default Project") created_at = Column(DateTime(timezone=True), server_default=func.now()) campaigns = relationship("Campaign", back_populates="project") knowledge_base = relationship("KnowledgeBase", back_populates="project", uselist=False) class Campaign(Base): __tablename__ = 'campaigns' id = Column(BigInteger, primary_key=True) campaign_name = Column(Text, default="Default Campaign") campaign_type = Column(Text, default="Email") project_id = Column(BigInteger, ForeignKey('projects.id'), default=1) created_at = Column(DateTime(timezone=True), server_default=func.now()) auto_send = Column(Boolean, default=False) loop_automation = Column(Boolean, default=False) ai_customization = Column(Boolean, default=False) max_emails_per_group = Column(BigInteger, default=40) loop_interval = Column(BigInteger, default=60) project = relationship("Project", back_populates="campaigns") email_campaigns = relationship("EmailCampaign", back_populates="campaign") search_terms = relationship("SearchTerm", back_populates="campaign") campaign_leads = relationship("CampaignLead", back_populates="campaign") class CampaignLead(Base): __tablename__ = 'campaign_leads' id = Column(BigInteger, primary_key=True) campaign_id = Column(BigInteger, ForeignKey('campaigns.id')) lead_id = Column(BigInteger, ForeignKey('leads.id')) status = Column(Text) created_at = Column(DateTime(timezone=True), server_default=func.now()) lead = relationship("Lead", back_populates="campaign_leads") campaign = relationship("Campaign", back_populates="campaign_leads") class KnowledgeBase(Base): __tablename__ = 'knowledge_base' id = Column(BigInteger, primary_key=True) project_id = Column(BigInteger, ForeignKey('projects.id'), nullable=False) kb_name = Column(Text) kb_bio = Column(Text) kb_values = Column(Text) contact_name = Column(Text) contact_role = Column(Text) contact_email = Column(Text) company_description = Column(Text) company_mission = Column(Text) company_target_market = Column(Text) company_other = Column(Text) product_name = Column(Text) product_description = Column(Text) product_target_customer = Column(Text) product_other = Column(Text) other_context = Column(Text) example_email = Column(Text) created_at = Column(DateTime(timezone=True), server_default=func.now()) updated_at = Column(DateTime(timezone=True), onupdate=func.now()) project = relationship("Project", back_populates="knowledge_base") class LeadSource(Base): __tablename__ = 'lead_sources' id = Column(BigInteger, primary_key=True) lead_id = Column(BigInteger, ForeignKey('leads.id')) search_term_id = Column(BigInteger, ForeignKey('search_terms.id')) url = Column(Text) page_title = Column(Text) meta_description = Column(Text) scrape_duration = Column(Text) meta_tags = Column(Text) phone_numbers = Column(Text) content = Column(Text) tags = Column(Text) http_status = Column(BigInteger) created_at = Column(DateTime(timezone=True), server_default=func.now()) lead = relationship("Lead", back_populates="lead_sources") search_term = relationship("SearchTerm", back_populates="lead_sources") class Lead(Base): __tablename__ = 'leads' id = Column(BigInteger, primary_key=True) email = Column(Text, unique=True) phone = Column(Text) first_name = Column(Text) last_name = Column(Text) company = Column(Text) job_title = Column(Text) created_at = Column(DateTime(timezone=True), server_default=func.now()) campaign_leads = relationship("CampaignLead", back_populates="lead") lead_sources = relationship("LeadSource", back_populates="lead") email_campaigns = relationship("EmailCampaign", back_populates="lead") class EmailTemplate(Base): __tablename__ = 'email_templates' id = Column(BigInteger, primary_key=True) campaign_id = Column(BigInteger, ForeignKey('campaigns.id')) template_name = Column(Text) subject = Column(Text) body_content = Column(Text) created_at = Column(DateTime(timezone=True), server_default=func.now()) is_ai_customizable = Column(Boolean, default=False) campaign = relationship("Campaign") email_campaigns = relationship("EmailCampaign", back_populates="template") class EmailCampaign(Base): __tablename__ = 'email_campaigns' id = Column(BigInteger, primary_key=True) campaign_id = Column(BigInteger, ForeignKey('campaigns.id')) lead_id = Column(BigInteger, ForeignKey('leads.id')) template_id = Column(BigInteger, ForeignKey('email_templates.id')) customized_subject = Column(Text) customized_content = Column(Text) original_subject = Column(Text) original_content = Column(Text) status = Column(Text) engagement_data = Column(JSON) message_id = Column(Text) sent_at = Column(DateTime(timezone=True)) ai_customized = Column(Boolean, default=False) campaign = relationship("Campaign", back_populates="email_campaigns") lead = relationship("Lead", back_populates="email_campaigns") template = relationship("EmailTemplate", back_populates="email_campaigns") class OptimizedSearchTerm(Base): __tablename__ = 'optimized_search_terms' id = Column(BigInteger, primary_key=True) original_term_id = Column(BigInteger, ForeignKey('search_terms.id')) term = Column(Text) created_at = Column(DateTime(timezone=True), server_default=func.now()) original_term = relationship("SearchTerm", back_populates="optimized_terms") class SearchTermEffectiveness(Base): __tablename__ = 'search_term_effectiveness' id = Column(BigInteger, primary_key=True) search_term_id = Column(BigInteger, ForeignKey('search_terms.id')) total_results = Column(BigInteger) valid_leads = Column(BigInteger) irrelevant_leads = Column(BigInteger) blogs_found = Column(BigInteger) directories_found = Column(BigInteger) created_at = Column(DateTime(timezone=True), server_default=func.now()) search_term = relationship("SearchTerm", back_populates="effectiveness") class SearchTermGroup(Base): __tablename__ = 'search_term_groups' id = Column(BigInteger, primary_key=True) name = Column(Text) email_template = Column(Text) description = Column(Text) created_at = Column(DateTime(timezone=True), server_default=func.now()) search_terms = relationship("SearchTerm", back_populates="group") class SearchTerm(Base): __tablename__ = 'search_terms' id = Column(BigInteger, primary_key=True) group_id = Column(BigInteger, ForeignKey('search_term_groups.id')) campaign_id = Column(BigInteger, ForeignKey('campaigns.id')) term = Column(Text) category = Column(Text) created_at = Column(DateTime(timezone=True), server_default=func.now()) group = relationship("SearchTermGroup", back_populates="search_terms") campaign = relationship("Campaign", back_populates="search_terms") optimized_terms = relationship("OptimizedSearchTerm", back_populates="original_term") lead_sources = relationship("LeadSource", back_populates="search_term") effectiveness = relationship("SearchTermEffectiveness", back_populates="search_term", uselist=False) class AIRequestLog(Base): __tablename__ = 'ai_request_logs' id = Column(BigInteger, primary_key=True) function_name = Column(Text) prompt = Column(Text) response = Column(Text) created_at = Column(DateTime(timezone=True), server_default=func.now()) lead_id = Column(BigInteger, ForeignKey('leads.id')) email_campaign_id = Column(BigInteger, ForeignKey('email_campaigns.id')) model_used = Column(Text) lead = relationship("Lead") email_campaign = relationship("EmailCampaign") class AutomationLog(Base): __tablename__ = 'automation_logs' id = Column(BigInteger, primary_key=True) campaign_id = Column(BigInteger, ForeignKey('campaigns.id')) search_term_id = Column(BigInteger, ForeignKey('search_terms.id')) leads_gathered = Column(BigInteger) emails_sent = Column(BigInteger) start_time = Column(DateTime(timezone=True), server_default=func.now()) end_time = Column(DateTime(timezone=True)) status = Column(Text) logs = Column(JSON) campaign = relationship("Campaign") search_term = relationship("SearchTerm") Base.metadata.create_all(engine)