diff --git a/aleksis/apps/matrix/models.py b/aleksis/apps/matrix/models.py
index e991dad018a0590173994c321308d5cee2c097e0..c9bd5ec853073dbef6fbe3b6e36762cc91893830 100644
--- a/aleksis/apps/matrix/models.py
+++ b/aleksis/apps/matrix/models.py
@@ -30,6 +30,13 @@ class MatrixProfile(ExtensibleModel):
 
     change_tracker = FieldTracker()
 
+    class Meta:
+        verbose_name = _("Matrix profile")
+        verbose_name_plural = _("Matrix profiles")
+
+    def __str__(self):
+        return self.matrix_id
+
     @classmethod
     def build_matrix_id(cls, username: str, homeserver: Optional[str] = None) -> str:
         """Build a Matrix ID from a username."""
@@ -52,10 +59,6 @@ class MatrixProfile(ExtensibleModel):
             new_profile.save()
         return new_profile
 
-    class Meta:
-        verbose_name = _("Matrix profile")
-        verbose_name_plural = _("Matrix profiles")
-
 
 class MatrixRoom(ExtensiblePolymorphicModel):
     """Model for a Matrix room."""
@@ -71,6 +74,14 @@ class MatrixRoom(ExtensiblePolymorphicModel):
 
     change_tracker = FieldTracker(["group_id"])
 
+    class Meta:
+        verbose_name = _("Matrix room")
+        verbose_name_plural = _("Matrix rooms")
+        permissions = (("provision_group_in_matrix", "Can provision group in Matrix"),)
+
+    def __str__(self):
+        return self.room_id
+
     @classmethod
     def get_queryset(cls):
         """Get a queryset for only Matrix rooms."""
@@ -267,17 +278,19 @@ class MatrixRoom(ExtensiblePolymorphicModel):
         if get_site_preferences()["matrix__use_spaces"]:
             self.sync_space()
 
-    class Meta:
-        verbose_name = _("Matrix room")
-        verbose_name_plural = _("Matrix rooms")
-        permissions = (("provision_group_in_matrix", "Can provision group in Matrix"),)
-
 
 class MatrixSpace(MatrixRoom):
     children = models.ManyToManyField(
         to=MatrixRoom, verbose_name=_("Child rooms/spaces"), blank=True, related_name="parents"
     )
 
+    class Meta:
+        verbose_name = _("Matrix space")
+        verbose_name_plural = _("Matrix spaces")
+
+    def __str__(self):
+        return self.room_id
+
     @classmethod
     def get_queryset(cls):
         """Get a queryset with only Matrix spaces."""
@@ -355,7 +368,3 @@ class MatrixSpace(MatrixRoom):
         self.ensure_children()
         self.sync_children()
         self.sync_profiles()
-
-    class Meta:
-        verbose_name = _("Matrix space")
-        verbose_name_plural = _("Matrix spaces")
diff --git a/pyproject.toml b/pyproject.toml
index 5ef0db94a3be167b8a903970f302a7f512f15151..fa09b0134e48ee984b8b8d0d6881e118806ee754 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -9,10 +9,7 @@ include = ["CHANGELOG.rst", "LICENCE.rst", "aleksis/**/*.mo"]
 
 description = "AlekSIS (School Information System) — App Matrix (Integration with Matrix/Element)"
 authors = ["Jonathan Weth <dev@jonathanweth.de>"]
-maintainers = [
-    "Jonathan Weth <wethjo@katharineum.de>",
-    "Dominik George <dominik.george@teckids.org>"
-]
+maintainers = ["Jonathan Weth <dev@jonathanweth.de>", "Dominik George <dominik.george@teckids.org>"]
 license = "EUPL-1.2-or-later"
 homepage = "https://aleksis.org"
 repository = "https://edugit.org/AlekSIS/official/AlekSIS-App-Matrix"
@@ -25,29 +22,68 @@ classifiers = [
     "Typing :: Typed",
  ]
 
+[[tool.poetry.source]]
+name = "PyPI"
+priority = "primary"
+
 [[tool.poetry.source]]
 name = "gitlab"
 url = "https://edugit.org/api/v4/projects/461/packages/pypi/simple"
-secondary = true
-
+priority = "supplemental"
 [tool.poetry.dependencies]
 python = "^3.9"
 aleksis-core = "^3.0"
 
-[tool.poetry.dev-dependencies]
-aleksis-builddeps = ">=2023.1.dev0"
-matrix-synapse = "^1.49.2"
-pytest-xprocess = "^0.19.0"
-pytest-mock = "^3.7.0"
-
 [tool.poetry.plugins."aleksis.app"]
 matrix = "aleksis.apps.matrix.apps:DefaultConfig"
 
+
+[tool.poetry.group.dev.dependencies]
+django-stubs = "^4.2"
+
+safety = "^2.3.5"
+
+flake8 = "^6.0.0"
+flake8-django = "^1.0.0"
+flake8-fixme = "^1.1.1"
+flake8-mypy = "^17.8.0"
+flake8-bandit = "^4.1.1"
+flake8-builtins = "^2.0.0"
+flake8-docstrings = "^1.5.0"
+flake8-rst-docstrings = "^0.3.0"
+
+black = ">=21.0"
+flake8-black = "^0.3.0"
+
+isort = "^5.0.0"
+flake8-isort = "^6.0.0"
+
+curlylint = "^0.13.0"
+
+[tool.poetry.group.test.dependencies]
+pytest = "^7.2"
+pytest-django = "^4.1"
+pytest-django-testing-postgresql = "^0.2"
+pytest-cov = "^4.0.0"
+pytest-sugar = "^0.9.2"
+selenium = "<4.10.0"
+freezegun = "^1.1.0"
+
+[tool.poetry.group.docs]
+optional = true
+
+[tool.poetry.group.docs.dependencies]
+sphinx = "^7.0"
+sphinxcontrib-django = "^2.3.0"
+sphinxcontrib-svg2pdfconverter = "^1.1.1"
+sphinx-autodoc-typehints = "^1.7"
+sphinx_material = "^0.0.35"
+
 [tool.black]
 line-length = 100
 exclude = "/migrations/"
 
 [build-system]
-requires = ["poetry>=1.0"]
-build-backend = "poetry.masonry.api"
+requires = ["poetry-core>=1.0.0"]
+build-backend = "poetry.core.masonry.api"