| 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.LegacyUserState; | |
| 9 | import edu.ucsb.cs.scaffold.repository.LegacyUserStateRepository; | |
| 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 | // Serves only LegacyHomePage.tsx (via legacyClient.ts). State here is per-user with no | |
| 19 | // course scoping; the course-scoped counterpart is UserStateController at /api/user-state. | |
| 20 | @Tag(name = "Legacy User State") | |
| 21 | @RestController | |
| 22 | @RequiredArgsConstructor | |
| 23 | public class LegacyUserStateController { | |
| 24 | ||
| 25 | private final LegacyUserStateRepository legacyUserStateRepository; | |
| 26 | private final ObjectMapper objectMapper; | |
| 27 | ||
| 28 | @Operation(summary = "Get saved legacy user state by user ID") | |
| 29 | @GetMapping("/api/legacy/user-state/{userid}") | |
| 30 | public ResponseEntity<LegacyUserStateResponse> getUserState( | |
| 31 | @Parameter(description = "User ID (from users table)") @PathVariable Long userid) { | |
| 32 |
1
1. getUserState : replaced return value with null for edu/ucsb/cs/scaffold/controller/LegacyUserStateController::getUserState → KILLED |
return legacyUserStateRepository |
| 33 | .findByUserid(userid) | |
| 34 | .map( | |
| 35 | state -> | |
| 36 |
1
1. lambda$getUserState$0 : replaced return value with null for edu/ucsb/cs/scaffold/controller/LegacyUserStateController::lambda$getUserState$0 → KILLED |
ResponseEntity.ok( |
| 37 | new LegacyUserStateResponse( | |
| 38 | parseStringList(state.getStarredIds()), | |
| 39 | parseJsonNode(state.getDetailCards()), | |
| 40 | parseStringList(state.getMasteredSubconcepts())))) | |
| 41 |
1
1. lambda$getUserState$1 : replaced return value with null for edu/ucsb/cs/scaffold/controller/LegacyUserStateController::lambda$getUserState$1 → KILLED |
.orElseGet(() -> ResponseEntity.notFound().build()); |
| 42 | } | |
| 43 | ||
| 44 | @Operation(summary = "Upsert saved legacy user state by user ID") | |
| 45 | @PostMapping("/api/legacy/user-state") | |
| 46 | public ResponseEntity<Void> upsertUserState(@RequestBody LegacyUserStateRequest body) { | |
| 47 |
1
1. upsertUserState : negated conditional → KILLED |
if (body.userid() == null) { |
| 48 |
1
1. upsertUserState : replaced return value with null for edu/ucsb/cs/scaffold/controller/LegacyUserStateController::upsertUserState → KILLED |
return ResponseEntity.badRequest().build(); |
| 49 | } | |
| 50 | ||
| 51 | LegacyUserState state = | |
| 52 | legacyUserStateRepository.findByUserid(body.userid()).orElseGet(LegacyUserState::new); | |
| 53 |
1
1. upsertUserState : removed call to edu/ucsb/cs/scaffold/model/LegacyUserState::setUserid → KILLED |
state.setUserid(body.userid()); |
| 54 |
2
1. upsertUserState : removed call to edu/ucsb/cs/scaffold/model/LegacyUserState::setStarredIds → KILLED 2. upsertUserState : negated conditional → KILLED |
state.setStarredIds(writeJson(body.starredIds() == null ? List.of() : body.starredIds())); |
| 55 |
1
1. upsertUserState : removed call to edu/ucsb/cs/scaffold/model/LegacyUserState::setDetailCards → KILLED |
state.setDetailCards( |
| 56 | writeJson( | |
| 57 |
1
1. upsertUserState : negated conditional → KILLED |
body.detailCards() == null ? objectMapper.createArrayNode() : body.detailCards())); |
| 58 |
1
1. upsertUserState : removed call to edu/ucsb/cs/scaffold/model/LegacyUserState::setMasteredSubconcepts → KILLED |
state.setMasteredSubconcepts( |
| 59 |
1
1. upsertUserState : negated conditional → KILLED |
writeJson(body.masteredSubconcepts() == null ? List.of() : body.masteredSubconcepts())); |
| 60 | legacyUserStateRepository.save(state); | |
| 61 | ||
| 62 |
1
1. upsertUserState : replaced return value with null for edu/ucsb/cs/scaffold/controller/LegacyUserStateController::upsertUserState → KILLED |
return ResponseEntity.noContent().build(); |
| 63 | } | |
| 64 | ||
| 65 | private List<String> parseStringList(String json) { | |
| 66 | try { | |
| 67 |
1
1. parseStringList : replaced return value with Collections.emptyList for edu/ucsb/cs/scaffold/controller/LegacyUserStateController::parseStringList → KILLED |
return objectMapper.readValue(json, new TypeReference<>() {}); |
| 68 | } catch (JsonProcessingException e) { | |
| 69 | throw new IllegalStateException("Unable to parse stored string list JSON", e); | |
| 70 | } | |
| 71 | } | |
| 72 | ||
| 73 | private JsonNode parseJsonNode(String json) { | |
| 74 | try { | |
| 75 |
1
1. parseJsonNode : replaced return value with null for edu/ucsb/cs/scaffold/controller/LegacyUserStateController::parseJsonNode → KILLED |
return objectMapper.readTree(json); |
| 76 | } catch (JsonProcessingException e) { | |
| 77 | throw new IllegalStateException("Unable to parse stored JSON payload", e); | |
| 78 | } | |
| 79 | } | |
| 80 | ||
| 81 | private String writeJson(Object value) { | |
| 82 | try { | |
| 83 |
1
1. writeJson : replaced return value with "" for edu/ucsb/cs/scaffold/controller/LegacyUserStateController::writeJson → KILLED |
return objectMapper.writeValueAsString(value); |
| 84 | } catch (JsonProcessingException e) { | |
| 85 | throw new IllegalArgumentException("Unable to serialize JSON payload", e); | |
| 86 | } | |
| 87 | } | |
| 88 | ||
| 89 | public record LegacyUserStateRequest( | |
| 90 | Long userid, | |
| 91 | @JsonProperty("starred_ids") List<String> starredIds, | |
| 92 | @JsonProperty("detail_cards") JsonNode detailCards, | |
| 93 | @JsonProperty("mastered_subconcepts") List<String> masteredSubconcepts) {} | |
| 94 | ||
| 95 | public record LegacyUserStateResponse( | |
| 96 | @JsonProperty("starred_ids") List<String> starredIds, | |
| 97 | @JsonProperty("detail_cards") JsonNode detailCards, | |
| 98 | @JsonProperty("mastered_subconcepts") List<String> masteredSubconcepts) {} | |
| 99 | } | |
Mutations | ||
| 32 |
1.1 |
|
| 36 |
1.1 |
|
| 41 |
1.1 |
|
| 47 |
1.1 |
|
| 48 |
1.1 |
|
| 53 |
1.1 |
|
| 54 |
1.1 2.2 |
|
| 55 |
1.1 |
|
| 57 |
1.1 |
|
| 58 |
1.1 |
|
| 59 |
1.1 |
|
| 62 |
1.1 |
|
| 67 |
1.1 |
|
| 75 |
1.1 |
|
| 83 |
1.1 |