diff --git a/deployment/options.nix b/deployment/options.nix
index 1de9265f..df04b994 100644
--- a/deployment/options.nix
+++ b/deployment/options.nix
@@ -13,6 +13,7 @@ let
 in
 {
   options = {
+    enable = lib.mkEnableOption "Fediversity configuration";
     domain = mkOption {
       type =
         with types;
@@ -22,6 +23,7 @@ in
       description = ''
         Apex domain under which the services will be deployed.
       '';
+      default = "fediversity.net";
     };
     pixelfed = {
       enable = lib.mkEnableOption "Pixelfed";
diff --git a/panel/default.nix b/panel/default.nix
index 724404ef..41655c61 100644
--- a/panel/default.nix
+++ b/panel/default.nix
@@ -13,7 +13,6 @@ let
     exec ${pkgs.lib.getExe pkgs.python3} ${toString ./src/manage.py} $@
   '';
   jsonschema = pkgs.callPackage ./jsonschema.nix { } {
-    includeDefaults = false;
   };
   frontend-options = jsonschema.parseModule ../deployment/options.nix;
   schema = with builtins; toFile "schema.json" (toJSON frontend-options);
@@ -42,7 +41,7 @@ in
       DATABASE_URL = "sqlite:///${toString ./src}/db.sqlite3";
     };
     shellHook = ''
-      cp -f ${pydantic} ${builtins.toString ./src/panel/configuration/schema.py}
+      install -m 644 ${pydantic} ${builtins.toString ./src/panel/configuration/schema.py}
 
       ln -sf ${sources.htmx}/dist/htmx.js src/panel/static/htmx.min.js
       # in production, secrets are passed via CREDENTIALS_DIRECTORY by systemd.
diff --git a/panel/src/panel/models.py b/panel/src/panel/models.py
index 67426cb1..4652e183 100644
--- a/panel/src/panel/models.py
+++ b/panel/src/panel/models.py
@@ -1,13 +1,13 @@
 from django.db import models
 from django.contrib.auth.models import User
 
-from panel.configuration import forms
+from panel.configuration import schema
 
 from pydantic import BaseModel
 
 
 def get_default_config():
-    return forms.Configuration().model_dump_json()
+    return schema.Model().model_dump_json()
 
 
 class Configuration(models.Model):
@@ -26,4 +26,4 @@ class Configuration(models.Model):
 
     @property
     def parsed_value(self) -> BaseModel:
-        return forms.Configuration.model_validate_json(self.value)
+        return schema.Model.model_validate_json(self.value)
diff --git a/panel/src/panel/templates/configuration_form.html b/panel/src/panel/templates/configuration_form.html
index 8df2acd4..ac4e68c7 100644
--- a/panel/src/panel/templates/configuration_form.html
+++ b/panel/src/panel/templates/configuration_form.html
@@ -1,7 +1,7 @@
 {% extends "base.html" %}
 {% load rest_framework %}
 {% block content %}
-<form method="post" enctype="multipart/form-data" action="{% url 'save' %}">
+<form method="post" enctype="multipart/form-data" action="{% url 'configuration_form' %}">
   {% csrf_token %}
 
   {% render_form serializer %}
diff --git a/panel/src/panel/tests/test_configuration_form.py b/panel/src/panel/tests/test_configuration_form.py
index 805b0e34..47baec09 100644
--- a/panel/src/panel/tests/test_configuration_form.py
+++ b/panel/src/panel/tests/test_configuration_form.py
@@ -13,7 +13,7 @@ class ConfigurationForm(TestCase):
             password=self.password
         )
 
-        self.config_url = reverse('save')
+        self.config_url = reverse('configuration_form')
 
     def test_configuration_form_submission(self):
         config = Configuration.objects.create(
@@ -27,15 +27,13 @@ class ConfigurationForm(TestCase):
         context = response.context[0]
 
         # configuration should be disabled by default
-        self.assertFalse(context['view'].get_object().parsed_value.enable)
-        # ...and be displayed as such
-        self.assertFalse(context['form'].initial["enable"])
+        self.assertFalse(context['serializer'].instance.enable)
 
-        form_data = context['form'].initial.copy()
-        form_data.update(
-            enable=True,
-            mastodon_enable=True,
-        )
+        form_data = context['serializer'].instance.dict().copy()
+        form_data = {
+            "enable": True,
+            "mastodon.enable": True,
+        }
         print(form_data)
         response = self.client.post(self.config_url, data=form_data)
 
@@ -46,4 +44,4 @@ class ConfigurationForm(TestCase):
         self.assertTrue(config.parsed_value.enable)
         self.assertTrue(config.parsed_value.mastodon.enable)
         # this should not have changed
-        self.assertFalse(config.parsed_value.peertube.enable)
+        self.assertIsNone(config.parsed_value.peertube)
diff --git a/panel/src/panel/urls.py b/panel/src/panel/urls.py
index 011a2843..7865bad9 100644
--- a/panel/src/panel/urls.py
+++ b/panel/src/panel/urls.py
@@ -27,5 +27,4 @@ urlpatterns = [
     path("services/", views.ServiceList.as_view(), name='service_list'),
     path("configuration/", views.ConfigurationForm.as_view(), name='configuration_form'),
     path("deployment/status/", views.DeploymentStatus.as_view(), name='deployment_status'),
-    path("save/", views.Save.as_view(), name='save'),
 ]
diff --git a/panel/src/panel/views.py b/panel/src/panel/views.py
index a72c437c..9c7e9de1 100644
--- a/panel/src/panel/views.py
+++ b/panel/src/panel/views.py
@@ -8,7 +8,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin
 from django.contrib.auth.models import User
 from django.views.generic import TemplateView, DetailView
 from django.views.generic.edit import FormView
-from django.shortcuts import render
+from django.shortcuts import render, redirect
 
 from rest_framework.renderers import TemplateHTMLRenderer
 from rest_framework.response import Response
@@ -48,59 +48,24 @@ class ConfigurationForm(LoginRequiredMixin, APIView):
 
     def get(self, request):
         config = self.get_object()
+        serializer = schema.Model.drf_serializer(instance=config.parsed_value)
         return Response({
-            'serializer': schema.Model.drf_serializer(instance=config.parsed_value),
+            'serializer': serializer,
         })
 
-    # TODO(@fricklerhandwerk):
-    #     this should probably live somewhere else
-    def convert_enums_to_names(self, data_dict):
-        """
-        Recursively convert all enum values in a dictionary to their string names.
-        This handles nested dictionaries and lists as well.
-
-        Needed for converting a Pydantic `BaseModel` instance to a `Form` input.
-        """
-        if isinstance(data_dict, dict):
-            result = {}
-            for key, value in data_dict.items():
-                if isinstance(value, Enum):
-                    # Convert Enum to its name
-                    result[key] = value.name
-                elif isinstance(value, (dict, list)):
-                    # Recursively process nested structures
-                    result[key] = self.convert_enums_to_names(value)
-                else:
-                    # Keep other values as is
-                    result[key] = value
-            return result
-        elif isinstance(data_dict, list):
-            # Process each item in the list
-            return [self.convert_enums_to_names(item) for item in data_dict]
-        elif isinstance(data_dict, Enum):
-            # Convert single Enum value
-            return data_dict.name
-        else:
-            # Return non-dict, non-list, non-Enum values as is
-            return data_dict
-
-    def get_initial(self):
-        initial = super().get_initial()
+    def post(self, request):
         config = self.get_object()
-        config_dict = config.parsed_value.model_dump()
+        serializer = schema.Model.drf_serializer(
+            instance=config.parsed_value,
+            data=request.data
+        )
 
-        initial.update(self.convert_enums_to_names(config_dict))
-        return initial
-
-
-class Save(ConfigurationForm):
-    def form_valid(self, form):
-        obj = self.get_object()
-        obj.value = form.to_python().model_dump_json()
-        obj.save()
-
-        return super().form_valid(form)
+        if not serializer.is_valid():
+            return Response({'serializer': serializer})
 
+        config.value = json.dumps(serializer.validated_data)
+        config.save()
+        return redirect(self.success_url)
 
 class DeploymentStatus(ConfigurationForm):
     def form_valid(self, form):