from datetime import datetime from pydantic import BaseModel, EmailStr, Field from app.db.models import ClassMembership, User def normalize_class_permissions(permissions: list[str]) -> list[str]: return [ permission for permission in permissions if permission not in {"class_view", "member_view", "member_manage", "committee_manage"} ] class MembershipOut(BaseModel): id: int class_id: int class_name: str | None membership_role: str committee_role: str | None = None class_permissions: list[str] class UserOut(BaseModel): id: int email: str name: str student_id: str | None role: str status: str industry: str | None company: str | None position: str | None skills_tags: list[str] | None wechat_id: str | None phone: str | None avatar_url: str | None bio: str | None created_at: datetime memberships: list[MembershipOut] active_membership: MembershipOut | None = None enabled_modules: list[str] | None = None class UserPublic(BaseModel): id: int name: str student_id: str | None industry: str | None company: str | None position: str | None committee_role: str | None = None wechat_id: str | None phone: str | None avatar_url: str | None bio: str | None class UserListItem(BaseModel): id: int email: str name: str student_id: str | None role: str status: str industry: str | None company: str | None committee_role: str | None = None class_permissions: list[str] created_at: datetime memberships: list[MembershipOut] active_membership: MembershipOut | None = None class UserUpdate(BaseModel): email: EmailStr | None = None name: str | None = None industry: str | None = None company: str | None = None position: str | None = None wechat_id: str | None = None phone: str | None = None bio: str | None = None class UserStatusUpdate(BaseModel): status: str role: str | None = None class UserRoleUpdate(BaseModel): role: str class TeacherCreateRequest(BaseModel): class_id: int name: str = Field(min_length=1, max_length=100) email: EmailStr password: str = Field(min_length=8, max_length=128) class TeacherCreateResponse(BaseModel): message: str user: UserOut class TeacherAssignRequest(BaseModel): class_id: int email: EmailStr class TeacherAssignResponse(BaseModel): message: str user: UserOut class CommitteeRoleUpdate(BaseModel): class_id: int committee_role: str | None = None class ClassPermissionsUpdate(BaseModel): class_id: int class_permissions: list[str] class TokenResponse(BaseModel): token: str user: UserOut def build_membership_out(membership: ClassMembership) -> MembershipOut: return MembershipOut( id=membership.id, class_id=membership.class_id, class_name=membership.class_.name if membership.class_ else None, membership_role=membership.membership_role, committee_role=membership.committee_role, class_permissions=normalize_class_permissions(membership.get_class_permissions()), ) def build_user_out(user: User, class_id: int | None = None) -> UserOut: active_membership = user.get_membership(class_id) if class_id is not None else user.get_default_membership() memberships = [build_membership_out(membership) for membership in user.memberships] return UserOut( id=user.id, email=user.email, name=user.name, student_id=user.student_id, role=user.role, status=user.status, industry=user.industry, company=user.company, position=user.position, skills_tags=user.get_skills_list(), wechat_id=user.wechat_id, phone=user.phone, avatar_url=user.avatar_url, bio=user.bio, created_at=user.created_at, memberships=memberships, active_membership=build_membership_out(active_membership) if active_membership else None, ) def build_user_list_item(user: User, class_id: int | None = None) -> UserListItem: active_membership = user.get_membership(class_id) if class_id is not None else user.get_default_membership() memberships = [build_membership_out(membership) for membership in user.memberships] return UserListItem( id=user.id, email=user.email, name=user.name, student_id=user.student_id, role=user.role, status=user.status, industry=user.industry, company=user.company, committee_role=active_membership.committee_role if active_membership else None, class_permissions=normalize_class_permissions(active_membership.get_class_permissions()) if active_membership else [], created_at=user.created_at, memberships=memberships, active_membership=build_membership_out(active_membership) if active_membership else None, )