added committees and guilds

This commit is contained in:
Tiago Scholten 2026-06-07 21:36:06 +02:00
parent 649f10be3f
commit 1e1676952d
8 changed files with 86 additions and 27 deletions

View File

@ -1,4 +1,4 @@
from typing import Annotated from typing import Literal
from pydantic import Field from pydantic import Field
from .non_members import FormerMemberModel from .non_members import FormerMemberModel
@ -7,7 +7,7 @@ from .submodels import Address, LoginInfo
class MemberModel(FormerMemberModel): class MemberModel(FormerMemberModel):
# requires that Membership equals member # requires that Membership equals member
membership: Annotated[Membership, Field(pattern="member")] membership: Literal[Membership.member] = Membership.member
login: LoginInfo login: LoginInfo
address: Address address: Address

View File

@ -1,4 +1,4 @@
from typing import Annotated from typing import Literal
from pydantic import Field from pydantic import Field
from .person import PersonModel from .person import PersonModel
@ -13,12 +13,12 @@ class FormerMemberModel(PersonModel):
# company emails? # company emails?
class AlumnModel(FormerMemberModel): class AlumnModel(FormerMemberModel):
membership: Annotated[Membership, Field(pattern="alumn")] membership: Literal[Membership.alumn] = Membership.alumn
graduated: bool = False graduated: bool = False
receive_spam_mail: bool = True receive_spam_mail: bool = True
class ExternalModel(PersonModel): class ExternalModel(PersonModel):
membership: Annotated[Membership, Field(pattern="extern")] membership: Literal[Membership.extern] = Membership.extern
# TODO... payment??? # TODO... payment???
# TODO require login info?? # TODO require login info??

View File

@ -4,9 +4,9 @@ from fiber_package.util import EntityList
class AssociationModel(BaseModel): class AssociationModel(BaseModel):
full_name: str full_name: str
members: EntityList = EntityList("member", []) members: EntityList
# committees: GroupList("commmittee", 0) # type: ignore committees: GroupList
# events: GroupList("event", 0) # type: ignore guilds: GroupList
# activities: GroupList("activity", 0) # type: ignore # events: GroupList
# mailings: GroupList("mailing", 0) # type: ignore # activities: GroupList
# mailalias: GroupList("mailalias", 0) # type: ignore # mailings: GroupList

View File

@ -1,10 +1,15 @@
from pydantic import BaseModel from pydantic import BaseModel, model_validator
from fiber_package.util import EntityList, GroupList, GroupRef from fiber_package.util import EntityList, GroupList, GroupRef
from typing import Self
from datetime import date
from .enums import CommitteeType from .enums import CommitteeType
''' '''
A committee represents any group of members Committees are groups of members for a definite period.
Every committee has a list of editions.
An edition is a definite group of members with functions and a timespan.
''' '''
class CommitteeModel(BaseModel): class CommitteeModel(BaseModel):
@ -15,8 +20,8 @@ class CommitteeModel(BaseModel):
active: bool = True active: bool = True
editions: GroupList("committee_edition", []) editions: GroupList
current_edition: GroupRef("committee_edition", None) current_edition: GroupRef
@model_validator(mode='after') @model_validator(mode='after')
def current_edition_in_editions(self) -> Self: def current_edition_in_editions(self) -> Self:
@ -28,9 +33,12 @@ class CommitteeModel(BaseModel):
return self return self
class CommitteeEditionModel(BaseModel): class CommitteeEditionModel(BaseModel):
members: EntityList = EntityList("member", []) members: EntityList
functions: dict[UUID4, str] functions: dict[UUID4, str]
start_date: date
end_date: date | None # None means ongoing
@model_validator(mode='after') @model_validator(mode='after')
def functions_to_members_only(self) -> Self: def functions_to_members_only(self) -> Self:
for uuid in self.functions.keys(): for uuid in self.functions.keys():

View File

@ -2,8 +2,7 @@ from enum import StrEnum
class CommitteeType(StrEnum): class CommitteeType(StrEnum):
board_committee: "Board committee" board_committee: "Board committee"
GMM_committee: "GMM committee" gmm_committee: "GMM committee"
guild: "Guild" board: "board"
subassociation_board: "Subassociation board"

View File

@ -0,0 +1,42 @@
from pydantic import BaseModel, model_validator
from fiber_package.util import EntityList
from datetime import date
from typing import Self
'''
Guilds are groups of members for an indefinite period.
They have a list of members.
Removing old members from last_active is done in fiber
'''
class GuildModel(BaseModel):
full_name_EN: str
full_name_NL: str
description_EN: str
description_NL: str
members: EntityList
previous_members: EntityList
guild_masters: EntityList
last_active: dict[EntityRef, date]
@model_validator(mode='after')
def current_members_not_previous(self) -> Self:
for member in self.members:
if member in self.previous_members:
raise ValueError("There can be no overlap between members and previous members!")
return self
@model_validator(mode='after')
def guild_masters_are_members(self) -> Self:
for master in self.guild_masters:
if master not in self.members:
raise ValueError("All guild masters must be members!")
return self

View File

@ -2,5 +2,5 @@ from pydantic import BaseModel
from fiber_package.util import GroupList, EntityList from fiber_package.util import GroupList, EntityList
class RootGroupModel(BaseModel): class RootGroupModel(BaseModel):
associations: GroupList = GroupList("association", []) associations: GroupList
sys_admins: EntityList = EntityList("login", []) sys_admins: EntityList

View File

@ -2,22 +2,32 @@ from dataclasses import dataclass, field
from pydantic import UUID4 from pydantic import UUID4
'''
(Entity/Group)(List/Ref) represents a list / single instance of entities / groups.
This is for fiber to know in which Mongo collection to look.
the __iter__ function allows us to do things as
"for member in edition.members"
'''
@dataclass(slots=True) @dataclass(slots=True)
class EntityList: class EntityList:
template: str
uuids: list[UUID4] = field(default_factory=list) uuids: list[UUID4] = field(default_factory=list)
def __iter__(self):
return iter(self.uuids)
@dataclass(slots=True) @dataclass(slots=True)
class GroupList: class GroupList:
template: str
uuids: list[UUID4] = field(default_factory=list) uuids: list[UUID4] = field(default_factory=list)
def __iter__(self):
return iter(self.uuids)
@dataclass(slots=True) @dataclass(slots=True)
class EntityRef: class EntityRef:
template: str uuids: UUID4
uuids: UUID4 | None = None
@dataclass(slots=True) @dataclass(slots=True)
class GroupRef: class GroupRef:
template: str uuids: UUID4
uuids: UUID4 | None = None