from django.db import models class Book(models.Model): """Represents a book in the user's library.""" title = models.CharField(max_length=512) author = models.CharField(max_length=256, blank=True, default="") total_pages = models.PositiveIntegerField(default=0) cover_image = models.URLField(blank=True, default="") created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: db_table = "books_book" verbose_name = "Book" verbose_name_plural = "Books" ordering = ["title"] def __str__(self) -> str: return self.title class Chapter(models.Model): """A chapter within a book, containing the text/markdown content.""" book = models.ForeignKey( Book, on_delete=models.CASCADE, related_name="chapters", db_index=True, ) title = models.CharField(max_length=512) number = models.PositiveIntegerField() content = models.TextField(blank=True, default="") created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: db_table = "books_chapter" verbose_name = "Chapter" verbose_name_plural = "Chapters" ordering = ["book", "number"] constraints = [ models.UniqueConstraint( fields=["book", "number"], name="uq_book_chapter_number", ) ] def __str__(self) -> str: return f"{self.book.title} — Ch. {self.number}: {self.title}" class ReadingProgress(models.Model): """Tracks a user's reading progress within a book.""" user = models.ForeignKey( "users.User", on_delete=models.CASCADE, related_name="reading_progress", db_index=True, ) book = models.ForeignKey( Book, on_delete=models.CASCADE, related_name="reading_progress", db_index=True, ) current_chapter = models.PositiveIntegerField(default=1) current_position = models.PositiveIntegerField(default=0) percentage = models.FloatField(default=0.0) updated_at = models.DateTimeField(auto_now=True) class Meta: db_table = "books_reading_progress" verbose_name = "Reading Progress" verbose_name_plural = "Reading Progress" ordering = ["-updated_at"] constraints = [ models.UniqueConstraint( fields=["user", "book"], name="uq_reading_progress_user_book", ) ] def __str__(self) -> str: return f"{self.user} — {self.book.title} ({self.percentage:.0f}%)"