feat(sub): subscription logic (pre release)
This commit is contained in:
@@ -1,8 +1,22 @@
|
||||
from .addons import Addon
|
||||
from .invoice import Invoice
|
||||
from .orders import Order, OrderAddon
|
||||
from .pricing import PricingConfig
|
||||
from .sessions import Session
|
||||
from .subscription_addons import SubscriptionAddon
|
||||
from .subscriptions import Subscription
|
||||
from .transactions import BalanceTransaction
|
||||
from .users import User
|
||||
|
||||
__all__ = ["Addon", "BalanceTransaction", "Invoice", "PricingConfig", "Session", "User"]
|
||||
__all__ = [
|
||||
"Addon",
|
||||
"BalanceTransaction",
|
||||
"Invoice",
|
||||
"Order",
|
||||
"OrderAddon",
|
||||
"PricingConfig",
|
||||
"Session",
|
||||
"Subscription",
|
||||
"SubscriptionAddon",
|
||||
"User",
|
||||
]
|
||||
|
||||
48
db/models/orders.py
Normal file
48
db/models/orders.py
Normal file
@@ -0,0 +1,48 @@
|
||||
from enum import StrEnum
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from sqlalchemy import INTEGER, Enum, ForeignKey
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from db.base import Base
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from db.models import User
|
||||
|
||||
|
||||
class OrderStatus(StrEnum):
|
||||
PENDING = "pending"
|
||||
PAID = "paid"
|
||||
DISCARDED = "discarded"
|
||||
|
||||
|
||||
class OrderAddon(Base):
|
||||
__tablename__ = "order_addons"
|
||||
|
||||
id: Mapped[int] = mapped_column(
|
||||
INTEGER, nullable=False, unique=True, autoincrement=True, primary_key=True
|
||||
)
|
||||
order_id: Mapped[int] = mapped_column(ForeignKey("orders.id"), nullable=False)
|
||||
addon_id: Mapped[str] = mapped_column(ForeignKey("addons.id"), nullable=False)
|
||||
|
||||
order: Mapped["Order"] = relationship("Order", back_populates="addons", lazy="selectin")
|
||||
|
||||
|
||||
class Order(Base):
|
||||
__tablename__ = "orders"
|
||||
|
||||
id: Mapped[int] = mapped_column(
|
||||
INTEGER, nullable=False, autoincrement=True, unique=True, primary_key=True
|
||||
)
|
||||
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), nullable=False)
|
||||
|
||||
devices: Mapped[int] = mapped_column(INTEGER, nullable=False)
|
||||
duration_days: Mapped[int] = mapped_column(INTEGER, nullable=False)
|
||||
status: Mapped[OrderStatus] = mapped_column(
|
||||
Enum(OrderStatus, name="orderstatus"), nullable=False, default=OrderStatus.PENDING
|
||||
)
|
||||
|
||||
user: Mapped["User"] = relationship("User", back_populates="orders", lazy="selectin")
|
||||
addons: Mapped[list["OrderAddon"]] = relationship(
|
||||
"OrderAddon", back_populates="order", lazy="selectin"
|
||||
)
|
||||
23
db/models/subscription_addons.py
Normal file
23
db/models/subscription_addons.py
Normal file
@@ -0,0 +1,23 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from sqlalchemy import INTEGER, ForeignKey
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from db.base import Base
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from db.models import Subscription
|
||||
|
||||
|
||||
class SubscriptionAddon(Base):
|
||||
__tablename__ = "subscription_addons"
|
||||
|
||||
id: Mapped[int] = mapped_column(
|
||||
INTEGER, nullable=False, unique=True, autoincrement=True, primary_key=True
|
||||
)
|
||||
subscription_id: Mapped[int] = mapped_column(ForeignKey("subscriptions.id"), nullable=False)
|
||||
addon_id: Mapped[str] = mapped_column(ForeignKey("addons.id"), nullable=False)
|
||||
|
||||
subscription: Mapped["Subscription"] = relationship(
|
||||
"Subscription", back_populates="addons", lazy="selectin"
|
||||
)
|
||||
33
db/models/subscriptions.py
Normal file
33
db/models/subscriptions.py
Normal file
@@ -0,0 +1,33 @@
|
||||
import datetime
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from sqlalchemy import INTEGER, DateTime, Enum, ForeignKey
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from db.base import Base
|
||||
from schemas.enums import SubscriptionStatus
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from db.models import SubscriptionAddon, User
|
||||
|
||||
|
||||
class Subscription(Base):
|
||||
__tablename__ = "subscriptions"
|
||||
|
||||
id: Mapped[int] = mapped_column(
|
||||
INTEGER, nullable=False, autoincrement=True, unique=True, primary_key=True
|
||||
)
|
||||
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), nullable=False, unique=True)
|
||||
|
||||
devices: Mapped[int] = mapped_column(INTEGER, nullable=False)
|
||||
status: Mapped[SubscriptionStatus] = mapped_column(
|
||||
Enum(SubscriptionStatus, name="subscriptionstatus"),
|
||||
nullable=False,
|
||||
default=SubscriptionStatus.EXPIRED,
|
||||
)
|
||||
expires_at: Mapped[datetime.datetime] = mapped_column(DateTime(True), nullable=False)
|
||||
|
||||
user: Mapped["User"] = relationship("User", back_populates="subscription", lazy="selectin")
|
||||
addons: Mapped[list["SubscriptionAddon"]] = relationship(
|
||||
"SubscriptionAddon", back_populates="subscription", lazy="selectin"
|
||||
)
|
||||
@@ -6,7 +6,7 @@ from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
from db.base import Base
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from db.models.sessions import Session
|
||||
from db.models import Order, Session, Subscription
|
||||
|
||||
|
||||
class User(Base):
|
||||
@@ -22,6 +22,10 @@ class User(Base):
|
||||
|
||||
balance: Mapped[float] = mapped_column(REAL, nullable=False, default=0)
|
||||
|
||||
orders: Mapped[list["Order"]] = relationship("Order", back_populates="user", lazy="selectin")
|
||||
subscription: Mapped["Subscription"] = relationship(
|
||||
"Subscription", back_populates="user", lazy="selectin"
|
||||
)
|
||||
sessions: Mapped[list["Session"]] = relationship(back_populates="user", lazy="selectin")
|
||||
referal: Mapped["User | None"] = relationship(
|
||||
"User",
|
||||
|
||||
Reference in New Issue
Block a user