feat: added duration_days to /users/subscriptions

This commit is contained in:
2026-08-17 21:33:08 +07:00
parent 8b6c43f89a
commit 05914f0b23
5 changed files with 40 additions and 3 deletions

View File

@@ -0,0 +1,32 @@
"""+subscription.duration_days
Revision ID: f4ece5936e3d
Revises: 135672cdf14a
Create Date: 2026-08-17 21:23:17.900314
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = 'f4ece5936e3d'
down_revision: Union[str, Sequence[str], None] = '135672cdf14a'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('subscriptions', sa.Column('duration_days', sa.INTEGER(), nullable=True))
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('subscriptions', 'duration_days')
# ### end Alembic commands ###

View File

@@ -20,6 +20,7 @@ class Subscription(Base):
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), nullable=False, unique=True) user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), nullable=False, unique=True)
devices: Mapped[int] = mapped_column(INTEGER, nullable=False) devices: Mapped[int] = mapped_column(INTEGER, nullable=False)
duration_days: Mapped[int] = mapped_column(INTEGER, default=30, nullable=True)
status: Mapped[SubscriptionStatus] = mapped_column( status: Mapped[SubscriptionStatus] = mapped_column(
Enum(SubscriptionStatus, name="subscriptionstatus"), Enum(SubscriptionStatus, name="subscriptionstatus"),
nullable=False, nullable=False,

View File

@@ -30,6 +30,7 @@ async def get_subscription(ctx: AuthContext = Depends(get_auth_context)):
expires_at=None, expires_at=None,
addon_ids=[], addon_ids=[],
subscription_link=None, subscription_link=None,
duration_days=None,
) )
rw_user = await get_rw_user(get_sdk(), ctx.user.telegram_id, ctx.user.username) rw_user = await get_rw_user(get_sdk(), ctx.user.telegram_id, ctx.user.username)
@@ -39,6 +40,7 @@ async def get_subscription(ctx: AuthContext = Depends(get_auth_context)):
expires_at=sub.expires_at, expires_at=sub.expires_at,
addon_ids=[a.addon_id for a in sub.addons], addon_ids=[a.addon_id for a in sub.addons],
subscription_link=build_subscription_link(rw_user.short_uuid), subscription_link=build_subscription_link(rw_user.short_uuid),
duration_days=sub.duration_days,
) )

View File

@@ -4,11 +4,12 @@ from pydantic import BaseModel, Field
class SubscriptionData(BaseModel): class SubscriptionData(BaseModel):
has_subscription: bool = Field()
devices: int | None = Field(None) devices: int | None = Field(None)
expires_at: datetime | None = Field(None) expires_at: datetime | None = Field(None)
addon_ids: list[str] = Field(default_factory=list) addon_ids: list[str] = Field(default_factory=list)
subscription_link: str | None = Field(None) subscription_link: str | None = Field(None)
has_subscription: bool = Field() duration_days: int | None = Field(None)
class UserInfo(BaseModel): class UserInfo(BaseModel):

View File

@@ -72,7 +72,7 @@ async def replace_subscription_addons(
async def ensure_subscription( async def ensure_subscription(
user: User, session: AsyncSession, starts_at: datetime user: User, session: AsyncSession, starts_at: datetime, duration_days: int
) -> Subscription: ) -> Subscription:
subscription = user.subscription subscription = user.subscription
if subscription is not None: if subscription is not None:
@@ -83,6 +83,7 @@ async def ensure_subscription(
devices=0, devices=0,
status=SubscriptionStatus.EXPIRED, status=SubscriptionStatus.EXPIRED,
expires_at=starts_at, expires_at=starts_at,
duration_days=duration_days,
) )
session.add(subscription) session.add(subscription)
await session.flush() await session.flush()
@@ -121,7 +122,7 @@ async def apply_order_now(
pricing: PricingPlans, pricing: PricingPlans,
now: datetime, now: datetime,
) -> Subscription: ) -> Subscription:
subscription = await ensure_subscription(user, session, now) subscription = await ensure_subscription(user, session, now, order.duration_days)
addon_ids = [addon.addon_id for addon in order.addons] addon_ids = [addon.addon_id for addon in order.addons]
current_addons = [] if subscription.devices == 0 else get_subscription_addon_ids(subscription) current_addons = [] if subscription.devices == 0 else get_subscription_addon_ids(subscription)