diff --git a/common_lib/schema/enums.py b/common_lib/schema/enums.py
index 76b374e933bc421a72c81930ddc995df8155a70c..4131ed284ef49be68c0d063e04a5e44bc46209bf 100644
--- a/common_lib/schema/enums.py
+++ b/common_lib/schema/enums.py
@@ -1,4 +1,5 @@
 import graphene
+from django.db import models
 
 from exercise.models import TeamQuestionnaireState
 from running_exercise.models import LogType
@@ -7,3 +8,21 @@ from user.models import User
 QuestionnaireStateEnum = graphene.Enum.from_enum(TeamQuestionnaireState.Status)
 GroupEnum = graphene.Enum.from_enum(User.AuthGroup)
 LogTypeEnum = graphene.Enum.from_enum(LogType)
+
+
+class ExerciseEventTypeEnum(models.TextChoices):
+    CREATE = "create"
+    MODIFY = "modify"
+    DELETE = "delete"
+
+    @staticmethod
+    def create() -> "ExerciseEventTypeEnum":
+        return ExerciseEventTypeEnum(ExerciseEventTypeEnum.CREATE)
+
+    @staticmethod
+    def modify() -> "ExerciseEventTypeEnum":
+        return ExerciseEventTypeEnum(ExerciseEventTypeEnum.MODIFY)
+
+    @staticmethod
+    def delete() -> "ExerciseEventTypeEnum":
+        return ExerciseEventTypeEnum(ExerciseEventTypeEnum.DELETE)
diff --git a/common_lib/schema/types.py b/common_lib/schema/types.py
index 0c5dec793b8ca764611433f65a2e5fac79da89be..df7b7c657916f5946856a0abda0591fff144160c 100644
--- a/common_lib/schema/types.py
+++ b/common_lib/schema/types.py
@@ -1,15 +1,11 @@
-from typing import Any
-
 import graphene
-from django.db import models
 from graphene_django import DjangoObjectType
 
 from common_lib.schema.enums import (
     GroupEnum,
-    LogTypeEnum,
     QuestionnaireStateEnum,
+    LogTypeEnum,
 )
