Weiter am Dating gearbeitet
Some checks failed
Host-Based Deploy (Java 21 Fix) / build-and-run (push) Has been cancelled

This commit is contained in:
2026-04-04 00:09:08 +02:00
parent 87c85b1b17
commit d386f5a7a9
61 changed files with 29863 additions and 350 deletions

View File

@@ -1,15 +1,19 @@
package de.oaa.xxx.social;
import de.oaa.xxx.dating.DatingMatchRepository;
import de.oaa.xxx.social.dto.ConversationSummary;
import de.oaa.xxx.social.dto.FriendshipDto;
import de.oaa.xxx.social.dto.MessageDto;
import de.oaa.xxx.social.dto.UserProfile;
import de.oaa.xxx.social.entity.BlockEntity;
import de.oaa.xxx.social.entity.FriendshipEntity;
import de.oaa.xxx.social.entity.FriendshipEntity.Status;
import de.oaa.xxx.social.entity.MessageCause;
import de.oaa.xxx.social.entity.MessageEntity;
import de.oaa.xxx.social.repository.BlockRepository;
import de.oaa.xxx.social.repository.FriendshipRepository;
import de.oaa.xxx.social.repository.MessageRepository;
import de.oaa.xxx.subscription.SubscriptionLimitService;
import de.oaa.xxx.support.SupportUserService;
import de.oaa.xxx.user.UserEntity;
import de.oaa.xxx.user.UserRepository;
@@ -33,6 +37,9 @@ public class SocialController {
private final UserRepository userRepository;
private final FriendshipRepository friendshipRepository;
private final MessageRepository messageRepository;
private final BlockRepository blockRepository;
private final DatingMatchRepository datingMatchRepository;
private final SubscriptionLimitService subscriptionLimitService;
private final SseService sseService;
private final SystemMessageService systemMessageService;
private final UserService userService;
@@ -40,12 +47,18 @@ public class SocialController {
public SocialController(UserRepository userRepository,
FriendshipRepository friendshipRepository,
MessageRepository messageRepository,
BlockRepository blockRepository,
DatingMatchRepository datingMatchRepository,
SubscriptionLimitService subscriptionLimitService,
SseService sseService,
SystemMessageService systemMessageService,
UserService userService) {
this.userRepository = userRepository;
this.friendshipRepository = friendshipRepository;
this.messageRepository = messageRepository;
this.blockRepository = blockRepository;
this.datingMatchRepository = datingMatchRepository;
this.subscriptionLimitService = subscriptionLimitService;
this.sseService = sseService;
this.systemMessageService = systemMessageService;
this.userService = userService;
@@ -202,7 +215,7 @@ public class SocialController {
// ── Messages ──
@PostMapping("/messages")
public ResponseEntity<Void> sendMessage(@RequestBody SendMessageBody body, Principal principal) {
public ResponseEntity<Map<String, String>> sendMessage(@RequestBody SendMessageBody body, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
if (body.text() == null || body.text().isBlank()) return ResponseEntity.badRequest().build();
@@ -212,6 +225,23 @@ public class SocialController {
return ResponseEntity.status(403).build();
}
// Blockiert? (in beide Richtungen)
if (blockRepository.existsBlock(myId, body.receiverId())) {
return ResponseEntity.status(403).body(Map.of("reason", "BLOCKED"));
}
// Erste Nachricht in dieser Konversation → Bedingungen prüfen
if (!messageRepository.conversationExists(myId, body.receiverId())) {
boolean areFriends = friendshipRepository.findExisting(myId, body.receiverId())
.filter(f -> f.getStatus() == Status.ACCEPTED).isPresent();
boolean haveMatch = datingMatchRepository.existsByUsers(myId, body.receiverId());
boolean hasPro = subscriptionLimitService.hasActivePaidSubscription(myId);
if (!areFriends && !haveMatch && !hasPro) {
return ResponseEntity.status(403).body(Map.of("reason", "FIRST_MESSAGE_RESTRICTED"));
}
}
MessageEntity msg = new MessageEntity();
msg.setMessageId(UUID.randomUUID());
msg.setSenderId(myId);
@@ -297,6 +327,54 @@ public class SocialController {
return ResponseEntity.ok(Map.of("messages", messages.stream().map(this::toMessageDto).toList(), "hasMore", hasMore));
}
// ── Block ──
@PostMapping("/block/{userId}")
public ResponseEntity<Void> blockUser(@PathVariable("userId") UUID targetId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
if (myId.equals(targetId)) return ResponseEntity.badRequest().build();
// Bereits blockiert?
if (blockRepository.findByBlockerIdAndBlockedId(myId, targetId).isPresent()) {
return ResponseEntity.status(409).build();
}
// Block speichern
BlockEntity block = new BlockEntity();
block.setBlockId(UUID.randomUUID());
block.setBlockerId(myId);
block.setBlockedId(targetId);
block.setBlockedAt(LocalDateTime.now());
blockRepository.save(block);
LOGGER.info("User {} hat User {} blockiert", myId, targetId);
// Gesamte Konversation löschen
messageRepository.deleteConversation(myId, targetId);
// Bestehende Freundschaft aufheben
friendshipRepository.findExisting(myId, targetId).ifPresent(friendshipRepository::delete);
return ResponseEntity.status(201).build();
}
@DeleteMapping("/block/{userId}")
public ResponseEntity<Void> unblockUser(@PathVariable("userId") UUID targetId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
if (blockRepository.findByBlockerIdAndBlockedId(myId, targetId).isEmpty()) {
return ResponseEntity.notFound().build();
}
blockRepository.deleteByBlockerIdAndBlockedId(myId, targetId);
LOGGER.info("User {} hat User {} entblockt", myId, targetId);
return ResponseEntity.noContent().build();
}
@GetMapping("/block/{userId}")
public ResponseEntity<Map<String, Boolean>> getBlockStatus(@PathVariable("userId") UUID targetId, Principal principal) {
UUID myId = userService.requireUser(principal).getUserId();
boolean blockedByMe = blockRepository.findByBlockerIdAndBlockedId(myId, targetId).isPresent();
return ResponseEntity.ok(Map.of("blockedByMe", blockedByMe));
}
// ── Helpers ──
private UserProfile toUserProfileWithStatus(UserEntity user, UUID myId) {
@@ -348,7 +426,8 @@ public class SocialController {
user.getSichtbarkeitXp(),
user.getSichtbarkeitLockhistorie(),
user.getSichtbarkeitVorlieben(),
user.isProfilBeiVeroeffentlichungenSichtbar());
user.isProfilBeiVeroeffentlichungenSichtbar(),
user.isDatingAktiv());
}
private MessageDto toMessageDto(MessageEntity m) {