Skip to content

Commit 3746978

Browse files
authored
Merge pull request #14 from MEITREX/progress-visualization
add SkillValue and SkillAllUsersStats
2 parents 2080e62 + 46cb69d commit 3746978

8 files changed

Lines changed: 338 additions & 1 deletion

File tree

src/main/java/de/unistuttgart/iste/meitrex/skilllevel_service/controller/SkillLevelController.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import de.unistuttgart.iste.meitrex.common.user_handling.GlobalPermissionAccessValidator;
44
import de.unistuttgart.iste.meitrex.common.user_handling.LoggedInUser;
55
import de.unistuttgart.iste.meitrex.generated.dto.SkillLevels;
6+
import de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity.SkillAllUsersStatsEntity;
7+
import de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity.SkillValueEntity;
68
import de.unistuttgart.iste.meitrex.skilllevel_service.service.SkillLevelService;
79
import lombok.RequiredArgsConstructor;
810
import lombok.extern.slf4j.Slf4j;
@@ -13,7 +15,6 @@
1315
import org.springframework.stereotype.Controller;
1416

1517
import java.util.List;
16-
import java.util.Set;
1718
import java.util.UUID;
1819

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

48+
@QueryMapping(name = INTERNAL_NOAUTH_PREFIX + "skillsAllUsersStatsBySkillIds")
49+
public List<SkillAllUsersStatsEntity> skillsAllUsersStatsBySkillIds(@Argument final List<UUID> skillIds) {
50+
return skilllevelService.getSkillsAllUsersStatsForSkillIds(skillIds);
51+
}
52+
53+
@QueryMapping(name = INTERNAL_NOAUTH_PREFIX + "skillValuesBySkillIds")
54+
public List<SkillValueEntity> skillValuesBySkillIds(@Argument final List<UUID> skillIds, @ContextValue final LoggedInUser currentUser) {
55+
return skilllevelService.getSkillValuesForSkillIds(skillIds, currentUser.getId());
56+
}
4757

