diff --git a/backend/db/implementation/SqlAdminDAO.py b/backend/db/implementation/SqlAdminDAO.py index bb4f0e16..865c34a5 100644 --- a/backend/db/implementation/SqlAdminDAO.py +++ b/backend/db/implementation/SqlAdminDAO.py @@ -16,7 +16,7 @@ def get_admin(self, ident: int) -> AdminDataclass: return admin.to_domain_model() def get_all_admins(self) -> list[AdminDataclass]: - admins: list[Admin] = db.session.scalars(select(Admin)).all() + admins: list[Admin] = list(db.session.scalars(select(Admin)).all()) return [admin.to_domain_model() for admin in admins] def create_admin(self, name: str, email: str) -> None: diff --git a/backend/db/implementation/SqlGroupDAO.py b/backend/db/implementation/SqlGroupDAO.py index 7c9eb9e4..2cbb3efd 100644 --- a/backend/db/implementation/SqlGroupDAO.py +++ b/backend/db/implementation/SqlGroupDAO.py @@ -2,57 +2,64 @@ from db.extensions import db from db.interface.GroupDAO import GroupDAO from db.models.models import Group, Project, Student -from domain.models.models import GroupDataclass, StudentDataclass +from domain.models.GroupDataclass import GroupDataclass +from domain.models.StudentDataclass import StudentDataclass class SqlGroupDAO(GroupDAO): - def create_group(self, group: GroupDataclass, project_id: int): - project = Project.query.get(project_id) + def create_group(self, project_id: int) -> None: + project: Project | None = db.session.get(Project, ident=project_id) if not project: - raise ItemNotFoundError(f"Het project met id {project_id} kon niet in de databank gevonden worden") - new_group: Group = Group(project_id=project_id, project=project, students=students, ) - new_group.project_id = project_id - new_group.project = project + msg = f"Project with id {project} not found" + raise ItemNotFoundError(msg) + new_group: Group = Group(project_id=project_id, project=project) db.session.add(new_group) db.session.commit() - group.id = new_group.id - def get_group(self, group_id: int) -> GroupDataclass: - group = Group.query.get(group_id) + group: Group | None = db.session.get(Group, ident=group_id) if not group: - raise ItemNotFoundError(f"De groep met id {group_id} kon niet in de databank gevonden worden") + msg = f"Group with id {group_id} not found" + raise ItemNotFoundError(msg) return group.to_domain_model() def get_groups_of_project(self, project_id: int) -> list[GroupDataclass]: - project = Project.query.get(project_id) + project: Project | None = db.session.get(Project, ident=project_id) if not project: - raise ItemNotFoundError(f"Het project met id {project_id} kon niet in de databank gevonden worden") + msg = f"Project with id {project} not found" + raise ItemNotFoundError(msg) groups: list[Group] = project.groups return [group.to_domain_model() for group in groups] def get_groups_of_student(self, student_id: int) -> list[GroupDataclass]: - student = Student.query.get(student_id) + student: Student | None = db.session.get(Student, ident=student_id) if not student: - raise ItemNotFoundError(f"De student met id {student_id} kon niet in de databank gevonden worden") + msg = f"Student with id {student_id} not found" + raise ItemNotFoundError(msg) groups: list[Group] = student.groups return [group.to_domain_model() for group in groups] - def add_student_to_group(self, student_id: int, group_id: int): - student = Student.query.get(student_id) - group = Group.query.get(group_id) + def add_student_to_group(self, student_id: int, group_id: int) -> None: + student: Student | None = db.session.get(Student, ident=student_id) + group: Group | None = db.session.get(Group, ident=group_id) if not student: - raise ItemNotFoundError(f"De student met id {student_id} kon niet in de databank gevonden worden") + msg = f"Student with id {student_id} not found" + raise ItemNotFoundError(msg) if not group: - raise ItemNotFoundError(f"De group met id {group_id} kon niet in de databank gevonden worden") + msg = f"Group with id {group_id} not found" + raise ItemNotFoundError(msg) if student in group.students: - raise UniqueConstraintError(f"De student met id {student_id} zit al in de groep met id {group_id}") + msg = f"Student with id {student_id} already in group with id {group_id}" + raise UniqueConstraintError(msg) group.students.append(student) + db.session.add(group) + db.session.commit() def get_students_of_group(self, group_id: int) -> list[StudentDataclass]: - group = Group.query.get(group_id) + group: Group | None = db.session.get(Group, ident=group_id) if not group: - raise ItemNotFoundError(f"De group met id {group_id} kon niet in de databank gevonden worden") + msg = f"Group with id {group_id} not found" + raise ItemNotFoundError(msg) students: list[Student] = group.students return [student.to_domain_model() for student in students] diff --git a/backend/db/implementation/SqlProjectDAO.py b/backend/db/implementation/SqlProjectDAO.py index be6e4851..460636c0 100644 --- a/backend/db/implementation/SqlProjectDAO.py +++ b/backend/db/implementation/SqlProjectDAO.py @@ -1,38 +1,39 @@ +from datetime import datetime + from db.errors.database_errors import ItemNotFoundError from db.extensions import db from db.interface.ProjectDAO import ProjectDAO from db.models.models import Project, Subject -from domain.models.models import ProjectDataclass +from domain.models.ProjectDataclass import ProjectDataclass class SqlProjectDAO(ProjectDAO): - def create_project(self, project: ProjectDataclass, subject_id: int): - subject = Subject.query.get(subject_id) + def create_project(self, subject_id: int, name: str, deadline: datetime, archived: bool, requirements: str, + visible: bool, max_student: int) -> None: + subject: Subject | None = db.session.get(Subject, subject_id) if not subject: - raise ItemNotFoundError(f"Het subject met id {subject_id} kon niet in de databank gevonden worden") - - new_project = Project() - new_project.subject_id = subject_id - new_project.name = project.name - new_project.deadline = project.deadline - new_project.archived = project.archived - new_project.requirements = project.requirements - new_project.visible = project.visible - new_project.max_students = project.max_students + msg = f"Subject with id {subject_id} not found" + raise ItemNotFoundError(msg) + + new_project: Project = Project(subject_id=subject_id, subject=subject, name=name, deadline=deadline, + archived=archived, requirements=requirements, visible=visible, + max_students=max_student) + db.session.add(new_project) db.session.commit() - project.id = new_project.id def get_project(self, project_id: int) -> ProjectDataclass: - project = Project.query.get(project_id) + project: Project | None = db.session.get(Project, ident=project_id) if not project: - raise ItemNotFoundError(f"Het project met id {project_id} kon niet in de databank gevonden worden") + msg = f"Project with id {project_id} not found" + raise ItemNotFoundError(msg) return project.to_domain_model() - def get_projects(self, subject_id: int) -> list[ProjectDataclass]: - subject = Subject.query.get(subject_id) + def get_projects_of_subject(self, subject_id: int) -> list[ProjectDataclass]: + subject: Subject | None = db.session.get(Subject, ident=subject_id) if not subject: - raise ItemNotFoundError(f"Het subject met id {subject_id} kon niet in de databank gevonden worden") + msg = f"Subject with id {subject_id} not found" + raise ItemNotFoundError(msg) projects: list[Project] = subject.projects return [project.to_domain_model() for project in projects] diff --git a/backend/db/implementation/SqlStudentDAO.py b/backend/db/implementation/SqlStudentDAO.py index 39c2a95c..affd6a5d 100644 --- a/backend/db/implementation/SqlStudentDAO.py +++ b/backend/db/implementation/SqlStudentDAO.py @@ -16,7 +16,7 @@ def get_student(self, ident: int) -> StudentDataclass: return student.to_domain_model() def get_all_students(self) -> list[StudentDataclass]: - students: list[Student] = db.session.scalars(select(Student)).all() + students: list[Student] = list(db.session.scalars(select(Student)).all()) return [student.to_domain_model() for student in students] def create_student(self, name: str, email: str) -> None: diff --git a/backend/db/implementation/SqlTeacherDAO.py b/backend/db/implementation/SqlTeacherDAO.py index 38319608..3ac6383f 100644 --- a/backend/db/implementation/SqlTeacherDAO.py +++ b/backend/db/implementation/SqlTeacherDAO.py @@ -12,13 +12,13 @@ def get_teacher(self, ident: int) -> TeacherDataclass: teacher: Teacher | None = db.session.get(Teacher, ident) if not teacher: - msg = f"Teacher with id {ident} not found" + msg = f"Teacher with id {ident} not found" raise ItemNotFoundError(msg) return teacher.to_domain_model() def get_all_teachers(self) -> list[TeacherDataclass]: - teachers: list[Teacher] = db.session.scalars(select(Teacher)).all() + teachers: list[Teacher] = list(db.session.scalars(select(Teacher)).all()) return [teacher.to_domain_model() for teacher in teachers] def create_teacher(self, name: str, email: str) -> None: diff --git a/backend/db/implementation/SqlUserDAO.py b/backend/db/implementation/SqlUserDAO.py index 0f27b964..89508490 100644 --- a/backend/db/implementation/SqlUserDAO.py +++ b/backend/db/implementation/SqlUserDAO.py @@ -1,29 +1,25 @@ +from sqlalchemy import select + from db.errors.database_errors import ItemNotFoundError from db.extensions import db from db.interface.UserDAO import UserDAO from db.models.models import User -from domain.models.models import UserDataclass +from domain.models.UserDataclass import UserDataclass class SqlUserDAO(UserDAO): def get_user(self, ident: int) -> UserDataclass: - user: User = User.query.get(ident=ident) - + user: User | None = db.session.get(User, ident=ident) if not user: - raise ItemNotFoundError("UserDataClass with given id not found.") - + msg = f"User with id {ident} not found" + raise ItemNotFoundError(msg) return user.to_domain_model() def get_all_users(self) -> list[UserDataclass]: - users: list[User] = User.query.all() + users: list[User] = list(db.session.scalars(select(User)).all()) return [user.to_domain_model() for user in users] - def create_user(self, user: UserDataclass): - new_user: User = User() - new_user.email = user.email - new_user.name = user.name - + def create_user(self, name: str, email: str) -> None: + new_user: User = User(name=name, email=email) db.session.add(new_user) db.session.commit() - - user.id = new_user.id diff --git a/backend/db/interface/GroupDAO.py b/backend/db/interface/GroupDAO.py index d37b6a8c..5c9370eb 100644 --- a/backend/db/interface/GroupDAO.py +++ b/backend/db/interface/GroupDAO.py @@ -1,19 +1,19 @@ from abc import ABC, abstractmethod -from domain.models.models import GroupDataclass, StudentDataclass +from domain.models.GroupDataclass import GroupDataclass +from domain.models.StudentDataclass import StudentDataclass class GroupDAO(ABC): @abstractmethod - def create_group(self, group: GroupDataclass, project_id: int): + def create_group(self, project_id: int) -> None: """ Creëert een nieuw GroupDataClass in de database en associeert het met een ProjectDataClass. - :param group: De GroupDataClass domeinmodel-instantie die aan de database moet worden toegevoegd. - :param project_id: De identificatie van de ProjectDataClass waarmee het GroupDataClass geassocieerd wordt. + :param project_id: Id van het project dat gelinkt is aan de groep :raises: ItemNotFoundException: Als er geen ProjectDataClass met de opgegeven `project_id` in de database is. """ - raise NotImplementedError() + raise NotImplementedError @abstractmethod def get_group(self, group_id: int) -> GroupDataclass: @@ -24,7 +24,7 @@ def get_group(self, group_id: int) -> GroupDataclass: :raises ItemNotFoundException: Als er geen GroupDataClass met de opgegeven `group_id` in de database bestaat. :returns: De domeinmodel-instantie van het opgehaalde GroupDataClass. """ - raise NotImplementedError() + raise NotImplementedError @abstractmethod def get_groups_of_project(self, project_id: int) -> list[GroupDataclass]: @@ -34,7 +34,7 @@ def get_groups_of_project(self, project_id: int) -> list[GroupDataclass]: :param project_id: Het subject waarvan de projecten opgehaald moeten worden. :return: Een lijst van projecten die bij een bepaald project horen. """ - raise NotImplementedError() + raise NotImplementedError @abstractmethod def get_groups_of_student(self, student_id: int) -> list[GroupDataclass]: @@ -44,10 +44,10 @@ def get_groups_of_student(self, student_id: int) -> list[GroupDataclass]: :param student_id: De student waarvan de groepen opgehaald moeten worden. :return: Een lijst van groepen die bij een bepaald student horen. """ - raise NotImplementedError() + raise NotImplementedError @abstractmethod - def add_student_to_group(self, student_id: int, group_id: int): + def add_student_to_group(self, student_id: int, group_id: int) -> None: """ Gaat een student toevoegen aan een groep @@ -55,7 +55,7 @@ def add_student_to_group(self, student_id: int, group_id: int): :param group_id: De groep waaraan de student moet toegevoegd worden. :raises ItemNotFoundException: Als er geen group/student met gegeven id in de databank zit. """ - raise NotImplementedError() + raise NotImplementedError def get_students_of_group(self, group_id: int) -> list[StudentDataclass]: """ @@ -64,4 +64,4 @@ def get_students_of_group(self, group_id: int) -> list[StudentDataclass]: :param group_id: De groep waarvan de studenten worden opgeroepen :raises ItemNotFoundException: Als er geen group met gegeven id in de databank zit. """ - raise NotImplementedError() + raise NotImplementedError diff --git a/backend/db/interface/ProjectDAO.py b/backend/db/interface/ProjectDAO.py index 4cdd591f..90ad6101 100644 --- a/backend/db/interface/ProjectDAO.py +++ b/backend/db/interface/ProjectDAO.py @@ -1,19 +1,26 @@ from abc import ABC, abstractmethod +from datetime import datetime -from domain.models.models import ProjectDataclass +from domain.models.ProjectDataclass import ProjectDataclass class ProjectDAO(ABC): @abstractmethod - def create_project(self, project: ProjectDataclass, subject_id: int): + def create_project(self, subject_id: int, name: str, deadline: datetime, archived: bool, requirements: str, + visible: bool, max_student: int) -> None: """ Creëert een nieuw ProjectDataClass in de database en associeert het met een SubjectDataClass. - :param project: De ProjectDataClass domeinmodel-instantie die aan de database moet worden toegevoegd. + :param max_student: maximaal aantal studenten per groep per project + :param visible: of het project zichtbaar is voor de studenten + :param requirements: Uitleg van het project + :param archived: Of het project gearchiveerd is + :param name: De naam van het project + :param deadline: De deadline van het project :param subject_id: De identificatie van de SubjectDataClass waarmee het ProjectDataClass geassocieerd wordt. :raises: ItemNotFoundException: Als er geen SubjectDataClass met de opgegeven `teacher_id` in de database is. """ - raise NotImplementedError() + raise NotImplementedError @abstractmethod def get_project(self, project_id: int) -> ProjectDataclass: @@ -24,14 +31,14 @@ def get_project(self, project_id: int) -> ProjectDataclass: :raises ItemNotFoundException: Als er geen ProjectDataClass met de opgegeven `project_id` in de database bestaat :returns: De domeinmodel-instantie van het opgehaalde ProjectDataClass. """ - raise NotImplementedError() + raise NotImplementedError @abstractmethod - def get_projects(self, subject_id: int) -> list[ProjectDataclass]: + def get_projects_of_subject(self, subject_id: int) -> list[ProjectDataclass]: """ Haalt alle projecten op die bij een bepaald subject horen. :param subject_id: Het subject waarvan de projecten opgehaald moeten worden. :return: Een lijst van projecten die bij een bepaald subject horen. """ - raise NotImplementedError() + raise NotImplementedError diff --git a/backend/db/interface/UserDAO.py b/backend/db/interface/UserDAO.py index 5f92bd51..f609162b 100644 --- a/backend/db/interface/UserDAO.py +++ b/backend/db/interface/UserDAO.py @@ -1,6 +1,6 @@ from abc import ABC, abstractmethod -from domain.models.models import UserDataclass +from domain.models.UserDataclass import UserDataclass class UserDAO(ABC): @@ -13,7 +13,7 @@ def get_user(self, ident: int) -> UserDataclass: :return: De user die overeenkomt met de gegeven id. :raises ItemNotFoundException: Als geen user met het gegeven id gevonden werd. """ - raise NotImplementedError() + raise NotImplementedError @abstractmethod def get_all_users(self) -> list[UserDataclass]: @@ -22,13 +22,14 @@ def get_all_users(self) -> list[UserDataclass]: :return: Een lijst van alle users. """ - raise NotImplementedError() + raise NotImplementedError @abstractmethod - def create_user(self, user: UserDataclass): + def create_user(self, name: str, email: str) -> None: """ Maakt een nieuwe user aan. - :param user: De user die aangemaakt moet worden. + :param name: De naam van de nieuwe user + :param email: De email van de nieuwe user """ - raise NotImplementedError() + raise NotImplementedError diff --git a/backend/fill_database_mock.py b/backend/fill_database_mock.py index 2939167a..d618087e 100644 --- a/backend/fill_database_mock.py +++ b/backend/fill_database_mock.py @@ -1,120 +1,17 @@ -from datetime import datetime - from app import app from db.extensions import db from db.implementation.SqlAdminDAO import SqlAdminDAO -from db.implementation.SqlGroupDAO import SqlGroupDAO -from db.implementation.SqlProjectDAO import SqlProjectDAO from db.implementation.SqlStudentDAO import SqlStudentDAO from db.implementation.SqlSubjectDAO import SqlSubjectDAO -from db.implementation.SqlSubmissionDAO import SqlSubmissionDAO from db.implementation.SqlTeacherDAO import SqlTeacherDAO -from db.implementation.SqlUserDAO import SqlUserDAO -from db.interface.AdminDAO import AdminDAO -from db.interface.GroupDAO import GroupDAO -from db.interface.ProjectDAO import ProjectDAO -from db.interface.StudentDAO import StudentDAO -from db.interface.SubjectDAO import SubjectDAO -from db.interface.SubmissionDAO import SubmissionDAO -from db.interface.TeacherDAO import TeacherDAO -from domain.models.SubjectDataclass import SubjectDataclass -from domain.models.TeacherDataclass import TeacherDataclass if __name__ == "__main__": with app.app_context(): - db.create_all() - teacher_dao: TeacherDAO = SqlTeacherDAO() - subject_dao: SubjectDAO = SqlSubjectDAO() - user_dao: UserDAO = SqlUserDAO() - admin_dao: AdminDAO = SqlAdminDAO() - student_dao: StudentDAO = SqlStudentDAO() - project_dao: ProjectDAO = SqlProjectDAO() - group_dao: GroupDAO = SqlGroupDAO() - submission_dao: SubmissionDAO = SqlSubmissionDAO() - - # Maak nieuwe user aan. - Gunnar = UserDataclass(name="Gunnar Brinkamann", email="gunnartjeDeLeerkracht@gmail.com") - Alberic = UserDataclass(name="Alberic Loos", email="albericLoos@lala.com") - Bob = UserDataclass(name="Bob", email="bob@lala.com") - Rien = UserDataclass(name="Rien", email="rientje@gmail.com") - - # voeg users toe aan de databank - user_dao.create_user(Gunnar) - user_dao.create_user(Alberic) - user_dao.create_user(Bob) - user_dao.create_user(Rien) - - # voeg admin toe aan de databank - admin_dao.create_admin(name="Mario", email="mario@luigi.com") - - # voeg teacher toe aan de databank - teacher_dao.create_teacher(Gunnar.id) - teacher_dao.create_teacher(Rien.id) - - # voeg student toe aan de databank - student_dao.create_student(Alberic.id) - student_dao.create_student(Bob.id) - - # maak subjects aan - AD2 = SubjectDataclass(name="AD2") - AD3 = SubjectDataclass(name="AD3") - - # maak project aan - AD2_project = ProjectDataclass(name="AD2_project", - subject_id=AD2.id, - archived=False, - deadline=datetime(2024, 3, 1, 12, 0, 0), - max_students=5, - visible=True, - requirements="lala") - - # maak een groep aan - Group_1_AD2 = GroupDataclass(project_id=AD2_project.id) - Group_2_AD2 = GroupDataclass(project_id=AD2_project.id) - # maak een submission aan - AD2_project_submission1 = SubmissionDataclass(date_time=datetime(2024, 3, 1, 12, 0, 0), - group_id=Group_1_AD2.id, - message="lalalalalalalalalalalal", - state=0, - student_id=Alberic.id) - - AD2_project_submission2 = SubmissionDataclass(date_time=datetime(2024, 3, 1, 12, 0, 0), - group_id=Group_1_AD2.id, - message="lalalalalalalalalalalal", - state=0, - student_id=Bob.id) - - # voeg subjects toe aan de databank - subject_dao.create_subject(AD2, Gunnar.id) - subject_dao.create_subject(AD3, Gunnar.id) - - # laat student vak volgen - subject_dao.add_subject_student(AD2.id, Bob.id) - subject_dao.add_subject_student(AD3.id, Bob.id) - - # maak assistenten ook teachers van de subjects - subject_dao.add_subject_teacher(AD2.id, Rien.id) - - # voeg project toe - project_dao.create_project(AD2_project, subject_id=AD2.id) - - # voeg de groepen toe aan de databank - group_dao.create_group(group=Group_1_AD2, project_id=AD2_project.id) - group_dao.create_group(group=Group_2_AD2, project_id=AD2_project.id) - - # voeg studenten toe aan de groep - group_dao.add_student_group(student_id=Alberic.id, group_id=Group_1_AD2.id) - group_dao.add_student_group(student_id=Bob.id, group_id=Group_1_AD2.id) - - # voeg de submission toe - submission_dao.create_submission(submission=AD2_project_submission1, - group_id=Group_1_AD2.id, - student_id=Alberic.id) - - submission_dao.create_submission(submission=AD2_project_submission2, - group_id=Group_1_AD2.id, - student_id=Bob.id) + db.create_all() - print(admin_dao.get_admin(Gunnar.id)) + admin_dao = SqlAdminDAO() + student_dao = SqlStudentDAO() + teacher_dao = SqlTeacherDAO() + subject_dao = SqlSubjectDAO() diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 47494028..69bedea1 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -85,7 +85,9 @@ ignore = [ "INP001", # File `...` is part of an implicit namespace package "S101", # is nodig voor de testen "TCH001", # Move application import `...` into a type-checking block (dit is enkel voor performance) - "RUF009" # Do not perform function call `...` in dataclass defaults but needed for sql alchemy + "RUF009", # Do not perform function call `...` in dataclass defaults but needed for sql alchemy + "PLR0913", # Too many arguments in function + "FBT001" # Boolean-typed positional argument in function dfinition ] # Allow fix for all enabled rules (when `--fix`) is provided. diff --git a/backend/routes/teachers.py b/backend/routes/teachers.py index e3f1a22e..69c69323 100644 --- a/backend/routes/teachers.py +++ b/backend/routes/teachers.py @@ -46,6 +46,6 @@ def create_teacher() -> Response: dao: TeacherDAO = SqlTeacherDAO() lesgever = TeacherDataclass(**teacher_data) # Vul alle velden van het dataobject in met de json - dao.create_teacher(lesgever) + dao.create_teacher(lesgever.name, lesgever.email) return Response(json.dumps(lesgever.to_dict()), status=HTTPStatus.CREATED)