mirror of
https://github.com/BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot.git
synced 2026-04-24 07:00:34 +00:00
- Add MULTI_TARIFF_ENABLED feature flag for gradual rollout
- Migration 0041: remove unique constraint on subscriptions.user_id
- Migration 0042: add remnawave_short_id (NOT NULL, UNIQUE) to subscriptions
- Each subscription gets its own Remnawave user (user_{tg_id}_{short_id})
- Add _resolve_subscription() to all 30+ bot handlers for per-subscription routing
- Add my_subscriptions.py with list/detail views and delegation handlers
- Refactor cabinet subscription.py (4687 lines -> 10 focused modules)
- Add subscription_id parameter to all cabinet API endpoints
- Adapt all services: autopay, wheel, contests, campaign, guest purchase,
monitoring, blocked users, account merge, promo codes, payments
- Replace all user.subscription (singular) with user.subscriptions iteration
- IDOR protection via get_subscription_by_id_for_user on all endpoints
- Full backward compatibility: MULTI_TARIFF_ENABLED=False = legacy behavior
57 lines
1.5 KiB
Python
57 lines
1.5 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class SubscriptionResponse(BaseModel):
|
|
id: int
|
|
user_id: int
|
|
status: str
|
|
actual_status: str
|
|
is_trial: bool
|
|
start_date: datetime
|
|
end_date: datetime
|
|
traffic_limit_gb: int
|
|
traffic_used_gb: float
|
|
device_limit: int
|
|
autopay_enabled: bool
|
|
autopay_days_before: int | None = None
|
|
subscription_url: str | None = None
|
|
subscription_crypto_link: str | None = None
|
|
connected_squads: list[str] = Field(default_factory=list)
|
|
created_at: datetime | None = None
|
|
updated_at: datetime | None = None
|
|
|
|
|
|
class SubscriptionCreateRequest(BaseModel):
|
|
user_id: int
|
|
is_trial: bool = False
|
|
duration_days: int | None = Field(None, ge=1, le=36500)
|
|
traffic_limit_gb: int | None = Field(None, ge=0, le=1_000_000)
|
|
device_limit: int | None = Field(None, ge=1, le=10_000)
|
|
squad_uuid: str | None = None
|
|
connected_squads: list[str] | None = None
|
|
replace_existing: bool = False
|
|
subscription_id: int | None = Field(
|
|
default=None,
|
|
description='ID of existing subscription to replace (required in multi-tariff mode when replace_existing=true)',
|
|
)
|
|
|
|
|
|
class SubscriptionExtendRequest(BaseModel):
|
|
days: int = Field(..., gt=0, le=36500)
|
|
|
|
|
|
class SubscriptionTrafficRequest(BaseModel):
|
|
gb: int = Field(..., gt=0, le=1_000_000)
|
|
|
|
|
|
class SubscriptionDevicesRequest(BaseModel):
|
|
devices: int = Field(..., gt=0, le=10_000)
|
|
|
|
|
|
class SubscriptionSquadRequest(BaseModel):
|
|
squad_uuid: str
|