from pydantic import root_validator from typing import List, Optional, TYPE_CHECKING from sqlmodel import SQLModel, Field, Relationship from database.auth.models import UserRead if TYPE_CHECKING: from database.auth.models import User class RoomBase(SQLModel): name: str = Field(max_length=20) public: bool = Field(default=False) class RoomCreate(RoomBase): pass class Room(RoomBase, table=True): id: Optional[int] = Field(default=None, primary_key=True) id_code: str = Field(index=True) members: List['Member'] = Relationship(back_populates="room") class AnonymousBase(SQLModel): username: str = Field(max_length=20) class AnonymousCreate(AnonymousBase): pass class Anonymous(AnonymousBase, table=True): id: Optional[int] = Field(default=None, primary_key=True) reconnect_code: str = Field(index=True) member: 'Member' = Relationship(back_populates="anonymous") class Member(SQLModel, table = True): id: Optional[int] = Field(default=None, primary_key=True) user_id: Optional[int] = Field(foreign_key="user.id", default=None) user: Optional["User"] = Relationship(back_populates='members') anonymous_id: Optional[int] = Field(foreign_key="anonymous.id", default=None) anonymous: Optional[Anonymous] = Relationship(back_populates="member") room_id: int = Field(foreign_key="room.id") room: Room = Relationship(back_populates='members') is_admin: bool = False waiting: bool = False online: bool = False waiter_code: Optional[str] = Field(default= None) id_code: str class RoomRead(RoomBase): id_code: str #members: List['Member'] class AnonymousRead(AnonymousBase): reconnect_code: str class Username(SQLModel): username: str class MemberWithRelations(SQLModel): is_admin: bool user: UserRead | None = None anonymous: AnonymousRead | None = None class MemberRead(SQLModel): username: str reconnect_code: str = '' isUser: bool isAdmin: bool id_code: str class MemberSerializer(MemberRead): member: MemberWithRelations @root_validator def parse_member(cls, values): member = values.get('member') if member == None: return values member_obj = member.user or member.anonymous if member_obj is None: raise ValueError('User or anonymous required') return {"username": member_obj.username, "reconnect_code": getattr(member_obj, "reconnect_code", ""), "isAdmin": member.is_admin, "isUser": member.user != None}