NotebookLMClone / data /models.py
github-actions[bot]
Sync from GitHub e48aa5f27523b35a22c1a01acbb2b835cdc28984
aacd162
from __future__ import annotations
from datetime import datetime
from sqlalchemy import DateTime, Float, ForeignKey, Integer, String, Text, func, JSON
from sqlalchemy.orm import Mapped, mapped_column, relationship
from data.db import Base
class User(Base):
__tablename__ = "users"
id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
email: Mapped[str] = mapped_column(String(255), nullable=False, unique=True, index=True)
display_name: Mapped[str | None] = mapped_column(String(255))
avatar_url: Mapped[str | None] = mapped_column(String(1024))
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), server_default=func.now(), nullable=False
)
notebooks: Mapped[list[Notebook]] = relationship(
"Notebook", back_populates="owner", cascade="all, delete-orphan"
)
class Notebook(Base):
__tablename__ = "notebooks"
id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
owner_user_id: Mapped[int] = mapped_column(
ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True
)
title: Mapped[str] = mapped_column(String(255), nullable=False)
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), server_default=func.now(), nullable=False
)
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False
)
owner: Mapped[User] = relationship("User", back_populates="notebooks")
sources: Mapped[list[Source]] = relationship(
"Source", back_populates="notebook", cascade="all, delete-orphan"
)
chat_threads: Mapped[list[ChatThread]] = relationship(
"ChatThread", back_populates="notebook", cascade="all, delete-orphan"
)
artifacts: Mapped[list[Artifact]] = relationship(
"Artifact", back_populates="notebook", cascade="all, delete-orphan"
)
class Source(Base):
__tablename__ = "sources"
id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
notebook_id: Mapped[int] = mapped_column(
ForeignKey("notebooks.id", ondelete="CASCADE"), nullable=False, index=True
)
type: Mapped[str] = mapped_column(String(50), nullable=False)
title: Mapped[str | None] = mapped_column(String(255))
original_name: Mapped[str | None] = mapped_column(String(1024))
url: Mapped[str | None] = mapped_column(String(2048))
storage_path: Mapped[str | None] = mapped_column(String(1024))
status: Mapped[str] = mapped_column(String(50), nullable=False, default="pending")
ingested_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
notebook: Mapped[Notebook] = relationship("Notebook", back_populates="sources")
citations: Mapped[list[MessageCitation]] = relationship(
"MessageCitation", back_populates="source", cascade="all, delete-orphan"
)
class ChatThread(Base):
__tablename__ = "chat_threads"
id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
notebook_id: Mapped[int] = mapped_column(
ForeignKey("notebooks.id", ondelete="CASCADE"), nullable=False, index=True
)
title: Mapped[str | None] = mapped_column(String(255))
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), server_default=func.now(), nullable=False
)
notebook: Mapped[Notebook] = relationship("Notebook", back_populates="chat_threads")
messages: Mapped[list[Message]] = relationship(
"Message", back_populates="thread", cascade="all, delete-orphan"
)
class Message(Base):
__tablename__ = "messages"
id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
thread_id: Mapped[int] = mapped_column(
ForeignKey("chat_threads.id", ondelete="CASCADE"), nullable=False, index=True
)
role: Mapped[str] = mapped_column(String(20), nullable=False)
content: Mapped[str] = mapped_column(Text, nullable=False)
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), server_default=func.now(), nullable=False
)
thread: Mapped[ChatThread] = relationship("ChatThread", back_populates="messages")
citations: Mapped[list[MessageCitation]] = relationship(
"MessageCitation", back_populates="message", cascade="all, delete-orphan"
)
class MessageCitation(Base):
__tablename__ = "message_citations"
id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
message_id: Mapped[int] = mapped_column(
ForeignKey("messages.id", ondelete="CASCADE"), nullable=False, index=True
)
source_id: Mapped[int] = mapped_column(
ForeignKey("sources.id", ondelete="CASCADE"), nullable=False, index=True
)
chunk_ref: Mapped[str | None] = mapped_column(String(255))
quote: Mapped[str | None] = mapped_column(Text)
score: Mapped[float | None] = mapped_column(Float)
message: Mapped[Message] = relationship("Message", back_populates="citations")
source: Mapped[Source] = relationship("Source", back_populates="citations")
class Artifact(Base):
"""Generated artifacts: quizzes, podcasts, reports."""
__tablename__ = "artifacts"
id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
notebook_id: Mapped[int] = mapped_column(
ForeignKey("notebooks.id", ondelete="CASCADE"), nullable=False, index=True
)
type: Mapped[str] = mapped_column(String(50), nullable=False) # 'quiz', 'podcast', 'report'
title: Mapped[str | None] = mapped_column(String(255))
status: Mapped[str] = mapped_column(String(50), nullable=False, default="pending")
file_path: Mapped[str | None] = mapped_column(String(1024))
artifact_metadata: Mapped[dict | None] = mapped_column("metadata", JSON)
content: Mapped[str | None] = mapped_column(Text)
error_message: Mapped[str | None] = mapped_column(Text)
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), server_default=func.now(), nullable=False
)
generated_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
notebook: Mapped[Notebook] = relationship("Notebook", back_populates="artifacts")