-from common_lib.schema.simple_types import Simple
 from exercise.models import (
     Exercise,
     Team,
@@ -28,6 +24,7 @@ from exercise_definition.models import (
     Inject,
     Response,
     FileInfo,
+    Role,
     Content,
     Control,
     Channel,
@@ -41,78 +38,75 @@ from running_exercise.models import (
     ActionLog,
     EmailThread,
     Email,
+    ThreadParticipant,
     ToolDetails,
     InjectDetails,
     CustomInjectDetails,
     QuestionnaireAnswer,
-    ThreadParticipant,
 )
-from user.models import InstructorOfExercise, User, Tag
+from user.models import User, Tag, InstructorOfExercise
 
 
-def select_by_group(user: User, all: Any, some: Any) -> Any:
-    if user.group >= User.AuthGroup.INSTRUCTOR:
-        return all
-    return some
+class RestrictedUser(DjangoObjectType):
+    class Meta:
+        model = User
+        exclude = ("definitions", "exercises", "teams", "password")
+
+    group = graphene.Field(GroupEnum)
+
+
+class RestrictedExercise(DjangoObjectType):
+    id = graphene.ID(source="id")
+    uuid = graphene.UUID(source="uuid")
+
+    class Meta:
+        model = Exercise
+        fields = ()
+
+
+class RestrictedTeam(DjangoObjectType):
+    class Meta:
+        model = Team
+        fields = ("id", "exercise", "name", "role", "email_address")
+
+
+class ExerciseDefinitionType(graphene.ObjectType):
+    id = graphene.Int()
+    name = graphene.String()
 
 
 class ToolType(DjangoObjectType):
     class Meta:
         model = Tool
+        exclude = ["responses"]
 
-    definition = graphene.Field(Simple.DefinitionType, required=True)
+    definition = graphene.Field(ExerciseDefinitionType)
 
 
 class DefinitionType(DjangoObjectType):
     class Meta:
         model = Definition
+        exclude = ["milestones"]
 
-    files = graphene.List(graphene.NonNull(Simple.FileInfoType), required=True)
-    learning_objectives = graphene.List(
-        graphene.NonNull(Simple.LearningObjectiveType),
-        required=True,
-    )
-    addresses = graphene.List(
-        graphene.NonNull(Simple.EmailAddressType), required=True
-    )
-    injects = graphene.List(
-        graphene.NonNull(Simple.DefinitionInjectType), required=True
-    )
-    tools = graphene.List(graphene.NonNull(Simple.ToolType), required=True)
-    roles = graphene.List(
-        graphene.NonNull(Simple.DefinitionRoleType), required=True
-    )
-    channels = graphene.List(
-        graphene.NonNull(Simple.DefinitionChannelType), required=True
-    )
-    questionnaires = graphene.List(
-        graphene.NonNull(Simple.QuestionnaireType), required=True
-    )
-    exercises = graphene.List(
-        graphene.NonNull(Simple.ExerciseType), required=True
-    )
-    user_set = graphene.List(graphene.NonNull(Simple.UserType), required=True)
+    tools = graphene.List(graphene.NonNull(ToolType), required=True)
+    user_set = graphene.List(RestrictedUser)
 
     def resolve_user_set(self, info):
         return self.user_set.all()
 
 
+class DefinitionRoleType(DjangoObjectType):
+    class Meta:
+        model = Role
+
+
 class ExerciseType(DjangoObjectType):
     class Meta:
         model = Exercise
 
-    definition = graphene.Field(Simple.DefinitionType)
-    teams = graphene.List(graphene.NonNull(Simple.TeamType), required=True)
-    email_participants = graphene.List(
-        graphene.NonNull(Simple.EmailParticipantType), required=True
-    )
-    user_set = graphene.List(graphene.NonNull(Simple.UserType), required=True)
-    threads = graphene.List(
-        graphene.NonNull(Simple.EmailThreadType), required=True
-    )
-
-    def resolve_definition(self, info):
-        return select_by_group(info.context.user, self.definition, None)
+    # change the definition field type to hide some definition fields
+    definition = graphene.Field(ExerciseDefinitionType)
+    user_set = graphene.List(RestrictedUser)
 
     def resolve_teams(self, info):
         user = info.context.user
@@ -128,43 +122,21 @@ class ExerciseType(DjangoObjectType):
         # trainee or instructor assigned to specific team
         return self.teams.filter(users__user=user)
 
-    def resolve_email_participants(self, info):
-        return select_by_group(
-            info.context.user,
-            self.email_participants.all(),
-            self.email_participants.filter(
-                team__in=info.context.user.teams.all()
-            ),
-        )
-
     def resolve_user_set(self, info):
-        return select_by_group(
-            info.context.user, self.user_set.all(), User.objects.none()
-        )
-
-    def resolve_threads(self, info):
-        return select_by_group(
-            info.context.user,
-            self.threads.all(),
-            self.threads.filter(
-                participants__team__in=info.context.user.teams.all()
-            ),
-        )
+        if info.context.user.group == User.AuthGroup.TRAINEE:
+            return User.objects.none()
+        return self.user_set.all()
 
 
 class TeamType(DjangoObjectType):
     class Meta:
         model = Team
 
-    exercise = graphene.Field(Simple.ExerciseType, required=True)
-    email_address = graphene.Field(Simple.EmailAddressType, required=True)
-    team_questionnaire_states = graphene.List(
-        graphene.NonNull(Simple.TeamQuestionnaireStateType), required=True
-    )
-    logs = graphene.List(graphene.NonNull(Simple.ActionLogType), required=True)
-    user_set = graphene.List(graphene.NonNull(Simple.UserType), required=True)
+    user_set = graphene.List(RestrictedUser)
 
     def resolve_user_set(self, info):
+        if info.context.user.group == User.AuthGroup.TRAINEE:
+            return User.objects.none()
         return self.user_set.all()
 
 
@@ -172,8 +144,6 @@ class ContentType(DjangoObjectType):
     class Meta:
         model = Content
 
-    file_info = graphene.Field(Simple.FileInfoType, required=True)
-
 
 class ControlType(DjangoObjectType):
     class Meta:
@@ -189,53 +159,45 @@ class ToolDetailsType(DjangoObjectType):
     class Meta:
         model = ToolDetails
 
-    tool = graphene.Field(Simple.ToolType, required=True)
-    content = graphene.Field(ContentType, required=True)
-    user = graphene.Field(Simple.UserType)
+    user = graphene.Field(RestrictedUser)
+    tool = graphene.Field(ToolType, required=True)
 
 
 class InjectDetailsType(DjangoObjectType):
     class Meta:
         model = InjectDetails
 
-    inject = graphene.Field(Simple.DefinitionInjectType, required=True)
-
 
 class CustomInjectDetailsType(DjangoObjectType):
     class Meta:
         model = CustomInjectDetails
 
-    user = graphene.Field(Simple.UserType)
+    user = graphene.Field(RestrictedUser)
 
 
 class EmailType(DjangoObjectType):
     class Meta:
         model = Email
 
-    thread = graphene.Field(Simple.EmailThreadType, required=True)
-    sender = graphene.Field(Simple.EmailParticipantType, required=True)
-    user = graphene.Field(Simple.UserType)
+    user = graphene.Field(RestrictedUser)
 
 
 class QuestionType(DjangoObjectType):
     class Meta:
         model = Question
 
-    questionnaire = graphene.Field(Simple.QuestionnaireType, required=True)
-
     def resolve_correct(self, info):
-        return select_by_group(info.context.user, self.correct, 0)
+        user = info.context.user
+
+        if user.group == User.AuthGroup.TRAINEE:
+            return 0
+        return self.correct
 
 
 class QuestionnaireType(DjangoObjectType):
     class Meta:
         model = Questionnaire
 
-    definition = graphene.Field(Simple.DefinitionType, required=True)
-    team_questionnaire_states = graphene.List(
-        graphene.NonNull(Simple.TeamQuestionnaireStateType), required=True
-    )
-
 
 class ActionLogDetails(graphene.Union):
     class Meta:
@@ -253,112 +215,88 @@ class ActionLogType(DjangoObjectType):
         model = ActionLog
         exclude = ["details_id"]
 
-    team = graphene.Field(Simple.TeamType, required=True)
-    channel = graphene.Field(Simple.DefinitionChannelType, required=True)
-    type = graphene.Field(LogTypeEnum, required=True)
     details = graphene.Field(ActionLogDetails, required=True)
+    type = graphene.Field(LogTypeEnum, required=True)
 
 
 class MilestoneType(DjangoObjectType):
     class Meta:
         model = Milestone
-
-    definition = graphene.Field(Simple.DefinitionType, required=True)
-    milestone_states = graphene.List(
-        graphene.NonNull(Simple.MilestoneStateType), required=True
-    )
-    activity = graphene.Field(Simple.LearningActivityType, required=True)
+        exclude = ["milestone_states", "definition"]
 
 
 class MilestoneStateType(DjangoObjectType):
     class Meta:
         model = MilestoneState
 
-    milestone = graphene.Field(MilestoneType, required=True)
-    activity = graphene.Field(Simple.TeamLearningActivityType, required=True)
-    team_ids = graphene.List(graphene.NonNull(graphene.ID), required=True)
+    team_ids = graphene.List(graphene.ID)
 
     def resolve_team_ids(self, info):
         return [team.id for team in self.team_state.teams.all()]
 
 
-class ThreadParticipantType(DjangoObjectType):
-    class Meta:
-        model = ThreadParticipant
-
-
 class EmailThreadType(DjangoObjectType):
     class Meta:
         model = EmailThread
 
-    participants = graphene.List(
-        graphene.NonNull(Simple.EmailParticipantType), required=True
-    )
-    exercise = graphene.Field(Simple.ExerciseType, required=True)
-    emails = graphene.List(graphene.NonNull(EmailType), required=True)
     last_email = graphene.Field(EmailType, required=False)
 
-    def resolve_participants(self, info):
-        return self.participants.all()
-
     def resolve_last_email(self, info):
         return self.emails.order_by("timestamp").last()
 
 
+class ExtendedToolType(DjangoObjectType):
+    class Meta:
+        model = Tool
+
+    definition = graphene.Field(ExerciseDefinitionType)
+
+
 class ToolResponseType(DjangoObjectType):
     class Meta:
         model = Response
 
-    tool = graphene.Field(Simple.ToolType, required=True)
-
 
 class EmailAddressType(DjangoObjectType):
     class Meta:
         model = EmailAddress
 
-    definition = graphene.Field(Simple.DefinitionType, required=True)
+    definition = graphene.Field(ExerciseDefinitionType)
 
 
 class EmailTemplateType(DjangoObjectType):
     class Meta:
         model = EmailTemplate
+        exclude = ["email_address"]
 
     sender = graphene.String()
-    email_address = graphene.Field(Simple.EmailAddressType, required=True)
 
     def resolve_sender(self, info):
         return self.email_address.address
 
 
+class ThreadParticipantType(DjangoObjectType):
+    class Meta:
+        model = ThreadParticipant
+
+
 class EmailParticipantType(DjangoObjectType):
     class Meta:
         model = EmailParticipant
 
-    exercise = graphene.Field(Simple.ExerciseType, required=True)
-    definition_address = graphene.Field(Simple.EmailAddressType)
-    team = graphene.Field(Simple.TeamType)
-    threads = graphene.List(
-        graphene.NonNull(Simple.EmailThreadType), required=True
-    )
-    emails = graphene.List(graphene.NonNull(Simple.EmailType), required=True)
-
 
 class DefinitionInjectType(DjangoObjectType):
     class Meta:
         model = Inject
-        exclude = ["alternatives"]
-
-    definition = graphene.Field(Simple.DefinitionType, required=True)
+        exclude = ["definition", "alternatives"]
 
 
 class FileInfoType(DjangoObjectType):
     class Meta:
         model = FileInfo
 
-    definition = graphene.Field(Simple.DefinitionType, required=True)
-
 
-class ExerciseConfigType(graphene.ObjectType):
+class GrapheneConfig(graphene.ObjectType):
     exercise_duration = graphene.Int()
     email_between_teams = graphene.Boolean()
     show_exercise_time = graphene.Boolean()
@@ -367,19 +305,15 @@ class ExerciseConfigType(graphene.ObjectType):
 
 
 class UserType(DjangoObjectType):
+    definitions = graphene.List(ExerciseDefinitionType)
+    exercises = graphene.List(RestrictedExercise)
+    teams = graphene.List(RestrictedTeam)
+    group = graphene.Field(GroupEnum)
+
     class Meta:
         model = User
         exclude = ["password"]
 
-    definitions = graphene.List(
-        graphene.NonNull(Simple.DefinitionType), required=True
-    )
-    exercises = graphene.List(
-        graphene.NonNull(Simple.ExerciseType), required=True
-    )
-    teams = graphene.List(graphene.NonNull(Simple.TeamType), required=True)
-    group = graphene.Field(GroupEnum, required=True)
-
     def resolve_definitions(self, info):
         return self.definitions.all()
 
@@ -393,95 +327,60 @@ class UserType(DjangoObjectType):
 class TagType(DjangoObjectType):
     class Meta:
         model = Tag
-        exclude_fields = ["user_set"]
-
-
-class ExerciseEventTypeEnum(models.TextChoices):
-    CREATE = "create"
-    MODIFY = "modify"
-    DELETE = "delete"
-
-    @staticmethod
-    def create() -> "ExerciseEventTypeEnum":
-        return ExerciseEventTypeEnum(ExerciseEventTypeEnum.CREATE)
-
-    @staticmethod
-    def modify() -> "ExerciseEventTypeEnum":
-        return ExerciseEventTypeEnum(ExerciseEventTypeEnum.MODIFY)
-
-    @staticmethod
-    def delete() -> "ExerciseEventTypeEnum":
-        return ExerciseEventTypeEnum(ExerciseEventTypeEnum.DELETE)
+        exclude_fields = ("user_set",)
 
 
 class DefinitionChannelType(DjangoObjectType):
     class Meta:
         model = Channel
 
-    definition = graphene.Field(Simple.DefinitionType, required=True)
+
+class TeamQuestionnaireStateType(DjangoObjectType):
+    class Meta:
+        model = TeamQuestionnaireState
+
+    status = graphene.Field(QuestionnaireStateEnum)
 
 
 class QuestionnaireAnswerType(DjangoObjectType):
     class Meta:
         model = QuestionnaireAnswer
 
-    team_questionnaire_state = graphene.Field(
-        Simple.TeamQuestionnaireStateType, required=True
-    )
-
     def resolve_is_correct(self, info):
-        return select_by_group(info.context.user, self.is_correct, None)
-
-
-class TeamQuestionnaireStateType(DjangoObjectType):
-    class Meta:
-        model = TeamQuestionnaireState
+        user = info.context.user
+        if user.is_anonymous:
+            return self.is_correct
 
-    status = graphene.Field(QuestionnaireStateEnum, required=True)
-    team = graphene.Field(Simple.TeamType, required=True)
-    questionnaire = graphene.Field(Simple.QuestionnaireType, required=True)
-    answers = graphene.List(
-        graphene.NonNull(QuestionnaireAnswerType), required=True
-    )
+        if user.group == User.AuthGroup.TRAINEE:
+            return None
+        return self.is_correct
 
 
 class LearningObjectiveType(DjangoObjectType):
     class Meta:
         model = LearningObjective
 
-    definition = graphene.Field(Simple.DefinitionType, required=True)
-
 
 class LearningActivityType(DjangoObjectType):
     class Meta:
         model = LearningActivity
 
-    objective = graphene.Field(Simple.LearningObjectiveType, required=True)
-
 
 class TeamLearningObjectiveType(DjangoObjectType):
+    reached = graphene.Boolean()
+
     class Meta:
         model = TeamLearningObjective
 
-    objective = graphene.Field(Simple.LearningObjectiveType, required=True)
-    reached = graphene.Boolean()
-
     def resolve_reached(self, info):
         return self.reached()
 
 
 class TeamLearningActivityType(DjangoObjectType):
+    reached = graphene.Boolean()
+
     class Meta:
         model = TeamLearningActivity
 
-    team_objective = graphene.Field(
-        Simple.TeamLearningObjectiveType, required=True
-    )
-    activity = graphene.Field(Simple.LearningActivityType, required=True)
-    milestone_states = graphene.List(
-        graphene.NonNull(Simple.MilestoneStateType), required=True
-    )
-    reached = graphene.Boolean()
-
     def resolve_reached(self, info):
         return self.reached()
diff --git a/common_lib/schema/types_new.py b/common_lib/schema/types_new.py
new file mode 100644
index 0000000000000000000000000000000000000000..0c5dec793b8ca764611433f65a2e5fac79da89be
--- /dev/null
+++ b/common_lib/schema/types_new.py
@@ -0,0 +1,487 @@
+from typing import Any
+
+import graphene
+from django.db import models
+from graphene_django import DjangoObjectType
+
+from common_lib.schema.enums import (
+    GroupEnum,
+    LogTypeEnum,
+    QuestionnaireStateEnum,
+)
+from common_lib.schema.simple_types import Simple
+from exercise.models import (
+    Exercise,
+    Team,
+    MilestoneState,
+    EmailParticipant,
+    TeamQuestionnaireState,
+    TeamLearningObjective,
+    TeamLearningActivity,
+)
+from exercise_definition.models import (
+    Milestone,
+    Definition,
+    Tool,
+    EmailAddress,
+    EmailTemplate,
+    Inject,
+    Response,
+    FileInfo,
+    Content,
+    Control,
+    Channel,
+    Overlay,
+    Questionnaire,
+    Question,
+    LearningObjective,
+    LearningActivity,
+)
+from running_exercise.models import (
+    ActionLog,
+    EmailThread,
+    Email,
+    ToolDetails,
+    InjectDetails,
+    CustomInjectDetails,
+    QuestionnaireAnswer,
+    ThreadParticipant,
+)
+from user.models import InstructorOfExercise, User, Tag
+
+
+def select_by_group(user: User, all: Any, some: Any) -> Any:
+    if user.group >= User.AuthGroup.INSTRUCTOR:
+        return all
+    return some
+
+
+class ToolType(DjangoObjectType):
+    class Meta:
+        model = Tool
+
+    definition = graphene.Field(Simple.DefinitionType, required=True)
+
+
+class DefinitionType(DjangoObjectType):
+    class Meta:
+        model = Definition
+
+    files = graphene.List(graphene.NonNull(Simple.FileInfoType), required=True)
+    learning_objectives = graphene.List(
+        graphene.NonNull(Simple.LearningObjectiveType),
+        required=True,
+    )
+    addresses = graphene.List(
+        graphene.NonNull(Simple.EmailAddressType), required=True
+    )
+    injects = graphene.List(
+        graphene.NonNull(Simple.DefinitionInjectType), required=True
+    )
+    tools = graphene.List(graphene.NonNull(Simple.ToolType), required=True)
+    roles = graphene.List(
+        graphene.NonNull(Simple.DefinitionRoleType), required=True
+    )
+    channels = graphene.List(
+        graphene.NonNull(Simple.DefinitionChannelType), required=True
+    )
+    questionnaires = graphene.List(
+        graphene.NonNull(Simple.QuestionnaireType), required=True
+    )
+    exercises = graphene.List(
+        graphene.NonNull(Simple.ExerciseType), required=True
+    )
+    user_set = graphene.List(graphene.NonNull(Simple.UserType), required=True)
+
+    def resolve_user_set(self, info):
+        return self.user_set.all()
+
+
+class ExerciseType(DjangoObjectType):
+    class Meta:
+        model = Exercise
+
+    definition = graphene.Field(Simple.DefinitionType)
+    teams = graphene.List(graphene.NonNull(Simple.TeamType), required=True)
+    email_participants = graphene.List(
+        graphene.NonNull(Simple.EmailParticipantType), required=True
+    )
+    user_set = graphene.List(graphene.NonNull(Simple.UserType), required=True)
+    threads = graphene.List(
+        graphene.NonNull(Simple.EmailThreadType), required=True
+    )
+
+    def resolve_definition(self, info):
+        return select_by_group(info.context.user, self.definition, None)
+
+    def resolve_teams(self, info):
+        user = info.context.user
+        if user.group == User.AuthGroup.ADMIN:
+            return self.teams.all()
+        if (
+            user.group == User.AuthGroup.INSTRUCTOR
+            and InstructorOfExercise.objects.filter(
+                exercise=self, user=user
+            ).exists()
+        ):  # Instructor is assigned as an instructor of the exercise
+            return self.teams.all()
+        # trainee or instructor assigned to specific team
+        return self.teams.filter(users__user=user)
+
+    def resolve_email_participants(self, info):
+        return select_by_group(
+            info.context.user,
+            self.email_participants.all(),
+            self.email_participants.filter(
+                team__in=info.context.user.teams.all()
+            ),
+        )
+
+    def resolve_user_set(self, info):
+        return select_by_group(
+            info.context.user, self.user_set.all(), User.objects.none()
+        )
+
+    def resolve_threads(self, info):
+        return select_by_group(
+            info.context.user,
+            self.threads.all(),
+            self.threads.filter(
+                participants__team__in=info.context.user.teams.all()
+            ),
+        )
+
+
+class TeamType(DjangoObjectType):
+    class Meta:
+        model = Team
+
+    exercise = graphene.Field(Simple.ExerciseType, required=True)
+    email_address = graphene.Field(Simple.EmailAddressType, required=True)
+    team_questionnaire_states = graphene.List(
+        graphene.NonNull(Simple.TeamQuestionnaireStateType), required=True
+    )
+    logs = graphene.List(graphene.NonNull(Simple.ActionLogType), required=True)
+    user_set = graphene.List(graphene.NonNull(Simple.UserType), required=True)
+
+    def resolve_user_set(self, info):
+        return self.user_set.all()
+
+
+class ContentType(DjangoObjectType):
+    class Meta:
+        model = Content
+
+    file_info = graphene.Field(Simple.FileInfoType, required=True)
+
+
+class ControlType(DjangoObjectType):
+    class Meta:
+        model = Control
+
+
+class OverlayType(DjangoObjectType):
+    class Meta:
+        model = Overlay
+
+
+class ToolDetailsType(DjangoObjectType):
+    class Meta:
+        model = ToolDetails
+
+    tool = graphene.Field(Simple.ToolType, required=True)
+    content = graphene.Field(ContentType, required=True)
+    user = graphene.Field(Simple.UserType)
+
+
+class InjectDetailsType(DjangoObjectType):
+    class Meta:
+        model = InjectDetails
+
+    inject = graphene.Field(Simple.DefinitionInjectType, required=True)
+
+
+class CustomInjectDetailsType(DjangoObjectType):
+    class Meta:
+        model = CustomInjectDetails
+
+    user = graphene.Field(Simple.UserType)
+
+
+class EmailType(DjangoObjectType):
+    class Meta:
+        model = Email
+
+    thread = graphene.Field(Simple.EmailThreadType, required=True)
+    sender = graphene.Field(Simple.EmailParticipantType, required=True)
+    user = graphene.Field(Simple.UserType)
+
+
+class QuestionType(DjangoObjectType):
+    class Meta:
+        model = Question
+
+    questionnaire = graphene.Field(Simple.QuestionnaireType, required=True)
+
+    def resolve_correct(self, info):
+        return select_by_group(info.context.user, self.correct, 0)
+
+
+class QuestionnaireType(DjangoObjectType):
+    class Meta:
+        model = Questionnaire
+
+    definition = graphene.Field(Simple.DefinitionType, required=True)
+    team_questionnaire_states = graphene.List(
+        graphene.NonNull(Simple.TeamQuestionnaireStateType), required=True
+    )
+
+
+class ActionLogDetails(graphene.Union):
+    class Meta:
+        types = [
+            ToolDetailsType,
+            InjectDetailsType,
+            CustomInjectDetailsType,
+            EmailType,
+            QuestionnaireType,
+        ]
+
+
+class ActionLogType(DjangoObjectType):
+    class Meta:
+        model = ActionLog
+        exclude = ["details_id"]
+
+    team = graphene.Field(Simple.TeamType, required=True)
+    channel = graphene.Field(Simple.DefinitionChannelType, required=True)
+    type = graphene.Field(LogTypeEnum, required=True)
+    details = graphene.Field(ActionLogDetails, required=True)
+
+
+class MilestoneType(DjangoObjectType):
+    class Meta:
+        model = Milestone
+
+    definition = graphene.Field(Simple.DefinitionType, required=True)
+    milestone_states = graphene.List(
+        graphene.NonNull(Simple.MilestoneStateType), required=True
+    )
+    activity = graphene.Field(Simple.LearningActivityType, required=True)
+
+
+class MilestoneStateType(DjangoObjectType):
+    class Meta:
+        model = MilestoneState
+
+    milestone = graphene.Field(MilestoneType, required=True)
+    activity = graphene.Field(Simple.TeamLearningActivityType, required=True)
+    team_ids = graphene.List(graphene.NonNull(graphene.ID), required=True)
+
+    def resolve_team_ids(self, info):
+        return [team.id for team in self.team_state.teams.all()]
+
+
+class ThreadParticipantType(DjangoObjectType):
+    class Meta:
+        model = ThreadParticipant
+
+
+class EmailThreadType(DjangoObjectType):
+    class Meta:
+        model = EmailThread
+
+    participants = graphene.List(
+        graphene.NonNull(Simple.EmailParticipantType), required=True
+    )
+    exercise = graphene.Field(Simple.ExerciseType, required=True)
+    emails = graphene.List(graphene.NonNull(EmailType), required=True)
+    last_email = graphene.Field(EmailType, required=False)
+
+    def resolve_participants(self, info):
+        return self.participants.all()
+
+    def resolve_last_email(self, info):
+        return self.emails.order_by("timestamp").last()
+
+
+class ToolResponseType(DjangoObjectType):
+    class Meta:
+        model = Response
+
+    tool = graphene.Field(Simple.ToolType, required=True)
+
+
+class EmailAddressType(DjangoObjectType):
+    class Meta:
+        model = EmailAddress
+
+    definition = graphene.Field(Simple.DefinitionType, required=True)
+
+
+class EmailTemplateType(DjangoObjectType):
+    class Meta:
+        model = EmailTemplate
+
+    sender = graphene.String()
+    email_address = graphene.Field(Simple.EmailAddressType, required=True)
+
+    def resolve_sender(self, info):
+        return self.email_address.address
+
+
+class EmailParticipantType(DjangoObjectType):
+    class Meta:
+        model = EmailParticipant
+
+    exercise = graphene.Field(Simple.ExerciseType, required=True)
+    definition_address = graphene.Field(Simple.EmailAddressType)
+    team = graphene.Field(Simple.TeamType)
+    threads = graphene.List(
+        graphene.NonNull(Simple.EmailThreadType), required=True
+    )
+    emails = graphene.List(graphene.NonNull(Simple.EmailType), required=True)
+
+
+class DefinitionInjectType(DjangoObjectType):
+    class Meta:
+        model = Inject
+        exclude = ["alternatives"]
+
+    definition = graphene.Field(Simple.DefinitionType, required=True)
+
+
+class FileInfoType(DjangoObjectType):
+    class Meta:
+        model = FileInfo
+
+    definition = graphene.Field(Simple.DefinitionType, required=True)
+
+
+class ExerciseConfigType(graphene.ObjectType):
+    exercise_duration = graphene.Int()
+    email_between_teams = graphene.Boolean()
+    show_exercise_time = graphene.Boolean()
+    enable_roles = graphene.Boolean()
+    custom_email_suffix = graphene.String()
+
+
+class UserType(DjangoObjectType):
+    class Meta:
+        model = User
+        exclude = ["password"]
+
+    definitions = graphene.List(
+        graphene.NonNull(Simple.DefinitionType), required=True
+    )
+    exercises = graphene.List(
+        graphene.NonNull(Simple.ExerciseType), required=True
+    )
+    teams = graphene.List(graphene.NonNull(Simple.TeamType), required=True)
+    group = graphene.Field(GroupEnum, required=True)
+
+    def resolve_definitions(self, info):
+        return self.definitions.all()
+
+    def resolve_exercises(self, info):
+        return self.exercises.all()
+
+    def resolve_teams(self, info):
+        return self.teams.all()
+
+
+class TagType(DjangoObjectType):
+    class Meta:
+        model = Tag
+        exclude_fields = ["user_set"]
+
+
+class ExerciseEventTypeEnum(models.TextChoices):
+    CREATE = "create"
+    MODIFY = "modify"
+    DELETE = "delete"
+
+    @staticmethod
+    def create() -> "ExerciseEventTypeEnum":
+        return ExerciseEventTypeEnum(ExerciseEventTypeEnum.CREATE)
+
+    @staticmethod
+    def modify() -> "ExerciseEventTypeEnum":
+        return ExerciseEventTypeEnum(ExerciseEventTypeEnum.MODIFY)
+
+    @staticmethod
+    def delete() -> "ExerciseEventTypeEnum":
+        return ExerciseEventTypeEnum(ExerciseEventTypeEnum.DELETE)
+
+
+class DefinitionChannelType(DjangoObjectType):
+    class Meta:
+        model = Channel
+
+    definition = graphene.Field(Simple.DefinitionType, required=True)
+
+
+class QuestionnaireAnswerType(DjangoObjectType):
+    class Meta:
+        model = QuestionnaireAnswer
+
+    team_questionnaire_state = graphene.Field(
+        Simple.TeamQuestionnaireStateType, required=True
+    )
+
+    def resolve_is_correct(self, info):
+        return select_by_group(info.context.user, self.is_correct, None)
+
+
+class TeamQuestionnaireStateType(DjangoObjectType):
+    class Meta:
+        model = TeamQuestionnaireState
+
+    status = graphene.Field(QuestionnaireStateEnum, required=True)
+    team = graphene.Field(Simple.TeamType, required=True)
+    questionnaire = graphene.Field(Simple.QuestionnaireType, required=True)
+    answers = graphene.List(
+        graphene.NonNull(QuestionnaireAnswerType), required=True
+    )
+
+
+class LearningObjectiveType(DjangoObjectType):
+    class Meta:
+        model = LearningObjective
+
+    definition = graphene.Field(Simple.DefinitionType, required=True)
+
+
+class LearningActivityType(DjangoObjectType):
+    class Meta:
+        model = LearningActivity
+
+    objective = graphene.Field(Simple.LearningObjectiveType, required=True)
+
+
+class TeamLearningObjectiveType(DjangoObjectType):
+    class Meta:
+        model = TeamLearningObjective
+
+    objective = graphene.Field(Simple.LearningObjectiveType, required=True)
+    reached = graphene.Boolean()
+
+    def resolve_reached(self, info):
+        return self.reached()
+
+
+class TeamLearningActivityType(DjangoObjectType):
+    class Meta:
+        model = TeamLearningActivity
+
+    team_objective = graphene.Field(
+        Simple.TeamLearningObjectiveType, required=True
+    )
+    activity = graphene.Field(Simple.LearningActivityType, required=True)
+    milestone_states = graphene.List(
+        graphene.NonNull(Simple.MilestoneStateType), required=True
+    )
+    reached = graphene.Boolean()
+
+    def resolve_reached(self, info):
+        return self.reached()
diff --git a/common_lib/subscription_handler.py b/common_lib/subscription_handler.py
index cad2ac310c5c7f12b6ae14c00480d34db0a0a86a..fe919424d187b471c5da56dcbde285d137a23137 100644
--- a/common_lib/subscription_handler.py
+++ b/common_lib/subscription_handler.py
@@ -1,6 +1,6 @@
 from typing import List
 
-from common_lib.schema.types import ExerciseEventTypeEnum
+from common_lib.schema.enums import ExerciseEventTypeEnum
 from common_lib.utils import get_subscription_group
 from exercise.models import (
     Team,
diff --git a/exercise/lib/exercise_manager.py b/exercise/lib/exercise_manager.py
index e2a5b1fff36c5c7a6d795f8abd908834bf2064df..e3062b1269f1b42a9c6384cc78e59f8dd6970506 100644
--- a/exercise/lib/exercise_manager.py
+++ b/exercise/lib/exercise_manager.py
@@ -8,7 +8,7 @@ from rest_framework.request import Request
 
 from common_lib.exceptions import ExerciseOperationException
 from common_lib.logger import logger, log_user_msg
-from common_lib.schema.types import ExerciseEventTypeEnum
+from common_lib.schema.enums import ExerciseEventTypeEnum
 from common_lib.subscription_handler import SubscriptionHandler
 from common_lib.utils import get_model
 from exercise.graphql_inputs import CreateExerciseInput, ConfigOverrideInput
diff --git a/exercise/schema/query.py b/exercise/schema/query.py
index ae2285b4f47f4ebce42de03c67e677feba884f72..8f104b607b7455f29e9da1154f97fd2480cf36fe 100644
--- a/exercise/schema/query.py
+++ b/exercise/schema/query.py
@@ -11,6 +11,8 @@ from common_lib.schema.types import (
     MilestoneType,
     FileInfoType,
     DefinitionChannelType,
+    LearningObjectiveType,
+    QuestionnaireType,
 )
 from common_lib.utils import get_model
 from exercise.models import Exercise
@@ -20,6 +22,8 @@ from exercise_definition.models import (
     Milestone,
     FileInfo,
     Channel,
+    LearningObjective,
+    Questionnaire,
 )
 from user.models import User
 
@@ -94,6 +98,17 @@ class Query(graphene.ObjectType):
         description="Retrieve all channels for an exercise",
     )
 
+    learning_objectives = graphene.List(
+        LearningObjectiveType,
+        exercise_id=graphene.ID(required=True),
+        description="Retrieve all learning objectives for an exercise",
+    )
+    questionnaires = graphene.List(
+        QuestionnaireType,
+        exercise_id=graphene.ID(required=True),
+        description="Retrieve all questionnaires for an exercise",
+    )
+
     @protected(User.AuthGroup.TRAINEE)
     def resolve_exercises(
         self,
@@ -186,3 +201,21 @@ class Query(graphene.ObjectType):
     ) -> List[Channel]:
         exercise_access(info.context, int(exercise_id))
         return Channel.objects.filter(definition__exercises__in=[exercise_id])
+
+    @protected(User.AuthGroup.INSTRUCTOR)
+    def resolve_learning_objectives(
+        self, info, exercise_id: str
+    ) -> List[LearningObjective]:
+        exercise_access(info.context, int(exercise_id))
+        return LearningObjective.objects.filter(
+            definition__exercises__in=[exercise_id]
+        )
+
+    @protected(User.AuthGroup.INSTRUCTOR)
+    def resolve_questionnaires(
+        self, info, exercise_id: str
+    ) -> List[Questionnaire]:
+        exercise_access(info.context, int(exercise_id))
+        return Questionnaire.objects.filter(
+            definition__exercises__in=[exercise_id]
+        )
diff --git a/exercise/subscription.py b/exercise/subscription.py
index 390c4a461671f1258b84f4604c265560de8f56e7..61fe9db39867fe76054624d2600b098520d0c24c 100644
--- a/exercise/subscription.py
+++ b/exercise/subscription.py
@@ -2,7 +2,7 @@ import channels_graphql_ws
 import graphene
 
 from aai.decorators import protected
-from common_lib.schema.types import ExerciseEventTypeEnum
+from common_lib.schema.enums import ExerciseEventTypeEnum
 from common_lib.schema.types import ExerciseType
 from user.models import User
 
diff --git a/running_exercise/lib/loop_thread.py b/running_exercise/lib/loop_thread.py
index 542f8ecdfc9b5d053d9869332fef88ae281845eb..fdf6bc4fe658fc92eaffe2b914558f10aa2faff2 100644
--- a/running_exercise/lib/loop_thread.py
+++ b/running_exercise/lib/loop_thread.py
@@ -2,7 +2,7 @@ import time
 from threading import Thread
 
 from common_lib.logger import logger
-from common_lib.schema.types import ExerciseEventTypeEnum
+from common_lib.schema.enums import ExerciseEventTypeEnum
 from common_lib.subscription_handler import SubscriptionHandler
 from common_lib.utils import get_model
 from exercise.models import Exercise
diff --git a/running_exercise/schema/query.py b/running_exercise/schema/query.py
index ee248c4b29979490d8eb059f420baf7123962ce5..5b7ea3b5eb803ec46362124c4b34edfcc04f16ac 100644
--- a/running_exercise/schema/query.py
+++ b/running_exercise/schema/query.py
@@ -16,10 +16,10 @@ from common_lib.schema.types import (
     EmailParticipantType,
     EmailTemplateType,
     TeamType,
-    ExerciseConfigType,
+    GrapheneConfig,
     TeamQuestionnaireStateType,
+    ExtendedToolType,
 )
-from common_lib.schema.simple_types import Simple
 from common_lib.utils import get_model, has_role
 from exercise.models import (
     Team,
@@ -54,7 +54,7 @@ class Query(graphene.ObjectType):
         description="Retrieve all team roles for the running exercise",
     )
     team_tools = graphene.List(
-        Simple.ToolType,
+        ExtendedToolType,
         team_id=graphene.ID(required=True),
         description="Retrieve all tools available to the specific team",
     )
@@ -79,6 +79,11 @@ class Query(graphene.ObjectType):
         channel_id=graphene.ID(required=True),
         description="Retrieve all team action logs for the specific channel",
     )
+    team_milestone = graphene.Field(
+        MilestoneStateType,
+        milestone_state_id=graphene.ID(required=True),
+        description="Retrieve a specific milestone state",
+    )
     team_milestones = graphene.List(
         MilestoneStateType,
         team_id=graphene.ID(required=True),
@@ -150,7 +155,7 @@ class Query(graphene.ObjectType):
         description="Retrieve the amount of time left in the running exercise in seconds"
     )
     exercise_config = graphene.Field(
-        ExerciseConfigType,
+        GrapheneConfig,
         exercise_id=graphene.ID(required=True),
         description="Retrieve the config for the current running exercise",
     )
@@ -259,6 +264,14 @@ class Query(graphene.ObjectType):
         team_access(info.context, int(team_id))
         return ActionLog.objects.filter(team_id=team_id, channel_id=channel_id)
 
+    @protected(User.AuthGroup.INSTRUCTOR)
+    def resolve_team_milestone(
+        self, info, milestone_state_id: str
+    ) -> MilestoneState:
+        milestone_state = get_model(MilestoneState, id=int(milestone_state_id))
+        exercise_access(info.context, milestone_state.team_state.exercise_id)
+        return milestone_state
+
     @protected(User.AuthGroup.INSTRUCTOR)
     def resolve_team_milestones(
         self, info, team_id: str, visible_only: bool = True
@@ -371,14 +384,12 @@ class Query(graphene.ObjectType):
         return max(0, exercise_duration_s - int(running_exercise.elapsed_s))
 
     @protected(User.AuthGroup.TRAINEE)
-    def resolve_exercise_config(
-        self, info, exercise_id: str
-    ) -> ExerciseConfigType:
+    def resolve_exercise_config(self, info, exercise_id: str) -> GrapheneConfig:
         exercise_access(info.context, int(exercise_id))
         exercise = get_model(Exercise, id=int(exercise_id))
 
         config: Config = exercise.config
-        return ExerciseConfigType(
+        return GrapheneConfig(
             exercise_duration=config.exercise_duration,
             email_between_teams=config.has_enabled(
                 Feature.email_between_teams()