123 lines
4.8 KiB
Python
123 lines
4.8 KiB
Python
"""Summary model for storing YouTube video summaries."""
|
|
|
|
from sqlalchemy import Column, String, Text, Float, DateTime, ForeignKey, JSON, Integer, Boolean, Index
|
|
from sqlalchemy.orm import relationship
|
|
import uuid
|
|
from datetime import datetime
|
|
import secrets
|
|
|
|
from backend.core.database_registry import registry
|
|
from backend.models.base import Model
|
|
|
|
Base = registry.Base
|
|
|
|
|
|
class Summary(Model):
|
|
"""Summary model for storing processed video summaries."""
|
|
|
|
__tablename__ = "summaries"
|
|
__table_args__ = {"extend_existing": True}
|
|
|
|
# Primary key
|
|
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
|
|
|
|
# Foreign key to user (nullable for anonymous summaries)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=True, index=True)
|
|
|
|
# Video information
|
|
video_id = Column(String(20), nullable=False, index=True)
|
|
video_title = Column(Text)
|
|
video_url = Column(Text, nullable=False)
|
|
video_duration = Column(Integer) # Duration in seconds
|
|
channel_name = Column(String(255))
|
|
published_at = Column(DateTime)
|
|
|
|
# Transcript and summary
|
|
transcript = Column(Text)
|
|
summary = Column(Text)
|
|
key_points = Column(JSON) # Array of key points
|
|
main_themes = Column(JSON) # Array of main themes
|
|
chapters = Column(JSON) # Array of chapter objects with timestamps
|
|
actionable_insights = Column(JSON) # Array of actionable insights
|
|
|
|
# AI processing details
|
|
model_used = Column(String(50))
|
|
processing_time = Column(Float) # Time in seconds
|
|
confidence_score = Column(Float)
|
|
quality_score = Column(Float)
|
|
|
|
# Cost tracking
|
|
input_tokens = Column(Integer)
|
|
output_tokens = Column(Integer)
|
|
cost_usd = Column(Float)
|
|
|
|
# Configuration used
|
|
summary_length = Column(String(20)) # brief, standard, detailed
|
|
focus_areas = Column(JSON) # Array of focus areas
|
|
include_timestamps = Column(Boolean, default=False)
|
|
|
|
# Source tracking (added for unified storage)
|
|
source = Column(String(20), default="frontend") # frontend, cli, api, migrated_from_file
|
|
job_id = Column(String(36), nullable=True) # Pipeline job ID
|
|
|
|
# History management fields
|
|
is_starred = Column(Boolean, default=False, index=True)
|
|
notes = Column(Text) # User's personal notes
|
|
tags = Column(JSON) # Array of user tags
|
|
shared_token = Column(String(64), unique=True, nullable=True) # For sharing
|
|
is_public = Column(Boolean, default=False)
|
|
view_count = Column(Integer, default=0)
|
|
|
|
# Timestamps
|
|
created_at = Column(DateTime, default=datetime.utcnow)
|
|
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
|
|
|
# Relationships
|
|
user = relationship("backend.models.user.User", back_populates="summaries")
|
|
exports = relationship("backend.models.summary.ExportHistory", back_populates="summary", cascade="all, delete-orphan")
|
|
agent_analyses = relationship("backend.models.agent_models.AgentSummary", back_populates="summary", cascade="all, delete-orphan")
|
|
|
|
# Enhanced export relationships (Story 4.4)
|
|
export_metadata = relationship("backend.models.enhanced_export.ExportMetadata", back_populates="summary", cascade="all, delete-orphan")
|
|
sections = relationship("backend.models.enhanced_export.SummarySection", back_populates="summary", cascade="all, delete-orphan")
|
|
|
|
def __repr__(self):
|
|
return f"<Summary(video_id='{self.video_id}', user_id='{self.user_id}', model='{self.model_used}')>"
|
|
|
|
def generate_share_token(self):
|
|
"""Generate a unique share token for this summary."""
|
|
self.shared_token = secrets.token_urlsafe(32)
|
|
return self.shared_token
|
|
|
|
|
|
# Create composite indexes for performance
|
|
Index('idx_user_starred', Summary.user_id, Summary.is_starred)
|
|
Index('idx_user_created', Summary.user_id, Summary.created_at)
|
|
|
|
|
|
class ExportHistory(Model):
|
|
"""Track export history for summaries."""
|
|
|
|
__tablename__ = "export_history"
|
|
__table_args__ = {"extend_existing": True}
|
|
|
|
# Primary key
|
|
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
|
|
|
|
# Foreign keys
|
|
summary_id = Column(String(36), ForeignKey("summaries.id"), nullable=False, index=True)
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=True)
|
|
|
|
# Export details
|
|
export_format = Column(String(20), nullable=False) # markdown, pdf, html, json, text
|
|
file_size = Column(Integer) # Size in bytes
|
|
file_path = Column(Text) # Storage path if saved
|
|
|
|
# Metadata
|
|
created_at = Column(DateTime, default=datetime.utcnow)
|
|
|
|
# Relationships
|
|
summary = relationship("backend.models.summary.Summary", back_populates="exports")
|
|
|
|
def __repr__(self):
|
|
return f"<ExportHistory(summary_id='{self.summary_id}', format='{self.export_format}')>" |