69 lines
3.0 KiB
Python
69 lines
3.0 KiB
Python
"""
|
|
Podcast Maker Models
|
|
|
|
Database models for podcast project persistence and state management.
|
|
"""
|
|
|
|
from sqlalchemy import Column, Integer, String, DateTime, Float, Boolean, JSON, Text, Index
|
|
from sqlalchemy.ext.declarative import declarative_base
|
|
from datetime import datetime
|
|
|
|
# Use the same Base as subscription models for consistency
|
|
from models.subscription_models import Base
|
|
|
|
|
|
class PodcastProject(Base):
|
|
"""
|
|
Database model for podcast project state.
|
|
Stores complete project state to enable cross-device resume.
|
|
"""
|
|
|
|
__tablename__ = "podcast_projects"
|
|
|
|
# Primary fields
|
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
project_id = Column(String(255), unique=True, nullable=False, index=True) # User-facing project ID
|
|
user_id = Column(String(255), nullable=False, index=True) # Clerk user ID
|
|
|
|
# Project metadata
|
|
idea = Column(String(1000), nullable=False) # Episode idea or URL
|
|
duration = Column(Integer, nullable=False) # Duration in minutes
|
|
speakers = Column(Integer, nullable=False, default=1) # Number of speakers
|
|
budget_cap = Column(Float, nullable=False, default=50.0) # Budget cap in USD
|
|
|
|
# Project state (stored as JSON)
|
|
# This mirrors the PodcastProjectState interface from frontend
|
|
analysis = Column(JSON, nullable=True) # PodcastAnalysis
|
|
queries = Column(JSON, nullable=True) # List[Query]
|
|
selected_queries = Column(JSON, nullable=True) # Array of query IDs
|
|
research = Column(JSON, nullable=True) # Research object
|
|
raw_research = Column(JSON, nullable=True) # BlogResearchResponse
|
|
estimate = Column(JSON, nullable=True) # PodcastEstimate
|
|
script_data = Column(JSON, nullable=True) # Script object
|
|
render_jobs = Column(JSON, nullable=True) # List[Job]
|
|
knobs = Column(JSON, nullable=True) # Knobs settings
|
|
research_provider = Column(String(50), nullable=True, default="google") # Research provider
|
|
|
|
# UI state
|
|
show_script_editor = Column(Boolean, default=False)
|
|
show_render_queue = Column(Boolean, default=False)
|
|
current_step = Column(String(50), nullable=True) # 'create' | 'analysis' | 'research' | 'script' | 'render'
|
|
|
|
# Status
|
|
status = Column(String(50), default="draft", nullable=False, index=True) # draft, in_progress, completed, archived
|
|
is_favorite = Column(Boolean, default=False, index=True)
|
|
|
|
# Final combined video URL (persisted for reloads)
|
|
final_video_url = Column(String(1000), nullable=True) # URL to final combined podcast video
|
|
|
|
# Timestamps
|
|
created_at = Column(DateTime, default=datetime.utcnow, nullable=False, index=True)
|
|
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False, index=True)
|
|
|
|
# Composite indexes for common query patterns
|
|
__table_args__ = (
|
|
Index('idx_user_status_created', 'user_id', 'status', 'created_at'),
|
|
Index('idx_user_favorite_updated', 'user_id', 'is_favorite', 'updated_at'),
|
|
)
|
|
|