Coverage for bc/kwai-bc-teams/src/kwai_bc_teams/domain/team.py: 89%
45 statements
« prev ^ index » next coverage.py v7.11.0, created at 2024-01-01 00:00 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2024-01-01 00:00 +0000
1"""Module for defining the team entity."""
3from dataclasses import dataclass, field, replace
4from typing import ClassVar, ItemsView, Iterator, Mapping, Self, Type
6from kwai_core.domain.entity import DataclassEntity
7from kwai_core.domain.value_objects.identifier import IntIdentifier
8from kwai_core.domain.value_objects.unique_id import UniqueId
10from kwai_bc_teams.domain.team_member import TeamMember
13class TeamIdentifier(IntIdentifier):
14 """Identifier for a team."""
17class TeamMemberAlreadyExistException(Exception):
18 """Raised when the member is already part of the team."""
21class TeamMembers(Mapping[UniqueId, TeamMember]):
22 """A immutable dictionary with members of a team."""
24 def __init__(self, members: Mapping[UniqueId, TeamMember] | None = None):
25 self._members = {} if members is None else dict(members)
27 def add(self, team_member: TeamMember) -> Self:
28 """Add a new team member.
30 This class is immutable, so this method will return a new instance.
31 """
32 return type(self)(self._members | {team_member.member.uuid: team_member})
34 def remove(self, team_member: TeamMember) -> Self:
35 """Remove a team member.
37 This class is immutable, so this method will return a new instance.
38 """
39 result = type(self)(self._members)
40 del result._members[team_member.member.uuid]
41 return result
43 def items(self) -> ItemsView[UniqueId, TeamMember]:
44 """Return the items of the team members."""
45 return self._members.items()
47 def __contains__(self, key):
48 """Check if the key is in the dictionary."""
49 return key in self._members
51 def __getitem__(self, key: UniqueId):
52 """Return the item with the given key."""
53 return self._members.get(key)
55 def __iter__(self) -> Iterator[UniqueId]:
56 """Create an iterator."""
57 return iter(self._members)
59 def __len__(self) -> int:
60 """Return the number of items."""
61 return len(self._members)
63 def __hash__(self):
64 """Create a hash."""
65 return hash(self._members.items())
68@dataclass(kw_only=True, eq=False, slots=True, frozen=True)
69class TeamEntity(DataclassEntity):
70 """Entity for a team of the club.
72 Attributes:
73 name: The name of the team.
74 active: Is this team active?
75 remark: A remark about this team.
76 members: Members of this team.
77 """
79 ID: ClassVar[Type] = TeamIdentifier
81 name: str
82 active: bool = True
83 remark: str = ""
84 members: TeamMembers = field(default_factory=TeamMembers)
86 def __str__(self):
87 """Return string representation of the team entity."""
88 return f"<Team id={self.id} name={self.name}>"
90 def __repr__(self):
91 """Return representation of the team entity."""
92 return f"<{self.__class__.__name__} id={self.id} name={self.name!r}>"
94 def add_member(self, team_member: TeamMember) -> Self:
95 """Add a member to the team."""
96 if team_member.member.uuid in self.members:
97 raise TeamMemberAlreadyExistException(
98 f"Team member (id={team_member.member.id}) already part of team {self.name}"
99 )
100 return replace(
101 self,
102 members=self.members.add(team_member),
103 )
105 def remove_member(self, team_member: TeamMember) -> Self:
106 """Remove a team member."""
107 return replace(self, members=self.members.remove(team_member))