from datetime import datetime from sqlalchemy import Boolean, Column, DateTime, ForeignKey, Integer, JSON, String, Text from .database import Base # === Phase 1: Core === class User(Base): __tablename__ = "users" id = Column(Integer, primary_key=True, index=True) username = Column(String(50), unique=True, nullable=False) hashed_password = Column(String(255), nullable=False) created_at = Column(DateTime, default=datetime.utcnow) class Character(Base): __tablename__ = "characters" id = Column(Integer, primary_key=True, index=True) name = Column(String(100), nullable=False) niche = Column(String(200), nullable=False) topics = Column(JSON, default=list) tone = Column(Text) visual_style = Column(JSON, default=dict) social_accounts = Column(JSON, default=dict) affiliate_links = Column(JSON, default=list) avatar_url = Column(String(500)) is_active = Column(Boolean, default=True) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) # === Phase 2: Content Generation === class Post(Base): __tablename__ = "posts" id = Column(Integer, primary_key=True, index=True) character_id = Column(Integer, ForeignKey("characters.id"), nullable=False) content_type = Column(String(20), default="text") # text, image, video, carousel text_content = Column(Text) hashtags = Column(JSON, default=list) image_url = Column(String(500)) video_url = Column(String(500)) media_urls = Column(JSON, default=list) affiliate_links_used = Column(JSON, default=list) llm_provider = Column(String(50)) llm_model = Column(String(100)) platform_hint = Column(String(20)) # which platform this was generated for status = Column(String(20), default="draft") # draft, approved, scheduled, published, failed created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) # === Phase 4: Affiliate Links === class AffiliateLink(Base): __tablename__ = "affiliate_links" id = Column(Integer, primary_key=True, index=True) character_id = Column(Integer, ForeignKey("characters.id"), nullable=True) # null = global network = Column(String(100), nullable=False) # amazon, clickbank, etc. name = Column(String(200), nullable=False) url = Column(String(1000), nullable=False) tag = Column(String(100)) topics = Column(JSON, default=list) # relevant topics for auto-insertion is_active = Column(Boolean, default=True) click_count = Column(Integer, default=0) created_at = Column(DateTime, default=datetime.utcnow) # === Phase 5: Scheduling === class EditorialPlan(Base): __tablename__ = "editorial_plans" id = Column(Integer, primary_key=True, index=True) character_id = Column(Integer, ForeignKey("characters.id"), nullable=False) name = Column(String(200), nullable=False) frequency = Column(String(20), default="daily") # daily, twice_daily, weekly, custom posts_per_day = Column(Integer, default=1) platforms = Column(JSON, default=list) # ["facebook", "instagram", "youtube"] content_types = Column(JSON, default=list) # ["text", "image", "video"] posting_times = Column(JSON, default=list) # ["09:00", "18:00"] start_date = Column(DateTime) end_date = Column(DateTime, nullable=True) is_active = Column(Boolean, default=False) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) class ScheduledPost(Base): __tablename__ = "scheduled_posts" id = Column(Integer, primary_key=True, index=True) plan_id = Column(Integer, ForeignKey("editorial_plans.id"), nullable=True) post_id = Column(Integer, ForeignKey("posts.id"), nullable=False) platform = Column(String(20), nullable=False) scheduled_at = Column(DateTime, nullable=False) published_at = Column(DateTime, nullable=True) status = Column(String(20), default="pending") # pending, publishing, published, failed error_message = Column(Text, nullable=True) external_post_id = Column(String(200), nullable=True) created_at = Column(DateTime, default=datetime.utcnow) # === Phase 6-10: Social Accounts === class SocialAccount(Base): __tablename__ = "social_accounts" id = Column(Integer, primary_key=True, index=True) character_id = Column(Integer, ForeignKey("characters.id"), nullable=False) platform = Column(String(20), nullable=False) # facebook, instagram, youtube, tiktok account_name = Column(String(200)) account_id = Column(String(200)) access_token = Column(Text) refresh_token = Column(Text, nullable=True) token_expires_at = Column(DateTime, nullable=True) page_id = Column(String(200), nullable=True) # Facebook page ID extra_data = Column(JSON, default=dict) # platform-specific data is_active = Column(Boolean, default=True) created_at = Column(DateTime, default=datetime.utcnow) # === Phase 11: Comment Management === class Comment(Base): __tablename__ = "comments" id = Column(Integer, primary_key=True, index=True) scheduled_post_id = Column(Integer, ForeignKey("scheduled_posts.id"), nullable=True) platform = Column(String(20), nullable=False) external_comment_id = Column(String(200)) author_name = Column(String(200)) author_id = Column(String(200)) content = Column(Text) ai_suggested_reply = Column(Text, nullable=True) approved_reply = Column(Text, nullable=True) reply_status = Column(String(20), default="pending") # pending, approved, replied, ignored replied_at = Column(DateTime, nullable=True) created_at = Column(DateTime, default=datetime.utcnow) # === System Settings === class SystemSetting(Base): __tablename__ = "system_settings" id = Column(Integer, primary_key=True, index=True) key = Column(String(100), unique=True, nullable=False) value = Column(JSON) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)