forked from andika/membership-be
1. Added member_since to GET Response- - Endpoint: GET /api/admin/users/{user_id}- Now includes: member_since: 2024-03-15T10:30:00Z (or null)2. Created NEW PUT Endpoint for Admin User Profile Updates- Endpoint: PUT /api/admin/users/{user_id}- Permission Required: users.edit (admins and superadmins have this)
This commit is contained in:
Binary file not shown.
83
server.py
83
server.py
@@ -483,6 +483,31 @@ class InviteUserRequest(BaseModel):
|
|||||||
last_name: Optional[str] = None
|
last_name: Optional[str] = None
|
||||||
phone: Optional[str] = None
|
phone: Optional[str] = None
|
||||||
|
|
||||||
|
class AdminUpdateUserRequest(BaseModel):
|
||||||
|
"""Admin-only endpoint for updating user profile fields"""
|
||||||
|
first_name: Optional[str] = None
|
||||||
|
last_name: Optional[str] = None
|
||||||
|
phone: Optional[str] = None
|
||||||
|
address: Optional[str] = None
|
||||||
|
city: Optional[str] = None
|
||||||
|
state: Optional[str] = None
|
||||||
|
zipcode: Optional[str] = None
|
||||||
|
date_of_birth: Optional[datetime] = None
|
||||||
|
member_since: Optional[datetime] = None
|
||||||
|
# Partner information
|
||||||
|
partner_first_name: Optional[str] = None
|
||||||
|
partner_last_name: Optional[str] = None
|
||||||
|
partner_is_member: Optional[bool] = None
|
||||||
|
partner_plan_to_become_member: Optional[bool] = None
|
||||||
|
referred_by_member_name: Optional[str] = None
|
||||||
|
|
||||||
|
@validator('date_of_birth', 'member_since', pre=True)
|
||||||
|
def empty_str_to_none(cls, v):
|
||||||
|
"""Convert empty string to None for optional datetime fields"""
|
||||||
|
if v == '' or v is None:
|
||||||
|
return None
|
||||||
|
return v
|
||||||
|
|
||||||
class InvitationResponse(BaseModel):
|
class InvitationResponse(BaseModel):
|
||||||
id: str
|
id: str
|
||||||
email: str
|
email: str
|
||||||
@@ -2275,10 +2300,68 @@ async def get_user_by_id(
|
|||||||
"email_verified": user.email_verified,
|
"email_verified": user.email_verified,
|
||||||
"newsletter_subscribed": user.newsletter_subscribed,
|
"newsletter_subscribed": user.newsletter_subscribed,
|
||||||
"lead_sources": user.lead_sources,
|
"lead_sources": user.lead_sources,
|
||||||
|
"member_since": user.member_since.isoformat() if user.member_since else None,
|
||||||
"created_at": user.created_at.isoformat() if user.created_at else None,
|
"created_at": user.created_at.isoformat() if user.created_at else None,
|
||||||
"updated_at": user.updated_at.isoformat() if user.updated_at else None
|
"updated_at": user.updated_at.isoformat() if user.updated_at else None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@api_router.put("/admin/users/{user_id}")
|
||||||
|
async def update_user_profile(
|
||||||
|
user_id: str,
|
||||||
|
request: AdminUpdateUserRequest,
|
||||||
|
db: Session = Depends(get_db),
|
||||||
|
current_user: User = Depends(require_permission("users.edit"))
|
||||||
|
):
|
||||||
|
"""Update user profile fields (admin only)"""
|
||||||
|
user = db.query(User).filter(User.id == user_id).first()
|
||||||
|
if not user:
|
||||||
|
raise HTTPException(status_code=404, detail="User not found")
|
||||||
|
|
||||||
|
# Update basic personal information
|
||||||
|
if request.first_name is not None:
|
||||||
|
user.first_name = request.first_name
|
||||||
|
if request.last_name is not None:
|
||||||
|
user.last_name = request.last_name
|
||||||
|
if request.phone is not None:
|
||||||
|
user.phone = request.phone
|
||||||
|
if request.address is not None:
|
||||||
|
user.address = request.address
|
||||||
|
if request.city is not None:
|
||||||
|
user.city = request.city
|
||||||
|
if request.state is not None:
|
||||||
|
user.state = request.state
|
||||||
|
if request.zipcode is not None:
|
||||||
|
user.zipcode = request.zipcode
|
||||||
|
if request.date_of_birth is not None:
|
||||||
|
user.date_of_birth = request.date_of_birth
|
||||||
|
|
||||||
|
# Update member_since (admin only)
|
||||||
|
if request.member_since is not None:
|
||||||
|
user.member_since = request.member_since
|
||||||
|
|
||||||
|
# Update partner information
|
||||||
|
if request.partner_first_name is not None:
|
||||||
|
user.partner_first_name = request.partner_first_name
|
||||||
|
if request.partner_last_name is not None:
|
||||||
|
user.partner_last_name = request.partner_last_name
|
||||||
|
if request.partner_is_member is not None:
|
||||||
|
user.partner_is_member = request.partner_is_member
|
||||||
|
if request.partner_plan_to_become_member is not None:
|
||||||
|
user.partner_plan_to_become_member = request.partner_plan_to_become_member
|
||||||
|
if request.referred_by_member_name is not None:
|
||||||
|
user.referred_by_member_name = request.referred_by_member_name
|
||||||
|
|
||||||
|
user.updated_at = datetime.now(timezone.utc)
|
||||||
|
db.commit()
|
||||||
|
db.refresh(user)
|
||||||
|
|
||||||
|
logger.info(f"Admin {current_user.email} updated profile for user {user.email}")
|
||||||
|
|
||||||
|
return {
|
||||||
|
"message": "User profile updated successfully",
|
||||||
|
"user_id": str(user.id)
|
||||||
|
}
|
||||||
|
|
||||||
@api_router.put("/admin/users/{user_id}/validate")
|
@api_router.put("/admin/users/{user_id}/validate")
|
||||||
async def validate_user(
|
async def validate_user(
|
||||||
user_id: str,
|
user_id: str,
|
||||||
|
|||||||
Reference in New Issue
Block a user