diff --git a/AKModel/locale/de_DE/LC_MESSAGES/django.po b/AKModel/locale/de_DE/LC_MESSAGES/django.po
index 2b85f9cabf45d7c2398782df49543b7eb1d000de..740582d5542aabdd299b4f9ead47e1e4a0299903 100644
--- a/AKModel/locale/de_DE/LC_MESSAGES/django.po
+++ b/AKModel/locale/de_DE/LC_MESSAGES/django.po
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-10-28 16:39+0000\n"
+"POT-Creation-Date: 2021-10-28 20:45+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -652,10 +652,8 @@ msgid "Two AK Slots for the same AK scheduled at the same time"
 msgstr "Zwei AK Slots eines AKs wurden zur selben Zeit platziert"
 
 #: AKModel/models.py:466
-msgid "AK Slot is scheduled in a room with less space than interest"
-msgstr ""
-"AK Slot wurde in einem Raum mit weniger Plätzen als am AK Interessierten "
-"platziert"
+msgid "Room does not have enough space for interest in scheduled AK Slot"
+msgstr "Room hat nicht genug Platz für das Interesse am geplanten AK-Slot"
 
 #: AKModel/models.py:467
 msgid "AK Slot is scheduled outside the event's availabilities"
@@ -1007,6 +1005,11 @@ msgstr "Resolutionsabsicht?"
 msgid "Category (for Wishes)"
 msgstr "Kategorie (für Wünsche)"
 
+#~ msgid "AK Slot is scheduled in a room with less space than interest"
+#~ msgstr ""
+#~ "AK Slot wurde in einem Raum mit weniger Plätzen als am AK Interessierten "
+#~ "platziert"
+
 #~ msgid "Confirm"
 #~ msgstr "Bestätigen"
 
diff --git a/AKModel/migrations/0048_constraint_violation_text.py b/AKModel/migrations/0048_constraint_violation_text.py
new file mode 100644
index 0000000000000000000000000000000000000000..71ff08930117ce501e78b3b6a7a1dd5b83d0800c
--- /dev/null
+++ b/AKModel/migrations/0048_constraint_violation_text.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.1.8 on 2021-10-28 20:47
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('AKModel', '0047_room_capacity_help'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='constraintviolation',
+            name='type',
+            field=models.CharField(choices=[('ots', 'Owner has two parallel slots'), ('soa', "AK Slot was scheduled outside the AK's availabilities"), ('rts', 'Room has two AK slots scheduled at the same time'), ('rng', 'Room does not satisfy the requirement of the scheduled AK'), ('acc', 'AK Slot is scheduled at the same time as an AK listed as a conflict'), ('abp', 'AK Slot is scheduled before an AK listed as a prerequisite'), ('aar', 'AK Slot for AK with intention to submit a resolution is scheduled after resolution deadline'), ('acm', 'AK Slot in a category is outside that categories availabilities'), ('asc', 'Two AK Slots for the same AK scheduled at the same time'), ('rce', 'Room does not have enough space for interest in scheduled AK Slot'), ('soe', "AK Slot is scheduled outside the event's availabilities")], help_text='Type of violation, i.e. what kind of constraint was violated', max_length=3, verbose_name='Type'),
+        ),
+    ]
diff --git a/AKModel/models.py b/AKModel/models.py
index de03c22daeffd3506055f4ec4c43c35a55ee0099..98dad77046d3003826a67b0fdf01b644a0e67aa3 100644
--- a/AKModel/models.py
+++ b/AKModel/models.py
@@ -463,7 +463,7 @@ class ConstraintViolation(models.Model):
             'AK Slot for AK with intention to submit a resolution is scheduled after resolution deadline')
         AK_CATEGORY_MISMATCH = 'acm', _('AK Slot in a category is outside that categories availabilities')
         AK_SLOT_COLLISION = 'asc', _('Two AK Slots for the same AK scheduled at the same time')
-        ROOM_CAPACITY_EXCEEDED = 'rce', _('AK Slot is scheduled in a room with less space than interest')
+        ROOM_CAPACITY_EXCEEDED = 'rce', _('Room does not have enough space for interest in scheduled AK Slot')
         SLOT_OUTSIDE_EVENT = 'soe', _('AK Slot is scheduled outside the event\'s availabilities')
 
     class ViolationLevel(models.IntegerChoices):
