GayathriArjun commited on
Commit
b1b7430
·
1 Parent(s): f58c397

pet and guest api changes

Browse files
app/models/guest_model.py CHANGED
@@ -4,23 +4,15 @@ from typing import List, Optional, Dict, Any
4
  import uuid
5
  import logging
6
 
 
 
7
  logger = logging.getLogger(__name__)
8
 
9
  class GuestModel:
10
  """Model for managing guest profiles in the database"""
11
 
12
  @staticmethod
13
- async def create_guest(
14
- customer_id: str,
15
- first_name: str,
16
- last_name: Optional[str] = None,
17
- email: Optional[str] = None,
18
- phone_number: Optional[str] = None,
19
- gender: Optional[str] = None,
20
- date_of_birth: Optional[datetime] = None,
21
- relationship: Optional[str] = None,
22
- notes: Optional[str] = None
23
- ) -> Optional[str]:
24
  """
25
  Create a new guest profile for a user.
26
 
@@ -43,21 +35,24 @@ class GuestModel:
43
 
44
  guest_id = str(uuid.uuid4())
45
  current_time = datetime.utcnow()
 
46
 
47
  guest_data = {
48
  "guest_id": guest_id,
49
  "customer_id": customer_id,
50
- "first_name": first_name,
51
- "last_name": last_name,
52
- "email": email,
53
- "phone_number": phone_number,
54
- "gender": gender,
55
- "date_of_birth": date_of_birth,
56
- "relationship": relationship,
57
- "notes": notes,
58
  "created_at": current_time,
59
  "updated_at": current_time
60
  }
 
 
61
 
62
  result = await guests_collection.insert_one(guest_data)
63
 
 
4
  import uuid
5
  import logging
6
 
7
+ from app.utils.db import prepare_for_db
8
+
9
  logger = logging.getLogger(__name__)
10
 
11
  class GuestModel:
12
  """Model for managing guest profiles in the database"""
13
 
14
  @staticmethod
15
+ async def create_guest(customer_id: str,guest_data:dict) -> Optional[str]:
 
 
 
 
 
 
 
 
 
 
16
  """
17
  Create a new guest profile for a user.
18
 
 
35
 
36
  guest_id = str(uuid.uuid4())
37
  current_time = datetime.utcnow()
38
+ print("gusest_data",guest_data)
39
 
40
  guest_data = {
41
  "guest_id": guest_id,
42
  "customer_id": customer_id,
43
+ "first_name": guest_data["first_name"],
44
+ "last_name": guest_data["last_name"],
45
+ "email": guest_data["email"],
46
+ "phone_number": guest_data["phone_number"],
47
+ "gender": guest_data["gender"].value,
48
+ "date_of_birth": guest_data["date_of_birth"],
49
+ "relationship": guest_data['relationship'].value,
50
+ "notes": guest_data['notes'],
51
  "created_at": current_time,
52
  "updated_at": current_time
53
  }
54
+
55
+ guest_data = prepare_for_db(guest_data)
56
 
57
  result = await guests_collection.insert_one(guest_data)
58
 
app/models/pet_model.py CHANGED
@@ -4,6 +4,8 @@ from typing import List, Optional, Dict, Any
4
  import uuid
5
  import logging
6
 
 
 
7
  logger = logging.getLogger(__name__)
8
 
9
  class PetModel:
@@ -12,17 +14,7 @@ class PetModel:
12
  @staticmethod
13
  async def create_pet(
14
  customer_id: str,
15
- pet_name: str,
16
- species: str,
17
- breed: Optional[str] = None,
18
- date_of_birth: Optional[datetime] = None,
19
- age: Optional[int] = None,
20
- weight: Optional[float] = None,
21
- gender: Optional[str] = None,
22
- temperament: Optional[str] = None,
23
- health_notes: Optional[str] = None,
24
- is_vaccinated: bool = False,
25
- pet_photo_url: Optional[str] = None
26
  ) -> Optional[str]:
