diff --git a/src/api/schedule.py b/src/api/schedule.py
index cf26a3c40645dca72214468a74a38440c28ee055..b2c72da4d4d1d9776f79113e9e0d8b0b05e1600a 100644
--- a/src/api/schedule.py
+++ b/src/api/schedule.py
@@ -227,7 +227,7 @@ class ScheduleEncoder(json.JSONEncoder):
             'name': obj.name,
             'slug': obj.slug,
             'guid': obj.id,
-            # Future TODO: # 'type': obj., # channel vs. cluster vs. virtual vs. ...?
+            # Future TODO: # 'type': obj., # cluster vs. virtual vs. ...?
             # 'description_en': obj.description_en,
             # 'description_de': obj.description_de,
             # Future TODO  'url': obj.get_absolute_url(),
diff --git a/src/api/serializers.py b/src/api/serializers.py
index f6a5ef970628ac7ce536c1bfb077dd660f40aad3..0482602b6703c3ec903071e3a53c00fff041369a 100644
--- a/src/api/serializers.py
+++ b/src/api/serializers.py
@@ -147,8 +147,7 @@ class AssemblySerializer(HubModelSerializer):
             'slug',
             'id',
             'name',
-            'state_assembly',
-            'state_channel',
+            'state',
             'hierarchy',
             'parent',
             'assembly_location',
@@ -158,7 +157,7 @@ class AssemblySerializer(HubModelSerializer):
             'rooms_url',
             'badges_url',
         ]
-        staff_only_fields = ['state_assembly', 'state_channel', 'hierarchy']
+        staff_only_fields = ['state', 'hierarchy']
 
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
diff --git a/src/api/tests/badges/create_redeem_token.py b/src/api/tests/badges/create_redeem_token.py
index aa74f060b0375cb5f4022d56cff1e1f1d4ec41dc..cfa4f21299828b0e172abd7e5044b91749747341 100644
--- a/src/api/tests/badges/create_redeem_token.py
+++ b/src/api/tests/badges/create_redeem_token.py
@@ -26,7 +26,7 @@ class CreateRedeemTokenTests(TestCase):
             end=datetime(2020, 12, 30, 23, 45, 00, tzinfo=tz),
         )
         self.conf.save()