4858
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity;
2+
import jakarta.persistence.*;
3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
5+
import lombok.Data;
6+
import lombok.NoArgsConstructor;
7+
import java.util.UUID;
8+
/** * Database entity which represents for every skill the skillStats for all users in the course. */
9+
10+
@Entity(name = "SkillAllUsersStats")
11+
@Data
12+
@Builder
13+
@NoArgsConstructor
14+
@AllArgsConstructor
15+
public class SkillAllUsersStatsEntity {
16+
17+
@Id private UUID skillId;
18+
19+
/** * Current sum of the skill values from all users in a course with this skill. */
20+
@Column(nullable = false) private float skillValueSum;
21+
22+
/** * Current participant count of the skill level. */
23+
@Column(nullable = false) private int participantCount;
24+
25+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity;
2+
import jakarta.persistence.*;
3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
5+
import lombok.Data;
6+
import lombok.NoArgsConstructor;
7+
import java.util.UUID;
8+
/** * Database entity which represents for every skill the skillValue in the course. */
9+
10+
@Entity(name = "SkillValue")
11+
@Data
12+
@Builder
13+
@NoArgsConstructor
14+
@AllArgsConstructor
15+
public class SkillValueEntity {
16+
17+
@Id private UUID skillId;
18+
19+
/** * Current skill value. Can range from 0 to 1. */
20+
@Column(nullable = false) private float skillValue;
21+
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package de.unistuttgart.iste.meitrex.skilllevel_service.persistence.repository;
2+
import de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity.SkillAllUsersStatsEntity;
3+
import org.springframework.data.jpa.repository.JpaRepository;
4+
import org.springframework.stereotype.Repository;
5+
import java.util.UUID;
6+
7+
@Repository
8+
public interface SkillAllUsersStatsRepository extends JpaRepository<SkillAllUsersStatsEntity, UUID> {
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package de.unistuttgart.iste.meitrex.skilllevel_service.persistence.repository;
2+
import de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity.SkillValueEntity;
3+
import org.springframework.data.jpa.repository.JpaRepository;
4+
import org.springframework.stereotype.Repository;
5+
import java.util.UUID;
6+
7+
@Repository
8+
public interface SkillValueRepository extends JpaRepository<SkillValueEntity, UUID> {
9+
}

src/main/java/de/unistuttgart/iste/meitrex/skilllevel_service/service/SkillLevelService.java

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import de.unistuttgart.iste.meitrex.common.event.ItemResponse;
77
import de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity.AllSkillLevelsEntity;
88
import de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity.SkillAbilityEntity;
9+
import de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity.SkillAllUsersStatsEntity;
910
import de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity.SkillLevelEntity;
1011
import de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity.SkillsForCourse;
1112
import de.unistuttgart.iste.meitrex.skilllevel_service.persistence.mapper.SkillLevelMapper;
@@ -17,10 +18,13 @@
1718
import jakarta.transaction.Transactional;
1819
import lombok.RequiredArgsConstructor;
1920
import lombok.extern.slf4j.Slf4j;
21+
2022
import org.springframework.stereotype.Service;
2123

2224
import java.util.*;
2325

26+
import de.unistuttgart.iste.meitrex.skilllevel_service.persistence.entity.SkillValueEntity;
27+
2428
@Service
2529
@Slf4j
2630
@RequiredArgsConstructor
@@ -77,7 +81,92 @@ public List<SkillLevels> getSkillLevelsForCourse(UUID courseId, UUID userId) {
7781
*/
7882
public List<SkillLevels> getSkillLevelsForSkillIds(List<UUID> skillIds, UUID userId) {
7983
return getSkillLevelEntitiesForSkillIds(skillIds, userId).stream().map(mapper::entityToDto).toList();
84+
}
85+
86+
/**
87+
* Returns the stats for the skills for all users from the course of the skills.
88+
*
89+
* @param skillIds List of skillIds
90+
* @return List of SkillAllUsersStatsEntity that represents stats
91+
* like skillValueSum and participantCount of the given skills
92+
*/
93+
public List<SkillAllUsersStatsEntity> getSkillsAllUsersStatsForSkillIds(List<UUID> skillIds) {
94+
List<SkillAllUsersStatsEntity> skillAllUsersStats = new ArrayList<>();
95+
for (UUID skillId : skillIds) {
96+
skillAllUsersStats.add(getSkillAllUsersStatsForSkillId(skillId));
97+
}
98+
return skillAllUsersStats;
99+
}
100+
101+
/**
102+
* Returns the skill's stats for a given skillId.
103+
*
104+
* @param skillId skillId of skillLevels
105+
* @return SkillValueAllUsersStatsEntity that represents stats
106+
* like skillValue sum and participantCount of the given skills
107+
*/
108+
private SkillAllUsersStatsEntity getSkillAllUsersStatsForSkillId(UUID skillId) {
109+
List<AllSkillLevelsEntity> skillLevels = skillLevelsRepository.findByIdSkillId(skillId);
110+
List<Float> skillValues = new ArrayList<>();
111+
for (AllSkillLevelsEntity skillLevel : skillLevels) {
112+
skillValues.add(getSkillValueForSkillLevel(skillLevel));
113+
}
114+
float skillValueSum = 0f;
115+
for (Float skillValue : skillValues) {
116+
skillValueSum += skillValue;
117+
}
118+
SkillAllUsersStatsEntity skillAllUsersStats = new SkillAllUsersStatsEntity();
119+
skillAllUsersStats.setSkillId(skillId);
120+
skillAllUsersStats.setParticipantCount(skillValues.size());
121+
if (skillValues.isEmpty()) {
122+
skillAllUsersStats.setSkillValueSum(0f);
123+
} else {
124+
skillAllUsersStats.setSkillValueSum(skillValueSum);
125+
}
126+
return skillAllUsersStats;
127+
}
80128

129+
/**
130+
* Returns the skill value for a given skillLevel by combining all 6 skillLevelEntities.
131+
*
132+
* @param skillLevel skillLevel of a skill
133+
* @return A float value that represents the skill value of a skill
134+
*/
135+
private Float getSkillValueForSkillLevel(AllSkillLevelsEntity skillLevel) {
136+
List<Float> values = List.of(
137+
skillLevel.getRemember().getValue(),
138+
skillLevel.getUnderstand().getValue(),
139+
skillLevel.getApply().getValue(),
140+
skillLevel.getAnalyze().getValue(),
141+
skillLevel.getEvaluate().getValue(),
142+
skillLevel.getCreate().getValue()
143+
);
144+
List<Float> nonZeroValues = values.stream().filter(v -> v > 0f).toList();
145+
if (nonZeroValues.isEmpty()) {
146+
return 0f;
147+
} else {
148+
float sum = nonZeroValues.stream().reduce(0f, Float::sum);
149+
return sum / nonZeroValues.size();
150+
}
151+
}
152+
153+
/**
154+
* return the skill values for the given user and skills
155+
*
156+
* @param skillIds the ids of the skills
157+
* @param userId the id of the user
158+
* @return the skill values for the given user and skills
159+
*/
160+
public List<SkillValueEntity> getSkillValuesForSkillIds(List <UUID> skillIds, UUID userId) {
161+
List<AllSkillLevelsEntity> skillLevels = getSkillLevelEntitiesForSkillIds(skillIds, userId);
162+
List<SkillValueEntity> skillValues = new ArrayList<>();
163+
for (AllSkillLevelsEntity skillLevel : skillLevels) {
164+
SkillValueEntity entity = new SkillValueEntity();
165+
entity.setSkillId(skillLevel.getId().getSkillId());
166+
entity.setSkillValue(getSkillValueForSkillLevel(skillLevel));
167+
skillValues.add(entity);
168+
}
169+
return skillValues;
81170
}
82171

83172
/**

src/main/resources/graphql/service/schema.graphqls

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ type Query {
3636
"""
3737
_internal_noauth_skillLevelForUserBySkillIds(skillIds: [UUID!]!, userId: UUID!): [SkillLevels!]!
3838

39+
_internal_noauth_skillsAllUsersStatsBySkillIds(skillIds: [UUID!]!): [SkillAllUsersStats!]!
40+
41+
_internal_noauth_skillValuesBySkillIds(skillIds: [UUID!]!): [SkillValue!]!
3942
}
4043

4144
type Mutation {
@@ -129,4 +132,19 @@ type SkillLevelLogItem {
129132
the probability of a correct response, that M-Elo predicts
130133
"""
131134
predictedCorrectness:Float!
135+
}
136+
137+
type SkillValue {
138+
skillId: UUID!
139+
140+
skillValue: Float!
141+
}
142+
143+
type SkillAllUsersStats {
144+
145+
skillId: UUID!
146+
147+
skillValueSum: Float!
148+
149+
participantCount: Int!
132150
}

0 commit comments

Comments
 (0)