- Add project_manager to all role dropdowns (UserList filter, create modal, UserDetail edit form) - Add indigo badge color for project_manager in user list table - Expose pm_client_ids in UserResponse schema and all admin user endpoints - Add pm_client_ids to frontend User type - Add UserAssignmentsPanel to UserDetail sidebar: PM users see client toggle list; other roles see client → team membership picker - Add flexible hooks (useTeamsForClient, useAssignPMAny, useRemovePMAny, useAddTeamMemberAny, useRemoveTeamMemberAny) - Fix useClient guard against literal "undefined" string causing 404 requests Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
94 lines
1.9 KiB
Python
94 lines
1.9 KiB
Python
from typing import Optional
|
|
from pydantic import BaseModel, EmailStr
|
|
from ..models.user import UserRole, AuthProvider
|
|
|
|
|
|
class LoginRequest(BaseModel):
|
|
email: EmailStr
|
|
password: str
|
|
|
|
|
|
class LoginResponse(BaseModel):
|
|
access_token: str
|
|
token_type: str = "bearer"
|
|
user_id: str
|
|
role: str
|
|
|
|
|
|
class MicrosoftLoginRequest(BaseModel):
|
|
"""Request schema for Microsoft authentication."""
|
|
id_token: str
|
|
|
|
|
|
class MicrosoftLoginResponse(BaseModel):
|
|
"""Response schema for Microsoft authentication."""
|
|
access_token: str
|
|
token_type: str = "bearer"
|
|
user_id: str
|
|
role: str
|
|
email: str
|
|
full_name: str
|
|
auth_provider: AuthProvider
|
|
|
|
|
|
class RefreshResponse(BaseModel):
|
|
access_token: str
|
|
token_type: str = "bearer"
|
|
user_id: str
|
|
role: str
|
|
email: str
|
|
full_name: str
|
|
|
|
|
|
class LogoutResponse(BaseModel):
|
|
message: str = "Successfully logged out"
|
|
|
|
|
|
# User management schemas for admin routes
|
|
class UserResponse(BaseModel):
|
|
id: str
|
|
email: EmailStr
|
|
full_name: str
|
|
role: UserRole
|
|
auth_provider: AuthProvider
|
|
is_active: bool
|
|
created_at: Optional[str] = None
|
|
pm_client_ids: list[str] = []
|
|
|
|
|
|
class UserListResponse(BaseModel):
|
|
users: list[UserResponse]
|
|
total: int
|
|
page: int
|
|
size: int
|
|
|
|
|
|
class CreateUserRequest(BaseModel):
|
|
email: EmailStr
|
|
password: str
|
|
full_name: str
|
|
role: UserRole = UserRole.CLIENT
|
|
|
|
|
|
class UpdateUserRequest(BaseModel):
|
|
email: Optional[EmailStr] = None
|
|
full_name: Optional[str] = None
|
|
role: Optional[UserRole] = None
|
|
is_active: Optional[bool] = None
|
|
|
|
|
|
class ChangePasswordRequest(BaseModel):
|
|
current_password: str
|
|
new_password: str
|
|
|
|
|
|
class ResetPasswordRequest(BaseModel):
|
|
email: EmailStr
|
|
|
|
|
|
class AdminStatsResponse(BaseModel):
|
|
total_users: int
|
|
total_jobs: int
|
|
jobs_by_status: dict[str, int]
|
|
active_jobs_today: int
|
|
avg_processing_time_hours: float
|