@@ -499,7 +499,7 @@ class ConstraintViolation(models.Model):
     manually_resolved = models.BooleanField(verbose_name=_('Manually Resolved'), default=False,
                                             help_text=_('Mark this violation manually as resolved'))
 
-    fields = ['ak_owner', 'room', 'requirement', 'category']
+    fields = ['ak_owner', 'room', 'requirement', 'category', 'comment']
     fields_mm = ['_aks', '_ak_slots']
 
     def __init__(self, *args, **kwargs):
diff --git a/AKScheduling/locale/de_DE/LC_MESSAGES/django.po b/AKScheduling/locale/de_DE/LC_MESSAGES/django.po
index 5ed003e89f16deaac8e309561323c1cb974345d0..dbf3a8a68a102d3e42918a9df20f6a338a662886 100644
--- a/AKScheduling/locale/de_DE/LC_MESSAGES/django.po
+++ b/AKScheduling/locale/de_DE/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-05-09 18:23+0000\n"
+"POT-Creation-Date: 2021-10-28 20:45+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,6 +17,24 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
+#: AKScheduling/models.py:507
+#, python-format
+msgid ""
+"Not enough space for AK interest (Interest: %(interest)d, Capacity: "
+"%(capacity)d)"
+msgstr ""
+"Nicht genug Platz für AK-Interesse (Interesse: %(interest)d, Kapazität: "
+"%(capacity)d)"
+
+#: AKScheduling/models.py:519
+#, python-format
+msgid ""
+"Space is too close to AK interest (Interest: %(interest)d, Capacity: "
+"%(capacity)d)"
+msgstr ""
+"Verfügbarer Platz zu dicht an Interesse (Interesse: %(interest)d, Kapazität: "
+"%(capacity)d)"
+
 #: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:11
 #: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:11
 #: AKScheduling/templates/admin/AKScheduling/scheduling.html:10
@@ -62,7 +80,7 @@ msgstr "Seit"
 
 #: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:134
 #: AKScheduling/templates/admin/AKScheduling/manage_tracks.html:243
-#: AKScheduling/templates/admin/AKScheduling/scheduling.html:197
+#: AKScheduling/templates/admin/AKScheduling/scheduling.html:208
 #: AKScheduling/templates/admin/AKScheduling/unscheduled.html:34
 msgid "Event Status"
 msgstr "Event-Status"
@@ -103,23 +121,23 @@ msgstr "AK-Track hinzufügen"
 msgid "AKs without track"
 msgstr "AKs ohne Track"
 
-#: AKScheduling/templates/admin/AKScheduling/scheduling.html:87
+#: AKScheduling/templates/admin/AKScheduling/scheduling.html:91
 msgid "Day (Horizontal)"
 msgstr "Tag (horizontal)"
 
-#: AKScheduling/templates/admin/AKScheduling/scheduling.html:94
+#: AKScheduling/templates/admin/AKScheduling/scheduling.html:98
 msgid "Day (Vertical)"
 msgstr "Tag (vertikal)"
 
-#: AKScheduling/templates/admin/AKScheduling/scheduling.html:105
+#: AKScheduling/templates/admin/AKScheduling/scheduling.html:109
 msgid "Event (Horizontal)"
 msgstr "Event (horizontal)"
 
-#: AKScheduling/templates/admin/AKScheduling/scheduling.html:114
+#: AKScheduling/templates/admin/AKScheduling/scheduling.html:118
 msgid "Event (Vertical)"
 msgstr "Event (vertikal)"
 
-#: AKScheduling/templates/admin/AKScheduling/scheduling.html:141
+#: AKScheduling/templates/admin/AKScheduling/scheduling.html:146
 msgid "Room"
 msgstr "Raum"
 
diff --git a/AKScheduling/models.py b/AKScheduling/models.py
index 24f544f155606a440ae08cd9d6c9ba37c275654f..e5b079a4901312bb2422e0ef3201a72204d30e4d 100644
--- a/AKScheduling/models.py
+++ b/AKScheduling/models.py
@@ -1,5 +1,6 @@
 from django.db.models.signals import post_save, m2m_changed
 from django.dispatch import receiver
+from django.utils.translation import gettext_lazy as _
 
 from AKModel.availability.models import Availability
 from AKModel.models import AK, AKSlot, Room, Event, AKOwner, ConstraintViolation