27
  """
28
  Create a new pet profile for a user.
@@ -49,24 +41,28 @@ class PetModel:
49
 
50
  pet_id = str(uuid.uuid4())
51
  current_time = datetime.utcnow()
 
 
52
 
53
  pet_data = {
54
  "pet_id": pet_id,
55
  "customer_id": customer_id,
56
- "pet_name": pet_name,
57
- "species": species,
58
- "breed": breed,
59
- "date_of_birth": date_of_birth,
60
- "age": age,
61
- "weight": weight,
62
- "gender": gender,
63
- "temperament": temperament,
64
- "health_notes": health_notes,
65
- "is_vaccinated": is_vaccinated,
66
- "pet_photo_url": pet_photo_url,
67
  "created_at": current_time,
68
  "updated_at": current_time
69
  }
 
 
70
 
71
  result = await pets_collection.insert_one(pet_data)
72
 
 
4
  import uuid
5
  import logging
6
 
7
+ from app.utils.db import prepare_for_db
8
+
9
  logger = logging.getLogger(__name__)
10
 
11
  class PetModel:
 
14
  @staticmethod
15
  async def create_pet(
16
  customer_id: str,
17
+ pet_data:dict
 
 
 
 
 
 
 
 
 
 
18
  ) -> Optional[str]:
19
  """
20
  Create a new pet profile for a user.
 
41
 
42
  pet_id = str(uuid.uuid4())
43
  current_time = datetime.utcnow()
44
+
45
+ print("petdata",pet_data)
46
 
47
  pet_data = {
48
  "pet_id": pet_id,
49
  "customer_id": customer_id,
50
+ "pet_name": pet_data['pet_name'],
51
+ "species": pet_data['species'].value,
52
+ "breed": pet_data['breed'],
53
+ "date_of_birth": pet_data['date_of_birth'],
54
+ "age": pet_data['age'],
55
+ "weight": pet_data['weight'],
56
+ "gender": pet_data['gender'].value,
57
+ "temperament": pet_data['temperament'].value,
58
+ "health_notes": pet_data['health_notes'],
59
+ "is_vaccinated": pet_data['is_vaccinated'],
60
+ "pet_photo_url": pet_data['pet_photo_url'],
61
  "created_at": current_time,
62
  "updated_at": current_time
63
  }
64
+
65
+ pet_data = prepare_for_db(pet_data)
66
 
67
  result = await pets_collection.insert_one(pet_data)
68
 
app/routers/guest_router.py CHANGED
@@ -36,9 +36,8 @@ async def get_current_user(token: str = Depends(security)) -> Dict[str, Any]:
36
  detail="Invalid or expired token"
37
  )
38
 
39
- @router.get("/{customer_id}/guests", response_model=GuestListResponse)
40
  async def get_user_guests(
41
- customer_id: str,
42
  current_user: Dict[str, Any] = Depends(get_current_user)
43
  ):
44
  """
@@ -49,11 +48,7 @@ async def get_user_guests(
49
  """
50
  try:
51
  # Verify user can only access their own guests
52
- if current_user.get("customer_id") != customer_id:
53
- raise HTTPException(
54
- status_code=status.HTTP_403_FORBIDDEN,
55
- detail="Access denied. You can only view your own guests."
56
- )
57
 
58
  guests_data = await GuestModel.get_user_guests(customer_id)
59
 
@@ -73,9 +68,8 @@ async def get_user_guests(
73
  detail="Failed to retrieve guests"
74
  )
75
 
76
- @router.post("/{customer_id}/guests", response_model=GuestResponse, status_code=status.HTTP_201_CREATED)
77
  async def create_guest(
78
- customer_id: str,
79
  guest_data: GuestCreateRequest,
80
  current_user: Dict[str, Any] = Depends(get_current_user)
81
  ):
