schemas.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. from pydantic import BaseModel, EmailStr, Field, ConfigDict
  2. from typing import Optional, List
  3. from datetime import datetime
  4. # Response models
  5. class MaterialBase(BaseModel):
  6. id: int
  7. name_en: Optional[str] = None
  8. name_ru: Optional[str] = None
  9. name_me: Optional[str] = None
  10. desc_en: Optional[str] = None
  11. desc_ru: Optional[str] = None
  12. desc_me: Optional[str] = None
  13. price_per_cm3: float
  14. is_active: bool
  15. class ServiceBase(BaseModel):
  16. id: int
  17. name_en: Optional[str] = None
  18. name_ru: Optional[str] = None
  19. name_me: Optional[str] = None
  20. desc_en: Optional[str] = None
  21. desc_ru: Optional[str] = None
  22. desc_me: Optional[str] = None
  23. tech_type: Optional[str] = None
  24. is_active: bool
  25. # Management models
  26. class MaterialCreate(BaseModel):
  27. name_en: str
  28. name_ru: str
  29. name_me: str
  30. desc_en: str
  31. desc_ru: str
  32. desc_me: str
  33. price_per_cm3: float
  34. is_active: bool = True
  35. class MaterialUpdate(BaseModel):
  36. name_en: Optional[str] = None
  37. name_ru: Optional[str] = None
  38. name_me: Optional[str] = None
  39. desc_en: Optional[str] = None
  40. desc_ru: Optional[str] = None
  41. desc_me: Optional[str] = None
  42. price_per_cm3: Optional[float] = None
  43. is_active: Optional[bool] = None
  44. class ServiceCreate(BaseModel):
  45. name_en: str
  46. name_ru: str
  47. name_me: str
  48. desc_en: str
  49. desc_ru: str
  50. desc_me: str
  51. tech_type: Optional[str] = None
  52. is_active: bool = True
  53. class ServiceUpdate(BaseModel):
  54. name_en: Optional[str] = None
  55. name_ru: Optional[str] = None
  56. name_me: Optional[str] = None
  57. desc_en: Optional[str] = None
  58. desc_ru: Optional[str] = None
  59. desc_me: Optional[str] = None
  60. tech_type: Optional[str] = None
  61. is_active: Optional[bool] = None
  62. # Order creation models
  63. class OrderFileBase(BaseModel):
  64. filename: str
  65. file_size: Optional[int]
  66. class OrderCreate(BaseModel):
  67. first_name: str = Field(..., min_length=1)
  68. last_name: str = Field(..., min_length=1)
  69. phone: str = Field(..., min_length=5)
  70. email: EmailStr
  71. shipping_address: str = Field(..., min_length=10)
  72. model_link: Optional[str] = None
  73. quantity: int = Field(1, ge=1)
  74. notes: Optional[str] = None
  75. # User models
  76. class UserCreate(BaseModel):
  77. email: EmailStr
  78. password: str = Field(..., min_length=6)
  79. first_name: Optional[str] = None
  80. last_name: Optional[str] = None
  81. phone: Optional[str] = None
  82. shipping_address: Optional[str] = None
  83. preferred_language: Optional[str] = "en"
  84. class UserUpdate(BaseModel):
  85. first_name: Optional[str] = None
  86. last_name: Optional[str] = None
  87. phone: Optional[str] = None
  88. shipping_address: Optional[str] = None
  89. preferred_language: Optional[str] = None
  90. class UserLogin(BaseModel):
  91. email: EmailStr
  92. password: str
  93. class UserResponse(BaseModel):
  94. id: int
  95. email: EmailStr
  96. first_name: Optional[str] = None
  97. last_name: Optional[str] = None
  98. phone: Optional[str] = None
  99. shipping_address: Optional[str] = None
  100. preferred_language: str = "en"
  101. role: str
  102. ip_address: Optional[str] = None
  103. created_at: datetime
  104. model_config = ConfigDict(from_attributes=True)
  105. class AdminOrderUpdate(BaseModel):
  106. status: Optional[str] = None
  107. total_price: Optional[float] = None
  108. send_notification: Optional[bool] = False
  109. class EstimateRequest(BaseModel):
  110. material_id: int
  111. file_sizes: List[int] # in bytes
  112. file_quantities: Optional[List[int]] = None
  113. # Possible to add density or other params later
  114. class Token(BaseModel):
  115. access_token: str
  116. token_type: str
  117. class SocialLogin(BaseModel):
  118. provider: str # 'google' or 'facebook'
  119. token: str
  120. email: EmailStr
  121. first_name: Optional[str] = None
  122. last_name: Optional[str] = None
  123. preferred_language: Optional[str] = "en"
  124. class ForgotPassword(BaseModel):
  125. email: EmailStr
  126. class ResetPassword(BaseModel):
  127. token: str
  128. new_password: str = Field(..., min_length=6)
  129. class PhotoUpdate(BaseModel):
  130. is_public: bool
  131. class OrderResponse(OrderCreate):
  132. id: int
  133. status: str
  134. total_price: Optional[float] = None
  135. estimated_price: Optional[float] = None
  136. material_name: Optional[str] = None
  137. material_price: Optional[float] = None
  138. created_at: datetime
  139. model_config = ConfigDict(from_attributes=True)