from sqlalchemy import Column, Integer, String, Boolean, DateTime, ForeignKey from sqlalchemy.orm import relationship from datetime import datetime, timedelta from config.database import Base class AccessCode(Base): __tablename__ = 'access_codes' id = Column(Integer, primary_key=True) code = Column(String(50), unique=True, nullable=False, index=True) # Code metadata created_at = Column(DateTime, default=datetime.utcnow, nullable=False) expires_at = Column(DateTime, nullable=False) # Code itself expires (1 week default) # Usage tracking is_used = Column(Boolean, default=False, nullable=False) used_at = Column(DateTime, nullable=True) used_by_email = Column(String(255), nullable=True) used_by_user_id = Column(Integer, ForeignKey('users.id'), nullable=True) # Access grant info access_duration_days = Column(Integer, default=30, nullable=False) # 1 month for beta testers # Code type and promo info code_type = Column(String(20), default='beta', nullable=False) # 'beta' or 'promo' discount_percentage = Column(Integer, nullable=True) # For promo codes (e.g., 50 for 50% off) promo_target = Column(String(20), nullable=True) # 'all' or 'first_time_only' description = Column(String(500), nullable=True) # Custom description (e.g., "50% off for first-time users") # Optional note note = Column(String(255), nullable=True) # e.g., "Beta tester - Conference 2025" # Relationships user = relationship("User", foreign_keys=[used_by_user_id], backref="access_code_used") def __repr__(self): return f"" def is_valid(self): """Check if code is still valid (not used and not expired)""" return not self.is_used and datetime.utcnow() < self.expires_at def to_dict(self): return { 'id': self.id, 'code': self.code, 'created_at': self.created_at.isoformat() if self.created_at else None, 'expires_at': self.expires_at.isoformat() if self.expires_at else None, 'is_used': self.is_used, 'used_at': self.used_at.isoformat() if self.used_at else None, 'used_by_email': self.used_by_email, 'access_duration_days': self.access_duration_days, 'code_type': self.code_type, 'discount_percentage': self.discount_percentage, 'promo_target': self.promo_target, 'description': self.description, 'note': self.note, 'is_valid': self.is_valid() }