@@ -88,24 +82,11 @@ async def create_guest(
88
  """
89
  try:
90
  # Verify user can only create guests for themselves
91
- if current_user.get("customer_id") != customer_id:
92
- raise HTTPException(
93
- status_code=status.HTTP_403_FORBIDDEN,
94
- detail="Access denied. You can only create guests for yourself."
95
- )
96
 
97
  # Create guest in database
98
- guest_id = await GuestModel.create_guest(
99
- customer_id=customer_id,
100
- first_name=guest_data.first_name,
101
- last_name=guest_data.last_name,
102
- email=guest_data.email,
103
- phone_number=guest_data.phone_number,
104
- gender=guest_data.gender.value if guest_data.gender else None,
105
- date_of_birth=guest_data.date_of_birth,
106
- relationship=guest_data.relationship.value if guest_data.relationship else None,
107
- notes=guest_data.notes
108
- )
109
 
110
  if not guest_id:
111
  raise HTTPException(
@@ -132,9 +113,8 @@ async def create_guest(
132
  detail="Failed to create guest profile"
133
  )
134
 
135
- @router.put("/{customer_id}/guests/{guest_id}", response_model=GuestResponse)
136
  async def update_guest(
137
- customer_id: str,
138
  guest_id: str,
139
  guest_data: GuestUpdateRequest,
140
  current_user: Dict[str, Any] = Depends(get_current_user)
@@ -149,11 +129,7 @@ async def update_guest(
149
  """
150
  try:
151
  # Verify user can only update their own guests
152
- if current_user.get("customer_id") != customer_id:
153
- raise HTTPException(
154
- status_code=status.HTTP_403_FORBIDDEN,
155
- detail="Access denied. You can only update your own guests."
156
- )
157
 
158
  # Check if guest exists and belongs to user
159
  existing_guest = await GuestModel.get_guest_by_id(guest_id)
@@ -211,9 +187,8 @@ async def update_guest(
211
  detail="Failed to update guest profile"
212
  )
213
 
214
- @router.delete("/{customer_id}/guests/{guest_id}", response_model=GuestDeleteResponse)
215
  async def delete_guest(
216
- customer_id: str,
217
  guest_id: str,
218
  current_user: Dict[str, Any] = Depends(get_current_user)
219
  ):
@@ -226,11 +201,7 @@ async def delete_guest(
226
  """
227
  try:
228
  # Verify user can only delete their own guests
229
- if current_user.get("customer_id") != customer_id:
230
- raise HTTPException(
231
- status_code=status.HTTP_403_FORBIDDEN,
232
- detail="Access denied. You can only delete your own guests."
233
- )
234
 
235
  # Check if guest exists and belongs to user
236
  existing_guest = await GuestModel.get_guest_by_id(guest_id)
 
36
  detail="Invalid or expired token"
37
  )
38
 
39
+ @router.get("/guests", response_model=GuestListResponse)
40
  async def get_user_guests(
 
41
  current_user: Dict[str, Any] = Depends(get_current_user)
42
  ):
43
  """
 
48
  """
49
  try:
50
  # Verify user can only access their own guests
51
+ customer_id=current_user.get("customer_id")
 
 
 
 
52
 
53
  guests_data = await GuestModel.get_user_guests(customer_id)
54
 
 
68
  detail="Failed to retrieve guests"
69
  )
70
 
71
+ @router.post("/guests", response_model=GuestResponse, status_code=status.HTTP_201_CREATED)
72
  async def create_guest(
 
73
  guest_data: GuestCreateRequest,
74
  current_user: Dict[str, Any] = Depends(get_current_user)
75
  ):
 
82
  """
83
  try:
84
  # Verify user can only create guests for themselves
85
+ customer_id=current_user.get("customer_id")
 
 
 
 
86
 
87
  # Create guest in database
88
+
89
+ guest_id=await GuestModel.create_guest(customer_id,guest_data.dict())
 
 
 
 
 
 
 
 
 
90
 
91
  if not guest_id:
92
  raise HTTPException(
 
113
  detail="Failed to create guest profile"
114
  )
115
 
116
+ @router.put("/guests/{guest_id}", response_model=GuestResponse)
117
  async def update_guest(
 
118
  guest_id: str,
119
  guest_data: GuestUpdateRequest,
120
  current_user: Dict[str, Any] = Depends(get_current_user)
 
129
  """
130
  try:
131
  # Verify user can only update their own guests
132
+ customer_id=current_user.get("customer_id")
 
 
 
 
133
 
134
  # Check if guest exists and belongs to user
135
  existing_guest = await GuestModel.get_guest_by_id(guest_id)
 
187
  detail="Failed to update guest profile"
188
  )
189
 
190
+ @router.delete("/guests/{guest_id}", response_model=GuestDeleteResponse)
191
  async def delete_guest(
 
192
  guest_id: str,
193
  current_user: Dict[str, Any] = Depends(get_current_user)
194
  ):
 
201
  """
202
  try:
203
  # Verify user can only delete their own guests
204
+ customer_id=current_user.get("customer_id")
 
 
 
 
205
 
206
  # Check if guest exists and belongs to user
207
  existing_guest = await GuestModel.get_guest_by_id(guest_id)
app/routers/pet_router.py CHANGED
@@ -36,9 +36,8 @@ async def get_current_user(token: str = Depends(security)) -> Dict[str, Any]:
36
  detail="Invalid or expired token"
37
  )
38
 
39
- @router.get("/{customer_id}/pets", response_model=PetListResponse)
40
  async def get_user_pets(
41
- customer_id: str,
42
  current_user: Dict[str, Any] = Depends(get_current_user)
43
  ):
44
  """
@@ -49,11 +48,7 @@ async def get_user_pets(
49
  """
50
  try:
51
  # Verify user can only access their own pets
52
- if current_user.get("customer_id") != customer_id:
53
- raise HTTPException(
54
- status_code=status.HTTP_403_FORBIDDEN,
55
- detail="Access denied. You can only view your own pets."
56
- )
57
 
58
  pets_data = await PetModel.get_user_pets(customer_id)
59
 
@@ -73,9 +68,8 @@ async def get_user_pets(
73
  detail="Failed to retrieve pets"
74
  )
75
 
76
- @router.post("/{customer_id}/pets", response_model=PetResponse, status_code=status.HTTP_201_CREATED)
77
  async def create_pet(
78
- customer_id: str,
79
  pet_data: PetCreateRequest,
80
  current_user: Dict[str, Any] = Depends(get_current_user)
81
  ):
@@ -88,27 +82,11 @@ async def create_pet(
88
  """
89
  try:
90
  # Verify user can only create pets for themselves
91
- if current_user.get("customer_id") != customer_id:
92
- raise HTTPException(
93
- status_code=status.HTTP_403_FORBIDDEN,
94
- detail="Access denied. You can only create pets for yourself."
95
- )
96
-
97
  # Create pet in database
98
- pet_id = await PetModel.create_pet(
99
- customer_id=customer_id,
100
- pet_name=pet_data.pet_name,
101
- species=pet_data.species.value,
102
- breed=pet_data.breed,
103
- date_of_birth=pet_data.date_of_birth,
104
- age=pet_data.age,
105
- weight=pet_data.weight,
106
- gender=pet_data.gender.value if pet_data.gender else None,
107
- temperament=pet_data.temperament.value if pet_data.temperament else None,
108
- health_notes=pet_data.health_notes,
109
- is_vaccinated=pet_data.is_vaccinated,
110
- pet_photo_url=pet_data.pet_photo_url
111
- )
112
 
113
  if not pet_id:
114
  raise HTTPException(
@@ -135,9 +113,8 @@ async def create_pet(
135
  detail="Failed to create pet profile"
136
  )
137
 
138
- @router.put("/{customer_id}/pets/{pet_id}", response_model=PetResponse)
139
  async def update_pet(
140
- customer_id: str,
141
  pet_id: str,
142
  pet_data: PetUpdateRequest,
143
  current_user: Dict[str, Any] = Depends(get_current_user)
@@ -152,11 +129,7 @@ async def update_pet(
152
  """
153
  try:
154
  # Verify user can only update their own pets
155
- if current_user.get("customer_id") != customer_id:
156
- raise HTTPException(
157
- status_code=status.HTTP_403_FORBIDDEN,
158
- detail="Access denied. You can only update your own pets."
159
- )
160
 
161
  # Check if pet exists and belongs to user
162
  existing_pet = await PetModel.get_pet_by_id(pet_id)
@@ -214,9 +187,8 @@ async def update_pet(
214
  detail="Failed to update pet profile"
215
  )
216
 
217
- @router.delete("/{customer_id}/pets/{pet_id}", response_model=PetDeleteResponse)
218
  async def delete_pet(
219
- customer_id: str,
220
  pet_id: str,
221
  current_user: Dict[str, Any] = Depends(get_current_user)
222
  ):
@@ -229,11 +201,7 @@ async def delete_pet(
229
  """
230
  try:
231
  # Verify user can only delete their own pets
232
- if current_user.get("customer_id") != customer_id:
233
- raise HTTPException(
234
- status_code=status.HTTP_403_FORBIDDEN,
235
- detail="Access denied. You can only delete your own pets."
236
- )
237
 
238
  # Check if pet exists and belongs to user
239
  existing_pet = await PetModel.get_pet_by_id(pet_id)
 
36
  detail="Invalid or expired token"
37
  )
38
 
39
+ @router.get("/pets", response_model=PetListResponse)
40
  async def get_user_pets(
 
41
  current_user: Dict[str, Any] = Depends(get_current_user)
42
  ):
43
  """
 
48
  """
49
  try:
50
  # Verify user can only access their own pets
51
+ customer_id=current_user.get("customer_id")
 
 
 
 
52
 
53
  pets_data = await PetModel.get_user_pets(customer_id)
54
 
 
68
  detail="Failed to retrieve pets"
69
  )
70
 
71
+ @router.post("/pets", response_model=PetResponse, status_code=status.HTTP_201_CREATED)
72
  async def create_pet(
 
73
  pet_data: PetCreateRequest,
74
  current_user: Dict[str, Any] = Depends(get_current_user)
75
  ):
 
82
  """
83
  try:
84
  # Verify user can only create pets for themselves
85
+ customer_id=current_user.get("customer_id")
86
+
87
+
88
+ pet_id = await PetModel.create_pet(customer_id,pet_data.dict())
 
 
89
  # Create pet in database
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
  if not pet_id:
92
  raise HTTPException(
 
113
  detail="Failed to create pet profile"
114
  )
115
 
116
+ @router.put("/pets/{pet_id}", response_model=PetResponse)
117
  async def update_pet(
 
118
  pet_id: str,
119
  pet_data: PetUpdateRequest,
120
  current_user: Dict[str, Any] = Depends(get_current_user)
 
129
  """
130
  try:
131
  # Verify user can only update their own pets
132
+ customer_id=current_user.get("customer_id")
 
 
 
 
133
 
134
  # Check if pet exists and belongs to user
135
  existing_pet = await PetModel.get_pet_by_id(pet_id)
 
187
  detail="Failed to update pet profile"
188
  )
189
 
190
+ @router.delete("/pets/{pet_id}", response_model=PetDeleteResponse)
191
  async def delete_pet(
 
192
  pet_id: str,
193
  current_user: Dict[str, Any] = Depends(get_current_user)
194
  ):
 
201
  """
202
  try:
203
  # Verify user can only delete their own pets
204
+ customer_id=current_user.get("customer_id")
 
 
 
 
205
 
206
  # Check if pet exists and belongs to user
207
  existing_pet = await PetModel.get_pet_by_id(pet_id)
app/schemas/guest_schema.py CHANGED
@@ -1,6 +1,6 @@
1
  from pydantic import BaseModel, Field, validator, EmailStr
2
  from typing import Optional, List
3
- from datetime import datetime
4
  from enum import Enum
5
 
6
  class GenderEnum(str, Enum):
@@ -21,7 +21,7 @@ class GuestCreateRequest(BaseModel):
21
  email: Optional[EmailStr] = Field(None, description="Guest's email address")
22
  phone_number: Optional[str] = Field(None, max_length=20, description="Guest's phone number")
23
  gender: Optional[GenderEnum] = Field(None, description="Guest's gender")
24
- date_of_birth: Optional[datetime] = Field(None, description="Guest's date of birth for age calculation")
25
  relationship: Optional[RelationshipEnum] = Field(None, description="Relationship to the user")
26
  notes: Optional[str] = Field(None, max_length=500, description="Additional notes about the guest")
27
 
@@ -49,10 +49,10 @@ class GuestCreateRequest(BaseModel):
49
  @validator('date_of_birth')
50
  def validate_date_of_birth(cls, v):
51
  if v is not None:
52
- if v > datetime.now():
53
  raise ValueError('Date of birth cannot be in the future')
54
  # Check if age would be reasonable (not more than 120 years old)
55
- age = (datetime.now() - v).days // 365
56
  if age > 120:
57
  raise ValueError('Date of birth indicates unrealistic age')
58
  return v
@@ -92,10 +92,10 @@ class GuestUpdateRequest(BaseModel):
92
  @validator('date_of_birth')
93
  def validate_date_of_birth(cls, v):
94
  if v is not None:
95
- if v > datetime.now():
96
  raise ValueError('Date of birth cannot be in the future')
97
  # Check if age would be reasonable (not more than 120 years old)
98
- age = (datetime.now() - v).days // 365
99
  if age > 120:
100
  raise ValueError('Date of birth indicates unrealistic age')
101
  return v
 
1
  from pydantic import BaseModel, Field, validator, EmailStr
2
  from typing import Optional, List
3
+ from datetime import datetime,date
4
  from enum import Enum
5
 
6
  class GenderEnum(str, Enum):
 
21
  email: Optional[EmailStr] = Field(None, description="Guest's email address")
22
  phone_number: Optional[str] = Field(None, max_length=20, description="Guest's phone number")
23
  gender: Optional[GenderEnum] = Field(None, description="Guest's gender")
24
+ date_of_birth: Optional[date] = Field(None, description="Guest's date of birth for age calculation")
25
  relationship: Optional[RelationshipEnum] = Field(None, description="Relationship to the user")
26
  notes: Optional[str] = Field(None, max_length=500, description="Additional notes about the guest")
27
 
 
49
  @validator('date_of_birth')
50
  def validate_date_of_birth(cls, v):
51
  if v is not None:
52
+ if v > date.today():
53
  raise ValueError('Date of birth cannot be in the future')
54
  # Check if age would be reasonable (not more than 120 years old)
55
+ age = (date.today() - v).days // 365
56
  if age > 120:
57
  raise ValueError('Date of birth indicates unrealistic age')
58
  return v
 
92
  @validator('date_of_birth')
93
  def validate_date_of_birth(cls, v):
94
  if v is not None:
95
+ if v > date.today():
96
  raise ValueError('Date of birth cannot be in the future')
97
  # Check if age would be reasonable (not more than 120 years old)
98
+ age = (date.today() - v).days // 365
99
  if age > 120:
100
  raise ValueError('Date of birth indicates unrealistic age')
101
  return v
app/schemas/pet_schema.py CHANGED
@@ -1,6 +1,6 @@
1
  from pydantic import BaseModel, Field, validator
2
  from typing import Optional, List
3
- from datetime import datetime
4
  from enum import Enum
5
 
6
  class SpeciesEnum(str, Enum):
@@ -24,7 +24,7 @@ class PetCreateRequest(BaseModel):
24
  pet_name: str = Field(..., min_length=1, max_length=100, description="Name of the pet")
25
  species: SpeciesEnum = Field(..., description="Species of the pet")
26
  breed: Optional[str] = Field(None, max_length=100, description="Breed of the pet")
27
- date_of_birth: Optional[datetime] = Field(None, description="Pet's date of birth")
28
  age: Optional[int] = Field(None, ge=0, le=50, description="Pet's age in years")
29
  weight: Optional[float] = Field(None, ge=0, le=200, description="Pet's weight in kg")
30
  gender: Optional[GenderEnum] = Field(None, description="Pet's gender")
@@ -52,7 +52,7 @@ class PetUpdateRequest(BaseModel):
52
  pet_name: Optional[str] = Field(None, min_length=1, max_length=100, description="Name of the pet")
53
  species: Optional[SpeciesEnum] = Field(None, description="Species of the pet")
54
  breed: Optional[str] = Field(None, max_length=100, description="Breed of the pet")
55
- date_of_birth: Optional[datetime] = Field(None, description="Pet's date of birth")
56
  age: Optional[int] = Field(None, ge=0, le=50, description="Pet's age in years")
57
  weight: Optional[float] = Field(None, ge=0, le=200, description="Pet's weight in kg")
58
  gender: Optional[GenderEnum] = Field(None, description="Pet's gender")
 
1
  from pydantic import BaseModel, Field, validator
2
  from typing import Optional, List
3
+ from datetime import datetime,date
4
  from enum import Enum
5
 
6
  class SpeciesEnum(str, Enum):
 
24
  pet_name: str = Field(..., min_length=1, max_length=100, description="Name of the pet")
25
  species: SpeciesEnum = Field(..., description="Species of the pet")
26
  breed: Optional[str] = Field(None, max_length=100, description="Breed of the pet")
27
+ date_of_birth: Optional[date] = Field(None, description="Pet's date of birth")
28
  age: Optional[int] = Field(None, ge=0, le=50, description="Pet's age in years")
29
  weight: Optional[float] = Field(None, ge=0, le=200, description="Pet's weight in kg")
30
  gender: Optional[GenderEnum] = Field(None, description="Pet's gender")
 
52
  pet_name: Optional[str] = Field(None, min_length=1, max_length=100, description="Name of the pet")
53
  species: Optional[SpeciesEnum] = Field(None, description="Species of the pet")
54
  breed: Optional[str] = Field(None, max_length=100, description="Breed of the pet")
55
+ date_of_birth: Optional[date] = Field(None, description="Pet's date of birth")
56
  age: Optional[int] = Field(None, ge=0, le=50, description="Pet's age in years")
57
  weight: Optional[float] = Field(None, ge=0, le=200, description="Pet's weight in kg")
58
  gender: Optional[GenderEnum] = Field(None, description="Pet's gender")
app/utils/db.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import datetime,date
2
+ from decimal import Decimal
3
+ from typing import Any
4
+ from pydantic import BaseModel
5
+
6
+ def prepare_for_db(obj: Any) -> Any:
7
+ """
8
+ Recursively sanitizes the object to be MongoDB-compatible:
9
+ - Converts Decimal to float
10
+ - Converts datetime with tzinfo to naive datetime
11
+ - Converts Pydantic BaseModel to dict
12
+ """
13
+ if isinstance(obj, Decimal):
14
+ return float(obj)
15
+ elif isinstance(obj, date) and not isinstance(obj, datetime):
16
+ return datetime(obj.year, obj.month, obj.day)
17
+ elif isinstance(obj, datetime):
18
+ return obj.replace(tzinfo=None)
19
+ elif isinstance(obj, BaseModel):
20
+ return prepare_for_db(obj.dict())
21
+ elif isinstance(obj, dict):
22
+ return {k: prepare_for_db(v) for k, v in obj.items()}
23
+ elif isinstance(obj, list):
24
+ return [prepare_for_db(v) for v in obj]
25
+ else:
26
+ return obj