Coverage for polar/models/downloadable.py: 100%
30 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-12-05 16:17 +0000
« prev ^ index » next coverage.py v7.10.6, created at 2025-12-05 16:17 +0000
1from datetime import datetime 1ab
2from enum import StrEnum 1ab
3from uuid import UUID 1ab
5from sqlalchemy import ( 1ab
6 TIMESTAMP,
7 ForeignKey,
8 Integer,
9 String,
10 UniqueConstraint,
11 Uuid,
12)
13from sqlalchemy.orm import Mapped, declared_attr, mapped_column, relationship 1ab
15from polar.kit.db.models import RecordModel 1ab
17from .benefit import Benefit 1ab
18from .customer import Customer 1ab
19from .file import File 1ab
22class DownloadableStatus(StrEnum): 1ab
23 granted = "granted" 1ab
24 revoked = "revoked" 1ab
27class Downloadable(RecordModel): 1ab
28 __tablename__ = "downloadables" 1ab
29 __table_args__ = (UniqueConstraint("customer_id", "file_id", "benefit_id"),) 1ab
31 file_id: Mapped[UUID] = mapped_column( 1ab
32 Uuid, ForeignKey("files.id"), nullable=False, index=True
33 )
35 @declared_attr 1ab
36 def file(cls) -> Mapped[File]: 1ab
37 return relationship(File, lazy="raise") 1ab
39 status: Mapped[DownloadableStatus] = mapped_column(String, nullable=False) 1ab
41 customer_id: Mapped[UUID] = mapped_column( 1ab
42 Uuid,
43 ForeignKey("customers.id", ondelete="cascade"),
44 nullable=False,
45 # Don't create an index for customer_id
46 # as it's covered by the unique constraint, being the leading column of it
47 index=False,
48 )
50 @declared_attr 1ab
51 def customer(cls) -> Mapped[Customer]: 1ab
52 return relationship("Customer", lazy="raise") 1ab
54 benefit_id: Mapped[UUID] = mapped_column( 1ab
55 Uuid,
56 ForeignKey("benefits.id", ondelete="cascade"),
57 nullable=False,
58 index=True,
59 )
61 @declared_attr 1ab
62 def benefit(cls) -> Mapped[Benefit]: 1ab
63 return relationship("Benefit", lazy="raise") 1ab
65 downloaded: Mapped[int] = mapped_column(Integer, nullable=False, default=0) 1ab
67 last_downloaded_at: Mapped[datetime | None] = mapped_column( 1ab
68 TIMESTAMP(timezone=True),
69 nullable=True,
70 )