beatmatchr/backend/models.py
2025-11-10 16:11:36 -05:00

84 lines
2.7 KiB
Python

from __future__ import annotations
import uuid
from datetime import datetime
from sqlalchemy import Column, DateTime, Float, ForeignKey, JSON, String, Text, Integer
from sqlalchemy.orm import relationship
from .db import Base, db_session
class TimestampMixin:
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
updated_at = Column(
DateTime,
default=datetime.utcnow,
onupdate=datetime.utcnow,
nullable=False,
)
class Project(Base, TimestampMixin):
__tablename__ = "projects"
id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
name = Column(String, nullable=False)
audio_tracks = relationship("AudioTrack", back_populates="project", cascade="all, delete-orphan")
source_clips = relationship("SourceClip", back_populates="project", cascade="all, delete-orphan")
lyrics = relationship("Lyrics", back_populates="project", uselist=False, cascade="all, delete-orphan")
class AudioTrack(Base, TimestampMixin):
__tablename__ = "audio_tracks"
id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
project_id = Column(String, ForeignKey("projects.id"), nullable=False, index=True)
storage_path = Column(Text, nullable=False)
local_path = Column(Text, nullable=True)
duration_seconds = Column(Float, nullable=True)
bpm = Column(Float, nullable=True)
beat_grid = Column(JSON, nullable=True)
project = relationship("Project", back_populates="audio_tracks")
class SourceClip(Base, TimestampMixin):
__tablename__ = "source_clips"
id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
project_id = Column(String, ForeignKey("projects.id"), nullable=False, index=True)
origin = Column(String, nullable=False)
original_url = Column(Text, nullable=True)
storage_path = Column(Text, nullable=False)
thumbnail_path = Column(Text, nullable=True)
duration_seconds = Column(Float, nullable=True)
width = Column(Integer, nullable=True)
height = Column(Integer, nullable=True)
fps = Column(Float, nullable=True)
project = relationship("Project", back_populates="source_clips")
class Lyrics(Base, TimestampMixin):
__tablename__ = "lyrics"
id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
project_id = Column(String, ForeignKey("projects.id"), nullable=False, unique=True, index=True)
source = Column(String, nullable=False)
raw_text = Column(Text, nullable=False)
timed_words = Column(JSON, nullable=True)
timed_lines = Column(JSON, nullable=True)
project = relationship("Project", back_populates="lyrics")
__all__ = [
"Project",
"AudioTrack",
"SourceClip",
"Lyrics",
"db_session",
]