from sqlalchemy import create_engine, Column, Integer, String, Boolean, DateTime, JSON, ForeignKey from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker, relationship from datetime import datetime DATABASE_URL = "sqlite:///./mailer.db" engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False}) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) Base = declarative_base() class User(Base): __tablename__ = "users" id = Column(Integer, primary_key=True, index=True) email = Column(String, unique=True, index=True) sender_name = Column(String, nullable=True) reply_to = Column(String, nullable=True) google_token = Column(JSON) # Stores credentials object as JSON created_at = Column(DateTime, default=datetime.utcnow) class Campaign(Base): __tablename__ = "campaigns" id = Column(Integer, primary_key=True, index=True) name = Column(String) subject = Column(String) user_id = Column(Integer, ForeignKey("users.id")) steps = Column(JSON) # List of {day: int, message: str} status = Column(String, default="active") # active, paused, finished created_at = Column(DateTime, default=datetime.utcnow) class Lead(Base): __tablename__ = "leads" id = Column(Integer, primary_key=True, index=True) email = Column(String, index=True) campaign_id = Column(Integer, ForeignKey("campaigns.id")) data = Column(JSON) # Placeholders like {name: "John", company: "Google"} current_step = Column(Integer, default=0) last_contact_at = Column(DateTime) thread_id = Column(String, nullable=True) # Gmail Thread ID status = Column(String, default="pending") # pending, emailed, replied, bounced created_at = Column(DateTime, default=datetime.utcnow) def init_db(): Base.metadata.create_all(bind=engine)