-        self.assembly = Assembly(name='TestAssembly', slug='asmbly', conference=self.conf, state_assembly=Assembly.State.PLACED)
+        self.assembly = Assembly(name='TestAssembly', slug='asmbly', conference=self.conf, state=Assembly.State.PLACED)
         self.assembly.save()
 
         self.badge = Badge(
diff --git a/src/api/tests/events.py b/src/api/tests/events.py
index 581e8f958a64f6ad37531bd4dfaf47ee045746b4..4b042acd753a3dbb5674d6550c36cff6f5b4fe50 100644
--- a/src/api/tests/events.py
+++ b/src/api/tests/events.py
@@ -22,7 +22,7 @@ class EventsTestCase(TestCase):
         self.human_cm = ConferenceMember(conference=self.conference1, user=self.human_user)
         self.human_cm.save()
 
-        assembly = Assembly(conference=self.conference1, name='DUMMY', slug='dummy', state_assembly=Assembly.State.ACCEPTED, is_official=True)
+        assembly = Assembly(conference=self.conference1, name='DUMMY', slug='dummy', state=Assembly.State.ACCEPTED, is_official=True)
         assembly.save()
 
         self.event = Event(
diff --git a/src/api/tests/map.py b/src/api/tests/map.py
index 7261e596f05cd215e4e4ca9870cdf9a1c91ab706..0afe71ff41251045078656606a77d465e042f221 100644
--- a/src/api/tests/map.py
+++ b/src/api/tests/map.py
@@ -50,7 +50,7 @@ class MapTest(TestCase):
 
         # set POI on assembly and accept it
         self.assembly.location_point = Point(8.9, 52.9)
-        self.assembly.state_assembly = Assembly.State.ACCEPTED
+        self.assembly.state = Assembly.State.ACCEPTED
         self.assembly.save()
         ConferenceExportCache.objects.all().delete()
 
@@ -61,7 +61,7 @@ class MapTest(TestCase):
         self.assertEqual(0, len(content['features']))
 
         # change state to 'placed', now there should be a POI
-        self.assembly.state_assembly = Assembly.State.PLACED
+        self.assembly.state = Assembly.State.PLACED
         self.assembly.save()
         ConferenceExportCache.objects.all().delete()
         resp = self.client.get(url)
@@ -78,7 +78,7 @@ class MapTest(TestCase):
         self.assertEqual(self.assembly.is_cluster, feature.get('properties', {}).get('cluster'))
 
         # change assembly to 'hidden', POI should still be there
-        self.assembly.state_assembly = Assembly.State.HIDDEN
+        self.assembly.state = Assembly.State.HIDDEN
         self.assembly.save()
         ConferenceExportCache.objects.all().delete()
         resp = self.client.get(url)
diff --git a/src/api/tests/metrics.py b/src/api/tests/metrics.py
index 6f56c24324a186e8e0602d75e8b9cc4712c52afe..e025c86d8ce71be3ab5926571c7dcdbfc504b343 100644
--- a/src/api/tests/metrics.py
+++ b/src/api/tests/metrics.py
@@ -32,7 +32,7 @@ class MetricsTest(TestCase):
         assembly = Assembly(
             name='TestAssembly',
             slug='asmbly',
-            state_assembly=Assembly.State('planned'),
+            state=Assembly.State('planned'),
             conference=conf,
         )
         assembly.save()
diff --git a/src/api/tests/permissions.py b/src/api/tests/permissions.py
index 92fef7d754435b8bacbd57c7be073c0c93eb7e5b..4fa930ab119b4570fc25362e18cfc8995a12889f 100644
--- a/src/api/tests/permissions.py
+++ b/src/api/tests/permissions.py
@@ -202,7 +202,7 @@ class AssemblyPermissionTestCase(ConferencePermissionTestCase):
         self.assembly = self.view.assembly = Assembly.objects.create(
             name='TestAssembly',
             slug='asmbly',
-            state_assembly=Assembly.State('planned'),
+            state=Assembly.State('planned'),
             conference=self.conference,
         )
 
@@ -235,7 +235,7 @@ class IsPublicAssemblyReadOnlyTestCase(AssemblyPermissionTestCase):
 
     def test_get_allowed_public(self):
         request = self.factory.get('/')
-        self.assembly.state_assembly = Assembly.PUBLIC_STATES[0]
+        self.assembly.state = Assembly.PUBLIC_STATES[0]
         self.assembly.save()
 
         self.run_permission_test(IsPublicAssemblyReadOnly(), (True, True), request)
diff --git a/src/api/tests/schedule.py b/src/api/tests/schedule.py
index 3fa2c6d7e32b77ac512618798f806b370f897b64..3f3679b32bc7bb10431e8524b164c1e6ee71fcdf 100644
--- a/src/api/tests/schedule.py
+++ b/src/api/tests/schedule.py
@@ -30,7 +30,7 @@ class ScheduleTest(TestCase):
         self.conf.save()
         self.conf.tracks.create(slug='community', name='Community').save()
         self.conf.tracks.create(slug='security', name='Security').save()
-        self.assembly = Assembly(name='TestAssembly', slug='asmbly', conference=self.conf, state_assembly=Assembly.State.PLACED)
+        self.assembly = Assembly(name='TestAssembly', slug='asmbly', conference=self.conf, state=Assembly.State.PLACED)
         self.assembly.save()
         self.room = Room(conference=self.conf, assembly=self.assembly, name='Foo Room', room_type=Room.RoomType.STAGE)
         self.room.save()
@@ -52,7 +52,7 @@ class ScheduleTest(TestCase):
         content_parser(content_str)
 
         # prepare assembly for event-hosting, incl. room
-        self.assembly.state_channel = Assembly.State.ACCEPTED
+        self.assembly.state = Assembly.State.ACCEPTED
         self.assembly.save()
         r = self.assembly.rooms.create(conference=self.conf, name='Zelt', room_type='stage')
 
diff --git a/src/api/tests/workadventure.py b/src/api/tests/workadventure.py
index 7d673869f2aeac785dbd5065946e38eece7f6461..e49648de68d651c05aa96e2a728f03c288b70a80 100644
--- a/src/api/tests/workadventure.py
+++ b/src/api/tests/workadventure.py
@@ -94,9 +94,9 @@ class WorkAdventureMapServiceTestCase(_WorkAdventureTestCase):
         endpoint_data = response.json()
         self.assertEqual(0, len(endpoint_data))
 
-        self.assembly1a.state_assembly = Assembly.State.ACCEPTED
+        self.assembly1a.state = Assembly.State.ACCEPTED
         self.assembly1a.save()
-        self.assembly1b.state_assembly = Assembly.State.PLACED
+        self.assembly1b.state = Assembly.State.PLACED
         self.assembly1b.save()
 
         response = c.get(self.wa_url)
@@ -114,15 +114,15 @@ class WorkAdventureMapServiceTestCase(_WorkAdventureTestCase):
 
     def testPush(self):
         # prepare assembly objects
-        self.assembly1a.state_assembly = Assembly.State.ACCEPTED
-        self.assembly1a.save(update_fields=['state_assembly'])
-        assembly2 = Assembly(conference=self.conference1, slug='dummy2', name='Test Dummy 2', state_assembly=Assembly.State.ACCEPTED)
+        self.assembly1a.state = Assembly.State.ACCEPTED
+        self.assembly1a.save(update_fields=['state'])
+        assembly2 = Assembly(conference=self.conference1, slug='dummy2', name='Test Dummy 2', state=Assembly.State.ACCEPTED)
         assembly2.save()
-        assembly3 = Assembly(conference=self.conference1, slug='dummy3', name='Test Dummy 3', state_assembly=Assembly.State.ACCEPTED)
+        assembly3 = Assembly(conference=self.conference1, slug='dummy3', name='Test Dummy 3', state=Assembly.State.ACCEPTED)
         assembly3.save()
-        assembly4 = Assembly(conference=self.conference1, slug='dummy4', name='Test Dummy 4', state_assembly=Assembly.State.ACCEPTED)
+        assembly4 = Assembly(conference=self.conference1, slug='dummy4', name='Test Dummy 4', state=Assembly.State.ACCEPTED)
         assembly4.save()
-        assembly5 = Assembly(conference=self.conference1, slug='dummy5', name='Test Dummy 5', state_assembly=Assembly.State.ACCEPTED)
+        assembly5 = Assembly(conference=self.conference1, slug='dummy5', name='Test Dummy 5', state=Assembly.State.ACCEPTED)
         assembly5.save()
 
         # prepare room objects
@@ -227,9 +227,9 @@ class WorkAdventureEndpointTestCase:  # TODO: enable again -- _WorkAdventureTest
         response = c.get(url_a)
         self.assertEqual(response.status_code, 404, f'Expected to have WA endpoint return HTTP 404 instead of {response.status_code}.')
 
-        self.assembly1a.state_assembly = Assembly.State.ACCEPTED
+        self.assembly1a.state = Assembly.State.ACCEPTED
         self.assembly1a.save()
-        self.assembly1b.state_assembly = Assembly.State.PLACED
+        self.assembly1b.state = Assembly.State.PLACED
         self.assembly1b.save()
         endpoint_data = []
 
@@ -252,7 +252,7 @@ class WorkAdventureEndpointTestCase:  # TODO: enable again -- _WorkAdventureTest
     def testPush(self):
         # prepare assembly and room
         self.assembly1c.refresh_from_db()
-        self.assembly1c.state_assembly = Assembly.State.ACCEPTED
+        self.assembly1c.state = Assembly.State.ACCEPTED
         self.assembly1c.save()
 
         self.room1c.refresh_from_db()
diff --git a/src/api/views/maps.py b/src/api/views/maps.py
index 2b2824ff33ba3eb666bd8d76d9fb9bd477ae2a0d..754793f26456bcc0356456fe2dd517391d8ff001 100644
--- a/src/api/views/maps.py
+++ b/src/api/views/maps.py
@@ -71,7 +71,7 @@ class AssembliesExportView(ConferenceSlugMixin, APIView, metaclass=abc.ABCMeta):
 
     def get_queryset(self):
         exportable_states = [*Assembly.PLACED_STATES, Assembly.State.HIDDEN]
-        return Assembly.objects.filter(conference=self.conference, state_assembly__in=exportable_states)
+        return Assembly.objects.filter(conference=self.conference, state__in=exportable_states)
 
     def get_geometry_field(self, obj):
         return getattr(obj, self.geometry_field)
@@ -138,7 +138,7 @@ class C3NavExportView(ConferenceSlugMixin, APIView):
         data = []
 
         exportable_states = [*Assembly.PLACED_STATES, Assembly.State.HIDDEN]
-        qs = self.conference.assemblies.filter(state_assembly__in=exportable_states)
+        qs = self.conference.assemblies.filter(state__in=exportable_states)
         if request.GET.get('all') != '1':
             qs = qs.exclude(location_data__point=None, location_data__boundaries=None)
         for assembly in qs:  # type: Assembly
@@ -153,7 +153,7 @@ class C3NavExportView(ConferenceSlugMixin, APIView):
                     'description': {'de': assembly.description_de, 'en': assembly.description_en},
                     'public_url': hub_absolute('plainui:assembly', assembly_slug=assembly.slug),
                     'parent_id': assembly.parent_id,
-                    'children': assembly.children.filter(state_assembly__in=exportable_states).values_list('slug', flat=True) if assembly.is_cluster else None,
+                    'children': assembly.children.filter(state__in=exportable_states).values_list('slug', flat=True) if assembly.is_cluster else None,
                     'floor': assembly.get_location_floor_index(),
                     'location': loc_data.get('point'),  # assembly.get_location_point_xy(),
                     'polygons': loc_data.get('boundaries'),  # assembly.get_location_boundaries_xy(),
diff --git a/src/api/views/metrics.py b/src/api/views/metrics.py
index f8c3ef2b12d939800f3f494423ad39d945b288e3..cf82fdfa8b751b41f1f3aeeffdefa59b94810c1b 100644
--- a/src/api/views/metrics.py
+++ b/src/api/views/metrics.py
@@ -49,7 +49,6 @@ class MetricsView(TemplateView):
             'hub_conference_members_themes': {'help': 'used themes by members in the conference', 'type': 'gauge', 'values': {}},
             'hub_conference_tickets': {'help': 'registered tickets', 'type': 'counter', 'values': {}},
             'hub_conference_assemblies': {'help': "conference's assemblies", 'type': 'gauge', 'values': {}},
-            'hub_conference_channels': {'help': "conference's channels", 'type': 'gauge', 'values': {}},
             'hub_conference_badges_public': {'help': "conference's badges (public)", 'type': 'gauge', 'values': {}},
             'hub_conference_badges_hidden': {'help': "conference's badges (non-public)", 'type': 'gauge', 'values': {}},
             'hub_conference_badges_accepted': {'help': "conference's badges (accepted/assigned)", 'type': 'gauge', 'values': {}},
@@ -64,10 +63,7 @@ class MetricsView(TemplateView):
             slug = conference.slug
 
             # hub_conference_assemblies
-            self.report_assembly_metrics(metrics, conference, 'assembly', 'assemblies')
-
-            # hub_conference_channels
-            self.report_assembly_metrics(metrics, conference, 'channel', 'channels')
+            self.report_assembly_metrics(metrics, conference, 'assemblies')
 
             # hub_conference_rooms
             room_counts = {room_type: 0 for room_type in Room.RoomType.values}
@@ -145,11 +141,11 @@ class MetricsView(TemplateView):
         return context
 
     @staticmethod
-    def report_assembly_metrics(metrics, conference: Conference, lookup_key: str, report_key: str):
-        asm_count = Assembly.objects.filter(conference=conference).values(f'state_{lookup_key}').annotate(count=Count('*'))
+    def report_assembly_metrics(metrics, conference: Conference, report_key: str):
+        asm_count = Assembly.objects.filter(conference=conference).values('state').annotate(count=Count('*'))
         expected_states = list(Assembly.State.values)
         for line in asm_count:
-            metrics[f'hub_conference_{report_key}']['values'][f'{{conference="{conference.slug}",state="{line["state_" + lookup_key]}"}}'] = line['count']
-            expected_states.remove(line[f'state_{lookup_key}'])
+            metrics[f'hub_conference_{report_key}']['values'][f'{{conference="{conference.slug}",state="{line["state"]}"}}'] = line['count']
+            expected_states.remove(line['state'])
         for missing in expected_states:
             metrics[f'hub_conference_{report_key}']['values'][f'{{conference="{conference.slug}",state="{missing}"}}'] = 0
diff --git a/src/api/views/workadventure.py b/src/api/views/workadventure.py
index 4cc556758e114dd6822c9550e632c5115431ddd5..20d6c897316a120f1ac8c577dc9908d697b37f7f 100644
--- a/src/api/views/workadventure.py
+++ b/src/api/views/workadventure.py
@@ -75,7 +75,7 @@ class MapServiceView(ConferenceSlugMixin, APIView):
     def get(self, request, format=None):
         wa_rooms = []
         for room in Room.objects.filter(conference=self.conference, room_type=Room.RoomType.WORKADVENTURE).select_related('assembly'):
-            if room.assembly is not None and room.assembly.state_assembly not in Assembly.PUBLIC_STATES:
+            if room.assembly is not None and room.assembly.state not in Assembly.PUBLIC_STATES:
                 continue
             room_data = _export_room_data(room)
             wa_rooms.append(room_data)
diff --git a/src/backoffice/forms.py b/src/backoffice/forms.py
index 6162c071b3c40a43bafdd185f7ea45cd6843a02e..41fbcee23ce3b8c2929e1cdc91154a093bdfff2f 100644
--- a/src/backoffice/forms.py
+++ b/src/backoffice/forms.py
@@ -61,20 +61,12 @@ class ProfileForm(forms.ModelForm):
 class AssemblyCreateForm(forms.ModelForm):
     class Meta:
         model = Assembly
-        fields = ['slug', 'name', 'is_assembly', 'is_channel']
-
-    is_assembly = forms.BooleanField(initial=False, required=False, help_text=_('Assembly__is_assembly__help'), label=_('Assembly__is_assembly'))
-    is_channel = forms.BooleanField(initial=False, required=False, help_text=_('Assembly__is_channel__help'), label=_('Assembly__is_channel'))
+        fields = ['slug', 'name']
 
     def __init__(self, *args, **kwargs):
         self._conference = kwargs.pop('conference')
         super().__init__(*args, **kwargs)
 
-        if not self._conference.support_channels:
-            self.fields['is_assembly'].disabled = True
-            self.fields['is_assembly'].initial = True
-            del self.fields['is_channel']
-
         if self._conference.has_disclaimer('assembly'):
             self.fields['disclaimer'] = forms.BooleanField(
                 initial=False,
@@ -88,10 +80,6 @@ class AssemblyCreateForm(forms.ModelForm):
         if self._conference.has_disclaimer('assembly') and not self.cleaned_data['disclaimer']:
             self.add_error('disclaimer', _('Assembly__disclaimer-needed'))
 
-        if (not self.cleaned_data['is_assembly']) and (not self.cleaned_data['is_channel']):
-            self.add_error('is_assembly', _('Assembly__must_be_assembly_or_channel'))
-            self.add_error('is_channel', _('Assembly__must_be_assembly_or_channel'))
-
         if (slug := self.cleaned_data.get('slug')) and Assembly.objects.filter(conference=self._conference, slug=slug).exists():
             self.add_error('slug', _('Assembly__slug__alreadyexists'))
 
@@ -118,7 +106,7 @@ class AssemblyEditForm(TranslatedFieldsForm):
             'assembly_location': forms.Textarea(attrs={'rows': 4}),
         }
 
-    def __init__(self, *args, staff_access: bool, staff_mode: bool, assembly_staff_access: bool, channel_staff_access: bool, **kwargs):
+    def __init__(self, *args, staff_mode: bool, **kwargs):
         super().__init__(*args, **kwargs)
 
         # configure fields' widget customizations
@@ -127,7 +115,7 @@ class AssemblyEditForm(TranslatedFieldsForm):
         # configure fields
         assembly = self.instance
         conference = self.instance.conference
-        if assembly.basedata_readonly and not staff_access:
+        if assembly.basedata_readonly and not staff_mode:
             self.fields['name'].disabled = True
             self.fields['slug'].disabled = True
             self.fields['is_physical'].disabled = True
@@ -185,7 +173,7 @@ class AssemblyEditForm(TranslatedFieldsForm):
 class AssemblyMemberEditForm(forms.ModelForm):
     class Meta:
         model = AssemblyMember
-        fields = ['is_representative', 'can_manage_assembly', 'is_content_coordinator', 'is_production_coordinator', 'is_technical_contact', 'show_public']
+        fields = ['is_representative', 'can_manage_assembly', 'is_technical_contact', 'show_public']
 
     def clean(self):
         # call original .clean() which does some checks already
@@ -365,7 +353,7 @@ class EditAssemblyRoomForm(TranslatedFieldsForm):
         model = Room
         fields = ['name', 'slug', 'description', 'is_public_fahrplan', 'is_official', 'official_room_order', 'capacity']
 
-    def __init__(self, with_capacity=False, channel_staff=False, *args, **kwargs):
+    def __init__(self, with_capacity=False, staff_mode=False, *args, **kwargs):
         super().__init__(*args, **kwargs)
         self.fields['slug'].disabled = True
         if self.instance.room_type in Room.BACKEND_ROOMTYPES:
@@ -383,7 +371,7 @@ class EditAssemblyRoomForm(TranslatedFieldsForm):
         if self.instance.room_type in [Room.RoomType.HANGAR]:
             self.fields['name'].disabled = True
 
-        if not channel_staff:
+        if not staff_mode:
             del self.fields['is_public_fahrplan']
             del self.fields['is_official']
             del self.fields['official_room_order']
@@ -436,7 +424,7 @@ class EditAssemblyRoomWorkAdventureForm(TranslatedFieldsForm):
         model = Room
         fields = ['backend_status', 'backend_link', 'backend_link_branch']
 
-    def __init__(self, with_capacity=False, channel_staff=False, *args, **kwargs):
+    def __init__(self, with_capacity=False, staff_mode=False, *args, **kwargs):
         super().__init__(*args, **kwargs)
         self.fields['backend_status'].disabled = True
         self.fields['backend_link'].label = _('Room-workadventure_backend_link')
@@ -452,7 +440,7 @@ class EditAssemblyRoomHangarForm(TranslatedFieldsForm):
         model = Room
         fields = ['backend_status', 'backend_link']
 
-    def __init__(self, with_capacity=False, channel_staff=False, *args, **kwargs):
+    def __init__(self, with_capacity=False, staff_mode=False, *args, **kwargs):
         super().__init__(*args, **kwargs)
         self.fields['backend_status'].disabled = True
         self.fields['backend_link'].label = _('Room-hangar_backend_link')
diff --git a/src/backoffice/locale/de/LC_MESSAGES/django.po b/src/backoffice/locale/de/LC_MESSAGES/django.po
index 0fe2f38b5d6c7a05ecbc144d237abef8d55999ce..f305dd6cc073127046cf87e600c9a319d1eb8c39 100644
--- a/src/backoffice/locale/de/LC_MESSAGES/django.po
+++ b/src/backoffice/locale/de/LC_MESSAGES/django.po
@@ -17,24 +17,9 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-msgid "Assembly__is_assembly__help"
-msgstr "Ankreuzen, wenn ihr eine Assembly seid - egal ob physisch oder virtuell."
-
-msgid "Assembly__is_assembly"
-msgstr "Ich melde eine Assembly an."
-
-msgid "Assembly__is_channel__help"
-msgstr "Ankreuzen, wenn ihr ein Channel bzw. eine Bühne seid - sprich Vortragsprogramm bietet welches über Self-organized Sessions hinausgeht (Faustregel: ihr habt Streaming über das bzw. mit dem VOC). Wenn ihr nicht wisst was gemeint ist seid ihr kein Channel."
-
-msgid "Assembly__is_channel"
-msgstr "Ich melde einen Channel oder eine Bühne an."
-
 msgid "Assembly__disclaimer-needed"
 msgstr "Bitte beachte den Hinweis und bestätige, dass du ihn gelesen und verstanden hast."
 
-msgid "Assembly__must_be_assembly_or_channel"
-msgstr "Assembly und/oder Channel - nur \"keines von beiden\" ergibt keinen Sinn."
-
 msgid "Assembly__slug__alreadyexists"
 msgstr "Dieser Kurzname wird bereits von einer anderen Assembly benutzt."
 
@@ -313,11 +298,7 @@ msgid "no"
 msgstr "Nein"
 
 # use translation from core
-msgid "Assembly__state_assembly"
-msgstr ""
-
-# use translation from core
-msgid "Assembly__state_channel"
+msgid "Assembly__state"
 msgstr ""
 
 msgid "assemblycreate_title"
@@ -344,10 +325,10 @@ msgstr "Webseite"
 msgid "Assembly__hierarchy"
 msgstr "Einordnung"
 
-msgid "Assembly__state_assembly-planned__hint"
+msgid "Assembly__state-planned__hint"
 msgstr "Die Registrierung dieser Assembly ist noch nicht abgeschlossen."
 
-msgid "Assembly__state_assembly-planned__description"
+msgid "Assembly__state-planned__description"
 msgstr "Um die Registrierung dieses Assemblies abzuschließen, füllt bitte die Informationen und  restlichen Daten (z.B. Beschreibung) aus."
 
 msgid "Assembly__registration_details"
@@ -565,12 +546,6 @@ msgstr "Repräsentant"
 msgid "AssemblyMember__can_manage_assembly"
 msgstr "kann Assembly verwalten"
 
-msgid "AssemblyMember__is_content_coordinator"
-msgstr "Content-Koordinator"
-
-msgid "AssemblyMember__is_production_coordinator"
-msgstr "Produktions-Koordinator"
-
 msgid "AssemblyMember__is_technical_contact"
 msgstr "technische Ansprechperson"
 
@@ -804,9 +779,6 @@ msgstr "Assembly-Team"
 msgid "nav_vouchers"
 msgstr "Vouchers"
 
-msgid "nav_channels"
-msgstr "Channels-Team"
-
 msgid "nav_map"
 msgstr "Karte"
 
@@ -1744,9 +1716,6 @@ msgstr "abgelehnt"
 msgid "nav_assemblies_hidden"
 msgstr "versteckt"
 
-msgid "nav_assemblies_not_selected"
-msgstr "keine Teilnahme"
-
 msgid "lists"
 msgstr "Listen"
 
@@ -1844,24 +1813,6 @@ msgstr "Badge %(token)s aktiviert"
 msgid "BadgeToken__deactivated %(token)s"
 msgstr "Badge %(token)s deaktiviert"
 
-msgid "nav_channels_all"
-msgstr "alle"
-
-msgid "nav_channels_accepted"
-msgstr "akzeptiert"
-
-msgid "nav_channels_pending"
-msgstr "wartend"
-
-msgid "nav_channels_planned"
-msgstr "geplant"
-
-msgid "nav_channels_rejected"
-msgstr "abgelehnt"
-
-msgid "nav_channels_hidden"
-msgstr "versteckt"
-
 msgid "nav_conference"
 msgstr "Konferenz"
 
diff --git a/src/backoffice/locale/en/LC_MESSAGES/django.po b/src/backoffice/locale/en/LC_MESSAGES/django.po
index 5d000258f59f6e6f039863189dc3f7c11e32ce91..bcb669977d3e77c7d03160c6d1a981a4ac42bf02 100644
--- a/src/backoffice/locale/en/LC_MESSAGES/django.po
+++ b/src/backoffice/locale/en/LC_MESSAGES/django.po
@@ -17,24 +17,9 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-msgid "Assembly__is_assembly__help"
-msgstr "Tick this if you are an assembly - no matter whether physical or virtual."
-
-msgid "Assembly__is_assembly"
-msgstr "I'm registering an assembly."
-
-msgid "Assembly__is_channel__help"
-msgstr "Tick this if you are a channel or stage, i.e. you are doing events apart from self-organized sessions (rule of thumb: you do streaming via/with the VOC). If you don't know what we're talking about don't tick this box."
-
-msgid "Assembly__is_channel"
-msgstr "I'm registering a channel or stage."
-
 msgid "Assembly__disclaimer-needed"
 msgstr "Please read the disclaimer and acknowledge that you have understood and will adhere to it."
 
-msgid "Assembly__must_be_assembly_or_channel"
-msgstr "Assembly and/or channel - only neither of both doesn't make any sense."
-
 msgid "Assembly__slug__alreadyexists"
 msgstr "This slug is already used by another assembly."
 
@@ -312,14 +297,11 @@ msgstr "Yes"
 msgid "no"
 msgstr "No"
 
-msgid "Assembly__state_assembly"
+msgid "Assembly__state"
 msgstr "assembly"
 
-msgid "Assembly__state_channel"
-msgstr "channel"
-
 msgid "assemblycreate_title"
-msgstr "details of the new assembly/channel/stage"
+msgstr "details of the new assembly/stage"
 
 msgid "Assembly__registration__closed"
 msgstr "New assembly registrations for this conference are no longer possible."
@@ -342,10 +324,10 @@ msgstr "website"
 msgid "Assembly__hierarchy"
 msgstr "hierarchy"
 
-msgid "Assembly__state_assembly-planned__hint"
+msgid "Assembly__state-planned__hint"
 msgstr "This assembly's registration has not been completed."
 
-msgid "Assembly__state_assembly-planned__description"
+msgid "Assembly__state-planned__description"
 msgstr "To complete the registration of this assembly, please fill in the information and  remaining data (e.g. description)."
 
 msgid "Assembly__registration_details"
@@ -564,12 +546,6 @@ msgstr "representative"
 msgid "AssemblyMember__can_manage_assembly"
 msgstr "can manage assembly"
 
-msgid "AssemblyMember__is_content_coordinator"
-msgstr "content coordinator"
-
-msgid "AssemblyMember__is_production_coordinator"
-msgstr "production coordinator"
-
 msgid "AssemblyMember__is_technical_contact"
 msgstr "technical contact"
 
@@ -803,9 +779,6 @@ msgstr "assemblies team"
 msgid "nav_vouchers"
 msgstr "Vouchers"
 
-msgid "nav_channels"
-msgstr "channels team"
-
 msgid "nav_map"
 msgstr "map"
 
@@ -1749,9 +1722,6 @@ msgstr "rejected"
 msgid "nav_assemblies_hidden"
 msgstr "hidden"
 
-msgid "nav_assemblies_not_selected"
-msgstr "no participation"
-
 msgid "lists"
 msgstr "lists"
 
@@ -1848,24 +1818,6 @@ msgstr "Redeem token '%(token)s' activated."
 msgid "BadgeToken__deactivated %(token)s"
 msgstr "Redeem token '%(token)s' deactivated."
 
-msgid "nav_channels_all"
-msgstr "all"
-
-msgid "nav_channels_accepted"
-msgstr "accepted"
-
-msgid "nav_channels_pending"
-msgstr "pending"
-
-msgid "nav_channels_planned"
-msgstr "planned"
-
-msgid "nav_channels_rejected"
-msgstr "rejected"
-
-msgid "nav_channels_hidden"
-msgstr "hidden"
-
 msgid "nav_conference"
 msgstr "Conference"
 
diff --git a/src/backoffice/templates/backoffice/activitylog_card.html b/src/backoffice/templates/backoffice/activitylog_card.html
index f16a4b44cdf749ab5b5108c8223a045f3d753e9c..54026969ab818c864ba5bbd86450276ac93484a1 100644
--- a/src/backoffice/templates/backoffice/activitylog_card.html
+++ b/src/backoffice/templates/backoffice/activitylog_card.html
@@ -4,84 +4,112 @@
 
 {% gen_rand_str as alc_ident %}
 <div class="row mb-3">
-    <div class="col-md-12">
-        <div class="card" id="logentries_{{ alc_ident }}">
-            <div class="card-header">
-                <div class="d-inline-block float-end">
-                    <div class="btn-group d-none me-1" role="group" id="visible_logentries_{{ alc_ident }}">
-                      <input type="radio" class="btn-check" name="visible_logentries" id="visible_logentries_all_{{ alc_ident }}" autocomplete="off" checked>
-                      <label class="btn btn-sm btn-outline-primary" for="visible_logentries_all_{{ alc_ident }}">{% trans "activitylog_visibleentries_all" %}</label>
+  <div class="col-md-12">
+    <div class="card" id="logentries_{{ alc_ident }}">
+      <div class="card-header">
+        <div class="d-inline-block float-end">
+          <div class="btn-group d-none me-1"
+               role="group"
+               id="visible_logentries_{{ alc_ident }}">
+            <input type="radio"
+                   class="btn-check"
+                   name="visible_logentries"
+                   id="visible_logentries_all_{{ alc_ident }}"
+                   autocomplete="off"
+                   checked>
+            <label class="btn btn-sm btn-outline-primary"
+                   for="visible_logentries_all_{{ alc_ident }}">{% trans "activitylog_visibleentries_all" %}</label>
 
-                      <input type="radio" class="btn-check" name="visible_logentries" id="visible_logentries_msg_{{ alc_ident }}" autocomplete="off">
-                      <label class="btn btn-sm btn-outline-primary" for="visible_logentries_msg_{{ alc_ident }}">{% trans "activitylog_visibleentries_msg" %}</label>
-                    </div>
-                    {% if add_comment_url %}
-                    <button class="btn btn-sm btn-primary" title="{% trans "activitylog_addcomment" %}" data-bs-toggle="modal" data-bs-target="#addCommentModal_{{ alc_ident }}"><i class="bi bi-chat-left-text"></i></button>
-                    {% endif %}
-                </div>
-                {% trans 'ActivityLogEntrys' %}
+            <input type="radio"
+                   class="btn-check"
+                   name="visible_logentries"
+                   id="visible_logentries_msg_{{ alc_ident }}"
+                   autocomplete="off">
+            <label class="btn btn-sm btn-outline-primary"
+                   for="visible_logentries_msg_{{ alc_ident }}">{% trans "activitylog_visibleentries_msg" %}</label>
+          </div>
+          {% if add_comment_url %}
+            <button class="btn btn-sm btn-primary"
+                    title="{% trans "activitylog_addcomment" %}"
+                    data-bs-toggle="modal"
+                    data-bs-target="#addCommentModal_{{ alc_ident }}">
+              <i class="bi bi-chat-left-text"></i>
+            </button>
+          {% endif %}
+        </div>
+        {% trans "ActivityLogEntrys" %}
+      </div>
+      <div class="card-body">
+        {% for entry in object.logentries.all %}
+          <div class="mb-3 {% if entry.kind == entry.Kind.SYSTEM %}text-muted{% endif %} logentry"
+               data-has-msg="{% if entry.comment %}y{% else %}n{% endif %}">
+            {% if latest_note and latest_note.pk == entry.pk %}<a id="latest_note"></a>{% endif %}
+            <div class="border-bottom border-secondary mb-1{% if not entry.comment %} text-muted{% endif %}">
+              <abbr title="{{ entry.timestamp }}">{{ entry.timestamp|naturaltime }}</abbr>
+              <span class="mx-1 badge bg-light text-bg-light border border-secondary-subtle"><i class="bi bi-person"></i> {{ entry.user.username }}</span>
+              <span class="text-muted">{{ entry.get_kind_display }}</span>
             </div>
-            <div class="card-body">
-                {% for entry in object.logentries.all %}
-                    <div class="mb-3 {% if entry.kind == entry.Kind.SYSTEM %}text-muted{% endif %} logentry" data-has-msg="{% if entry.comment %}y{% else %}n{% endif %}">
-                        {% if latest_note and latest_note.pk == entry.pk %}<a id="latest_note"></a>{% endif %}
-                        <div class="border-bottom border-secondary mb-1{% if not entry.comment %} text-muted{% endif %}">
-                            <abbr title="{{ entry.timestamp }}">{{ entry.timestamp|naturaltime }}</abbr>
-                            <span class="mx-1 badge bg-light text-bg-light border border-secondary-subtle"><i class="bi bi-person"></i> {{ entry.user.username }}</span>
-                            <span class="text-muted">{{ entry.get_kind_display }}</span>
-                        </div>
-                        {% if entry.changes %}
-                            <i class="bi bi-table float-start"></i>
-                            <dl class="ms-4 mb-1 row small text-muted">
-                                {% for k, v in entry.changes.items %}
-                                    {% if k not in filtered_logentry_changes_keys %}
-                                    <dt class="col-md-3">{{ k }}:</dt>
-                                    <dd class="col-md-9">
-                                        {% if v|is_dict %}
-                                            <s class="fst-italic">{{ v.old }}</s>
-                                            {{ v.new }}
-                                        {% else %}
-                                            {{ v }}
-                                        {% endif %}
-                                    </dd>
-                                    {% endif %}
-                                {% endfor %}
-                            </dl>
-                        {% endif %}
-                        {% if entry.comment %}
-                            <i class="bi bi-chat-left-text float-start"></i>
-                            <div class="ms-4 border-1 bg-primary-subtle">
-                                {{ entry.comment }}
-                            </div>
-                        {% endif %}
-                    </div>
+            {% if entry.changes %}
+              <i class="bi bi-table float-start"></i>
+              <dl class="ms-4 mb-1 row small text-muted">
+                {% for k, v in entry.changes.items %}
+                  {% if k not in filtered_logentry_changes_keys %}
+                    <dt class="col-md-3">{{ k }}:</dt>
+                    <dd class="col-md-9">
+                      {% if v|is_dict %}
+                        <s class="fst-italic">{{ v.old }}</s>
+                        {{ v.new }}
+                      {% else %}
+                        {{ v }}
+                      {% endif %}
+                    </dd>
+                  {% endif %}
                 {% endfor %}
-            </div>
-        </div>
+              </dl>
+            {% endif %}
+            {% if entry.comment %}
+              <i class="bi bi-chat-left-text float-start"></i>
+              <div class="ms-4 border-1 bg-primary-subtle">{{ entry.comment }}</div>
+            {% endif %}
+          </div>
+        {% endfor %}
+      </div>
     </div>
+  </div>
 </div>
 
 {% if add_comment_url %}
-<div class="modal fade" id="addCommentModal_{{ alc_ident }}" tabindex="-1" aria-labelledby="addCommentModalLabel" aria-hidden="true">
+  <div class="modal fade"
+       id="addCommentModal_{{ alc_ident }}"
+       tabindex="-1"
+       aria-labelledby="addCommentModalLabel"
+       aria-hidden="true">
     <div class="modal-dialog">
-        <div class="modal-content">
-            <div class="modal-header">
-                <h1 class="modal-title fs-5" id="addCommentModalLabel">{% trans "activitylog_addcomment" %}</h1>
-                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-            </div>
-            <div class="modal-body">
-                <p>{% trans "activitylog_addcomment_help" %}</p>
-                <form id="addcomment_{{ alc_ident }}" action="{{ add_comment_url }}" method="POST">
-                    {% csrf_token %}
-                    <textarea name="comment" class="form-control" placeholder="" required></textarea>
-                </form>
-            </div>
-            <div class="modal-footer">
-                <button class="btn btn-primary" form="addcomment_{{ alc_ident }}"><i class="bi bi-chat-left-text"></i> {% trans "activitylog_addcomment_do" %}</button>
-            </div>
+      <div class="modal-content">
+        <div class="modal-header">
+          <h1 class="modal-title fs-5" id="addCommentModalLabel">{% trans "activitylog_addcomment" %}</h1>
+          <button type="button"
+                  class="btn-close"
+                  data-bs-dismiss="modal"
+                  aria-label="Close"></button>
+        </div>
+        <div class="modal-body">
+          <p>{% trans "activitylog_addcomment_help" %}</p>
+          <form id="addcomment_{{ alc_ident }}"
+                action="{{ add_comment_url }}"
+                method="post">
+            {% csrf_token %}
+            <textarea name="comment" class="form-control" placeholder="" required></textarea>
+          </form>
         </div>
+        <div class="modal-footer">
+          <button class="btn btn-primary" form="addcomment_{{ alc_ident }}">
+            <i class="bi bi-chat-left-text"></i> {% trans "activitylog_addcomment_do" %}
+          </button>
+        </div>
+      </div>
     </div>
-</div>
+  </div>
 {% endif %}
 
 <script>
diff --git a/src/backoffice/templates/backoffice/assembly_basicdata.html b/src/backoffice/templates/backoffice/assembly_basicdata.html
index 4779b582fb8f1285464aff7c5eb3f2328486ba1e..203f33dbc539852e6a767771915adbffa08f88f3 100644
--- a/src/backoffice/templates/backoffice/assembly_basicdata.html
+++ b/src/backoffice/templates/backoffice/assembly_basicdata.html
@@ -40,15 +40,9 @@
     </div>
   </div>
   <div class="col-md-3">
-    <label class="form-label" for="id_state_assembly">{% trans "Assembly__state_assembly" %}</label>
-    <div id="id_state_assembly">{{ form.instance.get_state_assembly_display }}</div>
+    <label class="form-label" for="id_state">{% trans "Assembly__state" %}</label>
+    <div id="id_state">{{ form.instance.get_state_display }}</div>
   </div>
-  {% if conference.support_channels %}
-    <div class="col-md-3">
-      <label class="form-label" for="id_state_channel">{% trans "Assembly__state_channel" %}</label>
-      <div id="id_state_channel">{{ form.instance.get_state_channel_display }}</div>
-    </div>
-  {% endif %}
 </div>
 
 <div class="row">
diff --git a/src/backoffice/templates/backoffice/assembly_detail.html b/src/backoffice/templates/backoffice/assembly_detail.html
index af23a6f1c85adce251871ce058e2d44e45154d93..5e8c361cae94b89509380c5c8ae551deaeee149a 100644
--- a/src/backoffice/templates/backoffice/assembly_detail.html
+++ b/src/backoffice/templates/backoffice/assembly_detail.html
@@ -58,34 +58,27 @@
         <div class="card-body text-center">
           <p>{{ assembly.get_assembly_type_display }}</p>
           <p>
-            {% translate "Assembly__state_assembly" %}
+            {% translate "Assembly__state" %}
             <br>
-            <span class="font-weight-bold{% if assembly.is_public %} text-success{% elif assembly.state_assembly == 'rejected' %} text-danger{% endif %}">{{ assembly.get_state_assembly_display }}</span>
+            <span class="font-weight-bold {% if assembly.is_public %} text-success {% elif assembly.state == "rejected" %} text-danger {% endif %}">{{ assembly.get_state_display }}</span>
           </p>
-          {% if conference.support_channels %}
-            <p>
-              {% translate "Assembly__state_channel" %}
-              <br>
-              <span class="font-weight-bold{% if assembly.is_public %} text-success{% elif assembly.state_channel == 'rejected' %} text-danger{% endif %}">{{ assembly.get_state_channel_display }}</span>
-            </p>
-          {% endif %}
         </div>
       </div>
     </div>
   </div>
 
-  {% if assembly.state_assembly == "planned" %}
+  {% if assembly.state == "planned" %}
     <div class="row mt-3">
       <div class="col-md-12">
         <div class="card">
-          <div class="card-header bg-warning">{% trans "Assembly__state_assembly-planned__hint" %}</div>
-          <div class="card-body">{% blocktrans %}Assembly__state_assembly-planned__description{% endblocktrans %}</div>
+          <div class="card-header bg-warning">{% trans "Assembly__state-planned__hint" %}</div>
+          <div class="card-body">{% blocktrans %}Assembly__state-planned__description{% endblocktrans %}</div>
         </div>
       </div>
     </div>
   {% endif %}
 
-  {% if staff_access %}
+  {% if staff_mode %}
     <div class="row mt-3">
       <div class="col-md-12">
         <div class="card">
@@ -130,8 +123,8 @@
             {% with la=assembly.linked_assemblies %}
               {% if la|length > 0 %}
                 {% for linked in la %}
-                  {% if staff_access %}
-                    <a href="{% url 'backoffice:assembly' pk=linked.pk %}">{{ linked.name }}</a>
+                  {% if staff_mode %}
+                    <a href="{% url "backoffice:assembly" pk=linked.pk %}">{{ linked.name }}</a>
                   {% else %}
                     {{ linked.name }}
                   {% endif %}
diff --git a/src/backoffice/templates/backoffice/assembly_edit.html b/src/backoffice/templates/backoffice/assembly_edit.html
index 84743ef972261c01dc1d86154f622b15cb09acde..2dc76d30819679c5e0301d76bf07dec3ef60fbc5 100644
--- a/src/backoffice/templates/backoffice/assembly_edit.html
+++ b/src/backoffice/templates/backoffice/assembly_edit.html
@@ -26,7 +26,7 @@
           <div class="card-body">
             {% if assembly.basedata_readonly %}
               <div class="alert alert-warning"
-                   {% if staff_access %}style="text-decoration: line-through;"{% endif %}>
+                   {% if staff_mode %}style="text-decoration: line-through;"{% endif %}>
                 {% trans "assemblyedit_readonlybasedata" %}
               </div>
             {% endif %}
diff --git a/src/backoffice/templates/backoffice/assembly_editchildren.html b/src/backoffice/templates/backoffice/assembly_editchildren.html
index 68c0092a0ffbd31b4ca465af7e5549fe99d361f1..4ce555db99d71b779a4e5ac22db7db394c5a7da4 100644
--- a/src/backoffice/templates/backoffice/assembly_editchildren.html
+++ b/src/backoffice/templates/backoffice/assembly_editchildren.html
@@ -43,7 +43,7 @@
               <ul>
                 {% for child in children %}
                   <li>
-                    {% if child.state_assembly == "hidden" %}<i class="bi bi-eye-slash" title="hidden"></i>{% endif %}
+                    {% if child.state == "hidden" %}<i class="bi bi-eye-slash" title="hidden"></i>{% endif %}
                     <a href="{% url 'backoffice:assembly' pk=child.id %}">{{ child.name }}</a>
                     <form action="{% url 'backoffice:assembly-editchildren' pk=assembly.id %}"
                           method="post"
diff --git a/src/backoffice/templates/backoffice/assembly_list.html b/src/backoffice/templates/backoffice/assembly_list.html
index 8533161011ab7d3e272ed3b24c0cf7fb5b52ac01..ecb3527f8abe979ff3dd21138f10d017a2d0ee61 100644
--- a/src/backoffice/templates/backoffice/assembly_list.html
+++ b/src/backoffice/templates/backoffice/assembly_list.html
@@ -65,10 +65,7 @@
             {% endif %}
             <th>{% trans "Assembly__name" %}</th>
             <th title="{% trans "Assembly__is_official" %}">{% trans "Assembly__is_official__short" %}</th>
-            <th>{% trans "Assembly__state_assembly" %}</th>
-            {% if conference.support_channels %}
-              <th>{% trans "Assembly__state_channel" %}</th>
-            {% endif %}
+            <th>{% trans "Assembly__state" %}</th>
             <th>{% trans "Assembly__last_update" %}</th>
           </tr>
         </thead>
@@ -85,22 +82,13 @@
                 {% endspaceless %}
               </td>
               <td>{{ assembly.is_official|yesno }}</td>
-              <td class="{% if assembly.is_public_assembly %}text-success{% elif assembly.state_assembly == 'rejected' %}text-danger{% endif %}">
-                {% if assembly.state_assembly != 'none' %}
-                  {{ assembly.get_state_assembly_display }}
+              <td class="{% if assembly.is_public %}text-success{% elif assembly.state == 'rejected' %}text-danger{% endif %}">
+                {% if assembly.state != 'none' %}
+                  {{ assembly.get_state_display }}
                 {% else %}
                   -
                 {% endif %}
               </td>
-              {% if conference.support_channels %}
-                <td class="{% if assembly.is_public_channel %}text-success{% elif assembly.state_channel == 'rejected' %}text-danger{% endif %}">
-                  {% if assembly.state_channel != 'none' %}
-                    {{ assembly.get_state_channel_display }}
-                  {% else %}
-                    -
-                  {% endif %}
-                </td>
-              {% endif %}
               <td>
                 {% if assembly.last_update_assembly > assembly.last_update_staff %}
                   <span title="{% trans "Assembly__last_update_assembly" %}">{{ assembly.last_update_assembly|naturaltime }}</span>
diff --git a/src/backoffice/templates/backoffice/assembly_members.html b/src/backoffice/templates/backoffice/assembly_members.html
index 709497ad1a67ebff7983a1e0347f81c0a728cab1..3b8a197fb8ae8b514dfa2a31f9ad496942ab7a66 100644
--- a/src/backoffice/templates/backoffice/assembly_members.html
+++ b/src/backoffice/templates/backoffice/assembly_members.html
@@ -26,13 +26,7 @@
                   {% if staff_mode %}<th>Mail</th>{% endif %}
                   <th title="{% trans "AssemblyMember__is_representative" %}">R</th>
                   <th title="{% trans "AssemblyMember__can_manage_assembly" %}">M</th>
-                  {% if assembly.is_channel %}
-                    <th title="{% trans "AssemblyMember__is_content_coordinator" %}">C</th>
-                    <th title="{% trans "AssemblyMember__is_production_coordinator" %}">P</th>
-                  {% endif %}
-                  {% if assembly.is_assembly %}
-                    <th title="{% trans "AssemblyMember__is_technical_contact" %}">T</th>
-                  {% endif %}
+                  <th title="{% trans "AssemblyMember__is_technical_contact" %}">T</th>
                   <th title="{% trans "AssemblyMember__show_public" %}">S</th>
                   {% if can_manage %}
                     <th>{% trans "AssemblyMember__actions" %}</th>
@@ -66,31 +60,13 @@
                         -
                       {% endif %}
                     </td>
-                    {% if assembly.is_channel %}
-                      <td>
-                        {% if member.is_content_coordinator %}
-                          C
-                        {% else %}
-                          -
-                        {% endif %}
-                      </td>
-                      <td>
-                        {% if member.is_production_coordinator %}
-                          P
-                        {% else %}
-                          -
-                        {% endif %}
-                      </td>
-                    {% endif %}
-                    {% if assembly.is_assembly %}
-                      <td>
-                        {% if member.is_technical_contact %}
-                          T
-                        {% else %}
-                          -
-                        {% endif %}
-                      </td>
-                    {% endif %}
+                    <td>
+                      {% if member.is_technical_contact %}
+                        T
+                      {% else %}
+                        -
+                      {% endif %}
+                    </td>
                     <td>
                       {% if member.show_public %}
                         S
diff --git a/src/backoffice/templates/backoffice/assemblyteam_assembly_detail.html b/src/backoffice/templates/backoffice/assemblyteam_assembly_detail.html
index 59bb4e6200392b7e41ceeab7f0f70d5f935803aa..643104787160ef45ab64a27097d2e20e6366992c 100644
--- a/src/backoffice/templates/backoffice/assemblyteam_assembly_detail.html
+++ b/src/backoffice/templates/backoffice/assemblyteam_assembly_detail.html
@@ -71,18 +71,18 @@
       <div class="row mb-3">
         <div class="col-md-8">
           <div class="card">
-            <div class="card-header">{% trans "Assembly__state_assembly" %}</div>
+            <div class="card-header">{% trans "Assembly__state" %}</div>
             <div class="card-body">
               <div class="dropdown text-center">
-                <span class="fs-4 {% if object.is_public_assembly %}text-success{% elif object.state_assembly == 'rejected' %}text-danger{% endif %}">
-                  {{ object.get_state_assembly_display }}
+                <span class="fs-4 {% if object.is_public %}text-success{% elif object.state == 'rejected' %}text-danger{% endif %}">
+                  {{ object.get_state_display }}
                 </span>
                 <btn class="btn btn-sm btn-primary dropdown-toggle" role="button" data-bs-toggle="dropdown">
                 <i class="bi bi-pencil"></i>
                 </btn>
 
                 <ul class="dropdown-menu">
-                  {% if assembly.state_assembly == assembly.State.PLANNED %}
+                  {% if assembly.state == assembly.State.PLANNED %}
                     <li>
                       <a class="dropdown-item text-danger"
                          role="button"
@@ -98,7 +98,7 @@
                       </a>
                     </li>
 
-                  {% elif assembly.state_assembly == assembly.State.REGISTERED %}
+                  {% elif assembly.state == assembly.State.REGISTERED %}
                     <li>
                       <a class="dropdown-item text-success"
                          role="button"
@@ -121,7 +121,7 @@
                       </a>
                     </li>
 
-                  {% elif assembly.state_assembly == assembly.State.REJECTED %}
+                  {% elif assembly.state == assembly.State.REJECTED %}
                     <li>
                       <a class="dropdown-item text-warning"
                          role="button"
@@ -132,7 +132,7 @@
 
                   {% else %}
                     {% if assembly.is_public %}
-                      {% if assembly.state_assembly != 'placed' %}
+                      {% if assembly.state != 'placed' %}
                         <li>
                           <a class="dropdown-item text-secondary"
                              role="button"
@@ -141,7 +141,7 @@
                           </a>
                         </li>
                       {% endif %}
-                      {% if assembly.state_assembly != 'arrived' %}
+                      {% if assembly.state != 'arrived' %}
                         <li>
                           <a class="dropdown-item text-info"
                              role="button"
@@ -150,7 +150,7 @@
                           </a>
                         </li>
                       {% endif %}
-                      {% if assembly.state_assembly != 'confirmed' %}
+                      {% if assembly.state != 'confirmed' %}
                         <li>
                           <a class="dropdown-item text-success"
                              role="button"
@@ -234,7 +234,7 @@
     </div>
   </div>
 
-{% url 'backoffice:assemblyteam-detail' pk=object.pk as add_comment_url %}
-{% include 'backoffice/activitylog_card.html' with filtered_logentry_changes_keys="last_update_assembly"|split:"," %}
+  {% url 'backoffice:assemblyteam-detail' pk=object.pk as add_comment_url %}
+  {% include "backoffice/activitylog_card.html" with filtered_logentry_changes_keys="last_update_assembly"|split:"," %}
 
 {% endblock content %}
diff --git a/src/backoffice/templates/backoffice/assemblyteam_editposition.html b/src/backoffice/templates/backoffice/assemblyteam_editposition.html
index aec20bf0c062ed5bb369cbdfb593fd5bc15141e1..d369a93c6bdaef940fa0c008ce760c0759757013 100644
--- a/src/backoffice/templates/backoffice/assemblyteam_editposition.html
+++ b/src/backoffice/templates/backoffice/assemblyteam_editposition.html
@@ -23,7 +23,7 @@
             <input type="hidden" name="value" value="{{ new_value }}">
 
             <p>{% trans "Assembly__slug" %}: {{ assembly.slug }}</p>
-            <p>{% trans "Assembly__state_assembly" %}: {{ assembly.get_state_assembly_display }}</p>
+            <p>{% trans "Assembly__state" %}: {{ assembly.get_state_display }}</p>
 
             {% include "core/map.html" with map_config=conference.map_config.backoffice poi_id="poi" areas_id="areas" floor_id="floor" %}
 
diff --git a/src/backoffice/templates/backoffice/assemblyteam_editstate.html b/src/backoffice/templates/backoffice/assemblyteam_editstate.html
index 11d3f279503600963c2a4c4948d680ed78b264f8..79a88978f05754a0a2a5e85da6bd23ace662bee3 100644
--- a/src/backoffice/templates/backoffice/assemblyteam_editstate.html
+++ b/src/backoffice/templates/backoffice/assemblyteam_editstate.html
@@ -24,7 +24,7 @@
 
             <p>{% trans "Assembly__slug" %}: {{ assembly.slug }}</p>
             <p>
-              {% trans "Assembly__state_assembly" %}: <s class="text-danger">{{ assembly.get_state_assembly_display }}</s> <span class="text-success">{{ new_value_translated }}</span>
+              {% trans "Assembly__state" %}: <s class="text-danger">{{ assembly.get_state_display }}</s> <span class="text-success">{{ new_value_translated }}</span>
             </p>
 
             <p>{% trans "assemblyteam_addcomment_field" %}:</p>
diff --git a/src/backoffice/templates/backoffice/base.html b/src/backoffice/templates/backoffice/base.html
index fdcb86c8d82cbdee55ffaa39ac5298c332d4f343..95d11799b3a68973bb70713f97bf41e9a990daf7 100644
--- a/src/backoffice/templates/backoffice/base.html
+++ b/src/backoffice/templates/backoffice/base.html
@@ -67,14 +67,6 @@
               </a>
             </li>
           {% endif %}
-          {% if has_channel %}
-            <li class="nav-item">
-              <a class="nav-link{% if active_page == 'channels' %} active{% endif %}"
-                 href="{% url 'backoffice:channels' %}">{% trans "nav_channels" %}
-                {% if active_page == 'channels' %}<span class="visually-hidden">{{ activetab_srmarker }}</span>{% endif %}
-              </a>
-            </li>
-          {% endif %}
           {% if has_map %}
             <li class="nav-item">
               <a class="nav-link{% if active_page == 'map' %} active{% endif %}"
diff --git a/src/backoffice/templates/backoffice/index.html b/src/backoffice/templates/backoffice/index.html
index d4ba6322ae299f29d1684b185f60b461d8be2592..87bdd2f13ff4cf12be538011c5faf4120130530f 100644
--- a/src/backoffice/templates/backoffice/index.html
+++ b/src/backoffice/templates/backoffice/index.html
@@ -26,10 +26,10 @@
                   <a href="{% url 'backoffice:assembly' pk=assembly.id %}">{{ assembly.name }}</a>
                 </td>
                 <td>
-                  {{ assembly.get_state_assembly_display }}
-                  {% if assembly.state_assembly == 'planned' %}
+                  {{ assembly.get_state_display }}
+                  {% if assembly.state == 'planned' %}
                     <span class="text-danger font-weight-bold"
-                          title="{% trans "Assembly__state_assembly-planned__hint" %}">⚠</span>
+                          title="{% trans "Assembly__state-planned__hint" %}">⚠</span>
                   {% endif %}
                 </td>
               </tr>
diff --git a/src/backoffice/templates/backoffice/moderation_assembly-detail.html b/src/backoffice/templates/backoffice/moderation_assembly-detail.html
index 282cec37c9cf1bc6e776e26e81a44693f0315fae..3e24840ed766c168c240db3ad3817dc109306aaf 100644
--- a/src/backoffice/templates/backoffice/moderation_assembly-detail.html
+++ b/src/backoffice/templates/backoffice/moderation_assembly-detail.html
@@ -54,9 +54,9 @@
             <dd class="col-sm-9">
               {{ object.is_official|yesno }}
             </dd>
-            <dt class="col-sm-3">{% trans "Assembly__state_assembly" %}:</dt>
+            <dt class="col-sm-3">{% trans "Assembly__state" %}:</dt>
             <dd class="col-sm-9">
-              {{ object.get_state_assembly_display }}
+              {{ object.get_state_display }}
             </dd>
           </dl>
         </div>
diff --git a/src/backoffice/templates/backoffice/moderation_assembly-item.html b/src/backoffice/templates/backoffice/moderation_assembly-item.html
index b2a933c852dee083c5e850696d732fdbe8fa8826..defe3952107f2d1121ab2a55d72c3c589d845e00 100644
--- a/src/backoffice/templates/backoffice/moderation_assembly-item.html
+++ b/src/backoffice/templates/backoffice/moderation_assembly-item.html
@@ -5,7 +5,7 @@
    class="fw-bold">{{ assembly.slug }}</a>" <small>{{ assembly.name }}</small>
     <br>
 
-    <span class="text-{% if assembly.is_public %}success{% elif assembly.state_assembly != 'hidden' %}danger{% else %}secondary{% endif %}">{{ assembly.get_state_assembly_display }}</span>
+    <span class="text-{% if assembly.is_public %}success{% elif assembly.state != 'hidden' %}danger{% else %}secondary{% endif %}">{{ assembly.get_state_display }}</span>
     <br>
 
     <span class="text-muted">Kontakte:</span>
diff --git a/src/backoffice/templates/backoffice/moderation_assembly-list.html b/src/backoffice/templates/backoffice/moderation_assembly-list.html
index e9ddaae2045f637f28facecfcf6f3693936e6521..a1d9518c41f271420954f29f07c38d9e971225b4 100644
--- a/src/backoffice/templates/backoffice/moderation_assembly-list.html
+++ b/src/backoffice/templates/backoffice/moderation_assembly-list.html
@@ -66,10 +66,7 @@
             <th>{% trans "Assembly__slug" %}</th>
             <th>{% trans "Assembly__name" %}</th>
             <th title="{% trans "Assembly__is_official" %}">{% trans "Assembly__is_official__short" %}</th>
-            <th>{% trans "Assembly__state_assembly" %}</th>
-            {% if conference.support_channels %}
-              <th>{% trans "Assembly__state_channel" %}</th>
-            {% endif %}
+            <th>{% trans "Assembly__state" %}</th>
             <th>{% trans "Assembly__last_update" %}</th>
           </tr>
         </thead>
@@ -94,22 +91,13 @@
                 {% endspaceless %}
               </td>
               <td>{{ assembly.is_official|yesno }}</td>
-              <td class="{% if assembly.is_public_assembly %}text-success{% elif assembly.state_assembly == 'rejected' %}text-danger{% endif %}">
-                {% if assembly.state_assembly != 'none' %}
-                  {{ assembly.get_state_assembly_display }}
+              <td class="{% if assembly.is_public %}text-success{% elif assembly.state == 'rejected' %}text-danger{% endif %}">
+                {% if assembly.state != 'none' %}
+                  {{ assembly.get_state_display }}
                 {% else %}
                   -
                 {% endif %}
               </td>
-              {% if conference.support_channels %}
-                <td class="{% if assembly.is_public_channel %}text-success{% elif assembly.state_channel == 'rejected' %}text-danger{% endif %}">
-                  {% if assembly.state_channel != 'none' %}
-                    {{ assembly.get_state_channel_display }}
-                  {% else %}
-                    -
-                  {% endif %}
-                </td>
-              {% endif %}
               <td>
                 {% if assembly.last_update_assembly > assembly.last_update_staff %}
                   <span title="{% trans "Assembly__last_update_assembly" %}">{{ assembly.last_update_assembly|naturaltime }}</span>
diff --git a/src/backoffice/templates/backoffice/wa-map-list.html b/src/backoffice/templates/backoffice/wa-map-list.html
index 2d7a0f159b67babec8df3a4f6e6b117665b98bb1..94689a0a6f9f39ede73914e1a545180ca2ead4fa 100644
--- a/src/backoffice/templates/backoffice/wa-map-list.html
+++ b/src/backoffice/templates/backoffice/wa-map-list.html
@@ -68,7 +68,7 @@
                 <a href="{% url 'backoffice:workadventure-map-detail' pk=obj.pk %}">{{ obj.name|default:"-?-" }}</a>
               </td>
               <td>
-                <span class="{% if obj.assembly.is_public_assembly %}text-success{% else %}text-danger{% endif %}">Assembly</span>
+                <span class="{% if obj.assembly.is_public %}text-success{% else %}text-danger{% endif %}">Assembly</span>
                 {% include "backoffice/_room_backend_status.html" with object=obj backend_status_display="Backend" %}
                 {% include "backoffice/_room_wa_map_status.html" with object=obj display="Map" %}
               </td>
diff --git a/src/backoffice/tests/assemblies.py b/src/backoffice/tests/assemblies.py
index 0d19efc8a59f032b6c892ba2144319b1fdd100fb..a51bfd9d6c678373d3164233883bd7d5a76dccdd 100644
--- a/src/backoffice/tests/assemblies.py
+++ b/src/backoffice/tests/assemblies.py
@@ -10,9 +10,7 @@ from backoffice.tests import BackOfficeTestCase
 class AssemblyListViewTest(BackOfficeTestCase):
     def setUp(self):
         super().setUp()
-        self.assemblies = [
-            Assembly(slug=a, name=a, is_virtual=True, conference_id=self.conf.id, state_assembly=Assembly.State.ACCEPTED) for a in ('a1', 'a2', 'a3')
-        ]
+        self.assemblies = [Assembly(slug=a, name=a, is_virtual=True, conference_id=self.conf.id, state=Assembly.State.ACCEPTED) for a in ('a1', 'a2', 'a3')]
         for a in self.assemblies:
             a.save()
         self.assembly_links = [AssemblyLink(a=self.assemblies[0], b=self.assemblies[1]), AssemblyLink(a=self.assemblies[0], b=self.assemblies[2])]
@@ -91,7 +89,7 @@ class AssemblyCreateViewTest(BackOfficeTestCase):
 class AssemblyMembersViewTest(BackOfficeTestCase):
     def setUp(self):
         super().setUp()
-        self.assembly = Assembly.objects.create(slug='a1', name='a1', is_physical=True, conference_id=self.conf.id, state_assembly=Assembly.State.ACCEPTED)
+        self.assembly = Assembly.objects.create(slug='a1', name='a1', is_physical=True, conference_id=self.conf.id, state=Assembly.State.ACCEPTED)
         self.users: list[PlatformUser] = [
             PlatformUser.objects.create(
                 username=a,
diff --git a/src/backoffice/urls.py b/src/backoffice/urls.py
index 7e784306faff4afdb1fb66b9bf7e26dcab0e9ffd..99bca1229cb8360674c35f7f8960464e2583bf5c 100644
--- a/src/backoffice/urls.py
+++ b/src/backoffice/urls.py
@@ -6,7 +6,6 @@ from backoffice.views import (
     assemblyteam,
     auth,
     badges,
-    channelteam,
     events,
     misc,
     moderation,
@@ -63,8 +62,6 @@ urlpatterns = [
     path('wiki/page/<uuid:pk>/delete-revision', wiki.PageRevisionDeleteView.as_view(), name='wiki-page-revision-delete'),
     path('assemblies', assemblyteam.AssembliesView.as_view(), name='assemblies'),
     path('assemblies/list/<str:variant>', assemblyteam.AssembliesListsView.as_view(), name='assemblieslist'),
-    path('channels', channelteam.ChannelsView.as_view(), name='channels'),
-    path('channels/list/<str:variant>', channelteam.ChannelsListView.as_view(), name='channelslist'),
     path('assemblyteam/<uuid:pk>', assemblyteam.AssemblyView.as_view(), name='assemblyteam-detail'),
     path('assemblyteam/<uuid:pk>/state', assemblyteam.AssemblyEditStateView.as_view(), name='assemblyteam-editstate'),
     path('assemblyteam/<uuid:pk>/hierarchy', assemblyteam.AssemblyEditHierarchyView.as_view(), name='assemblyteam-edithierarchy'),
diff --git a/src/backoffice/views/assemblies/assemblies.py b/src/backoffice/views/assemblies/assemblies.py
index 1fdd977af4860530d4cc9b4140ee485af3b7c17b..3cda902cd38d4dc730d2608f7658aa3add65ee7c 100644
--- a/src/backoffice/views/assemblies/assemblies.py
+++ b/src/backoffice/views/assemblies/assemblies.py
@@ -81,8 +81,7 @@ class AssemblyCreateView(ConferenceLoginRequiredMixin, CreateView):
 
     def form_valid(self, form):
         form.instance.conference = self.conference
-        form.instance.state_assembly = Assembly.State.PLANNED if form.cleaned_data['is_assembly'] else Assembly.State.NONE
-        form.instance.state_channel = Assembly.State.PLANNED if self.conference.support_channels and form.cleaned_data['is_channel'] else Assembly.State.NONE
+        form.instance.state = Assembly.State.PLANNED
 
         form.instance.ensure_single_type_conference_match()
 
@@ -98,8 +97,7 @@ class AssemblyCreateView(ConferenceLoginRequiredMixin, CreateView):
             kind=ActivityLogEntry.Kind.ENTITY,
             slug=ActivityLogChange(new=form.instance.slug),
             name=ActivityLogChange(new=form.instance.name),
-            state_assembly=ActivityLogChange(new=form.instance.state_assembly),
-            state_channel=ActivityLogChange(new=form.instance.state_channel),
+            state=ActivityLogChange(new=form.instance.state),
         )
 
         # add current user as first member of the new assembly (so that editing is possible)
@@ -141,10 +139,7 @@ class AssemblyUpdateView(AssemblyMixin, UpdateView):
     def get_form_kwargs(self):
         kwargs = super().get_form_kwargs()
         kwargs['instance'] = self.assembly
-        kwargs['staff_access'] = self.staff_access
         kwargs['staff_mode'] = self.staff_mode
-        kwargs['assembly_staff_access'] = self.assembly_staff_access
-        kwargs['channel_staff_access'] = self.channel_staff_access
 
         return kwargs
 
@@ -266,13 +261,10 @@ class AssemblyUpdateView(AssemblyMixin, UpdateView):
         for fld, change in assembly.ensure_single_type_conference_match().items():
             changes[fld] = change
 
-        # auto-advance assembly/channel states from 'planned' to 'registered' on (first) save
-        if assembly.state_assembly == Assembly.State.PLANNED and (assembly.user_can_manage(self.request.user) or not self.staff_mode):
-            assembly.state_assembly = Assembly.State.REGISTERED
-            changes['state_assembly'] = (Assembly.State.PLANNED, Assembly.State.REGISTERED)
-        if assembly.state_channel == Assembly.State.PLANNED and (assembly.user_can_manage(self.request.user) or not self.staff_mode):
-            assembly.state_channel = Assembly.State.REGISTERED
-            changes['state_channel'] = (Assembly.State.PLANNED, Assembly.State.REGISTERED)
+        # auto-advance assembly states from 'planned' to 'registered' on (first) save
+        if assembly.state == Assembly.State.PLANNED and (assembly.user_can_manage(self.request.user) or not self.staff_mode):
+            assembly.state = Assembly.State.REGISTERED
+            changes['state'] = (Assembly.State.PLANNED, Assembly.State.REGISTERED)
 
         # check for valid parent on regular assemblies
         if assembly.hierarchy == Assembly.Hierarchy.REGULAR:
@@ -334,7 +326,7 @@ class AssemblyUpdateView(AssemblyMixin, UpdateView):
         # save the update data
         assembly.log_activity(
             user=self.request.user,
-            kind=ActivityLogEntry.Kind.STAFF if self.staff_access else ActivityLogEntry.Kind.ENTITY,
+            kind=ActivityLogEntry.Kind.STAFF if self.staff_mode else ActivityLogEntry.Kind.ENTITY,
             context='backoffice.assembly',
             **{k: (ActivityLogChange(old=str(v[0]), new=str(v[1])) if isinstance(v, tuple) else str(v)) for k, v in changes.items()},
         )
@@ -467,7 +459,7 @@ class AssemblyChildrenUpdateView(AssemblyMixin, View):
         candidates_qs = (
             Assembly.objects.associated_with_user(conference=self.conference, user=self.request.user)
             .filter(hierarchy=Assembly.Hierarchy.REGULAR, parent=None)
-            .exclude(state_assembly__in=[Assembly.State.NONE, Assembly.State.REJECTED, Assembly.State.HIDDEN, Assembly.State.PLANNED])
+            .exclude(state__in=[Assembly.State.REJECTED, Assembly.State.HIDDEN, Assembly.State.PLANNED])
         )
         candidates = list(candidates_qs.order_by('name'))
 
@@ -543,7 +535,7 @@ class AssemblyLinksUpdateView(AssemblyMixin, View):
         candidates_qs = (
             Assembly.objects.associated_with_user(conference=self.conference, user=self.request.user)
             .filter(hierarchy=Assembly.Hierarchy.REGULAR)
-            .exclude(state_assembly__in=[Assembly.State.NONE, Assembly.State.PLANNED, Assembly.State.HIDDEN, Assembly.State.REJECTED])
+            .exclude(state__in=[Assembly.State.PLANNED, Assembly.State.HIDDEN, Assembly.State.REJECTED])
             # Remove self from list (cannot link to self)
             .exclude(pk=self.assembly.pk)
             # Remove already linked assemblies
diff --git a/src/backoffice/views/assemblies/members.py b/src/backoffice/views/assemblies/members.py
index c6a0928544a821e516225d232a03a24f0ca942f7..fb304953ee4edaa1802d89da8a35e78d23d40000 100644
--- a/src/backoffice/views/assemblies/members.py
+++ b/src/backoffice/views/assemblies/members.py
@@ -55,7 +55,7 @@ class MemberListView(AssemblyMixin, ListView):
                 messages.success(self.request, format_lazy(_('Assembly__members__hidden'), user=m.member))
                 self.assembly.log_activity(
                     user=self.request.user,
-                    kind=ActivityLogEntry.Kind.ENTITY if not self.staff_access else ActivityLogEntry.Kind.STAFF,
+                    kind=ActivityLogEntry.Kind.ENTITY if not self.staff_mode else ActivityLogEntry.Kind.STAFF,
                     **{
                         'members.modified': m.member.username,
                         f'members[{m.member.username}].show_public': ActivityLogChange(
@@ -78,7 +78,7 @@ class MemberListView(AssemblyMixin, ListView):
                 messages.success(self.request, format_lazy(_('Assembly__members__shown'), user=m.member))
                 self.assembly.log_activity(
                     user=self.request.user,
-                    kind=ActivityLogEntry.Kind.ENTITY if not self.staff_access else ActivityLogEntry.Kind.STAFF,
+                    kind=ActivityLogEntry.Kind.ENTITY if not self.staff_mode else ActivityLogEntry.Kind.STAFF,
                     **{
                         'members.modified': m.member.username,
                         f'members[{m.member.username}].show_public': ActivityLogChange(
@@ -89,7 +89,7 @@ class MemberListView(AssemblyMixin, ListView):
                 )
 
             elif k == 'delete':
-                if int(v) == self.request.user.id and not self.staff_access:
+                if int(v) == self.request.user.id and not self.staff_mode:
                     messages.error(self.request, format_lazy(_('Assembly__members__cant_remove_self')))
                     continue
                 m = self.get_queryset().select_related('member').get(member_id=int(v))
@@ -100,7 +100,7 @@ class MemberListView(AssemblyMixin, ListView):
                 messages.success(self.request, format_lazy(_('Assembly__members__removed'), user=m.member))
                 self.assembly.log_activity(
                     user=self.request.user,
-                    kind=ActivityLogEntry.Kind.ENTITY if not self.staff_access else ActivityLogEntry.Kind.STAFF,
+                    kind=ActivityLogEntry.Kind.ENTITY if not self.staff_mode else ActivityLogEntry.Kind.STAFF,
                     **{
                         'members.removed': ActivityLogChange(
                             old=m.member.username,
@@ -129,7 +129,7 @@ class MemberCreateView(AssemblyMixin, FormView):
                 logger.info('added "%(member)s" to assembly %(assembly)s by %(user)s', {'member': u, 'assembly': self.assembly, 'user': self.request.user})
                 self.assembly.log_activity(
                     user=self.request.user,
-                    kind=ActivityLogEntry.Kind.ENTITY if not self.staff_access else ActivityLogEntry.Kind.STAFF,
+                    kind=ActivityLogEntry.Kind.ENTITY if not self.staff_mode else ActivityLogEntry.Kind.STAFF,
                     **{
                         'members.added': ActivityLogChange(
                             new=m.member.username,
@@ -138,7 +138,7 @@ class MemberCreateView(AssemblyMixin, FormView):
                 )
 
             else:  # noqa: PLR5501
-                if m.member == self.request.user and not self.staff_access:
+                if m.member == self.request.user and not self.staff_mode:
                     messages.error(self.request, format_lazy(_('Assembly__members__cant_modify_self')))
                 else:
                     messages.info(self.request, '= ' + str(u))
@@ -156,17 +156,6 @@ class MembersUpdateView(AssemblyMixin, UpdateView):
     template_name = 'backoffice/assembly_members_edit.html'
     form_class = AssemblyMemberEditForm
 
-    def get_form(self, *args, **kwargs):
-        frm = super().get_form(*args, **kwargs)
-
-        if not self.object.assembly.is_assembly:
-            del frm.fields['is_technical_contact']
-        if not self.object.assembly.is_channel:
-            del frm.fields['is_content_coordinator']
-            del frm.fields['is_production_coordinator']
-
-        return frm
-
     def get_object(self):
         return self.assembly.members.get(member__username=self.request.resolver_match.kwargs.get('uname'))
 
@@ -187,7 +176,7 @@ class MembersUpdateView(AssemblyMixin, UpdateView):
                 changes[f'members[{u}].{fld_name}'] = ActivityLogChange(old=str(old_value), new=str(new_value))
         self.assembly.log_activity(
             user=self.request.user,
-            kind=ActivityLogEntry.Kind.ENTITY if not self.staff_access else ActivityLogEntry.Kind.STAFF,
+            kind=ActivityLogEntry.Kind.ENTITY if not self.staff_mode else ActivityLogEntry.Kind.STAFF,
             **changes,
         )
         return redirect('backoffice:assembly-members', pk=self.assembly.pk)
diff --git a/src/backoffice/views/assemblies/rooms.py b/src/backoffice/views/assemblies/rooms.py
index 4d364858c76c0db319a8874d46022dec46ceb2c9..8e47ef8abf3f65e0c71d2ffc41b4287d4f7ea9ab 100644
--- a/src/backoffice/views/assemblies/rooms.py
+++ b/src/backoffice/views/assemblies/rooms.py
@@ -91,7 +91,7 @@ class AssemblyRoomUpdateView(AssemblyMixin, UpdateView):
 
     def get_form_kwargs(self):
         kwargs = super().get_form_kwargs()
-        kwargs['channel_staff'] = self.channel_staff_access
+        kwargs['staff_mode'] = self.staff_mode
         return kwargs
 
     def get_form(self, *args, **kwargs):
diff --git a/src/backoffice/views/assemblyteam.py b/src/backoffice/views/assemblyteam.py
index 50cab1e451c8cb35e33b0879415e8ed5c53f8033..04a1724b22e87261dbbd7a21c885de737a754791 100644
--- a/src/backoffice/views/assemblyteam.py
+++ b/src/backoffice/views/assemblyteam.py
@@ -35,16 +35,15 @@ class AssemblyTeamMixin(ConferenceLoginRequiredMixin):
     base_view_name = 'backoffice:assemblies'
     list_view_name = 'backoffice:assemblieslist'
     sidebar_caption = _('nav_assemblies')
-    status_field = 'state_assembly'
+    status_field = 'state'
 
     MODES = {
         'all': (Q(), _('nav_assemblies_all')),
-        'accepted': (Q(state_assembly__in=Assembly.PUBLIC_STATES), _('nav_assemblies_accepted')),
-        'pending': (Q(state_assembly__in=[Assembly.State.REGISTERED]), _('nav_assemblies_pending')),
-        'planned': (Q(state_assembly__in=[Assembly.State.PLANNED]), _('nav_assemblies_planned')),
-        'rejected': (Q(state_assembly__in=[Assembly.State.REJECTED]), _('nav_assemblies_rejected')),
-        'hidden': (Q(state_assembly__in=[Assembly.State.HIDDEN]), _('nav_assemblies_hidden')),
-        'not_selected': (Q(state_assembly__in=[Assembly.State.NONE]), _('nav_assemblies_not_selected')),
+        'accepted': (Q(state__in=Assembly.PUBLIC_STATES), _('nav_assemblies_accepted')),
+        'pending': (Q(state__in=[Assembly.State.REGISTERED]), _('nav_assemblies_pending')),
+        'planned': (Q(state__in=[Assembly.State.PLANNED]), _('nav_assemblies_planned')),
+        'rejected': (Q(state__in=[Assembly.State.REJECTED]), _('nav_assemblies_rejected')),
+        'hidden': (Q(state__in=[Assembly.State.HIDDEN]), _('nav_assemblies_hidden')),
     }
 
     def get_context_data(self, **kwargs):
@@ -126,11 +125,7 @@ class AssembliesListMixin(AssemblyTeamMixin):
         qs = Assembly.objects.associated_with_user(conference=self.conference, user=self.request.user, staff_can_see=True).order_by('slug')
         if mode == 'not_selected':
             pass
-        elif self.active_page == 'assemblies':
-            qs = qs.exclude(state_assembly=Assembly.State.NONE)
-        elif self.active_page == 'channels':
-            qs = qs.exclude(state_channel=Assembly.State.NONE)
-        else:
+        elif self.active_page != 'assemblies':
             logging.warning('AssembliesListMixin: unexpected active_page="%s"', self.active_page)
             qs = Assembly.objects.none()
 
@@ -451,16 +446,16 @@ class AssemblyEditStateView(SingleAssemblyTeamMixin, View):
 
         comment = request.POST.get('comment', '').strip()
 
-        old_value = assembly.state_assembly
-        assembly.state_assembly = value
-        assembly.save(update_fields=['state_assembly'])
+        old_value = assembly.state
+        assembly.state = value
+        assembly.save(update_fields=['state'])
         assembly.log_activity(
             user=self.request.user,
             kind=ActivityLogEntry.Kind.STAFF,
             comment=comment if comment else None,
-            state_assembly=ActivityLogChange(
+            state=ActivityLogChange(
                 old=old_value,
-                new=assembly.state_assembly,
+                new=assembly.state,
             ),
         )
 
@@ -575,7 +570,7 @@ class AssemblyEditPlacementView(SingleAssemblyTeamMixin, View):
         comment = request.POST.get('comment', '').strip()
 
         old_values = {
-            'state_assembly': assembly.state_assembly,
+            'state': assembly.state,
             'location_point': assembly.get_location_point_xy(),
             'location_boundaries': assembly.get_location_boundaries_xy(),
             'location_floor': assembly.get_location_floor_index(),
@@ -625,23 +620,23 @@ class AssemblyEditPlacementView(SingleAssemblyTeamMixin, View):
         if action == 'publish':
             # if assembly.location_point is not None or assembly.location_boundaries is not None:
             if assembly.location_data.get('point') or assembly.location_data.get('boundaries'):
-                assembly.state_assembly = Assembly.State.PLACED
-                changes['state_assembly'] = assembly.state_assembly
+                assembly.state = Assembly.State.PLACED
+                changes['state'] = assembly.state
             else:
                 messages.warning(request, gettext('assemblyedit_position_missingonpublish'))
                 return redirect('backoffice:assemblyteam-editposition', pk=assembly.pk)
 
         elif action == 'depublish':
             if assembly.is_placed:
-                assembly.state_assembly = Assembly.State.ACCEPTED
-                changes['state_assembly'] = assembly.state_assembly
+                assembly.state = Assembly.State.ACCEPTED
+                changes['state'] = assembly.state
             else:
                 messages.warning(request, gettext('assemblyedit_position_wasnotpublished'))
 
         elif action != 'save':
             messages.warning(request, gettext('assemblyedit_position_unknownaction'))
 
-        assembly.save(update_fields=['state_assembly', 'location_point', 'location_boundaries', 'location_floor', 'location_data'])
+        assembly.save(update_fields=['state', 'location_point', 'location_boundaries', 'location_floor', 'location_data'])
 
         # log the action
         messages.success(request, gettext('assemblyedit_changedposition'))
@@ -663,14 +658,14 @@ class AssemblyEditPlacementView(SingleAssemblyTeamMixin, View):
             **{k: ActivityLogChange(old=old_values[k], new=v) for k, v in changes.items() if old_values[k] != v},
         )
 
-        if assembly.state_assembly != old_values['state_assembly']:
+        if assembly.state != old_values['state']:
             messages.success(request, gettext('assemblyedit_changedstate'))
             logger.info(
                 'Assembly "%(assembly_slug)s" (%(assembly_pk)s): changed state to "%(state)s" upon request by <%(user)s>.',
                 {
                     'assembly_slug': assembly.slug,
                     'assembly_pk': assembly.pk,
-                    'state': assembly.state_assembly,
+                    'state': assembly.state,
                     'user': self.request.user.username,
                 },
             )
diff --git a/src/backoffice/views/channelteam.py b/src/backoffice/views/channelteam.py
deleted file mode 100644
index e8c259fdd23cc9c41e1ace79b024c0fdf5a045bf..0000000000000000000000000000000000000000
--- a/src/backoffice/views/channelteam.py
+++ /dev/null
@@ -1,33 +0,0 @@
-from django.db.models import Q
-from django.utils.translation import gettext_lazy as _
-
-from core.models.assemblies import Assembly
-
-from .assemblyteam import AssembliesListsView, AssembliesView
-
-
-class ChannelsMixin:
-    """sets options that configure the Assemblies views to work in Channels mode"""
-
-    MODES = {
-        'all': (Q(), _('nav_channels_all')),
-        'accepted': (Q(state_channel__in=Assembly.PUBLIC_STATES), _('nav_channels_accepted')),
-        'pending': (Q(state_channel__in=[Assembly.State.REGISTERED]), _('nav_channels_pending')),
-        'planned': (Q(state_channel__in=[Assembly.State.PLANNED]), _('nav_channels_planned')),
-        'rejected': (Q(state_channel__in=[Assembly.State.REJECTED]), _('nav_channels_rejected')),
-        'hidden': (Q(state_channel__in=[Assembly.State.HIDDEN]), _('nav_channels_hidden')),
-    }
-    permission_required = ['core.channel_team']
-    active_page = 'channels'
-    base_view_name = 'backoffice:channels'
-    list_view_name = 'backoffice:channelslist'
-    sidebar_caption = _('nav_channels')
-    status_field = 'state_channel'
-
-
-class ChannelsView(ChannelsMixin, AssembliesView):
-    pass
-
-
-class ChannelsListView(ChannelsMixin, AssembliesListsView):
-    pass
diff --git a/src/backoffice/views/mixins.py b/src/backoffice/views/mixins.py
index 9d2504930ed29426c6b97842dd8c535dee45f8d8..cdc2efa46e166c7015e3966aa56f4827e6a577cc 100644
--- a/src/backoffice/views/mixins.py
+++ b/src/backoffice/views/mixins.py
@@ -70,14 +70,6 @@ class ConferenceRequiredMixin(PermissionRequiredMixin):
     def is_assembly_team(self):
         return self.conferencemember.user.is_authenticated and self.conferencemember.has_perms('core.assembly_team', require_staff=True)
 
-    @property
-    def is_channel_team(self):
-        return (
-            self.conference.support_channels
-            and self.conferencemember.user.is_authenticated
-            and self.conferencemember.has_perms('core.channel_team', require_staff=True)
-        )
-
     def dispatch(self, request, *args, **kwargs):
         if self.require_conference and self.conference is None:
             return redirect('backoffice:conferences')
@@ -108,7 +100,6 @@ class ConferenceRequiredMixin(PermissionRequiredMixin):
                 {
                     'has_sos': self.conferencemember is not None,
                     'has_assemblies': self.is_assembly_team,
-                    'has_channel': self.is_channel_team,
                     'has_pages': self.conferencemember.has_perms('core.static_pages', require_staff=True),
                     'has_map': self.conferencemember.has_perms('core.map_edit', require_staff=True),
                     'has_assembly_registration_admin': self.conferencemember.has_perms('core.assembly_registration_admin', require_staff=True),
@@ -123,7 +114,6 @@ class ConferenceRequiredMixin(PermissionRequiredMixin):
             context.update(
                 {
                     'has_assemblies': False,
-                    'has_channel': False,
                     'has_pages': False,
                     'has_map': False,
                     'has_assembly_registration_admin': False,
@@ -168,12 +158,6 @@ class AssemblyMixin(ConferenceLoginRequiredMixin):
 
         # if _can_manage is set, user can edit assembly. This is a cache variable for the can_manage property
         self._can_manage = None
-        # if _staff_access is set, extra staff fields can be modified (internal comment, is_official)
-        self._staff_access = False
-        # if _assembly_staff_access is set, the field state_assembly can be modified
-        self._assembly_staff_access = False
-        # if _channels_staff_access is set, the field state_channel can be modified
-        self._channels_staff_access = False
 
         # configures the staff warning
         self._staff_mode = False
@@ -185,26 +169,11 @@ class AssemblyMixin(ConferenceLoginRequiredMixin):
         assembly = Assembly.objects.get(conference=self.conference, pk=self.request.resolver_match.kwargs.get(self.assembly_url_param))
 
         # check if it's the assembly team
-        if self.conferencemember.has_perms('core.assembly_team', require_staff=True):
-            self._assembly_staff_access = True
-            self._staff_access = self._staff_access or assembly.state_assembly != Assembly.State.NONE
+        if self.conferencemember.has_perms('core.manage_assembly', require_staff=True):
             self._staff_mode = True
 
-        # check if it's the channel team
-        if self.conferencemember.has_perms('core.channel_team', require_staff=True):
-            self._channels_staff_access = True
-            self._staff_access = self._staff_access or assembly.state_channel != Assembly.State.NONE
-            self._staff_mode = True
-
-        # check if the current user is associated as a contact
-        if assembly.has_user(self.request.user):
-            # don't set self._staff_mode = False here as this would prevent assembly team members to edit their own assemblies
-
-            if not self._staff_access and assembly.state_assembly in [Assembly.State.NONE] and assembly.state_channel in [Assembly.State.NONE]:
-                raise Assembly.DoesNotExist
-
         # neither owner/manager nor assembly team? go away
-        elif not self._assembly_staff_access and not self._channels_staff_access:
+        if not (assembly.has_user(self.request.user) or self._staff_mode):
             raise PermissionDenied
 
         self._assembly = assembly
@@ -226,18 +195,6 @@ class AssemblyMixin(ConferenceLoginRequiredMixin):
 
         return self._can_manage
 
-    @property
-    def staff_access(self):
-        return self._staff_access
-
-    @property
-    def assembly_staff_access(self):
-        return self._assembly_staff_access
-
-    @property
-    def channel_staff_access(self):
-        return self._channels_staff_access
-
     @property
     def staff_mode(self):
         return self._staff_mode
@@ -257,7 +214,6 @@ class AssemblyMixin(ConferenceLoginRequiredMixin):
         context['assembly'] = assembly = self.assembly
 
         context['can_manage'] = can_manage = self.can_manage
-        context['staff_access'] = self.staff_access
         context['staff_mode'] = self.staff_mode
 
         sidebar = []
@@ -268,7 +224,7 @@ class AssemblyMixin(ConferenceLoginRequiredMixin):
             'items': sidebar,
         }
 
-        # load backlink from the session if it set. Set by Assemblyteam / Channelsteam pages as there are a bunch of
+        # load backlink from the session if it set. Set by Assemblyteam pages as there are a bunch of
         # pages that will link to assembly views
         if 'assembly_back' in self.request.session:
             assembly_back = self.request.session['assembly_back']
diff --git a/src/backoffice/views/moderation.py b/src/backoffice/views/moderation.py
index 701fd6cc6563ccb08120051218a4bbc6146ede06..7cf71836cc96343c124aa9655b221bb04e970dd2 100644
--- a/src/backoffice/views/moderation.py
+++ b/src/backoffice/views/moderation.py
@@ -214,7 +214,7 @@ class ModerationAssemblyListView(ModerationAdminMixin, ListView):
     template_name = 'backoffice/moderation_assembly-list.html'
 
     def get_queryset(self):
-        qs = self.conference.assemblies.exclude(state_assembly=Assembly.State.NONE).order_by('slug')
+        qs = self.conference.assemblies.all().order_by('slug')
         return qs
 
 
@@ -222,7 +222,7 @@ class ModerationAssemblyDetailView(ModerationAdminMixin, DetailView):
     template_name = 'backoffice/moderation_assembly-detail.html'
 
     def get_queryset(self):
-        qs = self.conference.assemblies.exclude(state_assembly=Assembly.State.NONE)
+        qs = self.conference.assemblies.all()
         return qs
 
     def post(self, request, *args, **kwargs):
@@ -231,14 +231,11 @@ class ModerationAssemblyDetailView(ModerationAdminMixin, DetailView):
 
         if action == 'hide':
             changes = {}
-            if (prev_state_assembly := assembly.state_assembly) != Assembly.State.NONE:
-                assembly.state_assembly = Assembly.State.HIDDEN
-                changes['state_assembly'] = ActivityLogChange(old=prev_state_assembly, new=Assembly.State.HIDDEN)
-            if (prev_state_channel := assembly.state_channel) != Assembly.State.NONE:
-                assembly.state_channel = Assembly.State.HIDDEN
-                changes['state_channel'] = ActivityLogChange(old=prev_state_channel, new=Assembly.State.HIDDEN)
-
-            assembly.save(update_fields=['state_assembly', 'state_channel'])
+            prev_state = assembly.state
+            assembly.state = Assembly.State.HIDDEN
+            changes['state'] = ActivityLogChange(old=prev_state, new=Assembly.State.HIDDEN)
+
+            assembly.save(update_fields=['state'])
 
             # add log entries
             assembly.log_activity(
diff --git a/src/core/admin.py b/src/core/admin.py
index 48f9442eebb8bb22251b3bece871afa2829eee08..a4e365be5365498fd7ed056fccf9c8dce4d4c9ab 100644
--- a/src/core/admin.py
+++ b/src/core/admin.py
@@ -358,9 +358,9 @@ class ActivityLogEntryInline(GenericTabularInline):
 
 
 class AssemblyAdmin(GISModelAdmin):
-    list_display = ['conference', 'parent', 'slug', 'name', 'state_assembly', 'state_channel', 'is_official']
+    list_display = ['conference', 'parent', 'slug', 'name', 'state', 'is_official']
     list_display_links = ['slug', 'name']
-    list_filter = ['conference', 'parent', 'state_assembly', 'state_channel', 'is_official']
+    list_filter = ['conference', 'parent', 'state', 'is_official']
     readonly_fields = ['id', 'conference']
     search_fields = ['slug', 'name', 'description']
     inlines = [TagsInline, BadgeInline, AssemblyLinkInline, AssemblyMemberInline, ActivityLogEntryInline]
@@ -369,7 +369,7 @@ class AssemblyAdmin(GISModelAdmin):
         (
             'Organisation',
             {
-                'fields': ['id', 'conference', 'state_assembly', 'state_channel', 'hierarchy', 'parent', 'is_official'],
+                'fields': ['id', 'conference', 'state', 'hierarchy', 'parent', 'is_official'],
             },
         ),
         (
@@ -409,7 +409,7 @@ class AssemblyAdmin(GISModelAdmin):
                 (
                     'Organisation',
                     {
-                        'fields': ['id', 'conference', 'state_assembly', 'state_channel', 'hierarchy', 'is_official'],
+                        'fields': ['id', 'conference', 'state', 'hierarchy', 'is_official'],
                     },
                 ),
                 (
diff --git a/src/core/fixtures/anhalter.json b/src/core/fixtures/anhalter.json
index c34a24297f28900fbc29aa553f1fadfcb80a2a09..a6573e617872fe394618ea87c419b0ccfd592e4e 100644
--- a/src/core/fixtures/anhalter.json
+++ b/src/core/fixtures/anhalter.json
@@ -105,7 +105,7 @@
       "name": "Heart of Gold",
       "parent": null,
       "slug": "heart_of_gold",
-      "state_assembly": "confirmed",
+      "state": "confirmed",
       "assembly_link": null,
       "assembly_location": "",
       "is_physical": true,
@@ -121,7 +121,7 @@
       "description": "Wir haben da einen Computer gebaut. Und Planeten.",
       "parent": null,
       "slug": "main",
-      "state_assembly": "accepted",
+      "state": "accepted",
       "assembly_link": null,
       "assembly_location": "",
       "is_physical": true,
@@ -136,7 +136,7 @@
       "name": "Streaming",
       "parent": null,
       "slug": "media",
-      "state_assembly": "accepted",
+      "state": "accepted",
       "assembly_link": "https://streaming.media.ccc.de/",
       "assembly_location": "",
       "is_virtual": true,
@@ -151,7 +151,7 @@
       "name": "BigBlueButton",
       "parent": null,
       "slug": "bbb",
-      "state_assembly": "accepted",
+      "state": "accepted",
       "assembly_link": null,
       "assembly_location": "",
       "is_virtual": true,
diff --git a/src/core/integrations/workadventure.py b/src/core/integrations/workadventure.py
index 094bed765356d0f6fae4d68f81e1cc5d9ea671c9..2e9fdb8ae30b06c48dde0d81faef90faf6106564 100644
--- a/src/core/integrations/workadventure.py
+++ b/src/core/integrations/workadventure.py
@@ -79,7 +79,7 @@ class WorkAdventureIntegration:
         maps = {}
         for room in Room.objects.filter(conference=conference, room_type=Room.RoomType.WORKADVENTURE, blocked=False).select_related('assembly'):
             # skip non-public assemblies
-            if room.assembly is not None and room.assembly.state_assembly not in Assembly.PUBLIC_STATES:
+            if room.assembly is not None and room.assembly.state not in Assembly.PUBLIC_STATES:
                 continue
 
             # skip instances without a non-zero/-empty 'publishedSince' entry
diff --git a/src/core/locale/de/LC_MESSAGES/django.po b/src/core/locale/de/LC_MESSAGES/django.po
index 9ae72d69d8907ae25669e4fa02cca450fcbfb64c..9e15c00789c6c36a759c4e23ee3aae4ccde95311 100644
--- a/src/core/locale/de/LC_MESSAGES/django.po
+++ b/src/core/locale/de/LC_MESSAGES/django.po
@@ -233,8 +233,8 @@ msgstr "gesichtet"
 msgid "Assemblys"
 msgstr "Assemblies"
 
-msgid "Assembly__state-none"
-msgstr "(keine Teilnahme)"
+msgid "Assembly__manage__permission_title"
+msgstr "Kann Assemblies verwalten."
 
 msgid "Assembly__state-planned"
 msgstr "geplant"
@@ -312,18 +312,12 @@ msgstr "zusätzliche JSON-Daten von der Registrierung"
 msgid "Assembly__registration_data"
 msgstr "Registrierungs-Daten"
 
-msgid "Assembly__state_assembly"
+msgid "Assembly__state"
 msgstr "Status (Assembly)"
 
-msgid "Assembly__state_assembly__help"
+msgid "Assembly__state__help"
 msgstr "Status der Assembly (wird vom Assembly-Team gesetzt)"
 
-msgid "Assembly__state_channel"
-msgstr "Status (Channel)"
-
-msgid "Assembly__state_channel__help"
-msgstr "Status des Channels (wird von der Aufnahmeleitung/VOC gesetzt)"
-
 msgid "Assembly__hierarchy__help"
 msgstr "Art der Lokalität/Assemblies: normal vs. Gruppierung (Habitat)"
 
@@ -459,18 +453,6 @@ msgstr "Diese Person kann die Assembly verwalten, d.h. Räume, Veranstaltungen u
 msgid "AssemblyMember__can_manage_assembly"
 msgstr "Verwalter*in"
 
-msgid "AssemblyMember__is_content_coordinator__help"
-msgstr "Das Content-Team der Assembly hat eine primäre Ansprechperson für die anderen Content-Teams bzw. die Aufnahmeleitung."
-
-msgid "AssemblyMember__is_content_coordinator"
-msgstr "Content-Koordinator"
-
-msgid "AssemblyMember__is_production_coordinator__help"
-msgstr "primäre Ansprechperson für die technische Produktion des Vortragsprogramm das aus der Assembly versendet wird, kommuniziert mit VOC MCR / CDN"
-
-msgid "AssemblyMember__is_production_coordinator"
-msgstr "Produktions-Koordinator"
-
 msgid "AssemblyMember__is_technical_contact__help"
 msgstr "Ansprechperson für technische Fragen der Vor-Ort-Assembly, z.B. Strom und Netzwerk"
 
@@ -640,7 +622,7 @@ msgstr "Wenn du eine neue Badge akzeptierst wird sie standardmäßig mit dieser
 msgid "ConferenceMember__default_badge_visibility"
 msgstr "Sichtbarkeit neuer Badges"
 
-msgid "ConferenceMember__permission-confernece_admin"
+msgid "ConferenceMember__permission-conference_admin"
 msgstr "Konferenz-Admin: Kann die Veröffentlichungszeitpunkte der Konferenz verwalten"
 
 msgid "ConferenceMember__permission-assembly_team"
@@ -649,9 +631,6 @@ msgstr "Assembly-Team: alle Assemblies verwaltbar, auch noch nicht fertig angele
 msgid "ConferenceMember__permission-assembly_registration_admin"
 msgstr "Registrierungs-Admin: Verwalten der Registrierungsinformationen für Assemblies"
 
-msgid "ConferenceMember__permission-channel_team"
-msgstr "Channel-Team: alle Assemblies verwaltbar, auch noch nicht fertig angelegte und abgelehnte sind sichtbar"
-
 msgid "ConferenceMember__permission-static_pages"
 msgstr "Statische Seiten: Verwaltung von Info-Seiten"
 
@@ -805,12 +784,6 @@ msgstr "erlaube Assemblies an entfernten Standorten (ergänzt Orts-Angabe)"
 msgid "Conference__support_assembly_remote"
 msgstr "entf. Assemblies"
 
-msgid "Conference__support_channels__help"
-msgstr "Unterstützung für Channel/Bühnen (analog zu Assemblies)"
-
-msgid "Conference__support_channels"
-msgstr "Channels"
-
 msgid "Conference__mail_footer__help"
 msgstr "Text, welcher am Ende einer Nachricht angehängt wird (z.B. in E-Mails)"
 
@@ -1118,6 +1091,35 @@ msgstr "Kann Assembly Veranstaltungen verwalten."
 msgid "Event__kind__must_be_assembly"
 msgstr "Veranstaltungs-Art muss Assembly Veranstaltung sein"
 
+msgid "Official Event"
+msgstr ""
+
+msgid "Official Events"
+msgstr ""
+
+#, fuzzy
+#| msgid "AssemblyEvent__manage__permission_title"
+msgid "OfficialEvent__manage__permission_title"
+msgstr "Kann Assembly Veranstaltungen verwalten."
+
+#, fuzzy
+#| msgid "Event__kind__must_be_sos"
+msgid "Event__kind__must_be_official"
+msgstr "Veranstaltungs-Art muss Self Organized-Session sein"
+
+msgid "Lightning Talk"
+msgstr ""
+
+#, fuzzy
+#| msgid "SoS__manage__permission_title"
+msgid "LightningTalk__manage__permission_title"
+msgstr "Kann Self-Organized Sessions verwalten."
+
+#, fuzzy
+#| msgid "Event__kind-lightning"
+msgid "Event__kind__must_be_lightning"
+msgstr "Lightning Talk"
+
 msgid "Self-Organized Session"
 msgstr "Self-Organized Session"
 
@@ -2317,9 +2319,6 @@ msgstr "URL"
 msgid "Voucher__target-assembly"
 msgstr "Assembly"
 
-msgid "Voucher__target-channel"
-msgstr "Channel"
-
 msgid "Voucher__target-user"
 msgstr "Nutzer"
 
diff --git a/src/core/locale/en/LC_MESSAGES/django.po b/src/core/locale/en/LC_MESSAGES/django.po
index 8c9fb51dff563b83db5446f3ada513eb2a2542e8..6105d0db1e0733b6876eae2746e751d12af7891e 100644
--- a/src/core/locale/en/LC_MESSAGES/django.po
+++ b/src/core/locale/en/LC_MESSAGES/django.po
@@ -233,8 +233,8 @@ msgstr "patrolled"
 msgid "Assemblys"
 msgstr "Assemblies"
 
-msgid "Assembly__state-none"
-msgstr "(no participation)"
+msgid "Assembly__manage__permission_title"
+msgstr "Can manage assemblies."
 
 msgid "Assembly__state-planned"
 msgstr "planned"
@@ -312,18 +312,12 @@ msgstr "additional JSON data from registration"
 msgid "Assembly__registration_data"
 msgstr "registration data"
 
-msgid "Assembly__state_assembly"
+msgid "Assembly__state"
 msgstr "state (assembly)"
 
-msgid "Assembly__state_assembly__help"
+msgid "Assembly__state__help"
 msgstr "state of this assembly (set by the assemblies team)"
 
-msgid "Assembly__state_channel"
-msgstr "state (channel)"
-
-msgid "Assembly__state_channel__help"
-msgstr "state of this channel (set by the Aufnahmeleitung)"
-
 msgid "Assembly__hierarchy__help"
 msgstr "hierarchical type of this assembly - regular vs. grouped/habitat"
 
@@ -459,18 +453,6 @@ msgstr "This person may manage the assembly, i.e. create/edit/delete rooms, even
 msgid "AssemblyMember__can_manage_assembly"
 msgstr "Manager"
 
-msgid "AssemblyMember__is_content_coordinator__help"
-msgstr "This person is primary contact for other content teams or Aufnahmeleitung."
-
-msgid "AssemblyMember__is_content_coordinator"
-msgstr "Content Coordinator"
-
-msgid "AssemblyMember__is_production_coordinator__help"
-msgstr "primary contact for technical content production of this assembly, communicates with VOC MCR / CDN"
-
-msgid "AssemblyMember__is_production_coordinator"
-msgstr "Production Coordinator"
-
 msgid "AssemblyMember__is_technical_contact__help"
 msgstr "This person is able to clarify technical questions of the on-site assembly regarding e.g. power and network."
 
@@ -640,7 +622,7 @@ msgstr " When you accept a new badge, it will be displayed with this visibility
 msgid "ConferenceMember__default_badge_visibility"
 msgstr "visibility of new badges"
 
-msgid "ConferenceMember__permission-confernece_admin"
+msgid "ConferenceMember__permission-conference_admin"
 msgstr "Conference admin: can manage the conference's publication times"
 
 msgid "ConferenceMember__permission-assembly_team"
@@ -649,9 +631,6 @@ msgstr "assemblies team: manage all assemblies, see also incomplete and rejected
 msgid "ConferenceMember__permission-assembly_registration_admin"
 msgstr "Registration-Admin: Manage registration information for assemblies"
 
-msgid "ConferenceMember__permission-channel_team"
-msgstr "channel team: manage all assemblies, see also incomplete and rejected registrations"
-
 msgid "ConferenceMember__permission-static_pages"
 msgstr "static pages: manage information pages"
 
@@ -805,12 +784,6 @@ msgstr "support assemblies at remote physical locations (adds location field)"
 msgid "Conference__support_assembly_remote"
 msgstr "remote assemblies"
 
-msgid "Conference__support_channels__help"
-msgstr "support channels/stages management (analog to assemblies)"
-
-msgid "Conference__support_channels"
-msgstr "channels"
-
 msgid "Conference__mail_footer__help"
 msgstr "text which is appended to messages sent via this conference (e.g. in emails)"
 
@@ -1118,6 +1091,35 @@ msgstr "Can manage assembly events."
 msgid "Event__kind__must_be_assembly"
 msgstr "Event type must be assembly event"
 
+msgid "Official Event"
+msgstr ""
+
+msgid "Official Events"
+msgstr ""
+
+#, fuzzy
+#| msgid "AssemblyEvent__manage__permission_title"
+msgid "OfficialEvent__manage__permission_title"
+msgstr "Can manage assembly events."
+
+#, fuzzy
+#| msgid "Event__kind__must_be_sos"
+msgid "Event__kind__must_be_official"
+msgstr "Event type must be self-organized session"
+
+msgid "Lightning Talk"
+msgstr ""
+
+#, fuzzy
+#| msgid "SoS__manage__permission_title"
+msgid "LightningTalk__manage__permission_title"
+msgstr "Can manage self-organized sessions."
+
+#, fuzzy
+#| msgid "Event__kind-lightning"
+msgid "Event__kind__must_be_lightning"
+msgstr "lightning talk"
+
 msgid "Self-Organized Session"
 msgstr "self-organized session"
 
@@ -2315,9 +2317,6 @@ msgstr "URL"
 msgid "Voucher__target-assembly"
 msgstr "assembly"
 
-msgid "Voucher__target-channel"
-msgstr "channel"
-
 msgid "Voucher__target-user"
 msgstr "user"
 
diff --git a/src/core/management/commands/create_conference.py b/src/core/management/commands/create_conference.py
index 56fdba9ca4c72721ab9bd764c2ed0e83ae4d25bc..6882a8de11c13e2c6bf290dc723a3b636b56df81 100644
--- a/src/core/management/commands/create_conference.py
+++ b/src/core/management/commands/create_conference.py
@@ -104,8 +104,7 @@ def seed_conference(conf: Conference, year: int = 0):
         slug='sos',
         name='Self Organized Sessions',
         is_official=True,
-        state_assembly=Assembly.State.HIDDEN,
-        state_channel=Assembly.State.NONE,
+        state=Assembly.State.HIDDEN,
     )
 
     # create navigation (top level)
@@ -358,6 +357,7 @@ def seed_conference(conf: Conference, year: int = 0):
         description_en='Category for badges that are awarded for provided support',
     )
 
+
 def _validate_date(s: str) -> datetime:
     try:
         return datetime.strptime(s, '%Y')  # noqa: DTZ007
diff --git a/src/core/management/commands/sanitize_database.py b/src/core/management/commands/sanitize_database.py
index 0b56489e4ad3ec4ccf8b78426d1ab96aab279d57..91f77ec30d9c7788f2b7e5383b242109aa1d76d0 100644
--- a/src/core/management/commands/sanitize_database.py
+++ b/src/core/management/commands/sanitize_database.py
@@ -47,7 +47,7 @@ class Command(BaseCommand):
         print_delete_stat(AssemblyMember.objects.all().delete())
 
         print('Assembly(non-public/non-accepted)')
-        non_public_assemblies = Assembly.objects.exclude(state_assembly__in=Assembly.PUBLIC_STATES).exclude(state_channel__in=Assembly.PUBLIC_STATES)
+        non_public_assemblies = Assembly.objects.exclude(state__in=Assembly.PUBLIC_STATES)
         print('  events: ', end='', flush=True)
         print_delete_stat(Event.objects.filter(assembly__in=non_public_assemblies).delete())
         print('  assemblies: ', end='', flush=True)
diff --git a/src/core/migrations/0159_alter_conferencemember_options_and_more.py b/src/core/migrations/0159_alter_conferencemember_options_and_more.py
new file mode 100644
index 0000000000000000000000000000000000000000..4f12cbeb7a698b5d6d86f68cd0cadc9244353d6f
--- /dev/null
+++ b/src/core/migrations/0159_alter_conferencemember_options_and_more.py
@@ -0,0 +1,92 @@
+# Generated by Django 5.1.2 on 2024-11-07 01:27
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("core", "0158_alter_assembly_options"),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name="conferencemember",
+            options={
+                "permissions": [
+                    (
+                        "conference_admin",
+                        "ConferenceMember__permission-conference_admin",
+                    ),
+                    ("assembly_team", "ConferenceMember__permission-assembly_team"),
+                    (
+                        "assembly_registration_admin",
+                        "ConferenceMember__permission-assembly_registration_admin",
+                    ),
+                    ("static_pages", "ConferenceMember__permission-static_pages"),
+                    ("map_edit", "ConferenceMember__permission-map_edit"),
+                    ("moderation", "Orga: Moderation"),
+                    ("voucher_admin", "ConferenceMember__permission-voucher_admin"),
+                    ("scheduleadmin", "ConferenceMember__permission-scheduleadmin"),
+                    (
+                        "workadventure_admin",
+                        "ConferenceMember__permission-workadventure_admin",
+                    ),
+                ]
+            },
+        ),
+        migrations.RenameField(
+            model_name="assembly",
+            old_name="state_assembly",
+            new_name="state",
+        ),
+        migrations.AlterField(
+            model_name="assembly",
+            name="state",
+            field=models.CharField(
+                choices=[
+                    ("planned", "Assembly__state-planned"),
+                    ("registered", "Assembly__state-registered"),
+                    ("hidden", "Assembly__state-hidden"),
+                    ("accepted", "Assembly__state-accepted"),
+                    ("rejected", "Assembly__state-rejected"),
+                    ("placed", "Assembly__state-placed"),
+                    ("arrived", "Assembly__state-arrived_self"),
+                    ("confirmed", "Assembly__state-arrived_confirmed"),
+                ],
+                default="planned",
+                help_text="Assembly__state__help",
+                max_length=20,
+                verbose_name="Assembly__state",
+            ),
+        ),
+        migrations.RemoveField(
+            model_name="assembly",
+            name="state_channel",
+        ),
+        migrations.RemoveField(
+            model_name="assemblymember",
+            name="is_content_coordinator",
+        ),
+        migrations.RemoveField(
+            model_name="assemblymember",
+            name="is_production_coordinator",
+        ),
+        migrations.RemoveField(
+            model_name="conference",
+            name="support_channels",
+        ),
+        migrations.AlterField(
+            model_name="voucher",
+            name="target",
+            field=models.CharField(
+                choices=[
+                    ("assembly", "Voucher__target-assembly"),
+                    ("user", "Voucher__target-user"),
+                ],
+                help_text="Voucher__target__help",
+                max_length=20,
+                verbose_name="Voucher__target",
+            ),
+        ),
+    ]
diff --git a/src/core/models/assemblies.py b/src/core/models/assemblies.py
index a2e0fa7ca967d180b818c130ffecd7dff3b60fd2..a597cd9fb5235c76aaea652caabb37e2db8aae7f 100644
--- a/src/core/models/assemblies.py
+++ b/src/core/models/assemblies.py
@@ -10,7 +10,7 @@ from django.contrib.contenttypes.fields import GenericRelation
 from django.contrib.gis.db import models as gis_models
 from django.core.exceptions import ValidationError
 from django.db import models
-from django.db.models import Q, QuerySet
+from django.db.models import QuerySet
 from django.template.loader import render_to_string
 from django.utils.functional import cached_property
 from django.utils.html import escape as html_escape
@@ -37,15 +37,10 @@ class AssemblyQuerySet(ConferenceQuerySet['Assembly']):
     assembly_filter = 'self'
 
     def filter_to_public_objects(self, member: ConferenceMember | None = None) -> 'ConferenceQuerySet[Assembly]':
-        return self.filter(Q(state_assembly__in=self.model.PUBLIC_STATES) | Q(state_channel__in=self.model.PUBLIC_STATES))
+        return self.filter(state__in=self.model.PUBLIC_STATES)
 
     def filter_to_associated_objects(self, member: ConferenceMember, *, only_manageable: bool) -> 'ConferenceQuerySet[Assembly]':
-        return self.filter(members__member=member.user).exclude(
-            Q(
-                state_assembly__in=[Assembly.State.NONE, Assembly.State.HIDDEN],
-                state_channel__in=[Assembly.State.NONE, Assembly.State.HIDDEN],
-            )
-        )
+        return self.filter(members__member=member.user).exclude(state__in=[Assembly.State.HIDDEN])
 
 
 def get_banner_file_name(instance: 'Assembly', filename: str):
@@ -64,7 +59,6 @@ class Assembly(TaggedItemMixin, ActivityLogMixin, models.Model):
         ]
 
     class State(models.TextChoices):
-        NONE = 'none', _('Assembly__state-none')
         PLANNED = 'planned', _('Assembly__state-planned')
         REGISTERED = 'registered', _('Assembly__state-registered')
         HIDDEN = 'hidden', _('Assembly__state-hidden')
@@ -127,11 +121,8 @@ class Assembly(TaggedItemMixin, ActivityLogMixin, models.Model):
 
     registration_data = models.JSONField(blank=True, null=True, help_text=_('Assembly__registration_data__help'), verbose_name=_('Assembly__registration_data'))
 
-    state_assembly = models.CharField(
-        max_length=20, default=State.NONE, choices=State.choices, verbose_name=_('Assembly__state_assembly'), help_text=_('Assembly__state_assembly__help')
-    )
-    state_channel = models.CharField(
-        max_length=20, default=State.NONE, choices=State.choices, verbose_name=_('Assembly__state_channel'), help_text=_('Assembly__state_channel__help')
+    state = models.CharField(
+        max_length=20, default=State.PLANNED, choices=State.choices, verbose_name=_('Assembly__state'), help_text=_('Assembly__state__help')
     )
 
     hierarchy = models.CharField(
@@ -272,7 +263,7 @@ class Assembly(TaggedItemMixin, ActivityLogMixin, models.Model):
         set_physical = self.conference.support_assembly_physical and self.is_physical
         set_virtual = self.conference.support_assembly_virtual and self.is_virtual
         set_remote = self.conference.support_assembly_remote and self.is_remote
-        if self.state_assembly in self.PUBLIC_STATES and not (set_physical or set_virtual or set_remote):
+        if self.state in self.PUBLIC_STATES and not (set_physical or set_virtual or set_remote):
             x = _('Assembly__need_type')
             if self.conference.support_assembly_physical:
                 errors['is_physical'] = x
@@ -309,29 +300,13 @@ class Assembly(TaggedItemMixin, ActivityLogMixin, models.Model):
 
         return mark_safe(escaped)
 
-    @property
-    def is_assembly(self):
-        return self.state_assembly != self.State.NONE
-
-    @property
-    def is_channel(self):
-        return self.state_channel != self.State.NONE
-
     @cached_property
     def is_public(self):
-        return self.state_assembly in self.PUBLIC_STATES or self.state_channel in self.PUBLIC_STATES
+        return self.state in self.PUBLIC_STATES
 
     @cached_property
     def is_placed(self):
-        return self.state_assembly in self.PLACED_STATES or self.state_channel in self.PLACED_STATES
-
-    @cached_property
-    def is_public_assembly(self):
-        return self.state_assembly in self.PUBLIC_STATES
-
-    @cached_property
-    def is_public_channel(self):
-        return self.state_channel in self.PUBLIC_STATES
+        return self.state in self.PLACED_STATES
 
     @cached_property
     def is_cluster(self):
@@ -347,7 +322,7 @@ class Assembly(TaggedItemMixin, ActivityLogMixin, models.Model):
 
     @property
     def public_children(self):
-        return Assembly.objects.filter(parent=self).filter(state_assembly__in=Assembly.PUBLIC_STATES).order_by('name')
+        return Assembly.objects.filter(parent=self).filter(state__in=Assembly.PUBLIC_STATES).order_by('name')
 
     @property
     def linked_assemblies(self):
@@ -357,11 +332,7 @@ class Assembly(TaggedItemMixin, ActivityLogMixin, models.Model):
 
     @property
     def basedata_readonly(self):
-        return self.state_assembly not in [Assembly.State.NONE, Assembly.State.PLANNED, Assembly.State.REGISTERED] or self.state_channel not in [
-            Assembly.State.NONE,
-            Assembly.State.PLANNED,
-            Assembly.State.REGISTERED,
-        ]
+        return self.state not in [Assembly.State.PLANNED, Assembly.State.REGISTERED]
 
     def get_all_orga_contacts(self):
         return PlatformUser.objects.filter(pk__in=self.members.filter(is_representative=True).values_list('member_id', flat=True))
@@ -401,7 +372,7 @@ class Assembly(TaggedItemMixin, ActivityLogMixin, models.Model):
         if not user.is_authenticated:
             return False
 
-        if staff_can_manage and user.has_conference_staff_permission(self.conference, 'core.assembly_team', 'core.channel_team'):
+        if staff_can_manage and user.has_conference_staff_permission(self.conference, 'core.assembly_team'):
             return True
 
         return self.members.filter(member=user, can_manage_assembly=True).exists()
@@ -574,18 +545,6 @@ class AssemblyMember(models.Model):
         verbose_name=_('AssemblyMember__can_manage_assembly'),
     )
 
-    is_content_coordinator = models.BooleanField(
-        default=False,
-        help_text=_('AssemblyMember__is_content_coordinator__help'),
-        verbose_name=_('AssemblyMember__is_content_coordinator'),
-    )
-
-    is_production_coordinator = models.BooleanField(
-        default=False,
-        help_text=_('AssemblyMember__is_production_coordinator__help'),
-        verbose_name=_('AssemblyMember__is_production_coordinator'),
-    )
-
     is_technical_contact = models.BooleanField(
         default=False,
         help_text=_('AssemblyMember__is_technical_contact__help'),
@@ -600,10 +559,6 @@ class AssemblyMember(models.Model):
             yield 'representative'
         if self.can_manage_assembly:
             yield 'manager'
-        if self.is_content_coordinator:
-            yield 'content_coordinator'
-        if self.is_production_coordinator:
-            yield 'production_coordinator'
         if self.is_technical_contact:
             yield 'technical_contact'
 
@@ -613,10 +568,6 @@ class AssemblyMember(models.Model):
             res.append(gettext('AssemblyMember__is_representative__help'))
         if self.can_manage_assembly:
             res.append(gettext('AssemblyMember__can_manage_assembly'))
-        if self.is_content_coordinator:
-            res.append(gettext('AssemblyMember__is_content_coordinator'))
-        if self.is_production_coordinator:
-            res.append(gettext('AssemblyMember__is_production_coordinator'))
         if self.is_technical_contact:
             res.append(gettext('AssemblyMember__is_technical_contact'))
         return ', '.join(res)
diff --git a/src/core/models/base_managers.py b/src/core/models/base_managers.py
index 7463848f84b1ff3534dacd28ad3dc1ee56973986..a0b46d82e71f718ee2f861615cd2be6bb3002da6 100644
--- a/src/core/models/base_managers.py
+++ b/src/core/models/base_managers.py
@@ -79,7 +79,7 @@ class ConferenceManagerMixin(models.Manager, Generic[_ModelType]):
 
         allowed_members = AssemblyMember.objects.filter(member=member.user)
         allowed_members = allowed_members.filter(can_manage_assembly=True) if only_manageable else allowed_members
-        queryset = queryset.filter(**{f'{prefix}members__in': allowed_members}).exclude(**{f'{prefix}state_assembly__in': [Assembly.State.HIDDEN]})
+        queryset = queryset.filter(**{f'{prefix}members__in': allowed_members}).exclude(**{f'{prefix}state__in': [Assembly.State.HIDDEN]})
         return queryset
 
     def apply_self_organized_rights_filter(
diff --git a/src/core/models/base_queryset.py b/src/core/models/base_queryset.py
index f199213363589014dcaa80a75102432cedefa7ab..1ad0873efe68a80574d7321dcd3769b92c9923a0 100644
--- a/src/core/models/base_queryset.py
+++ b/src/core/models/base_queryset.py
@@ -79,7 +79,7 @@ class ConferenceQuerySet(QuerySet, Generic[_ModelType]):
         allowed_members = AssemblyMember.objects.filter(member=member.user)
         if only_manageable:
             allowed_members = allowed_members.filter(can_manage_assembly=True)
-        return self.filter(**{f'{prefix}members__in': allowed_members}).exclude(**{f'{prefix}state_assembly__in': [Assembly.State.HIDDEN]})
+        return self.filter(**{f'{prefix}members__in': allowed_members}).exclude(**{f'{prefix}state__in': [Assembly.State.HIDDEN]})
 
     def filter_to_associated_objects(self, member: ConferenceMember, *, only_manageable: bool) -> 'ConferenceQuerySet[_ModelType]':
         """Returns a queryset of objects that the member can manage.
diff --git a/src/core/models/conference.py b/src/core/models/conference.py
index 51b231760532cb529ba542e60f97246885b0d474..ca2682515ba885d29fc6f9dda189ce20da0a3155 100644
--- a/src/core/models/conference.py
+++ b/src/core/models/conference.py
@@ -78,14 +78,12 @@ class ConferenceMember(models.Model):
 
     class Meta:
         permissions = [
-            ('conference_admin', _('ConferenceMember__permission-confernece_admin')),
+            ('conference_admin', _('ConferenceMember__permission-conference_admin')),
             # Change conference settings (e.g., dates, ), update venue json.
             ('assembly_team', _('ConferenceMember__permission-assembly_team')),
             # See all assemblies, not only the accepted ones.
             ('assembly_registration_admin', _('ConferenceMember__permission-assembly_registration_admin')),
-            # See all assemblies, not only the accepted ones.
-            ('channel_team', _('ConferenceMember__permission-channel_team')),
-            # Channelteam, Assemblyteam for Channel-Type Assemblies (Assemblies that provide their own content)
+            # Manage the registration dates for assemblies.
             ('static_pages', _('ConferenceMember__permission-static_pages')),
             # Access to static pages, can be further limited by configuring static_page_groups.
             ('map_edit', _('ConferenceMember__permission-map_edit')),
@@ -325,12 +323,6 @@ class Conference(models.Model):
         verbose_name=_('Conference__support_assembly_remote'),
     )
 
-    support_channels = models.BooleanField(
-        default=False,
-        help_text=_('Conference__support_channels__help'),
-        verbose_name=_('Conference__support_channels'),
-    )
-
     mail_footer = models.TextField(
         blank=True,
         null=True,
diff --git a/src/core/models/events.py b/src/core/models/events.py
index 73e9b61674984a159b7fd9f36c49ae751e25f984..79d21032a3b4f56f58c83be2936c67a9690c666d 100644
--- a/src/core/models/events.py
+++ b/src/core/models/events.py
@@ -624,9 +624,7 @@ class Event(TaggedItemMixin, BackendMixin, ActivityLogMixin, models.Model):
 
 class AssemblyEventQuerySetMixin(ConferenceQuerySet[_ModelType]):
     def filter_to_public_objects(self, member: ConferenceMember | None = None) -> ConferenceQuerySet[_ModelType]:
-        return self.filter(Q(assembly__state_assembly__in=Assembly.PUBLIC_STATES) | Q(assembly__state_channel__in=Assembly.PUBLIC_STATES)).filter(
-            is_public=True
-        )
+        return self.filter(assembly__state__in=Assembly.PUBLIC_STATES, is_public=True)
 
 
 class AssemblyEventQuerySet(AssemblyEventQuerySetMixin['AssemblyEvent']):
diff --git a/src/core/models/rooms.py b/src/core/models/rooms.py
index 2a1e393205b428293052c90cf5e0517b60b69b90..5fba203967dc45fa99a3afdb0e4e49dacc69f6ce 100644
--- a/src/core/models/rooms.py
+++ b/src/core/models/rooms.py
@@ -44,9 +44,7 @@ class RoomManager(ConferenceManagerMixin['Room']):
     assembly_filter = 'assembly'
 
     def apply_public_filter(self, queryset: 'QuerySet[Room]', member: ConferenceMember | None = None) -> 'QuerySet[Room]':
-        return queryset.filter(blocked=False).filter(
-            Q(assembly__state_assembly__in=Assembly.PUBLIC_STATES) | Q(assembly__state_channel__in=Assembly.PUBLIC_STATES)
-        )
+        return queryset.filter(blocked=False).filter(assembly__state__in=Assembly.PUBLIC_STATES)
 
     def assignable_in_timeframe(self, conference: Conference, start: datetime, end: datetime, assembly: Optional[Assembly] = None, is_sos: bool = False):
         """
diff --git a/src/core/models/voucher.py b/src/core/models/voucher.py
index b6f437a5091627b4d4738aff6e01d9d45bd846a3..98ef02fb4a64778e24e60235d8a97aafa23469bf 100644
--- a/src/core/models/voucher.py
+++ b/src/core/models/voucher.py
@@ -28,17 +28,7 @@ class VoucherManager(models.Manager):
         assert assembly is not None
 
         # pre-filter on enabled vouchers in the assembly's conference
-        qs = self.get_queryset().filter(conference=assembly.conference, enabled=True)
-
-        # filter on the correct target type
-        if assembly.is_assembly and assembly.is_channel:
-            qs = qs.filter(target__in=Voucher.ASSEMBLY_TARGETS)
-        elif assembly.is_assembly:
-            qs = qs.filter(target=Voucher.Target.ASSEMBLY)
-        elif assembly.is_channel:
-            qs = qs.filter(target=Voucher.Target.CHANNEL)
-        else:
-            return qs.none()
+        qs = self.get_queryset().filter(conference=assembly.conference, enabled=True).filter(target=Voucher.Target.ASSEMBLY)
 
         # select vouchers which shall always be shown or ones assigned to the assembly
         associated_voucher_ids = VoucherEntry.objects.filter(assigned_assembly=assembly).distinct('voucher_id').values_list('voucher_id', flat=True)
@@ -77,9 +67,6 @@ class Voucher(models.Model):
         ASSEMBLY = 'assembly', _('Voucher__target-assembly')
         """This voucher is for assemblies."""
 
-        CHANNEL = 'channel', _('Voucher__target-channel')
-        """This voucher is for channels."""
-
         USER = 'user', _('Voucher__target-user')
         """This voucher is for an user."""
 
@@ -116,8 +103,6 @@ class Voucher(models.Model):
     objects = VoucherManager()
     logger = logging.getLogger(__name__)
 
-    ASSEMBLY_TARGETS = [Target.ASSEMBLY, Target.CHANNEL]
-
     def __str__(self):
         return self.name
 
@@ -137,7 +122,7 @@ class Voucher(models.Model):
     def do_auto_assignments(cls, conference: Conference = None, assemblies: List[Assembly] | None = None) -> int:
         qs = cls.objects.filter(conference=conference) if conference is not None else cls.objects.all()
         qs = qs.filter(enabled=True)
-        qs = qs.filter(target__in=Voucher.ASSEMBLY_TARGETS)
+        qs = qs.filter(target=Voucher.Target.ASSEMBLY)
 
         total = 0
         for voucher in qs.iterator():
@@ -150,14 +135,14 @@ class Voucher(models.Model):
         return total
 
     def do_auto_assignment(self, assemblies: List[Assembly]) -> int:
-        if self.target not in self.ASSEMBLY_TARGETS:
-            raise NotImplementedError('Auto-Assignment of non assemblies/channels not implemented yet.')
+        if self.target != self.Target.ASSEMBLY:
+            raise NotImplementedError('Auto-Assignment of non assemblies not implemented yet.')
 
         # nothing to do if we're not enabled or set to manual assignment
         if (not self.enabled) or self.assignment == self.Assignment.MANUAL:
             return 0
 
-        # work on all conference assemblies (and channels) if no list is provided
+        # work on all conference assemblies if no list is provided
         if assemblies is None:
             if self.assignment == self.Assignment.ON_PUBLIC:
                 assemblies = self.conference.assemblies.conference_accessible(self.conference)
@@ -176,11 +161,9 @@ class Voucher(models.Model):
         # iterate over all missing assignments
         total = 0
         for assembly in missing_assignments:
-            # skip non-public assembly/channel if auto-assignment is for public ones only
+            # skip non-public assembly if auto-assignment is for public ones only
             if self.assignment == self.Assignment.ON_PUBLIC:
-                if (self.target == self.Target.ASSEMBLY and not assembly.is_public_assembly) or (
-                    self.target == self.Target.CHANNEL and not assembly.is_public_channel
-                ):
+                if self.target == self.Target.ASSEMBLY and not assembly.is_public:
                     continue
 
             # abort (but warn) if no more available entries are available
@@ -214,7 +197,7 @@ class VoucherEntry(models.Model):
 
     @cached_property
     def target(self):
-        if self.voucher.target in Voucher.ASSEMBLY_TARGETS:
+        if self.voucher.target == Voucher.Target.ASSEMBLY:
             return self.assigned_assembly
 
         if self.voucher.target == Voucher.Target.USER:
@@ -233,7 +216,7 @@ class VoucherEntry(models.Model):
 
         else:
             # assembly assigned without a timestamp?
-            if self.voucher.target in Voucher.ASSEMBLY_TARGETS and self.assigned_assembly is not None:
+            if self.voucher.target == Voucher.Target.ASSEMBLY and self.assigned_assembly is not None:
                 self.assigned = timezone.now()
             else:
                 self.assigned_assembly = None
@@ -258,20 +241,13 @@ class VoucherEntry(models.Model):
         if self.assigned is not None or self.assigned_assembly is not None or self.assigned_user is not None:
             raise ValidationError(_('VoucherEntry__already_assigned'))
 
-        if self.voucher.target in Voucher.ASSEMBLY_TARGETS:
+        if self.voucher.target == Voucher.Target.ASSEMBLY:
             if not isinstance(target, Assembly):
-                raise ValueError("VoucherEntry's target must be an assembly or channel.")
+                raise ValueError("VoucherEntry's target must be an assembly.")
 
             if target.conference_id != self.voucher.conference_id:
                 raise ValueError('Voucher and assembly must be in the same conference!')
 
-            if self.voucher.target == Voucher.Target.ASSEMBLY:
-                if not target.is_assembly:
-                    raise ValueError("VoucherEntry's target must be an assembly.")
-            if self.voucher.target == Voucher.Target.CHANNEL:
-                if not target.is_channel:
-                    raise ValueError("VoucherEntry's target must be a channel.")
-
             self.assigned = timezone.now()
             self.assigned_assembly = target
             self.assigned_user = None
diff --git a/src/core/models/workadventure.py b/src/core/models/workadventure.py
index 3a3a1d46ddf4e10dc5df4757826aa54b1a73fca8..6088b10893b1432cc8b2d41e85aa277e5bdecfba 100644
--- a/src/core/models/workadventure.py
+++ b/src/core/models/workadventure.py
@@ -117,7 +117,7 @@ class WorkadventureSession(models.Model):
                 self.conference,
                 user=self.user,
             )
-            .filter(state_assembly__in=Assembly.PUBLIC_STATES)
+            .filter(state__in=Assembly.PUBLIC_STATES)
             .values_list('slug', flat=True)
         ):
             user_tags.add('assembly_' + slug)
diff --git a/src/core/tests/rooms.py b/src/core/tests/rooms.py
index 87c2fa9a3d431d7a5a4d092e63b607e2e3b0bbe5..cfb7994b404b69920c7ffb6b703873b42c51f7be 100644
--- a/src/core/tests/rooms.py
+++ b/src/core/tests/rooms.py
@@ -13,13 +13,13 @@ class RoomTests(TestCase):
         self.conference = Conference(slug='foo', name='Foo Conference', start=now() - timedelta(days=1), end=now() + timedelta(days=1))
         self.conference.save()
 
-        self.assembly1 = Assembly(conference=self.conference, slug='fnord', name='Fnord Assembly', state_assembly=Assembly.State.ACCEPTED, is_official=True)
+        self.assembly1 = Assembly(conference=self.conference, slug='fnord', name='Fnord Assembly', state=Assembly.State.ACCEPTED, is_official=True)
         self.assembly1.save()
-        self.assembly2 = Assembly(conference=self.conference, slug='banana', name='Obstgarten', state_assembly=Assembly.State.ARRIVED_CONFIRMED)
+        self.assembly2 = Assembly(conference=self.conference, slug='banana', name='Obstgarten', state=Assembly.State.ARRIVED_CONFIRMED)
         self.assembly2.save()
-        self.assembly3 = Assembly(conference=self.conference, slug='third', name='3. Rad', state_assembly=Assembly.State.ACCEPTED)
+        self.assembly3 = Assembly(conference=self.conference, slug='third', name='3. Rad', state=Assembly.State.ACCEPTED)
         self.assembly3.save()
-        self.assembly4 = Assembly(conference=self.conference, slug='gone', name='never shown', state_assembly=Assembly.State.HIDDEN)
+        self.assembly4 = Assembly(conference=self.conference, slug='gone', name='never shown', state=Assembly.State.HIDDEN)
         self.assembly4.save()
 
         self.room1a = Room(conference=self.conference, assembly=self.assembly1, room_type=Room.RoomType.LECTURE_HALL, name='1a')
diff --git a/src/core/tests/schedules.py b/src/core/tests/schedules.py
index 1fea3d274003d35b78a6ce27cb01873c7abf597e..b6b6fa78bc8f8862fd8bd966d83ff0e2da677c53 100644
--- a/src/core/tests/schedules.py
+++ b/src/core/tests/schedules.py
@@ -213,7 +213,7 @@ class ScheduleTests(TestCase):
             conference=self.conference,
             name='CCC',
             is_official=True,
-            state_assembly=Assembly.State.ACCEPTED,
+            state=Assembly.State.ACCEPTED,
         )
         r2 = a2.rooms.create(
             conference=self.conference,
@@ -331,7 +331,7 @@ class ScheduleTests(TestCase):
             end=datetime(2023, 12, 31, 15, 00, 0, tzinfo=timezone.utc),
         )
         self.conference.save()
-        self.assembly = Assembly(name='CCC', slug='ccc', conference=self.conference, state_assembly=Assembly.State.PLACED)
+        self.assembly = Assembly(name='CCC', slug='ccc', conference=self.conference, state=Assembly.State.PLACED)
         self.assembly.save()
 
         src = ScheduleSource.objects.create(
diff --git a/src/core/tests/vouchers.py b/src/core/tests/vouchers.py
index c598820be882e28a639d015078dbf4df71c5ac00..ebd18f2451123851c713e6b15ba84a6120ff0d7b 100644
--- a/src/core/tests/vouchers.py
+++ b/src/core/tests/vouchers.py
@@ -33,7 +33,7 @@ class VoucherTests(TestCase):
         self.guest.save()
 
         self.assembly = Assembly(conference=self.conference, slug='fnord', name='Fnord Assembly')
-        self.assembly.state_assembly = Assembly.State.ACCEPTED
+        self.assembly.state = Assembly.State.ACCEPTED
         self.assembly.save()
 
     def testBasics(self):
@@ -148,13 +148,13 @@ class VoucherTests(TestCase):
         self.assertEqual(entry.target, self.assembly)
 
         # setup a second assembly which is not 'public' yet
-        a2 = self.conference.assemblies.create(slug='second', name='test2', state_assembly=Assembly.State.REGISTERED)
+        a2 = self.conference.assemblies.create(slug='second', name='test2', state=Assembly.State.REGISTERED)
 
         # try auto-assignment again, should have no effect (assignment=ON_PUBLIC, only one public assembly which is already assigned)
         self.assertEqual(0, self.doAutoAssignment())
 
         # set assembly public, should trigger a warning as we don't have a free entry available
-        a2.state_assembly = Assembly.State.ACCEPTED
+        a2.state = Assembly.State.ACCEPTED
         a2.save()
         self.assertEqual(0, self.doAutoAssignment(expected_warnings=1))
 
diff --git a/src/core/tests/workadventure.py b/src/core/tests/workadventure.py
index fd6eb43b4088a113c4d28487532d5a3ca02d95e7..6d6b8ab9339433c27856d6c9ddad4d922ab0b93d 100644
--- a/src/core/tests/workadventure.py
+++ b/src/core/tests/workadventure.py
@@ -9,7 +9,7 @@ class WorkadventureSessionTests(TestCase):
     def setUp(self):
         self.conference = Conference(slug='test', name='Test Conference')
         self.conference.save()
-        self.assembly = self.conference.assemblies.create(slug='fnord', state_assembly=Assembly.State.ACCEPTED)
+        self.assembly = self.conference.assemblies.create(slug='fnord', state=Assembly.State.ACCEPTED)
         self.room = self.assembly.rooms.create(conference=self.conference, room_type=Room.RoomType.WORKADVENTURE, slug='fnord')
         self.user = PlatformUser(username='bernd')
         self.user.save()
diff --git a/src/plainui/tests/test_views.py b/src/plainui/tests/test_views.py
index 0fe5b37e36cebf5a549be6e1745160de762594d9..a4afb81d7ea4fe55ffdeb9e5f76b6d40f4181487 100644
--- a/src/plainui/tests/test_views.py
+++ b/src/plainui/tests/test_views.py
@@ -216,7 +216,7 @@ class ViewsTestBase(TestCase):
 class ViewsTest(ViewsTestBase):
     @override_locale('en')
     def test_EventView(self):
-        assembly = Assembly(conference=self.conf, name='DUMMY', slug='dummy', state_assembly=Assembly.State.ACCEPTED, is_official=True)
+        assembly = Assembly(conference=self.conf, name='DUMMY', slug='dummy', state=Assembly.State.ACCEPTED, is_official=True)
         assembly.save()
 
         tag = ConferenceTag(conference=self.conf, slug='test_tag', is_public=True, value_type='simple')
@@ -260,9 +260,9 @@ class ViewsTest(ViewsTestBase):
 
     @override_locale('en')
     def test_TagView(self):
-        assembly1 = Assembly(conference=self.conf, slug='d', name='DUMMY', state_assembly=Assembly.State.ACCEPTED)
+        assembly1 = Assembly(conference=self.conf, slug='d', name='DUMMY', state=Assembly.State.ACCEPTED)
         assembly1.save()
-        assembly2 = Assembly(conference=self.conf, slug='2', name='2nd', state_assembly=Assembly.State.ACCEPTED)
+        assembly2 = Assembly(conference=self.conf, slug='2', name='2nd', state=Assembly.State.ACCEPTED)
         assembly2.save()
 
         tag = ConferenceTag(conference=self.conf, slug='test_tag', is_public=True, value_type='simple')
@@ -305,7 +305,7 @@ class ViewsTest(ViewsTestBase):
         speaker2.save()
         member1 = PlatformUser(username='member1')
         member1.save()
-        assembly = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state_assembly=Assembly.State.PLACED)
+        assembly = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state=Assembly.State.PLACED)
         assembly.save()
         AssemblyMember(member=speaker1, is_representative=True, can_manage_assembly=True, show_public=True, assembly=assembly).save()
         AssemblyMember(member=speaker2, is_representative=True, can_manage_assembly=True, show_public=False, assembly=assembly).save()
@@ -375,7 +375,7 @@ class ViewsTest(ViewsTestBase):
         resp = self.client.get(reverse('plainui:assembly', kwargs={'assembly_slug': assembly.slug}))
         self.assertTrue(resp.context_data['is_favorite'])
 
-        sos_assembly = Assembly(conference=self.conf, slug='sos_assembly', name='SOS Assembly', state_assembly=Assembly.State.PLACED)
+        sos_assembly = Assembly(conference=self.conf, slug='sos_assembly', name='SOS Assembly', state=Assembly.State.PLACED)
         sos_assembly.save()
 
         # redirects to the sos page when accessing the sos assembly as the existence of the assembly page caused some confusion
@@ -386,7 +386,7 @@ class ViewsTest(ViewsTestBase):
 
     @override_locale('en')
     def test_AssembliesView(self):
-        assembly = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state_assembly=Assembly.State.PLACED)
+        assembly = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state=Assembly.State.PLACED)
         assembly.save()
 
         self.assertNeedsLogin(reverse('plainui:assemblies'))
@@ -396,7 +396,7 @@ class ViewsTest(ViewsTestBase):
 
     @override_locale('en')
     def test_AssembliesAllView(self):
-        assembly = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state_assembly=Assembly.State.PLACED)
+        assembly = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state=Assembly.State.PLACED)
         assembly.save()
 
         self.assertNeedsLogin(reverse('plainui:assemblies_all'))
@@ -406,7 +406,7 @@ class ViewsTest(ViewsTestBase):
 
     @override_locale('en')
     def test_AssembliesEventsView(self):
-        assembly = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state_assembly=Assembly.State.PLACED)
+        assembly = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state=Assembly.State.PLACED)
         assembly.save()
         room = Room(conference=self.conf, assembly=assembly, name='Some Room')
         room.save()
@@ -1174,7 +1174,7 @@ class ViewsTest(ViewsTestBase):
 
     @override_locale('en')
     def test_SearchView_post(self):
-        assembly = Assembly(conference=self.conf, slug='assembly1', name='asdf', state_assembly=Assembly.State.PLACED)
+        assembly = Assembly(conference=self.conf, slug='assembly1', name='asdf', state=Assembly.State.PLACED)
         assembly.save()
         event = Event(
             conference=self.conf,
@@ -1212,7 +1212,7 @@ class ViewsTest(ViewsTestBase):
 
     @override_locale('en')
     def test_ProfileView_get(self):
-        assembly = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state_assembly=Assembly.State.PLACED)
+        assembly = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state=Assembly.State.PLACED)
         assembly.save()
         event = Event(
             conference=self.conf,
@@ -1267,7 +1267,7 @@ class ViewsTest(ViewsTestBase):
     @override_locale('en')
     @patch('modeltranslation.settings.AVAILABLE_LANGUAGES', ['en', 'de'])
     def test_ProfileView_post(self):
-        assembly = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state_assembly=Assembly.State.PLACED)
+        assembly = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state=Assembly.State.PLACED)
         assembly.save()
         event = Event(
             conference=self.conf,
@@ -1690,9 +1690,9 @@ class ViewsTest(ViewsTestBase):
 
     @override_locale('en')
     def test_ModifyFavoritesView_post(self):
-        assembly1 = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state_assembly=Assembly.State.PLACED)
+        assembly1 = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state=Assembly.State.PLACED)
         assembly1.save()
-        assembly2 = Assembly(conference=self.conf, slug='assembly2', name='Assembly2', state_assembly=Assembly.State.PLACED)
+        assembly2 = Assembly(conference=self.conf, slug='assembly2', name='Assembly2', state=Assembly.State.PLACED)
         assembly2.save()
         event1 = Event(
             conference=self.conf,
@@ -2005,7 +2005,7 @@ class ViewsTest(ViewsTestBase):
         self.user.timezone = 'UTC'
         self.user.save()
 
-        assembly = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state_assembly=Assembly.State.PLACED)
+        assembly = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state=Assembly.State.PLACED)
         assembly.save()
         room = Room(conference=self.conf, assembly=assembly, name='Some Room', is_public_fahrplan=True)
         room.save()
@@ -2100,7 +2100,7 @@ class ViewsTest(ViewsTestBase):
         self.conf.end = datetime(2020, 1, 3, 0, 0, 0, tzinfo=UTC)
         self.conf.save()
 
-        assembly = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state_assembly=Assembly.State.PLACED)
+        assembly = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state=Assembly.State.PLACED)
         assembly.save()
         room = Room(conference=self.conf, assembly=assembly, name='Some Room', is_public_fahrplan=True)
         room.save()
@@ -2156,7 +2156,7 @@ class ViewsTest(ViewsTestBase):
         self.conf.end = now + timedelta(days=3)
         self.conf.save()
 
-        assembly = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state_assembly=Assembly.State.PLACED)
+        assembly = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state=Assembly.State.PLACED)
         assembly.save()
         room = Room(conference=self.conf, assembly=assembly, name='Room1')
         room.save()
@@ -2175,7 +2175,7 @@ class ViewsTest(ViewsTestBase):
         self.conf.end = now + timedelta(days=3)
         self.conf.save()
 
-        assembly = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state_assembly=Assembly.State.PLACED)
+        assembly = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state=Assembly.State.PLACED)
         assembly.save()
         room = Room(conference=self.conf, assembly=assembly, name='Room1')
         room.save()
