diff --git a/src/main/java/com/smartcalendar/controller/FriendshipController.java b/src/main/java/com/smartcalendar/controller/FriendshipController.java new file mode 100644 index 0000000..0fd00ef --- /dev/null +++ b/src/main/java/com/smartcalendar/controller/FriendshipController.java @@ -0,0 +1,55 @@ +package com.smartcalendar.controller; + +import com.smartcalendar.dto.SubscriptionRequest; +import com.smartcalendar.model.Friendship; +import com.smartcalendar.service.FriendshipService; +import jakarta.validation.Valid; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/api/friendships") +public class FriendshipController { + + private final FriendshipService friendshipService; + + @Autowired + public FriendshipController(FriendshipService friendshipService) { + this.friendshipService = friendshipService; + } + + @GetMapping("/my-subscriptions") + public ResponseEntity> getMySubscriptions( + @AuthenticationPrincipal UserDetails userDetails + ) { + Long currentUserId = Long.parseLong(userDetails.getUsername()); + List subscriptions = friendshipService.getSubscriptions(currentUserId); + return ResponseEntity.ok(subscriptions); + } + + @PostMapping("/subscribe") + public ResponseEntity subscribe( + @AuthenticationPrincipal UserDetails userDetails, + @RequestBody @Valid SubscriptionRequest request + ) { + Long currentUserId = Long.parseLong(userDetails.getUsername()); + Friendship subscription = friendshipService.createSubscription(currentUserId, request.getUser2Id()); + return ResponseEntity.status(HttpStatus.CREATED).body(subscription); + } + + @DeleteMapping("/unsubscribe/{followingId}") + public ResponseEntity unsubscribe( + @AuthenticationPrincipal UserDetails userDetails, + @PathVariable Long user2Id + ) { + Long currentUserId = Long.parseLong(userDetails.getUsername()); + friendshipService.deleteSubscription(currentUserId, user2Id); + return ResponseEntity.noContent().build(); + } +} diff --git a/src/main/java/com/smartcalendar/dto/SubscriptionRequest.java b/src/main/java/com/smartcalendar/dto/SubscriptionRequest.java new file mode 100644 index 0000000..8d35615 --- /dev/null +++ b/src/main/java/com/smartcalendar/dto/SubscriptionRequest.java @@ -0,0 +1,14 @@ +package com.smartcalendar.dto; + +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Data +public class SubscriptionRequest { + private Long user2Id; + + public Long getUser2Id() { + return user2Id; + } +} + diff --git a/src/main/java/com/smartcalendar/exceptions/ConflictException.java b/src/main/java/com/smartcalendar/exceptions/ConflictException.java new file mode 100644 index 0000000..3925333 --- /dev/null +++ b/src/main/java/com/smartcalendar/exceptions/ConflictException.java @@ -0,0 +1,11 @@ +package com.smartcalendar.exceptions; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(HttpStatus.CONFLICT) +public class ConflictException extends RuntimeException { + public ConflictException(String message) { + super(message); + } +} diff --git a/src/main/java/com/smartcalendar/exceptions/ResourceNotFoundException.java b/src/main/java/com/smartcalendar/exceptions/ResourceNotFoundException.java new file mode 100644 index 0000000..8f2549b --- /dev/null +++ b/src/main/java/com/smartcalendar/exceptions/ResourceNotFoundException.java @@ -0,0 +1,12 @@ +package com.smartcalendar.exceptions; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(HttpStatus.NOT_FOUND) +public class ResourceNotFoundException extends RuntimeException { + public ResourceNotFoundException(String message) { + super(message); + } +} + diff --git a/src/main/java/com/smartcalendar/model/Friendship.java b/src/main/java/com/smartcalendar/model/Friendship.java index 418ce00..c9dd657 100644 --- a/src/main/java/com/smartcalendar/model/Friendship.java +++ b/src/main/java/com/smartcalendar/model/Friendship.java @@ -16,7 +16,7 @@ public class Friendship { @Id //@GeneratedValue(strategy = GenerationType.IDENTITY) - private UUID id; + private Long id; @ManyToOne @JoinColumn(name = "user_id1") @@ -27,4 +27,12 @@ public class Friendship { @JoinColumn(name = "user_id2") @JsonBackReference(value = "friends2") private User user2; + + public void setUser1(User user1) { + this.user1 = user1; + } + + public void setUser2(User user2) { + this.user2 = user2; + } } diff --git a/src/main/java/com/smartcalendar/repository/FriendshipRepository.java b/src/main/java/com/smartcalendar/repository/FriendshipRepository.java new file mode 100644 index 0000000..873e877 --- /dev/null +++ b/src/main/java/com/smartcalendar/repository/FriendshipRepository.java @@ -0,0 +1,14 @@ +package com.smartcalendar.repository; + +import com.smartcalendar.model.Friendship; +import com.smartcalendar.model.User; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; +import java.util.Optional; + +public interface FriendshipRepository extends JpaRepository { + List findByUser1(User user1); + Optional findByUser1AndUser2(User user1, User user2); + boolean existsByUser1AndUser2(User user1, User user2); +} \ No newline at end of file diff --git a/src/main/java/com/smartcalendar/service/FriendshipService.java b/src/main/java/com/smartcalendar/service/FriendshipService.java new file mode 100644 index 0000000..7c6ef76 --- /dev/null +++ b/src/main/java/com/smartcalendar/service/FriendshipService.java @@ -0,0 +1,60 @@ +package com.smartcalendar.service; + +import com.smartcalendar.exceptions.ConflictException; +import com.smartcalendar.exceptions.ResourceNotFoundException; +import com.smartcalendar.model.Friendship; +import com.smartcalendar.model.User; +import com.smartcalendar.repository.FriendshipRepository; +import com.smartcalendar.repository.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class FriendshipService { + + private final FriendshipRepository friendshipRepository; + private final UserRepository userRepository; + + @Autowired + public FriendshipService(FriendshipRepository friendshipRepository, UserRepository userRepository) { + this.friendshipRepository = friendshipRepository; + this.userRepository = userRepository; + } + + public List getSubscriptions(Long user1Id) { + userRepository.findById(user1Id).orElseThrow(() -> + new ResourceNotFoundException("User not found with id: " + user1Id)); + return friendshipRepository.findByUser1(userRepository.findById(user1Id).get()); + } + + public Friendship createSubscription(Long user1Id, Long user2Id) { + userRepository.findById(user1Id).orElseThrow(() -> + new ResourceNotFoundException("User not found with id: " + user1Id)); + + userRepository.findById(user2Id).orElseThrow(() -> + new ResourceNotFoundException("User not found with id: " + user2Id)); + + User user1 = userRepository.findById(user1Id).get(); + User user2 = userRepository.findById(user2Id).get(); + + if (friendshipRepository.existsByUser1AndUser2(user1, user2)) { + throw new ConflictException("Subscription already exists"); + } + + Friendship subscription = new Friendship(); + subscription.setUser1(user1); + subscription.setUser2(user2); + + return friendshipRepository.save(subscription); + } + + public void deleteSubscription(Long user1Id, Long user2Id) { + Friendship subscription = friendshipRepository + .findByUser1AndUser2(userRepository.findById(user1Id).get(), userRepository.findById(user2Id).get()) + .orElseThrow(() -> new ResourceNotFoundException("Subscription not found")); + + friendshipRepository.delete(subscription); + } +} \ No newline at end of file