diff --git a/src/main/java/com/example/tampopotest/controller/ActivityController.java b/src/main/java/com/example/tampopotest/controller/ActivityController.java new file mode 100644 index 0000000..cb46b76 --- /dev/null +++ b/src/main/java/com/example/tampopotest/controller/ActivityController.java @@ -0,0 +1,246 @@ +package com.example.tampopotest.controller; + +import com.example.tampopotest.entity.Activity; +import com.example.tampopotest.entity.User; +import com.example.tampopotest.repository.ActivityRepository; +import com.example.tampopotest.repository.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.stream.Collectors; + +@RestController +@RequestMapping("/users/{user-id}/activities") +public class ActivityController { + + @Autowired + private ActivityRepository activityRepository; + + @Autowired + private UserRepository userRepository; + + // GET /users/{user-id}/activities - アクティビティ一覧を返す + @GetMapping + public ResponseEntity getActivities(@PathVariable("user-id") String userId) { + try { + Optional userOpt = userRepository.findByUserId(userId); + if (userOpt.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("データが存在しません"); + } + + List activities = activityRepository.findByUserId(userId); + List> response = activities.stream() + .map(activity -> { + Map activityMap = new HashMap<>(); + activityMap.put("activity-id", activity.getActivityId()); + activityMap.put("text", activity.getText()); + activityMap.put("updated-time", activity.getUpdatedTime() != null ? + activity.getUpdatedTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) : null); + return activityMap; + }) + .collect(Collectors.toList()); + + return ResponseEntity.ok(response); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("予期せぬエラー"); + } + } + + // POST /users/{user-id}/activities - アクティビティの作成 + @PostMapping(consumes = "application/x-www-form-urlencoded") + public ResponseEntity createActivity(@PathVariable("user-id") String userId, + @RequestParam("token") String token, + @RequestParam("activity-id") String activityId) { + try { + Optional userOpt = userRepository.findByUserId(userId); + if (userOpt.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("データが存在しません"); + } + + User user = userOpt.get(); + if (user.getToken() == null) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("未認証"); + } + + if (!user.getToken().equals(token)) { + return ResponseEntity.status(HttpStatus.FORBIDDEN).body("トークンの不一致"); + } + + Activity activity = new Activity(activityId, userId); + activityRepository.save(activity); + + Map response = new HashMap<>(); + response.put("activity-id", activity.getActivityId()); + response.put("text", activity.getText()); + response.put("updated-time", activity.getUpdatedTime() != null ? + activity.getUpdatedTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) : null); + + return ResponseEntity.ok(response); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("予期せぬエラー"); + } + } + + // GET /users/{user-id}/activities/{activity-id} - 単一アクティビティを返す + @GetMapping("/{activity-id}") + public ResponseEntity getActivity(@PathVariable("user-id") String userId, + @PathVariable("activity-id") String activityId) { + try { + Optional activityOpt = activityRepository.findByUserIdAndActivityId(userId, activityId); + if (activityOpt.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("データが存在しません"); + } + + Activity activity = activityOpt.get(); + Map response = new HashMap<>(); + response.put("activity-id", activity.getActivityId()); + response.put("text", activity.getText()); + response.put("updated-time", activity.getUpdatedTime() != null ? + activity.getUpdatedTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) : null); + + return ResponseEntity.ok(response); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("予期せぬエラー"); + } + } + + // DELETE /users/{user-id}/activities/{activity-id} - アクティビティの削除 + @DeleteMapping("/{activity-id}") + @Transactional + public ResponseEntity deleteActivity(@PathVariable("user-id") String userId, + @PathVariable("activity-id") String activityId, + @RequestParam("token") String token) { + try { + Optional userOpt = userRepository.findByUserId(userId); + if (userOpt.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("データが存在しません"); + } + + User user = userOpt.get(); + if (user.getToken() == null) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("未認証"); + } + + if (!user.getToken().equals(token)) { + return ResponseEntity.status(HttpStatus.FORBIDDEN).body("トークンの不一致"); + } + + Optional activityOpt = activityRepository.findByUserIdAndActivityId(userId, activityId); + if (activityOpt.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("データが存在しません"); + } + + activityRepository.deleteByUserIdAndActivityId(userId, activityId); + return ResponseEntity.ok().build(); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("予期せぬエラー"); + } + } + + // GET /users/{user-id}/activities/{activity-id}/text - アクティビティのテキスト取得 + @GetMapping("/{activity-id}/text") + public ResponseEntity getActivityText(@PathVariable("user-id") String userId, + @PathVariable("activity-id") String activityId) { + try { + Optional activityOpt = activityRepository.findByUserIdAndActivityId(userId, activityId); + if (activityOpt.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("データが存在しません"); + } + + return ResponseEntity.ok(activityOpt.get().getText()); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("予期せぬエラー"); + } + } + + // PUT /users/{user-id}/activities/{activity-id}/text - アクティビティのテキスト更新 + @PutMapping(value = "/{activity-id}/text", consumes = "application/x-www-form-urlencoded") + public ResponseEntity updateActivityText(@PathVariable("user-id") String userId, + @PathVariable("activity-id") String activityId, + @RequestParam("token") String token, + @RequestParam("new-text") String newText) { + try { + Optional userOpt = userRepository.findByUserId(userId); + if (userOpt.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("データが存在しません"); + } + + User user = userOpt.get(); + if (user.getToken() == null) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("未認証"); + } + + if (!user.getToken().equals(token)) { + return ResponseEntity.status(HttpStatus.FORBIDDEN).body("トークンの不一致"); + } + + Optional activityOpt = activityRepository.findByUserIdAndActivityId(userId, activityId); + if (activityOpt.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("データが存在しません"); + } + + Activity activity = activityOpt.get(); + activity.setText(newText); + activity.setUpdatedTime(LocalDateTime.now()); + activityRepository.save(activity); + + return ResponseEntity.ok(activity.getText()); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("予期せぬエラー"); + } + } + + // GET /users/{user-id}/activities/{activity-id}/updated-time - アクティビティの更新時刻取得 + @GetMapping("/{activity-id}/updated-time") + public ResponseEntity getActivityUpdatedTime(@PathVariable("user-id") String userId, + @PathVariable("activity-id") String activityId) { + try { + Optional activityOpt = activityRepository.findByUserIdAndActivityId(userId, activityId); + if (activityOpt.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("データが存在しません"); + } + + Activity activity = activityOpt.get(); + String updatedTime = activity.getUpdatedTime() != null ? + activity.getUpdatedTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) : null; + + return ResponseEntity.ok(updatedTime); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("予期せぬエラー"); + } + } + + // GET /users/{user-id}/activities/last-updated-time - 最終更新時刻取得 + @GetMapping("/last-updated-time") + public ResponseEntity getLastUpdatedTime(@PathVariable("user-id") String userId) { + try { + Optional userOpt = userRepository.findByUserId(userId); + if (userOpt.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("データが存在しません"); + } + + List activities = activityRepository.findByUserId(userId); + if (activities.isEmpty()) { + return ResponseEntity.ok(null); + } + + Optional lastUpdated = activities.stream() + .map(Activity::getUpdatedTime) + .filter(Objects::nonNull) + .max(LocalDateTime::compareTo); + + String result = lastUpdated.map(time -> time.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)) + .orElse(null); + + return ResponseEntity.ok(result); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("予期せぬエラー"); + } + } +}