@@ -64,7 +65,6 @@ def ak_changed_handler(sender, instance: AK, **kwargs):
     pass
 
 
-# TODO adapt for Room's reauirements
 @receiver(m2m_changed, sender=AK.owners.through)
 def ak_owners_changed_handler(sender, instance: AK, action: str, **kwargs):
     """
@@ -492,6 +492,72 @@ def akslot_changed_handler(sender, instance: AKSlot, **kwargs):
     # print(existing_violations_to_check)
     update_constraint_violations(new_violations, existing_violations_to_check)
 
+    # == Check for room capacity ==
+
+    violation_type = ConstraintViolation.ViolationType.ROOM_CAPACITY_EXCEEDED
+    new_violations = []
+
+    if instance.room and instance.room.capacity >= 0:
+        if instance.room.capacity < instance.ak.interest:
+            c = ConstraintViolation(
+                type=violation_type,
+                level=ConstraintViolation.ViolationLevel.VIOLATION,
+                event=event,
+                room=instance.room,
+                comment=_("Not enough space for AK interest (Interest: %(interest)d, Capacity: %(capacity)d)")
+                        % {'interest': instance.ak.interest, 'capacity': instance.room.capacity},
+            )
+            c.ak_slots_tmp.add(instance)
+            c.aks_tmp.add(instance.ak)
+            new_violations.append(c)
+        elif instance.room.capacity < instance.ak.interest + 5 or instance.room.capacity < instance.ak.interest * 1.25:
+            c = ConstraintViolation(
+                type=violation_type,
+                level=ConstraintViolation.ViolationLevel.WARNING,
+                event=event,
+                room=instance.room,
+                comment=_("Space is too close to AK interest (Interest: %(interest)d, Capacity: %(capacity)d)")
+                        % {'interest': instance.ak.interest, 'capacity': instance.room.capacity}
+            )
+            c.ak_slots_tmp.add(instance)
+            c.aks_tmp.add(instance.ak)
+            new_violations.append(c)
+
+    # Compare to/update list of existing violations of this type for this slot
+    existing_violations_to_check = list(instance.constraintviolation_set.filter(type=violation_type))
+    update_constraint_violations(new_violations, existing_violations_to_check)
+
+    if instance.start:
+        # For all owners (after recent change)...
+        for owner in instance.ak.owners.all():
+            # ...find other slots that might be overlapping...
+
+            for ak in owner.ak_set.all():
+                # ...find overlapping slots...
+                if ak != instance.ak:
+                    for other_slot in ak.akslot_set.filter(start__isnull=False):
+                        if instance.overlaps(other_slot):
+                            # ...and create a temporary violation if necessary...
+                            c = ConstraintViolation(
+                                type=violation_type,
+                                level=ConstraintViolation.ViolationLevel.VIOLATION,
+                                event=event,
+                                ak_owner=owner
+                            )
+                            c.aks_tmp.add(instance.ak)
+                            c.aks_tmp.add(other_slot.ak)
+                            c.ak_slots_tmp.add(instance)
+                            c.ak_slots_tmp.add(other_slot)
+                            new_violations.append(c)
+
+            print(f"{owner} has the following conflicts: {new_violations}")
+
+    # ... and compare to/update list of existing violations of this type
+    # belonging to the AK that was recently changed (important!)
+    existing_violations_to_check = list(instance.constraintviolation_set.filter(type=violation_type))
+    # print(existing_violations_to_check)
+    update_constraint_violations(new_violations, existing_violations_to_check)
+
 
 @receiver(post_save, sender=Room)
 def room_changed_handler(sender, **kwargs):
@@ -499,6 +565,22 @@ def room_changed_handler(sender, **kwargs):
     print(f"{sender} changed")
 
 
+@receiver(m2m_changed, sender=Room.properties.through)
+def room_requirements_changed_handler(sender, instance: Room, action: str, **kwargs):
+    """
+    Requirements of room changed
+    """
+    # Only signal after change (post_add, post_delete, post_clear) are relevant
+    if not action.startswith("post"):
+        return
+
+    # print(f"{instance} changed")
+
+    event = instance.event
+
+    # TODO React to changes
+
+
 @receiver(post_save, sender=Availability)
 def availability_changed_handler(sender, instance: Availability, **kwargs):
     # Changes might affect: category availability, AK availability, Room availability