Spaces:
Sleeping
Sleeping
feat: Add phone and project details to invitation validation response
Browse files- Added phone field to InvitationPublicResponse schema
- Enhanced validate endpoint to return project details when available:
- project_id, project_name, project_role_name, region_name
- Frontend now receives complete invitation context for better UX
- Phone number pre-filled in acceptance form
- Project context displayed during invitation acceptance
src/app/api/v1/invitations.py
CHANGED
|
@@ -293,9 +293,34 @@ async def validate_invitation_token(
|
|
| 293 |
suggested_first_name = name_parts[0]
|
| 294 |
suggested_last_name = " ".join(name_parts[1:])
|
| 295 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 296 |
return InvitationPublicResponse(
|
| 297 |
id=invitation.id,
|
| 298 |
email=invitation.email,
|
|
|
|
| 299 |
invited_role=invitation.invited_role,
|
| 300 |
status=invitation.status,
|
| 301 |
expires_at=invitation.expires_at,
|
|
@@ -304,7 +329,11 @@ async def validate_invitation_token(
|
|
| 304 |
is_expired=invitation.is_expired,
|
| 305 |
is_valid=invitation.is_pending,
|
| 306 |
suggested_first_name=suggested_first_name,
|
| 307 |
-
suggested_last_name=suggested_last_name
|
|
|
|
|
|
|
|
|
|
|
|
|
| 308 |
)
|
| 309 |
|
| 310 |
|
|
|
|
| 293 |
suggested_first_name = name_parts[0]
|
| 294 |
suggested_last_name = " ".join(name_parts[1:])
|
| 295 |
|
| 296 |
+
# Get project details if this is a project invitation
|
| 297 |
+
project_name = None
|
| 298 |
+
project_role_name = None
|
| 299 |
+
region_name = None
|
| 300 |
+
|
| 301 |
+
if invitation.project_id:
|
| 302 |
+
from app.models.project import Project
|
| 303 |
+
from app.models.project_role import ProjectRole
|
| 304 |
+
from app.models.project_region import ProjectRegion
|
| 305 |
+
|
| 306 |
+
# Get project name
|
| 307 |
+
project = db.query(Project).filter(Project.id == invitation.project_id).first()
|
| 308 |
+
project_name = project.title if project else None
|
| 309 |
+
|
| 310 |
+
# Get project role name
|
| 311 |
+
if invitation.project_role_id:
|
| 312 |
+
project_role = db.query(ProjectRole).filter(ProjectRole.id == invitation.project_role_id).first()
|
| 313 |
+
project_role_name = project_role.role_name if project_role else None
|
| 314 |
+
|
| 315 |
+
# Get region name
|
| 316 |
+
if invitation.project_region_id:
|
| 317 |
+
region = db.query(ProjectRegion).filter(ProjectRegion.id == invitation.project_region_id).first()
|
| 318 |
+
region_name = region.region_name if region else None
|
| 319 |
+
|
| 320 |
return InvitationPublicResponse(
|
| 321 |
id=invitation.id,
|
| 322 |
email=invitation.email,
|
| 323 |
+
phone=invitation.phone,
|
| 324 |
invited_role=invitation.invited_role,
|
| 325 |
status=invitation.status,
|
| 326 |
expires_at=invitation.expires_at,
|
|
|
|
| 329 |
is_expired=invitation.is_expired,
|
| 330 |
is_valid=invitation.is_pending,
|
| 331 |
suggested_first_name=suggested_first_name,
|
| 332 |
+
suggested_last_name=suggested_last_name,
|
| 333 |
+
project_id=invitation.project_id,
|
| 334 |
+
project_name=project_name,
|
| 335 |
+
project_role_name=project_role_name,
|
| 336 |
+
region_name=region_name
|
| 337 |
)
|
| 338 |
|
| 339 |
|
src/app/schemas/invitation.py
CHANGED
|
@@ -113,6 +113,7 @@ class InvitationPublicResponse(BaseModel):
|
|
| 113 |
"""Public schema for invitation validation (limited info)"""
|
| 114 |
id: UUID
|
| 115 |
email: str
|
|
|
|
| 116 |
invited_role: str
|
| 117 |
status: str
|
| 118 |
expires_at: datetime
|
|
|
|
| 113 |
"""Public schema for invitation validation (limited info)"""
|
| 114 |
id: UUID
|
| 115 |
email: str
|
| 116 |
+
phone: Optional[str] = None
|
| 117 |
invited_role: str
|
| 118 |
status: str
|
| 119 |
expires_at: datetime
|