diff --git a/.idea/league-manager.iml b/.idea/league-manager.iml
index e221225..a3234c3 100644
--- a/.idea/league-manager.iml
+++ b/.idea/league-manager.iml
@@ -3,8 +3,9 @@
+
-
+
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 1d3ce46..5653f38 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -3,5 +3,5 @@
-
+
\ No newline at end of file
diff --git a/backend/app/models/serie.py b/backend/app/models/serie.py
new file mode 100644
index 0000000..549148b
--- /dev/null
+++ b/backend/app/models/serie.py
@@ -0,0 +1,173 @@
+# app/models/serie.py
+from typing import TYPE_CHECKING
+
+from sqlmodel import Field, Relationship, Session, select
+
+from . import mixin
+from .base import BaseSQLModel, RowId
+from .user import PermissionRight, User
+
+if TYPE_CHECKING:
+ from .team import Team
+
+# region # Serie ##############################################################
+
+# Shared properties
+class SerieUserLinkBase(BaseSQLModel):
+ rights: PermissionRight = Field(default=PermissionRight.READ, nullable=False)
+
+# Properties to receive via API on creation
+class SerieUserLinkCreate(SerieUserLinkBase):
+ user_id: RowId = Field(nullable=False)
+
+# Properties to receive via API on update, all are optional
+class SerieUserLinkUpdate(SerieUserLinkBase):
+ pass
+
+# Database model (link tussen serie en user)
+class SerieUserLink(SerieUserLinkBase, table=True):
+ serie_id: RowId = Field(
+ foreign_key="serie.id",
+ primary_key=True,
+ nullable=False,
+ ondelete="CASCADE",
+ )
+ user_id: RowId = Field(
+ foreign_key="user.id",
+ primary_key=True,
+ nullable=False,
+ ondelete="CASCADE",
+ )
+
+ serie: "Serie" = Relationship(back_populates="user_links")
+ user: "User" = Relationship(back_populates="serie_links")
+
+# Properties to return via API
+class SerieUserLinkPublic(SerieUserLinkBase):
+ user_id: RowId
+ serie_id: RowId
+
+class SerieUserLinksPublic(BaseSQLModel):
+ data: list[SerieUserLinkPublic]
+ count: int
+
+# Shared properties
+class SerieBase(
+ mixin.Name,
+ mixin.Contact,
+ mixin.IsActive,
+ BaseSQLModel,
+):
+ pass
+
+# Properties to receive via API on creation
+class SerieCreate(SerieBase):
+ pass
+
+# Properties to receive via API on update, all are optional
+class SerieUpdate(SerieBase):
+ pass
+
+# Database model
+class Serie(mixin.RowId, SerieBase, table=True):
+
+ user_links: list["SerieUserLink"] = Relationship(back_populates="serie", cascade_delete=True)
+ #teams: list["Team"] = Relationship(back_populates="serie", cascade_delete=True)
+
+ @classmethod
+ def create(cls, *, session: Session, create_obj: SerieCreate) -> "Serie":
+ data_obj = create_obj.model_dump(exclude_unset=True)
+ db_obj = cls.model_validate(data_obj)
+ session.add(db_obj)
+ session.commit()
+ session.refresh(db_obj)
+ return db_obj
+
+ @classmethod
+ def update(cls, *, session: Session, db_obj: "Serie", in_obj: SerieUpdate) -> "Serie":
+ data_obj = in_obj.model_dump(exclude_unset=True)
+ db_obj.sqlmodel_update(data_obj)
+ session.add(db_obj)
+ session.commit()
+ session.refresh(db_obj)
+ return db_obj
+
+ def get_user_link(self, user: User) -> "SerieUserLink | None":
+ return next((link for link in self.user_links if link.user == user), None)
+
+ def add_user(
+ self,
+ user: User,
+ rights: PermissionRight = PermissionRight.READ,
+ *,
+ session: Session,
+ ) -> "SerieUserLink | None":
+ existing = self.get_user_link(user=user)
+ if existing is None:
+ new_link = SerieUserLink(serie=self, user=user, rights=rights)
+ self.user_links.append(new_link)
+ session.add(new_link)
+ session.commit()
+ return new_link
+ return None #TODO aanpassen??
+
+ def update_user(
+ self,
+ user: User,
+ rights: PermissionRight = PermissionRight.READ,
+ *,
+ session: Session,
+ ) -> "SerieUserLink | None":
+ link = self.get_user_link(user=user)
+ if link:
+ link.rights = rights
+ session.add(link)
+ session.commit()
+ return link
+ return None
+
+ def remove_user(self, user: User, *, session: Session) -> None:
+ link = self.get_user_link(user=user)
+ if link:
+ session.delete(link)
+ session.commit()
+
+ def user_has_rights(
+ self,
+ user: User,
+ rights: PermissionRight | None = None,
+ ) -> bool:
+ return any(
+ (
+ link.user == user
+ and link.rights
+ and (not rights or (link.rights & rights) == rights)
+ )
+ for link in self.user_links
+ )
+
+ def user_has_right(
+ self,
+ user: User,
+ rights: PermissionRight | None = None,
+ ) -> bool:
+ return any(
+ (
+ link.user == user
+ and link.rights
+ and (not rights or (link.rights & rights))
+ )
+ for link in self.user_links
+ )
+
+
+# API output models
+class SeriePublic(mixin.RowIdPublic, SerieBase):
+ pass
+
+
+class SeriesPublic(BaseSQLModel):
+ data: list[SeriePublic]
+ count: int
+
+# endregion
\ No newline at end of file