@@ -2194,7 +2194,7 @@ class ViewsTest(ViewsTestBase):
         self.conf.end = now + timedelta(days=3)
         self.conf.save()
 
-        assembly = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state_assembly=Assembly.State.PLACED)
+        assembly = Assembly(conference=self.conf, slug='assembly1', name='Assembly1', state=Assembly.State.PLACED)
         assembly.save()
         room = Room(conference=self.conf, assembly=assembly, name='Some Room')
         room.save()
@@ -2254,7 +2254,7 @@ class ViewsTest(ViewsTestBase):
     @freeze_time(datetime(2020, 1, 1, 1, 0, 0, tzinfo=UTC))
     @override_locale('en')
     def test_ChannelEventsView(self):
-        assembly = Assembly(conference=self.conf, slug='official', name='Official Assembly', state_assembly=Assembly.State.PLACED, is_official=True)
+        assembly = Assembly(conference=self.conf, slug='official', name='Official Assembly', state=Assembly.State.PLACED, is_official=True)
         assembly.save()
         room1 = Room(conference=self.conf, assembly=assembly, name='Stream1', is_official=True)
         room1.save()
@@ -2346,7 +2346,7 @@ class ViewsTest(ViewsTestBase):
     @override_settings(WORKADVENTURE_LOBBY_ROOM_SLUG='lobby')
     @override_locale('en')
     def test_WorkadventureEnter(self):
-        assembly = Assembly(conference=self.conf, slug='official', name='Official Assembly', state_assembly=Assembly.State.PLACED, is_official=True)
+        assembly = Assembly(conference=self.conf, slug='official', name='Official Assembly', state=Assembly.State.PLACED, is_official=True)
         assembly.save()
         lobby_room = Room(conference=self.conf, assembly=assembly, slug='lobby', room_type=Room.RoomType.WORKADVENTURE)
         lobby_room.save()