from datetime import datetime from sqlalchemy import Boolean, DateTime, Float, ForeignKey, Integer, String, Text from sqlalchemy.orm import Mapped, mapped_column, relationship from app.db.base_class import Base class Author(Base): """Author model for manga creators.""" id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) name: Mapped[str] = mapped_column(String(100), nullable=False, index=True) biography: Mapped[str | None] = mapped_column(Text, nullable=True) # Relationship with Manga manga_list = relationship("Manga", back_populates="author") created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False) updated_at: Mapped[datetime] = mapped_column( DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False ) class Publisher(Base): """Publisher model for manga books.""" id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) name: Mapped[str] = mapped_column(String(100), nullable=False, index=True) website: Mapped[str | None] = mapped_column(String(255), nullable=True) country: Mapped[str | None] = mapped_column(String(50), nullable=True) # Relationship with Manga manga_list = relationship("Manga", back_populates="publisher") created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False) updated_at: Mapped[datetime] = mapped_column( DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False ) class Genre(Base): """Genre model for manga classification.""" id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) name: Mapped[str] = mapped_column(String(50), nullable=False, index=True, unique=True) description: Mapped[str | None] = mapped_column(Text, nullable=True) # Relationship with Manga manga_list = relationship("MangaGenre", back_populates="genre") created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False) updated_at: Mapped[datetime] = mapped_column( DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False ) class Manga(Base): """Manga model representing a manga book in inventory.""" id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) title: Mapped[str] = mapped_column(String(255), nullable=False, index=True) original_title: Mapped[str | None] = mapped_column(String(255), nullable=True) isbn: Mapped[str | None] = mapped_column(String(20), nullable=True, index=True, unique=True) description: Mapped[str | None] = mapped_column(Text, nullable=True) # Volume information volume_number: Mapped[int | None] = mapped_column(Integer, nullable=True) total_volumes: Mapped[int | None] = mapped_column(Integer, nullable=True) # Foreign keys author_id: Mapped[int | None] = mapped_column(Integer, ForeignKey("author.id"), nullable=True) publisher_id: Mapped[int | None] = mapped_column( Integer, ForeignKey("publisher.id"), nullable=True ) # Relationships author = relationship("Author", back_populates="manga_list") publisher = relationship("Publisher", back_populates="manga_list") genres = relationship("MangaGenre", back_populates="manga") # Publication information publication_date: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) # Physical attributes page_count: Mapped[int | None] = mapped_column(Integer, nullable=True) # Inventory information price: Mapped[float | None] = mapped_column(Float, nullable=True) quantity: Mapped[int] = mapped_column(Integer, default=0, nullable=False) in_stock: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False) # Ratings and metadata rating: Mapped[float | None] = mapped_column(Float, nullable=True) language: Mapped[str | None] = mapped_column(String(50), nullable=True) cover_image_url: Mapped[str | None] = mapped_column(String(255), nullable=True) created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False) updated_at: Mapped[datetime] = mapped_column( DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False ) class MangaGenre(Base): """Junction table for many-to-many relationship between Manga and Genre.""" manga_id: Mapped[int] = mapped_column(Integer, ForeignKey("manga.id"), primary_key=True) genre_id: Mapped[int] = mapped_column(Integer, ForeignKey("genre.id"), primary_key=True) # Relationships manga = relationship("Manga", back_populates="genres") genre = relationship("Genre", back_populates="manga_list") created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False)