Spaces:
Sleeping
Sleeping
Commit ·
b1b7430
1
Parent(s): f58c397
pet and guest api changes
Browse files- app/models/guest_model.py +14 -19
- app/models/pet_model.py +18 -22
- app/routers/guest_router.py +10 -39
- app/routers/pet_router.py +11 -43
- app/schemas/guest_schema.py +6 -6
- app/schemas/pet_schema.py +3 -3
- app/utils/db.py +26 -0
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 |
-
|
| 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("/
|
| 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 |
-
|
| 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("/
|
| 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 |
-
|
| 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 |
-
|
| 99 |
-
|
| 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("/
|
| 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 |
-
|
| 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("/
|
| 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 |
-
|
| 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("/
|
| 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 |
-
|
| 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("/
|
| 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 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 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("/
|
| 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 |
-
|
| 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("/
|
| 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 |
-
|
| 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[
|
| 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 >
|
| 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 = (
|
| 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 >
|
| 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 = (
|
| 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[
|
| 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[
|
| 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
|