Coverage for app\schemas\billing.py: 94%
68 statements
« prev ^ index » next coverage.py v7.3.2, created at 2026-01-15 13:39 +0300
« prev ^ index » next coverage.py v7.3.2, created at 2026-01-15 13:39 +0300
1from pydantic import BaseModel, Field, field_validator
2from typing import Optional, Dict, List, Any
3from datetime import datetime
5class PlanBase(BaseModel):
6 name: str
7 code: str
8 description: Optional[str] = None
9 price: float
10 currency: str = "RUB"
11 limits: Dict[str, int] = {}
12 features: List[str] = []
13 is_active: bool = True
15 @field_validator("limits")
16 @classmethod
17 def validate_limits(cls, v: Dict[str, int]) -> Dict[str, int]:
18 for key, value in v.items():
19 if value < -1:
20 raise ValueError(f"Limit '{key}' cannot be less than -1 (use -1 for unlimited)")
21 return v
23class PlanCreate(PlanBase):
24 pass
26class PlanUpdate(BaseModel):
27 name: Optional[str] = None
28 price: Optional[float] = None
29 limits: Optional[Dict[str, int]] = None
30 is_active: Optional[bool] = None
32class Plan(PlanBase):
33 id: str
34 created_at: datetime
35 class Config:
36 from_attributes = True
38class SubscriptionBase(BaseModel):
39 plan_id: str
40 school_id: str
41 start_date: Optional[datetime] = None
42 end_date: Optional[datetime] = None
43 auto_renew: bool = True
45class SubscriptionCreate(SubscriptionBase):
46 pass
48class SubscriptionUpdate(BaseModel):
49 status: Optional[str] = None
50 plan_id: Optional[str] = None
51 start_date: Optional[datetime] = None
52 end_date: Optional[datetime] = None
53 auto_renew: Optional[bool] = None
55class Subscription(SubscriptionBase):
56 id: str
57 status: str
58 created_at: datetime
59 plan: Optional[Plan] = None
60 class Config:
61 from_attributes = True
63class UsageRecordBase(BaseModel):
64 metric_key: str
65 dimension: Optional[str] = None
66 value: float
67 period_start: datetime
68 period_end: datetime
70class UsageRecordCreate(UsageRecordBase):
71 school_id: str
72 subscription_id: Optional[str] = None
74class UsageRecord(UsageRecordBase):
75 id: str
76 school_id: str
77 subscription_id: Optional[str] = None
78 recorded_at: datetime
79 class Config:
80 from_attributes = True