Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import de.unistuttgart.iste.meitrex.common.user_handling.GlobalPermissionAccessValidator;
import de.unistuttgart.iste.meitrex.common.user_handling.LoggedInUser;
import de.unistuttgart.iste.meitrex.generated.dto.SkillLevels;
import de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity.SkillAllUsersStatsEntity;
import de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity.SkillValueEntity;
import de.unistuttgart.iste.meitrex.skilllevel_service.service.SkillLevelService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -13,7 +15,6 @@
import org.springframework.stereotype.Controller;

import java.util.List;
import java.util.Set;
import java.util.UUID;

@Slf4j
Expand Down Expand Up @@ -44,5 +45,14 @@ public List<SkillLevels> skillLevelForUserBySkillIds(@Argument final List<UUID>
return skilllevelService.getSkillLevelsForSkillIds(skillIds, userId);
}

@QueryMapping(name = INTERNAL_NOAUTH_PREFIX + "skillsAllUsersStatsBySkillIds")
public List<SkillAllUsersStatsEntity> skillsAllUsersStatsBySkillIds(@Argument final List<UUID> skillIds) {
return skilllevelService.getSkillsAllUsersStatsForSkillIds(skillIds);
}

@QueryMapping(name = INTERNAL_NOAUTH_PREFIX + "skillValuesBySkillIds")
public List<SkillValueEntity> skillValuesBySkillIds(@Argument final List<UUID> skillIds, @ContextValue final LoggedInUser currentUser) {
return skilllevelService.getSkillValuesForSkillIds(skillIds, currentUser.getId());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.UUID;
/** * Database entity which represents for every skill the skillStats for all users in the course. */

@Entity(name = "SkillAllUsersStats")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SkillAllUsersStatsEntity {

@Id private UUID skillId;

/** * Current sum of the skill values from all users in a course with this skill. */
@Column(nullable = false) private float skillValueSum;

/** * Current participant count of the skill level. */
@Column(nullable = false) private int participantCount;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.UUID;
/** * Database entity which represents for every skill the skillValue in the course. */

@Entity(name = "SkillValue")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SkillValueEntity {

@Id private UUID skillId;

/** * Current skill value. Can range from 0 to 1. */
@Column(nullable = false) private float skillValue;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package de.unistuttgart.iste.meitrex.skilllevel_service.persistence.repository;
import de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity.SkillAllUsersStatsEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.UUID;

@Repository
public interface SkillAllUsersStatsRepository extends JpaRepository<SkillAllUsersStatsEntity, UUID> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package de.unistuttgart.iste.meitrex.skilllevel_service.persistence.repository;
import de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity.SkillValueEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.UUID;

@Repository
public interface SkillValueRepository extends JpaRepository<SkillValueEntity, UUID> {
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import de.unistuttgart.iste.meitrex.common.event.ItemResponse;
import de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity.AllSkillLevelsEntity;
import de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity.SkillAbilityEntity;
import de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity.SkillAllUsersStatsEntity;
import de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity.SkillLevelEntity;
import de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity.SkillsForCourse;
import de.unistuttgart.iste.meitrex.skilllevel_service.persistence.mapper.SkillLevelMapper;
Expand All @@ -17,10 +18,13 @@
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Service;

import java.util.*;

import de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity.SkillValueEntity;

@Service
@Slf4j
@RequiredArgsConstructor
Expand Down Expand Up @@ -77,7 +81,92 @@ public List<SkillLevels> getSkillLevelsForCourse(UUID courseId, UUID userId) {
*/
public List<SkillLevels> getSkillLevelsForSkillIds(List<UUID> skillIds, UUID userId) {
return getSkillLevelEntitiesForSkillIds(skillIds, userId).stream().map(mapper::entityToDto).toList();
}

/**
* Returns the stats for the skills for all users from the course of the skills.
*
* @param skillIds List of skillIds
* @return List of SkillAllUsersStatsEntity that represents stats
* like skillValueSum and participantCount of the given skills
*/
public List<SkillAllUsersStatsEntity> getSkillsAllUsersStatsForSkillIds(List<UUID> skillIds) {
List<SkillAllUsersStatsEntity> skillAllUsersStats = new ArrayList<>();
for (UUID skillId : skillIds) {
skillAllUsersStats.add(getSkillAllUsersStatsForSkillId(skillId));
}
return skillAllUsersStats;
}

/**
* Returns the skill's stats for a given skillId.
*
* @param skillId skillId of skillLevels
* @return SkillValueAllUsersStatsEntity that represents stats
* like skillValue sum and participantCount of the given skills
*/
private SkillAllUsersStatsEntity getSkillAllUsersStatsForSkillId(UUID skillId) {
List<AllSkillLevelsEntity> skillLevels = skillLevelsRepository.findByIdSkillId(skillId);
List<Float> skillValues = new ArrayList<>();
for (AllSkillLevelsEntity skillLevel : skillLevels) {
skillValues.add(getSkillValueForSkillLevel(skillLevel));
}
float skillValueSum = 0f;
for (Float skillValue : skillValues) {
skillValueSum += skillValue;
}
SkillAllUsersStatsEntity skillAllUsersStats = new SkillAllUsersStatsEntity();
skillAllUsersStats.setSkillId(skillId);
skillAllUsersStats.setParticipantCount(skillValues.size());
if (skillValues.isEmpty()) {
skillAllUsersStats.setSkillValueSum(0f);
} else {
skillAllUsersStats.setSkillValueSum(skillValueSum);
}
return skillAllUsersStats;
}

/**
* Returns the skill value for a given skillLevel by combining all 6 skillLevelEntities.
*
* @param skillLevel skillLevel of a skill
* @return A float value that represents the skill value of a skill
*/
private Float getSkillValueForSkillLevel(AllSkillLevelsEntity skillLevel) {
List<Float> values = List.of(
skillLevel.getRemember().getValue(),
skillLevel.getUnderstand().getValue(),
skillLevel.getApply().getValue(),
skillLevel.getAnalyze().getValue(),
skillLevel.getEvaluate().getValue(),
skillLevel.getCreate().getValue()
);
List<Float> nonZeroValues = values.stream().filter(v -> v > 0f).toList();
if (nonZeroValues.isEmpty()) {
return 0f;
} else {
float sum = nonZeroValues.stream().reduce(0f, Float::sum);
return sum / nonZeroValues.size();
}
}

/**
* return the skill values for the given user and skills
*
* @param skillIds the ids of the skills
* @param userId the id of the user
* @return the skill values for the given user and skills
*/
public List<SkillValueEntity> getSkillValuesForSkillIds(List <UUID> skillIds, UUID userId) {
List<AllSkillLevelsEntity> skillLevels = getSkillLevelEntitiesForSkillIds(skillIds, userId);
List<SkillValueEntity> skillValues = new ArrayList<>();
for (AllSkillLevelsEntity skillLevel : skillLevels) {
SkillValueEntity entity = new SkillValueEntity();
entity.setSkillId(skillLevel.getId().getSkillId());
entity.setSkillValue(getSkillValueForSkillLevel(skillLevel));
skillValues.add(entity);
}
return skillValues;
}

/**
Expand Down
18 changes: 18 additions & 0 deletions src/main/resources/graphql/service/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ type Query {
"""
_internal_noauth_skillLevelForUserBySkillIds(skillIds: [UUID!]!, userId: UUID!): [SkillLevels!]!

_internal_noauth_skillsAllUsersStatsBySkillIds(skillIds: [UUID!]!): [SkillAllUsersStats!]!

_internal_noauth_skillValuesBySkillIds(skillIds: [UUID!]!): [SkillValue!]!
}

type Mutation {
Expand Down Expand Up @@ -129,4 +132,19 @@ type SkillLevelLogItem {
the probability of a correct response, that M-Elo predicts
"""
predictedCorrectness:Float!
}

type SkillValue {
skillId: UUID!

skillValue: Float!
}

type SkillAllUsersStats {

skillId: UUID!

skillValueSum: Float!

participantCount: Int!
}
Loading
Loading