| 1 | package edu.ucsb.cs.scaffold.controller; | |
| 2 | ||
| 3 | import com.fasterxml.jackson.annotation.JsonProperty; | |
| 4 | import com.fasterxml.jackson.core.JsonProcessingException; | |
| 5 | import com.fasterxml.jackson.core.type.TypeReference; | |
| 6 | import com.fasterxml.jackson.databind.JsonNode; | |
| 7 | import com.fasterxml.jackson.databind.ObjectMapper; | |
| 8 | import edu.ucsb.cs.scaffold.model.UserState; | |
| 9 | import edu.ucsb.cs.scaffold.repository.UserStateRepository; | |
| 10 | import io.swagger.v3.oas.annotations.Operation; | |
| 11 | import io.swagger.v3.oas.annotations.Parameter; | |
| 12 | import io.swagger.v3.oas.annotations.tags.Tag; | |
| 13 | import java.util.List; | |
| 14 | import lombok.RequiredArgsConstructor; | |
| 15 | import org.springframework.http.ResponseEntity; | |
| 16 | import org.springframework.web.bind.annotation.*; | |
| 17 | ||
| 18 | @Tag(name = "User State") | |
| 19 | @RestController | |
| 20 | @RequiredArgsConstructor | |
| 21 | public class UserStateController { | |
| 22 | ||
| 23 | private final UserStateRepository userStateRepository; | |
| 24 | private final ObjectMapper objectMapper; | |
| 25 | ||
| 26 | @Operation(summary = "Get saved user state by user ID") | |
| 27 | @GetMapping("/api/user-state/{userid}") | |
| 28 | public ResponseEntity<UserStateResponse> getUserState( | |
| 29 | @Parameter(description = "User ID (from users table)") @PathVariable Long userid) { | |
| 30 |
1
1. getUserState : replaced return value with null for edu/ucsb/cs/scaffold/controller/UserStateController::getUserState → KILLED |
return userStateRepository |
| 31 | .findByUserid(userid) | |
| 32 | .map( | |
| 33 | state -> | |
| 34 |
1
1. lambda$getUserState$0 : replaced return value with null for edu/ucsb/cs/scaffold/controller/UserStateController::lambda$getUserState$0 → KILLED |
ResponseEntity.ok( |
| 35 | new UserStateResponse( | |
| 36 | parseStringList(state.getStarredIds()), | |
| 37 | parseJsonNode(state.getDetailCards()), | |
| 38 | parseStringList(state.getMasteredSubconcepts())))) | |
| 39 |
1
1. lambda$getUserState$1 : replaced return value with null for edu/ucsb/cs/scaffold/controller/UserStateController::lambda$getUserState$1 → KILLED |
.orElseGet(() -> ResponseEntity.notFound().build()); |
| 40 | } | |
| 41 | ||
| 42 | @Operation(summary = "Upsert saved user state by user ID") | |
| 43 | @PostMapping("/api/user-state") | |
| 44 | public ResponseEntity<Void> upsertUserState(@RequestBody UserStateRequest body) { | |
| 45 |
1
1. upsertUserState : negated conditional → KILLED |
if (body.userid() == null) { |
| 46 |
1
1. upsertUserState : replaced return value with null for edu/ucsb/cs/scaffold/controller/UserStateController::upsertUserState → KILLED |
return ResponseEntity.badRequest().build(); |
| 47 | } | |
| 48 | ||
| 49 | UserState state = userStateRepository.findByUserid(body.userid()).orElseGet(UserState::new); | |
| 50 |
1
1. upsertUserState : removed call to edu/ucsb/cs/scaffold/model/UserState::setUserid → KILLED |
state.setUserid(body.userid()); |
| 51 |
2
1. upsertUserState : removed call to edu/ucsb/cs/scaffold/model/UserState::setStarredIds → KILLED 2. upsertUserState : negated conditional → KILLED |
state.setStarredIds(writeJson(body.starredIds() == null ? List.of() : body.starredIds())); |
| 52 |
1
1. upsertUserState : removed call to edu/ucsb/cs/scaffold/model/UserState::setDetailCards → KILLED |
state.setDetailCards( |
| 53 | writeJson( | |
| 54 |
1
1. upsertUserState : negated conditional → KILLED |
body.detailCards() == null ? objectMapper.createArrayNode() : body.detailCards())); |
| 55 |
1
1. upsertUserState : removed call to edu/ucsb/cs/scaffold/model/UserState::setMasteredSubconcepts → KILLED |
state.setMasteredSubconcepts( |
| 56 |
1
1. upsertUserState : negated conditional → KILLED |
writeJson(body.masteredSubconcepts() == null ? List.of() : body.masteredSubconcepts())); |
| 57 | userStateRepository.save(state); | |
| 58 | ||
| 59 |
1
1. upsertUserState : replaced return value with null for edu/ucsb/cs/scaffold/controller/UserStateController::upsertUserState → KILLED |
return ResponseEntity.noContent().build(); |
| 60 | } | |
| 61 | ||
| 62 | private List<String> parseStringList(String json) { | |
| 63 | try { | |
| 64 |
1
1. parseStringList : replaced return value with Collections.emptyList for edu/ucsb/cs/scaffold/controller/UserStateController::parseStringList → KILLED |
return objectMapper.readValue(json, new TypeReference<>() {}); |
| 65 | } catch (JsonProcessingException e) { | |
| 66 | throw new IllegalStateException("Unable to parse stored string list JSON", e); | |
| 67 | } | |
| 68 | } | |
| 69 | ||
| 70 | private JsonNode parseJsonNode(String json) { | |
| 71 | try { | |
| 72 |
1
1. parseJsonNode : replaced return value with null for edu/ucsb/cs/scaffold/controller/UserStateController::parseJsonNode → KILLED |
return objectMapper.readTree(json); |
| 73 | } catch (JsonProcessingException e) { | |
| 74 | throw new IllegalStateException("Unable to parse stored JSON payload", e); | |
| 75 | } | |
| 76 | } | |
| 77 | ||
| 78 | private String writeJson(Object value) { | |
| 79 | try { | |
| 80 |
1
1. writeJson : replaced return value with "" for edu/ucsb/cs/scaffold/controller/UserStateController::writeJson → KILLED |
return objectMapper.writeValueAsString(value); |
| 81 | } catch (JsonProcessingException e) { | |
| 82 | throw new IllegalArgumentException("Unable to serialize JSON payload", e); | |
| 83 | } | |
| 84 | } | |
| 85 | ||
| 86 | public record UserStateRequest( | |
| 87 | Long userid, | |
| 88 | @JsonProperty("starred_ids") List<String> starredIds, | |
| 89 | @JsonProperty("detail_cards") JsonNode detailCards, | |
| 90 | @JsonProperty("mastered_subconcepts") List<String> masteredSubconcepts) {} | |
| 91 | ||
| 92 | public record UserStateResponse( | |
| 93 | @JsonProperty("starred_ids") List<String> starredIds, | |
| 94 | @JsonProperty("detail_cards") JsonNode detailCards, | |
| 95 | @JsonProperty("mastered_subconcepts") List<String> masteredSubconcepts) {} | |
| 96 | } | |
Mutations | ||
| 30 |
1.1 |
|
| 34 |
1.1 |
|
| 39 |
1.1 |
|
| 45 |
1.1 |
|
| 46 |
1.1 |
|
| 50 |
1.1 |
|
| 51 |
1.1 2.2 |
|
| 52 |
1.1 |
|
| 54 |
1.1 |
|
| 55 |
1.1 |
|
| 56 |
1.1 |
|
| 59 |
1.1 |
|
| 64 |
1.1 |
|
| 72 |
1.1 |
|
| 80 |
1.1 |