""" BreakPilot Content Service - Database Models Educational Content Management mit Creative Commons Lizenzen """ from sqlalchemy import Column, String, Integer, Float, DateTime, JSON, ForeignKey, Enum, Table from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship from datetime import datetime import enum import uuid Base = declarative_base() # Content Type Enum class ContentType(str, enum.Enum): VIDEO = "video" PDF = "pdf" IMAGE_GALLERY = "image_gallery" MARKDOWN = "markdown" AUDIO = "audio" H5P = "h5p" # CC License Enum class CCLicense(str, enum.Enum): CC_BY = "CC-BY-4.0" CC_BY_SA = "CC-BY-SA-4.0" CC_BY_NC = "CC-BY-NC-4.0" CC_BY_NC_SA = "CC-BY-NC-SA-4.0" CC0 = "CC0-1.0" # Category Enum class ContentCategory(str, enum.Enum): MOVEMENT = "movement" MATH = "math" STEAM = "steam" LANGUAGE = "language" ARTS = "arts" SOCIAL = "social" MINDFULNESS = "mindfulness" # Content Status class ContentStatus(str, enum.Enum): DRAFT = "draft" REVIEW = "review" PUBLISHED = "published" ARCHIVED = "archived" # Many-to-Many: Content <-> Tags content_tags = Table( 'content_tags', Base.metadata, Column('content_id', String, ForeignKey('contents.id')), Column('tag_id', String, ForeignKey('tags.id')) ) class Content(Base): """Educational Content Model""" __tablename__ = 'contents' # Primary Key id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) # Creator Info creator_id = Column(String, nullable=False, index=True) # User ID from consent-service creator_name = Column(String, nullable=False) creator_email = Column(String) # Content Metadata title = Column(String(500), nullable=False, index=True) description = Column(String(5000)) content_type = Column(Enum(ContentType), nullable=False) category = Column(Enum(ContentCategory), nullable=False, index=True) # License license = Column(Enum(CCLicense), nullable=False, default=CCLicense.CC_BY_SA) # Age Range age_min = Column(Integer, default=6) age_max = Column(Integer, default=18) # Files & URLs files = Column(JSON, default=list) # List of file URLs in MinIO thumbnail_url = Column(String) embed_url = Column(String) # For YouTube, Vimeo, etc. # H5P Specific h5p_content_id = Column(String) # H5P content ID if type=h5p # Matrix Integration matrix_room_id = Column(String) # Associated Matrix room for discussion matrix_event_id = Column(String) # Matrix message event ID # Status status = Column(Enum(ContentStatus), default=ContentStatus.DRAFT, index=True) # Analytics downloads = Column(Integer, default=0) views = Column(Integer, default=0) avg_rating = Column(Float, default=0.0) rating_count = Column(Integer, default=0) impact_score = Column(Float, default=0.0) # Future: Impact-Scoring # Timestamps created_at = Column(DateTime, default=datetime.utcnow, nullable=False) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) published_at = Column(DateTime) # Relationships ratings = relationship("Rating", back_populates="content", cascade="all, delete-orphan") tags = relationship("Tag", secondary=content_tags, back_populates="contents") def __repr__(self): return f"" class Rating(Base): """Content Ratings by Teachers""" __tablename__ = 'ratings' id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) content_id = Column(String, ForeignKey('contents.id'), nullable=False) user_id = Column(String, nullable=False, index=True) # Teacher ID user_name = Column(String) stars = Column(Integer, nullable=False) # 1-5 comment = Column(String(2000)) created_at = Column(DateTime, default=datetime.utcnow) # Relationship content = relationship("Content", back_populates="ratings") def __repr__(self): return f"" class Tag(Base): """Content Tags for Search/Filter""" __tablename__ = 'tags' id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) name = Column(String(100), unique=True, nullable=False, index=True) category = Column(String(100)) # Optional grouping # Relationship contents = relationship("Content", secondary=content_tags, back_populates="tags") def __repr__(self): return f"" class Download(Base): """Download Tracking (für Impact-Scoring)""" __tablename__ = 'downloads' id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) content_id = Column(String, ForeignKey('contents.id'), nullable=False, index=True) user_id = Column(String, nullable=False, index=True) # Teacher ID downloaded_at = Column(DateTime, default=datetime.utcnow, index=True) ip_address = Column(String) # Optional, anonymisiert nach 7 Tagen def __repr__(self): return f""