diff --git a/dakiny_bot/database/models.py b/dakiny_bot/database/models.py index 494b036..3f28931 100644 --- a/dakiny_bot/database/models.py +++ b/dakiny_bot/database/models.py @@ -5,7 +5,8 @@ from sqlmodel import Column, Field, ForeignKey, Relationship, SQLModel class ElectionInformation(SQLModel, table=True): - """Represents all required information for an election. + """ + Represents all required information for an election. Attributes: name: Name of the election. @@ -14,6 +15,8 @@ class ElectionInformation(SQLModel, table=True): high_council_vote_msg_id: Message where the high council vote is presented. council_nomination_msg_id: Message where council nomination button is held. high_council_nomination_msg_id: Message where high council nomination button is held. + council_members: List of council members who ran during this election. + votes: All votes cast during this election. """ name: str = Field(sa_column=Column("ElectionName", VARCHAR, primary_key=True, unique=True), max_length=30) @@ -31,11 +34,13 @@ class ElectionInformation(SQLModel, table=True): sa_column=Column("HighCouncilNominationMsgId", BIGINT(unsigned=True), nullable=True), default=None ) - council_members: list["CouncilMembers"] = Relationship(back_populates="election", cascade_delete=True) + council_members: list["CouncilMember"] = Relationship(back_populates="election", cascade_delete=True) + votes: list["Vote"] = Relationship(back_populates="election", cascade_delete=True) -class CouncilMembers(SQLModel, table=True): - """Represents members involved in a given election. +class CouncilMember(SQLModel, table=True): + """ + Represents members involved in a given election. Records speech message ids for general election and high council position. Booleans record if the user was elected to a council/high council position. @@ -48,8 +53,12 @@ class CouncilMembers(SQLModel, table=True): clan_leader: Whether the user got elected to the Clan Leader position. discord_manager_speech_id: Message id of the user's Discord Manager speech. clan_leader_speech_id: Message id of the user's Clan Leader speech. + election: The election this user object is for. + votes: A list of votes for this user. """ + __tablename__: str = "CouncilMembers" + election_name: str = Field( sa_column=Column( "ElectionName", @@ -70,3 +79,39 @@ class CouncilMembers(SQLModel, table=True): clan_leader_speech_id: int = Field(sa_column=Column("ClanLeaderSpeechId", BIGINT(unsigned=True), nullable=True)) election: ElectionInformation | None = Relationship(back_populates="council_members") + votes: list["Vote"] = Relationship(back_populates="council_member") + + +class Vote(SQLModel, table=True): + """ + Represents a vote cast during an election. + + Attributes: + election_name: Election this vote was cast in. + voter_id: User id that cast the vote. + voted_for_id: User id that was voted for. + type: Type of election, council, discordmanager, or clanleader. + election: A link to the ElectionInformation object that the vote was cast in. + council_member: A link to the CouncilMember object that the vote is for. + """ + + __tablename__: str = "Votes" + + election_name: str = Field( + sa_column=Column( + "ElectionName", + VARCHAR, + ForeignKey("ElectionInformation.ElectionName", ondelete="CASCADE"), + primary_key=True, + ), + max_length=30, + ) + voter_id: int = Field(sa_column=Column("VoterId", BIGINT(unsigned=True), primary_key=True, nullable=False)) + # might have to set this foreign key later with alembic migration... + voted_for_id: int | None = Field( + sa_column=Column("VotedForId", BIGINT(unsigned=True), ForeignKey("CouncilMembers.member_id"), nullable=True) + ) + type: str = Field(sa_column=Column("Type", primary_key=True, nullable=False, default="council"), max_length=14) + + election: ElectionInformation | None = Relationship(back_populates="votes") + council_member: CouncilMember | None = Relationship(back_populates="votes")