diff --git a/docs/API-CHANGES-CHATROOM-INIT-MESSAGE.md b/docs/API-CHANGES-CHATROOM-INIT-MESSAGE.md new file mode 100644 index 00000000..56ceb8be --- /dev/null +++ b/docs/API-CHANGES-CHATROOM-INIT-MESSAGE.md @@ -0,0 +1,180 @@ +# API 변경 사항 - 채팅방 초기 메시지 개선 + +## 개요 + +채팅방 생성 시 표시되는 초기 메시지가 다음과 같이 개선되었습니다: + +1. **초기 메시지 2개로 분리**: 기존 1개의 메시지에서 2개의 별도 메시지로 분리 +2. **RelationshipStatus 기반 맞춤 메시지**: 사용자의 연애 상태에 따라 두 번째 메시지 내용 변경 +3. **애착유형 프롬프트 시스템 메시지**: 애착유형 테스트를 하지 않은 사용자에게 안내 메시지 표시 + +--- + +## 1. 초기 메시지 분리 + +### 변경 전 + +채팅방 생성 시 1개의 메시지만 저장: +``` +"{nickname}아 안녕! 나는 연애 고민 상담사 모모야..." +``` + +### 변경 후 + +채팅방 생성 시 2개의 메시지가 순차적으로 저장: + +| 순서 | SenderType | 내용 | +|------|------------|------| +| 1 | `ASSISTANT` | `"{nickname}아 안녕!"` 또는 `"{nickname}야 안녕!"` (조사 자동 처리) | +| 2 | `ASSISTANT` | 연애 상태에 따른 맞춤 메시지 (아래 참조) | + +--- + +## 2. RelationshipStatus 기반 맞춤 메시지 + +두 번째 초기 메시지는 사용자의 `RelationshipStatus`에 따라 다른 내용을 표시합니다. + +### 공통 Prefix +모든 메시지는 다음 내용으로 시작합니다: +``` +나는 연애 고민 상담사 모모야. +나와의 대화를 마무리하고 싶다면 종료하기 버튼을 눌러줘! 대화 종료 후에는 대화 요약 리포트를 보여줄게. +``` + +### RelationshipStatus별 메시지 + +| RelationshipStatus | 추가되는 메시지 | +|--------------------|----------------| +| `SEEING_SOMEONE` | "오늘은 어떤 고민 때문에 나를 찾아왔어? 마음에 두고 있는 상대와 있었던 상황을 이야기해 주면 내가 같이 고민해볼게!" | +| `IN_RELATIONSHIP` | "오늘은 어떤 고민 때문에 나를 찾아왔어? 먼저 연인과 있었던 갈등 상황을 이야기해 주면 내가 같이 고민해볼게!" | +| `BREAKUP` | "오늘은 어떤 고민 때문에 나를 찾아왔어? 이별 전후로 마음에 남아 있는 상황을 이야기해 주면 내가 같이 고민해볼게!" | +| `null` (미설정) | `SEEING_SOMEONE`과 동일한 메시지 | + +### 예시 - IN_RELATIONSHIP 사용자 + +```json +{ + "list": [ + { + "messageId": 1, + "senderType": "ASSISTANT", + "content": "민수야 안녕!", + "createdAt": "2026-01-30T10:00:00" + }, + { + "messageId": 2, + "senderType": "ASSISTANT", + "content": "나는 연애 고민 상담사 모모야.\n나와의 대화를 마무리하고 싶다면 종료하기 버튼을 눌러줘! 대화 종료 후에는 대화 요약 리포트를 보여줄게.\n오늘은 어떤 고민 때문에 나를 찾아왔어? 먼저 연인과 있었던 갈등 상황을 이야기해 주면 내가 같이 고민해볼게!", + "createdAt": "2026-01-30T10:00:01" + } + ] +} +``` + +--- + +## 3. 애착유형 프롬프트 시스템 메시지 + +### 조건 +다음 조건을 **모두** 만족할 때 시스템 메시지가 표시됩니다: +- 사용자의 `loveTypeCategory`가 `null` (애착유형 테스트 미완료) +- 해당 채팅방에 `USER` 타입 메시지가 없음 (첫 메시지 전송 전) + +### 동작 방식 + +#### GET /chatrooms/{chatRoomId}/messages 조회 시 +- 조건 충족 시 마지막에 `SYSTEM` 메시지가 **동적으로** 추가됨 +- DB에 저장되지 않음 (매 조회 시 동적 추가) +- `messageId`가 `null`로 반환됨 + +#### POST /chatrooms/{chatRoomId}/messages 첫 메시지 전송 시 +- 조건 충족 시 사용자 메시지 전송 **직전**에 `SYSTEM` 메시지가 DB에 저장됨 +- 이후 조회 시에는 저장된 `SYSTEM` 메시지가 반환됨 + +### 시스템 메시지 내용 +``` +잠깐! 애착유형 테스트를 하면, 더 정확한 상담이 가능해! 그대로 진행하면 바로 상담해줄게 +``` + +### 예시 - 애착유형 미설정 사용자, 첫 메시지 전송 전 + +```json +{ + "totalCount": 3, + "list": [ + { + "messageId": 1, + "senderType": "ASSISTANT", + "content": "민수야 안녕!", + "createdAt": "2026-01-30T10:00:00" + }, + { + "messageId": 2, + "senderType": "ASSISTANT", + "content": "나는 연애 고민 상담사 모모야...(생략)", + "createdAt": "2026-01-30T10:00:01" + }, + { + "messageId": null, + "senderType": "SYSTEM", + "content": "잠깐! 애착유형 테스트를 하면, 더 정확한 상담이 가능해! 그대로 진행하면 바로 상담해줄게", + "createdAt": "2026-01-30T10:00:02" + } + ] +} +``` + +> **Note:** `messageId`가 `null`인 경우 해당 메시지는 동적으로 추가된 것입니다. + +--- + +## 클라이언트 구현 가이드 + +### 메시지 렌더링 +1. `senderType`에 따라 메시지 스타일 구분: + - `ASSISTANT`: AI 상담사 메시지 (채팅 버블 왼쪽) + - `USER`: 사용자 메시지 (채팅 버블 오른쪽) + - `SYSTEM`: 시스템 안내 메시지 (중앙 정렬, 다른 스타일) + +2. `SYSTEM` 메시지 처리: + - 애착유형 테스트 유도 문구이므로, 탭 시 애착유형 테스트 화면으로 이동하는 것을 권장 + +3. `messageId`가 `null`인 경우: + - 해당 메시지는 서버에 저장되지 않은 동적 메시지 + - 북마크 등 messageId가 필요한 기능은 비활성화 + +### 온보딩 시 RelationshipStatus 설정 권장 +- 사용자가 `RelationshipStatus`를 설정하지 않은 경우 `SEEING_SOMEONE` 기본 메시지 표시 +- 더 개인화된 상담 경험을 위해 온보딩 시 연애 상태 설정을 권장 + +--- + +## 변경된 파일 목록 + +### Constants +- `GlobalConstants.java` + - `INIT_CHAT_MESSAGE_FIRST`: `" 안녕!"` (조사와 결합) + - `INIT_CHAT_MESSAGE_SECOND_PREFIX`: 공통 prefix + - `INIT_CHAT_MESSAGE_SECOND_SEEING_SOMEONE`: 썸 상태 메시지 + - `INIT_CHAT_MESSAGE_SECOND_IN_RELATIONSHIP`: 연애 중 메시지 + - `INIT_CHAT_MESSAGE_SECOND_BREAKUP`: 이별 후 메시지 + - `ATTACHMENT_TYPE_PROMPT_MESSAGE`: 애착유형 안내 메시지 + +### Domain Layer +- `ChatMessage.java` - `createSystemTextMessage()` 팩토리 메서드 추가 +- `ChatRoomDomainService.java` - `createSystemMessage()`, `createAiMessage()` 오버로드 추가 + +### Application Layer +- `ChatRoomManagementService.java` - 초기 메시지 2개 생성, `getSecondMessageByRelationshipStatus()` 메서드 추가 +- `ChatRoomService.java` - GET 조회 시 동적 시스템 메시지 추가 로직 +- `ChatService.java` - POST 전송 시 시스템 메시지 저장 로직 +- `ChatRoomQueryHelper.java` - `hasUserMessages()` 메서드 추가 +- `LoadMessagesPort.java` - `hasUserMessages()` 인터페이스 추가 + +### Adaptor Layer +- `ChatMessageRepository.java` - `existsByChatRoomIdAndSenderType()` 쿼리 추가 +- `ChatRoomPersistenceAdapter.java` - 포트 구현 + +### Tests +- `ChatRoomManagementServiceTest.java` - 5개 단위 테스트 추가 +- `ChatRoomIntegrationTest.java` - 통합 테스트 케이스 추가 diff --git a/docs/API-CHANGES-ONBOARDING-PROFILE.md b/docs/API-CHANGES-ONBOARDING-PROFILE.md new file mode 100644 index 00000000..30182382 --- /dev/null +++ b/docs/API-CHANGES-ONBOARDING-PROFILE.md @@ -0,0 +1,198 @@ +# API 변경 사항 - 온보딩 및 프로필 필드 확장 + +## 개요 + +온보딩 및 멤버 프로필에 다음 3개 필드가 추가되었습니다: +- `relationshipStatus` - 연애 상태 (Enum) +- `personalityType` - 본인 MBTI (String) +- `otherPersonalityType` - 상대방 MBTI (String) + +--- + +## 신규 Enum + +### RelationshipStatus + +| 값 | 설명 | +|---|------| +| `IN_RELATIONSHIP` | 연애 중 | +| `SEEING_SOMEONE` | 썸 타는 중 | +| `BREAKUP` | 이별 후 | + +--- + +## 변경된 API + +### 1. POST /members/onboarding (온보딩 - 회원가입) + +**변경 전 Request:** +```json +{ + "nickname": "닉네임", + "terms": [ + { "termsId": 1, "isAgreed": true } + ] +} +``` + +**변경 후 Request:** +```json +{ + "nickname": "닉네임", + "relationshipStatus": "IN_RELATIONSHIP", + "personalityType": "INTJ", + "otherPersonalityType": "ENFP", + "terms": [ + { "termsId": 1, "isAgreed": true } + ] +} +``` + +| 필드 | 타입 | 필수 여부 | 설명 | +|------|------|-----------|------| +| `nickname` | String | 필수 | 닉네임 (1-10자, 한글/영문/숫자) | +| `relationshipStatus` | Enum | 선택 | 연애 상태 | +| `personalityType` | String | 선택 | 본인 MBTI | +| `otherPersonalityType` | String | 선택 | 상대방 MBTI | +| `terms` | Array | 필수 | 약관 동의 목록 | + +--- + +### 2. GET /members (멤버 정보 조회) + +**변경 전 Response:** +```json +{ + "memberId": 1, + "nickname": "닉네임", + "email": "user@example.com", + "provider": "KAKAO", + "loveTypeCategory": "SECURE", + "anxietyRate": 0.3, + "avoidanceRate": 0.2, + "inviteCode": "ABC123", + "isCouple": true, + "startLoveDate": "2024-01-01", + "loveDay": 365 +} +``` + +**변경 후 Response:** +```json +{ + "memberId": 1, + "nickname": "닉네임", + "email": "user@example.com", + "provider": "KAKAO", + "loveTypeCategory": "SECURE", + "anxietyRate": 0.3, + "avoidanceRate": 0.2, + "inviteCode": "ABC123", + "isCouple": true, + "startLoveDate": "2024-01-01", + "loveDay": 365, + "relationshipStatus": "IN_RELATIONSHIP", + "personalityType": "INTJ", + "otherPersonalityType": "ENFP" +} +``` + +| 추가된 필드 | 타입 | 설명 | +|-------------|------|------| +| `relationshipStatus` | Enum (nullable) | 연애 상태 | +| `personalityType` | String (nullable) | 본인 MBTI | +| `otherPersonalityType` | String (nullable) | 상대방 MBTI | + +> **Note:** 기존 사용자의 경우 위 필드들이 `null`로 반환될 수 있습니다. + +--- + +### 3. PATCH /members (멤버 정보 수정) + +**변경 전 Request:** +```json +{ + "nickname": "새닉네임" +} +``` + +**변경 후 Request:** +```json +{ + "nickname": "새닉네임", + "relationshipStatus": "SEEING_SOMEONE", + "personalityType": "ENFP", + "otherPersonalityType": "INTJ" +} +``` + +| 필드 | 타입 | 필수 여부 | 설명 | +|------|------|-----------|------| +| `nickname` | String | 선택 | 닉네임 (1-10자, 한글/영문/숫자) | +| `relationshipStatus` | Enum | 선택 | 연애 상태 | +| `personalityType` | String | 선택 | 본인 MBTI | +| `otherPersonalityType` | String | 선택 | 상대방 MBTI | + +> **Note:** 모든 필드가 선택 사항입니다. 전달된 필드만 업데이트됩니다 (부분 업데이트 지원). + +**변경 전 Response:** +```json +{ + "nickname": "새닉네임" +} +``` + +**변경 후 Response:** +```json +{ + "nickname": "새닉네임", + "relationshipStatus": "SEEING_SOMEONE", + "personalityType": "ENFP", + "otherPersonalityType": "INTJ" +} +``` + +--- + +## 마이그레이션 가이드 + +### 기존 사용자 처리 +- 기존 사용자들의 `relationshipStatus`, `personalityType`, `otherPersonalityType` 값은 `null`입니다. +- 클라이언트에서 `null` 값을 적절히 처리해야 합니다. + +### 온보딩 화면 업데이트 +1. 닉네임 입력 후 추가 정보 입력 화면 구성 +2. 연애 상태 선택 (3가지 옵션) +3. MBTI 입력 (본인/상대방) + +### 프로필 수정 화면 업데이트 +1. 기존 닉네임 수정 기능 유지 +2. 연애 상태 변경 기능 추가 +3. MBTI 수정 기능 추가 + +--- + +## 변경 파일 목록 + +### Domain Layer +- `Member.java` - 3개 필드 추가, `signUp()` 오버로드, `updateMemberProfile()` 확장 + +### Application Layer +- `SignUpUseCase.java` - SignUpCommand에 3개 필드 추가 +- `GetMemberUseCase.java` - MemberResponseDto에 3개 필드 추가 +- `UpdateMemberUseCase.java` - Command/ResponseDto에 3개 필드 추가 +- `SignUpService.java` - 새 signUp 메서드 호출 +- `MemberCommandService.java` - updateMember에서 새 필드 처리 +- `MemberInfoService.java` - 응답에 새 필드 매핑 +- `MemberQueryHelper.java` - MemberInfoDto에 3개 필드 추가 + +### Adaptor Layer +- `MemberEntity.java` - 3개 nullable 컬럼 추가 +- `MemberMapper.java` - 양방향 매핑 확장 +- `MemberPersistenceAdapter.java` - RepositoryDto에 3개 필드 추가 +- `MemberRepositoryCustomImpl.java` - QueryDSL select 확장 +- `SignUpController.java` - RequestDto에 3개 필드 추가 +- `MemberController.java` - UpdateMemberRequestDto에 3개 필드 추가 + +### Enum +- `RelationshipStatus.java` - 신규 생성 diff --git a/sqls/MM-179.sql b/sqls/MM-179.sql new file mode 100644 index 00000000..ae9ebd62 --- /dev/null +++ b/sqls/MM-179.sql @@ -0,0 +1,27 @@ +-- MM-179: Add relationship_status, personality_type, and other_personality_type to member_entity +-- Author: Claude Code +-- Date: 2026-02-09 + +-- Add relationship_status column (ENUM stored as VARCHAR) +-- Possible values: 'IN_RELATIONSHIP', 'SEEING_SOMEONE', 'BREAKUP' +ALTER TABLE member_entity +ADD COLUMN relationship_status VARCHAR(255); + +-- Add personality_type column +ALTER TABLE member_entity +ADD COLUMN personality_type VARCHAR(255); + +-- Add other_personality_type column +ALTER TABLE member_entity +ADD COLUMN other_personality_type VARCHAR(255); + +-- Add comment for documentation +COMMENT ON COLUMN member_entity.relationship_status IS 'Relationship status: IN_RELATIONSHIP, SEEING_SOMEONE, BREAKUP'; +COMMENT ON COLUMN member_entity.personality_type IS 'Member personality type'; +COMMENT ON COLUMN member_entity.other_personality_type IS 'Partner personality type'; + +-- Optional: Add check constraint to ensure valid enum values +-- Uncomment if you want to enforce enum values at database level +-- ALTER TABLE member_entity +-- ADD CONSTRAINT chk_relationship_status +-- CHECK (relationship_status IN ('IN_RELATIONSHIP', 'SEEING_SOMEONE', 'BREAKUP') OR relationship_status IS NULL); diff --git a/src/main/java/makeus/cmc/malmo/adaptor/in/web/controller/MemberController.java b/src/main/java/makeus/cmc/malmo/adaptor/in/web/controller/MemberController.java index b0c2eb77..92f36274 100644 --- a/src/main/java/makeus/cmc/malmo/adaptor/in/web/controller/MemberController.java +++ b/src/main/java/makeus/cmc/malmo/adaptor/in/web/controller/MemberController.java @@ -16,6 +16,7 @@ import makeus.cmc.malmo.adaptor.in.web.dto.BaseListResponse; import makeus.cmc.malmo.adaptor.in.web.dto.BaseResponse; import makeus.cmc.malmo.application.port.in.member.*; +import makeus.cmc.malmo.domain.value.type.RelationshipStatus; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.core.userdetails.User; import org.springframework.web.bind.annotation.*; @@ -101,6 +102,9 @@ public BaseResponse updateMember( UpdateMemberUseCase.UpdateMemberCommand command = UpdateMemberUseCase.UpdateMemberCommand.builder() .memberId(Long.valueOf(user.getUsername())) .nickname(requestDto.getNickname()) + .relationshipStatus(requestDto.getRelationshipStatus()) + .personalityType(requestDto.getPersonalityType()) + .otherPersonalityType(requestDto.getOtherPersonalityType()) .build(); return BaseResponse.success(updateMemberUseCase.updateMember(command)); } @@ -242,10 +246,13 @@ public BaseResponse upda @Data public static class UpdateMemberRequestDto { - @NotBlank(message = "닉네임은 필수 입력값입니다.") @Size(min = 1, max = 10, message = "닉네임은 1자 이상 10자 이하여야 합니다.") @Pattern(regexp = "^[가-힣a-zA-Z0-9]+$", message = "닉네임은 한글, 영문, 숫자만 사용 가능합니다.") private String nickname; + + private RelationshipStatus relationshipStatus; + private String personalityType; + private String otherPersonalityType; } @Data diff --git a/src/main/java/makeus/cmc/malmo/adaptor/in/web/controller/SignUpController.java b/src/main/java/makeus/cmc/malmo/adaptor/in/web/controller/SignUpController.java index b2c3be01..71b38407 100644 --- a/src/main/java/makeus/cmc/malmo/adaptor/in/web/controller/SignUpController.java +++ b/src/main/java/makeus/cmc/malmo/adaptor/in/web/controller/SignUpController.java @@ -14,6 +14,7 @@ import makeus.cmc.malmo.adaptor.in.web.docs.SwaggerResponses; import makeus.cmc.malmo.adaptor.in.web.dto.BaseResponse; import makeus.cmc.malmo.application.port.in.member.SignUpUseCase; +import makeus.cmc.malmo.domain.value.type.RelationshipStatus; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.core.userdetails.User; import org.springframework.web.bind.annotation.PostMapping; @@ -58,6 +59,9 @@ public BaseResponse signUp( .terms(termsCommandList) .nickname(requestDto.getNickname()) .loveTypeId(requestDto.getLoveTypeId()) + .relationshipStatus(requestDto.getRelationshipStatus()) + .personalityType(requestDto.getPersonalityType()) + .otherPersonalityType(requestDto.getOtherPersonalityType()) .build(); signUpUseCase.signUp(command); @@ -75,7 +79,13 @@ public static class SignUpRequestDto { @Pattern(regexp = "^[가-힣a-zA-Z0-9]+$", message = "닉네임은 한글, 영문, 숫자만 사용 가능합니다.") private String nickname; - private Long loveTypeId; // Optional, 애착 유형 결과를 매핑하기 위한 ID + private Long loveTypeId; + + private RelationshipStatus relationshipStatus; + + private String personalityType; + + private String otherPersonalityType; } @Data diff --git a/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/adapter/ChatRoomPersistenceAdapter.java b/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/adapter/ChatRoomPersistenceAdapter.java index 8dea6e82..8e061dd9 100644 --- a/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/adapter/ChatRoomPersistenceAdapter.java +++ b/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/adapter/ChatRoomPersistenceAdapter.java @@ -16,6 +16,7 @@ import makeus.cmc.malmo.domain.model.chat.ChatRoom; import makeus.cmc.malmo.domain.value.id.ChatRoomId; import makeus.cmc.malmo.domain.value.id.MemberId; +import makeus.cmc.malmo.domain.value.type.SenderType; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; @@ -83,6 +84,11 @@ public long countMessagesByLevel(ChatRoomId chatRoomId, int level) { return chatMessageRepository.countByChatRoomIdAndLevel(chatRoomId.getValue(), level); } + @Override + public boolean hasUserMessages(ChatRoomId chatRoomId) { + return chatMessageRepository.existsByChatRoomIdAndSenderType(chatRoomId.getValue(), SenderType.USER); + } + @Override public List loadActiveChatRoomsByMemberId(MemberId memberId) { return chatRoomRepository.findActiveChatRoomsByMemberEntityId(memberId.getValue()) diff --git a/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/adapter/MemberPersistenceAdapter.java b/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/adapter/MemberPersistenceAdapter.java index 15d28e63..72af5421 100644 --- a/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/adapter/MemberPersistenceAdapter.java +++ b/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/adapter/MemberPersistenceAdapter.java @@ -20,6 +20,7 @@ import makeus.cmc.malmo.domain.value.id.MemberId; import makeus.cmc.malmo.domain.value.type.LoveTypeCategory; import makeus.cmc.malmo.domain.value.type.Provider; +import makeus.cmc.malmo.domain.value.type.RelationshipStatus; import org.springframework.stereotype.Component; import java.time.LocalDate; @@ -102,6 +103,9 @@ public static class MemberResponseRepositoryDto { private float anxietyRate; private String nickname; private String email; + private RelationshipStatus relationshipStatus; + private String personalityType; + private String otherPersonalityType; public MemberQueryHelper.MemberInfoDto toDto(int totalChatRoomCount, int totalCoupleQuestionCount) { return MemberQueryHelper.MemberInfoDto.builder() @@ -115,6 +119,9 @@ public MemberQueryHelper.MemberInfoDto toDto(int totalChatRoomCount, int totalCo .email(email) .totalChatRoomCount(totalChatRoomCount) .totalCoupleQuestionCount(totalCoupleQuestionCount) + .relationshipStatus(relationshipStatus) + .personalityType(personalityType) + .otherPersonalityType(otherPersonalityType) .build(); } } diff --git a/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/entity/member/MemberEntity.java b/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/entity/member/MemberEntity.java index d8702665..a4154877 100644 --- a/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/entity/member/MemberEntity.java +++ b/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/entity/member/MemberEntity.java @@ -14,6 +14,7 @@ import makeus.cmc.malmo.domain.value.type.LoveTypeCategory; import makeus.cmc.malmo.domain.value.type.MemberRole; import makeus.cmc.malmo.domain.value.type.Provider; +import makeus.cmc.malmo.domain.value.type.RelationshipStatus; import java.time.LocalDate; @@ -69,4 +70,11 @@ public class MemberEntity extends BaseTimeEntity { @Embedded private CoupleEntityId coupleEntityId; + + @Enumerated(value = EnumType.STRING) + private RelationshipStatus relationshipStatus; + + private String personalityType; + + private String otherPersonalityType; } diff --git a/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/mapper/MemberMapper.java b/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/mapper/MemberMapper.java index d14eefe0..30ac893e 100644 --- a/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/mapper/MemberMapper.java +++ b/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/mapper/MemberMapper.java @@ -33,6 +33,9 @@ public Member toDomain(MemberEntity entity) { entity.getStartLoveDate(), entity.getOauthToken(), entity.getCoupleEntityId() != null ? CoupleId.of(entity.getCoupleEntityId().getValue()) : null, + entity.getRelationshipStatus(), + entity.getPersonalityType(), + entity.getOtherPersonalityType(), entity.getCreatedAt(), entity.getModifiedAt(), entity.getDeletedAt() @@ -61,6 +64,9 @@ public MemberEntity toEntity(Member domain) { .startLoveDate(domain.getStartLoveDate()) .oauthToken(domain.getOauthToken()) .coupleEntityId(domain.getCoupleId() != null ? CoupleEntityId.of(domain.getCoupleId().getValue()) : null) + .relationshipStatus(domain.getRelationshipStatus()) + .personalityType(domain.getPersonalityType()) + .otherPersonalityType(domain.getOtherPersonalityType()) .createdAt(domain.getCreatedAt()) .modifiedAt(domain.getModifiedAt()) .deletedAt(domain.getDeletedAt()) diff --git a/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/repository/chat/ChatMessageRepository.java b/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/repository/chat/ChatMessageRepository.java index 29cae069..e2af50c7 100644 --- a/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/repository/chat/ChatMessageRepository.java +++ b/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/repository/chat/ChatMessageRepository.java @@ -1,6 +1,7 @@ package makeus.cmc.malmo.adaptor.out.persistence.repository.chat; import makeus.cmc.malmo.adaptor.out.persistence.entity.chat.ChatMessageEntity; +import makeus.cmc.malmo.domain.value.type.SenderType; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -20,4 +21,7 @@ public interface ChatMessageRepository extends JpaRepository 0 THEN true ELSE false END FROM ChatMessageEntity c WHERE c.chatRoomEntityId.value = :chatRoomId AND c.senderType = :senderType") + boolean existsByChatRoomIdAndSenderType(@Param("chatRoomId") Long chatRoomId, @Param("senderType") SenderType senderType); } diff --git a/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/repository/member/MemberRepositoryCustomImpl.java b/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/repository/member/MemberRepositoryCustomImpl.java index e88ae1cc..ca2d630f 100644 --- a/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/repository/member/MemberRepositoryCustomImpl.java +++ b/src/main/java/makeus/cmc/malmo/adaptor/out/persistence/repository/member/MemberRepositoryCustomImpl.java @@ -34,7 +34,10 @@ public Optional findMember memberEntity.avoidanceRate, memberEntity.anxietyRate, memberEntity.nickname, - memberEntity.email + memberEntity.email, + memberEntity.relationshipStatus, + memberEntity.personalityType, + memberEntity.otherPersonalityType )) .from(memberEntity) .leftJoin(coupleEntity) diff --git a/src/main/java/makeus/cmc/malmo/application/helper/chat_room/ChatRoomQueryHelper.java b/src/main/java/makeus/cmc/malmo/application/helper/chat_room/ChatRoomQueryHelper.java index 9c1382bf..b2a385fa 100644 --- a/src/main/java/makeus/cmc/malmo/application/helper/chat_room/ChatRoomQueryHelper.java +++ b/src/main/java/makeus/cmc/malmo/application/helper/chat_room/ChatRoomQueryHelper.java @@ -126,4 +126,8 @@ public long countMessagesByLevel(ChatRoomId chatRoomId, int level) { public Optional getLatestSummaryByLevel(ChatRoomId chatRoomId, int level) { return loadSummarizedMessages.loadLatestSummaryByLevel(chatRoomId, level); } + + public boolean hasUserMessages(ChatRoomId chatRoomId) { + return loadMessagesPort.hasUserMessages(chatRoomId); + } } diff --git a/src/main/java/makeus/cmc/malmo/application/helper/member/MemberQueryHelper.java b/src/main/java/makeus/cmc/malmo/application/helper/member/MemberQueryHelper.java index efad6a7d..80f3090c 100644 --- a/src/main/java/makeus/cmc/malmo/application/helper/member/MemberQueryHelper.java +++ b/src/main/java/makeus/cmc/malmo/application/helper/member/MemberQueryHelper.java @@ -13,6 +13,7 @@ import makeus.cmc.malmo.domain.value.id.MemberId; import makeus.cmc.malmo.domain.value.type.LoveTypeCategory; import makeus.cmc.malmo.domain.value.type.Provider; +import makeus.cmc.malmo.domain.value.type.RelationshipStatus; import org.springframework.stereotype.Component; import java.time.LocalDate; @@ -99,6 +100,10 @@ public static class MemberInfoDto { private int totalChatRoomCount; private int totalCoupleQuestionCount; + + private RelationshipStatus relationshipStatus; + private String personalityType; + private String otherPersonalityType; } @Data diff --git a/src/main/java/makeus/cmc/malmo/application/port/in/member/GetMemberUseCase.java b/src/main/java/makeus/cmc/malmo/application/port/in/member/GetMemberUseCase.java index b3c4465d..2c70c681 100644 --- a/src/main/java/makeus/cmc/malmo/application/port/in/member/GetMemberUseCase.java +++ b/src/main/java/makeus/cmc/malmo/application/port/in/member/GetMemberUseCase.java @@ -5,6 +5,7 @@ import makeus.cmc.malmo.domain.value.state.MemberState; import makeus.cmc.malmo.domain.value.type.LoveTypeCategory; import makeus.cmc.malmo.domain.value.type.Provider; +import makeus.cmc.malmo.domain.value.type.RelationshipStatus; import java.time.LocalDate; @@ -34,5 +35,9 @@ class MemberResponseDto { private float anxietyRate; private String nickname; private String email; + + private RelationshipStatus relationshipStatus; + private String personalityType; + private String otherPersonalityType; } } diff --git a/src/main/java/makeus/cmc/malmo/application/port/in/member/SignUpUseCase.java b/src/main/java/makeus/cmc/malmo/application/port/in/member/SignUpUseCase.java index 67ba62f0..9b926adf 100644 --- a/src/main/java/makeus/cmc/malmo/application/port/in/member/SignUpUseCase.java +++ b/src/main/java/makeus/cmc/malmo/application/port/in/member/SignUpUseCase.java @@ -2,6 +2,7 @@ import lombok.Builder; import lombok.Data; +import makeus.cmc.malmo.domain.value.type.RelationshipStatus; import java.util.List; @@ -16,6 +17,9 @@ class SignUpCommand { private List terms; private String nickname; private Long loveTypeId; + private RelationshipStatus relationshipStatus; + private String personalityType; + private String otherPersonalityType; } @Data diff --git a/src/main/java/makeus/cmc/malmo/application/port/in/member/UpdateMemberUseCase.java b/src/main/java/makeus/cmc/malmo/application/port/in/member/UpdateMemberUseCase.java index 0aee5b0f..93910217 100644 --- a/src/main/java/makeus/cmc/malmo/application/port/in/member/UpdateMemberUseCase.java +++ b/src/main/java/makeus/cmc/malmo/application/port/in/member/UpdateMemberUseCase.java @@ -2,6 +2,7 @@ import lombok.Builder; import lombok.Data; +import makeus.cmc.malmo.domain.value.type.RelationshipStatus; public interface UpdateMemberUseCase { @@ -12,11 +13,17 @@ public interface UpdateMemberUseCase { class UpdateMemberCommand { private Long memberId; private String nickname; + private RelationshipStatus relationshipStatus; + private String personalityType; + private String otherPersonalityType; } @Data @Builder class UpdateMemberResponseDto { private String nickname; + private RelationshipStatus relationshipStatus; + private String personalityType; + private String otherPersonalityType; } } diff --git a/src/main/java/makeus/cmc/malmo/application/port/out/chat/LoadMessagesPort.java b/src/main/java/makeus/cmc/malmo/application/port/out/chat/LoadMessagesPort.java index 9f358cba..0528b856 100644 --- a/src/main/java/makeus/cmc/malmo/application/port/out/chat/LoadMessagesPort.java +++ b/src/main/java/makeus/cmc/malmo/application/port/out/chat/LoadMessagesPort.java @@ -25,6 +25,8 @@ public interface LoadMessagesPort { long countMessagesByLevel(ChatRoomId chatRoomId, int level); + boolean hasUserMessages(ChatRoomId chatRoomId); + @Data @AllArgsConstructor class ChatRoomMessageRepositoryDto { diff --git a/src/main/java/makeus/cmc/malmo/application/service/chat/ChatRoomManagementService.java b/src/main/java/makeus/cmc/malmo/application/service/chat/ChatRoomManagementService.java index c388aa6d..4567a210 100644 --- a/src/main/java/makeus/cmc/malmo/application/service/chat/ChatRoomManagementService.java +++ b/src/main/java/makeus/cmc/malmo/application/service/chat/ChatRoomManagementService.java @@ -13,14 +13,19 @@ import makeus.cmc.malmo.domain.service.ChatRoomDomainService; import makeus.cmc.malmo.domain.value.id.ChatRoomId; import makeus.cmc.malmo.domain.value.id.MemberId; +import makeus.cmc.malmo.domain.value.type.RelationshipStatus; import makeus.cmc.malmo.util.JosaUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDateTime; import java.util.Optional; import static makeus.cmc.malmo.util.GlobalConstants.INIT_CHATROOM_LEVEL; -import static makeus.cmc.malmo.util.GlobalConstants.INIT_CHAT_MESSAGE; +import static makeus.cmc.malmo.util.GlobalConstants.INIT_CHAT_MESSAGE_FIRST; +import static makeus.cmc.malmo.util.GlobalConstants.INIT_CHAT_MESSAGE_SECOND_SEEING_SOMEONE; +import static makeus.cmc.malmo.util.GlobalConstants.INIT_CHAT_MESSAGE_SECOND_IN_RELATIONSHIP; +import static makeus.cmc.malmo.util.GlobalConstants.INIT_CHAT_MESSAGE_SECOND_BREAKUP; @Slf4j @Service @@ -53,12 +58,27 @@ public CreateChatRoomResponse createChatRoom(CreateChatRoomCommand command) { ChatRoom chatRoom = chatRoomDomainService.createChatRoom(memberId); ChatRoom savedChatRoom = chatRoomCommandHelper.saveChatRoom(chatRoom); - ChatMessage initMessage = chatRoomDomainService.createAiMessage( + LocalDateTime now = LocalDateTime.now(); + + // 초기 AI 메시지 2개 생성 및 저장 + // 첫 번째 메시지: nickname아 안녕! + ChatMessage firstMessage = chatRoomDomainService.createAiMessage( + ChatRoomId.of(savedChatRoom.getId()), + INIT_CHATROOM_LEVEL, + 1, + JosaUtils.아야(member.getNickname()) + INIT_CHAT_MESSAGE_FIRST, + now); + chatRoomCommandHelper.saveChatMessage(firstMessage); + + // 두 번째 메시지: 나는 연애 고민 상담사 모모야.~ (1초 뒤 시간으로 저장) + String secondMessageContent = getSecondMessageByRelationshipStatus(member.getRelationshipStatus()); + ChatMessage secondMessage = chatRoomDomainService.createAiMessage( ChatRoomId.of(savedChatRoom.getId()), INIT_CHATROOM_LEVEL, 1, - JosaUtils.아야(member.getNickname()) + INIT_CHAT_MESSAGE); - chatRoomCommandHelper.saveChatMessage(initMessage); + secondMessageContent, + now.plusSeconds(1)); + chatRoomCommandHelper.saveChatMessage(secondMessage); log.info("새 BEFORE_INIT 채팅방 생성: chatRoomId={}, memberId={}", savedChatRoom.getId(), memberId.getValue()); @@ -68,4 +88,15 @@ public CreateChatRoomResponse createChatRoom(CreateChatRoomCommand command) { .createdAt(savedChatRoom.getCreatedAt()) .build(); } + + String getSecondMessageByRelationshipStatus(RelationshipStatus status) { + if (status == null) { + return INIT_CHAT_MESSAGE_SECOND_SEEING_SOMEONE; + } + return switch (status) { + case SEEING_SOMEONE -> INIT_CHAT_MESSAGE_SECOND_SEEING_SOMEONE; + case IN_RELATIONSHIP -> INIT_CHAT_MESSAGE_SECOND_IN_RELATIONSHIP; + case BREAKUP -> INIT_CHAT_MESSAGE_SECOND_BREAKUP; + }; + } } diff --git a/src/main/java/makeus/cmc/malmo/application/service/chat/ChatRoomService.java b/src/main/java/makeus/cmc/malmo/application/service/chat/ChatRoomService.java index c62fdcf9..1b10ac34 100644 --- a/src/main/java/makeus/cmc/malmo/application/service/chat/ChatRoomService.java +++ b/src/main/java/makeus/cmc/malmo/application/service/chat/ChatRoomService.java @@ -4,6 +4,7 @@ import makeus.cmc.malmo.adaptor.in.aop.CheckValidMember; import makeus.cmc.malmo.application.helper.chat_room.ChatRoomCommandHelper; import makeus.cmc.malmo.application.helper.chat_room.ChatRoomQueryHelper; +import makeus.cmc.malmo.application.helper.member.MemberQueryHelper; import makeus.cmc.malmo.application.port.in.chat.DeleteChatRoomUseCase; import makeus.cmc.malmo.application.port.in.chat.GetChatRoomListUseCase; import makeus.cmc.malmo.application.port.in.chat.GetChatRoomMessagesUseCase; @@ -11,12 +12,17 @@ import makeus.cmc.malmo.application.port.out.chat.LoadMessagesPort; import makeus.cmc.malmo.domain.model.chat.ChatMessageSummary; import makeus.cmc.malmo.domain.model.chat.ChatRoom; +import makeus.cmc.malmo.domain.model.member.Member; import makeus.cmc.malmo.domain.value.id.ChatRoomId; import makeus.cmc.malmo.domain.value.id.MemberId; +import makeus.cmc.malmo.domain.value.type.SenderType; +import makeus.cmc.malmo.util.GlobalConstants; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; @RequiredArgsConstructor @@ -27,6 +33,7 @@ public class ChatRoomService private final ChatRoomQueryHelper chatRoomQueryHelper; private final ChatRoomCommandHelper chatRoomCommandHelper; + private final MemberQueryHelper memberQueryHelper; @Override @CheckValidMember @@ -79,12 +86,13 @@ public GetChatRoomListResponse getChatRoomList(GetChatRoomListCommand command) { @CheckValidMember public GetCurrentChatRoomMessagesResponse getChatRoomMessages(GetChatRoomMessagesCommand command) { MemberId memberId = MemberId.of(command.getUserId()); - chatRoomQueryHelper.validateChatRoomOwnership(memberId, ChatRoomId.of(command.getChatRoomId())); + ChatRoomId chatRoomId = ChatRoomId.of(command.getChatRoomId()); + chatRoomQueryHelper.validateChatRoomOwnership(memberId, chatRoomId); Page result = - chatRoomQueryHelper.getChatMessagesDtoAsc(ChatRoomId.of(command.getChatRoomId()), memberId, command.getPageable()); + chatRoomQueryHelper.getChatMessagesDtoAsc(chatRoomId, memberId, command.getPageable()); - List list = result.stream().map(cm -> + List list = new ArrayList<>(result.stream().map(cm -> GetChatRoomMessagesUseCase.ChatRoomMessageDto.builder() .messageId(cm.getMessageId()) .senderType(cm.getSenderType()) @@ -92,7 +100,22 @@ public GetCurrentChatRoomMessagesResponse getChatRoomMessages(GetChatRoomMessage .createdAt(cm.getCreatedAt()) .bookmarkId(cm.getBookmarkId()) .build()) - .toList(); + .toList()); + + // Check condition: no USER messages AND no loveTypeCategory + boolean hasUserMessages = chatRoomQueryHelper.hasUserMessages(chatRoomId); + Member member = memberQueryHelper.getMemberByIdOrThrow(memberId); + + if (!hasUserMessages && member.getLoveTypeCategory() == null) { + // Append dynamic SYSTEM message (not persisted) + list.add(GetChatRoomMessagesUseCase.ChatRoomMessageDto.builder() + .messageId(null) // Not persisted + .senderType(SenderType.SYSTEM) + .content(GlobalConstants.ATTACHMENT_TYPE_PROMPT_MESSAGE) + .createdAt(LocalDateTime.now()) + .bookmarkId(null) + .build()); + } return GetCurrentChatRoomMessagesResponse.builder() .messages(list) diff --git a/src/main/java/makeus/cmc/malmo/application/service/chat/ChatService.java b/src/main/java/makeus/cmc/malmo/application/service/chat/ChatService.java index fd60740a..98b6d5f2 100644 --- a/src/main/java/makeus/cmc/malmo/application/service/chat/ChatService.java +++ b/src/main/java/makeus/cmc/malmo/application/service/chat/ChatService.java @@ -17,6 +17,7 @@ import makeus.cmc.malmo.domain.value.id.ChatRoomId; import makeus.cmc.malmo.domain.value.id.MemberId; import makeus.cmc.malmo.util.ChatMessageSplitter; +import makeus.cmc.malmo.util.GlobalConstants; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -53,12 +54,25 @@ public SendChatMessageResponse processUserMessage(SendChatMessageCommand command Member member = memberQueryHelper.getMemberByIdOrThrow(memberId); ChatRoom chatRoom = chatRoomQueryHelper.getChatRoomByIdOrThrow(chatRoomId); + // BEFORE_INIT 상태인 경우 ALIVE로 전환 (첫 메시지 시) if (chatRoom.isBeforeInit()) { chatRoom.initialize(); chatRoomCommandHelper.saveChatRoom(chatRoom); log.info("채팅방 상태 전환: BEFORE_INIT -> ALIVE, chatRoomId={}", chatRoomId.getValue()); } + // 첫 메시지이고 애착 유형 미진단인 경우 시스템 메시지 추가 + boolean hasUserMessages = chatRoomQueryHelper.hasUserMessages(chatRoomId); + if (!hasUserMessages && member.getLoveTypeCategory() == null) { + ChatMessage systemMessage = chatRoomDomainService.createSystemMessage( + chatRoomId, + chatRoom.getLevel(), + chatRoom.getDetailedLevel(), + GlobalConstants.ATTACHMENT_TYPE_PROMPT_MESSAGE + ); + chatRoomCommandHelper.saveChatMessage(systemMessage); + } + // 현재 유저 메시지를 저장 ChatMessage savedUserMessage = saveUserMessage(chatRoom, command.getMessage()); diff --git a/src/main/java/makeus/cmc/malmo/application/service/member/MemberCommandService.java b/src/main/java/makeus/cmc/malmo/application/service/member/MemberCommandService.java index 752aaffc..b0ad5ca8 100644 --- a/src/main/java/makeus/cmc/malmo/application/service/member/MemberCommandService.java +++ b/src/main/java/makeus/cmc/malmo/application/service/member/MemberCommandService.java @@ -48,12 +48,20 @@ public class MemberCommandService implements UpdateMemberUseCase, UpdateStartLov public UpdateMemberResponseDto updateMember(UpdateMemberCommand command) { Member member = memberQueryHelper.getMemberByIdOrThrow(MemberId.of(command.getMemberId())); - member.updateMemberProfile(command.getNickname()); + member.updateMemberProfile( + command.getNickname(), + command.getRelationshipStatus(), + command.getPersonalityType(), + command.getOtherPersonalityType() + ); Member savedMember = memberCommandHelper.saveMember(member); return UpdateMemberResponseDto.builder() .nickname(savedMember.getNickname()) + .relationshipStatus(savedMember.getRelationshipStatus()) + .personalityType(savedMember.getPersonalityType()) + .otherPersonalityType(savedMember.getOtherPersonalityType()) .build(); } diff --git a/src/main/java/makeus/cmc/malmo/application/service/member/MemberInfoService.java b/src/main/java/makeus/cmc/malmo/application/service/member/MemberInfoService.java index 68e8bea0..b59e5765 100644 --- a/src/main/java/makeus/cmc/malmo/application/service/member/MemberInfoService.java +++ b/src/main/java/makeus/cmc/malmo/application/service/member/MemberInfoService.java @@ -32,6 +32,9 @@ public MemberResponseDto getMemberInfo(MemberInfoCommand command) { .totalCoupleQuestionCount(member.getTotalCoupleQuestionCount()) .nickname(member.getNickname()) .email(member.getEmail()) + .relationshipStatus(member.getRelationshipStatus()) + .personalityType(member.getPersonalityType()) + .otherPersonalityType(member.getOtherPersonalityType()) .build(); } diff --git a/src/main/java/makeus/cmc/malmo/application/service/member/SignUpService.java b/src/main/java/makeus/cmc/malmo/application/service/member/SignUpService.java index 704629b6..eb3751c5 100644 --- a/src/main/java/makeus/cmc/malmo/application/service/member/SignUpService.java +++ b/src/main/java/makeus/cmc/malmo/application/service/member/SignUpService.java @@ -33,7 +33,12 @@ public class SignUpService implements SignUpUseCase { @CheckValidMember public void signUp(SignUpUseCase.SignUpCommand command) { Member member = memberQueryHelper.getMemberByIdOrThrow(MemberId.of(command.getMemberId())); - member.signUp(command.getNickname()); + member.signUp( + command.getNickname(), + command.getRelationshipStatus(), + command.getPersonalityType(), + command.getOtherPersonalityType() + ); // 회원가입 전 애착 유형 검사를 진행했던 사용자인 경우 해당 정보를 가져와 덮어쓰기 if (command.getLoveTypeId() != null) { diff --git a/src/main/java/makeus/cmc/malmo/domain/model/chat/ChatMessage.java b/src/main/java/makeus/cmc/malmo/domain/model/chat/ChatMessage.java index 86a9f7f4..b41bb841 100644 --- a/src/main/java/makeus/cmc/malmo/domain/model/chat/ChatMessage.java +++ b/src/main/java/makeus/cmc/malmo/domain/model/chat/ChatMessage.java @@ -43,6 +43,27 @@ public static ChatMessage createAssistantTextMessage(ChatRoomId chatRoomId, int .build(); } + public static ChatMessage createAssistantTextMessage(ChatRoomId chatRoomId, int level, int detailedLevel, String content, LocalDateTime createdAt) { + return ChatMessage.builder() + .chatRoomId(chatRoomId) + .level(level) + .detailedLevel(detailedLevel) + .content(content) + .senderType(SenderType.ASSISTANT) + .createdAt(createdAt) + .build(); + } + + public static ChatMessage createSystemTextMessage(ChatRoomId chatRoomId, int level, int detailedLevel, String content) { + return ChatMessage.builder() + .chatRoomId(chatRoomId) + .level(level) + .detailedLevel(detailedLevel) + .content(content) + .senderType(SenderType.SYSTEM) + .build(); + } + public static ChatMessage from(Long id, ChatRoomId chatRoomId, int level, int detailedLevel, String content, SenderType senderType, LocalDateTime createdAt, LocalDateTime modifiedAt, LocalDateTime deletedAt) { return ChatMessage.builder() .id(id) diff --git a/src/main/java/makeus/cmc/malmo/domain/model/member/Member.java b/src/main/java/makeus/cmc/malmo/domain/model/member/Member.java index 3d7b70c9..ce2d2fc0 100644 --- a/src/main/java/makeus/cmc/malmo/domain/model/member/Member.java +++ b/src/main/java/makeus/cmc/malmo/domain/model/member/Member.java @@ -10,6 +10,7 @@ import makeus.cmc.malmo.domain.value.type.LoveTypeCategory; import makeus.cmc.malmo.domain.value.type.MemberRole; import makeus.cmc.malmo.domain.value.type.Provider; +import makeus.cmc.malmo.domain.value.type.RelationshipStatus; import java.time.LocalDate; import java.time.LocalDateTime; @@ -43,6 +44,10 @@ public class Member { private String oauthToken; private CoupleId coupleId; + private RelationshipStatus relationshipStatus; + private String personalityType; + private String otherPersonalityType; + // BaseTimeEntity fields private LocalDateTime createdAt; private LocalDateTime modifiedAt; @@ -81,6 +86,9 @@ public static Member from( LocalDate startLoveDate, String oauthToken, CoupleId coupleId, + RelationshipStatus relationshipStatus, + String personalityType, + String otherPersonalityType, LocalDateTime createdAt, LocalDateTime modifiedAt, LocalDateTime deletedAt @@ -104,6 +112,9 @@ public static Member from( .startLoveDate(startLoveDate) .oauthToken(oauthToken) .coupleId(coupleId) + .relationshipStatus(relationshipStatus) + .personalityType(personalityType) + .otherPersonalityType(otherPersonalityType) .createdAt(createdAt) .modifiedAt(modifiedAt) .deletedAt(deletedAt) @@ -131,8 +142,27 @@ public void signUp(String nickname) { this.memberState = MemberState.ALIVE; } - public void updateMemberProfile(String nickname) { + public void signUp(String nickname, RelationshipStatus relationshipStatus, String personalityType, String otherPersonalityType) { this.nickname = nickname; + this.relationshipStatus = relationshipStatus; + this.personalityType = personalityType; + this.otherPersonalityType = otherPersonalityType; + this.memberState = MemberState.ALIVE; + } + + public void updateMemberProfile(String nickname, RelationshipStatus relationshipStatus, String personalityType, String otherPersonalityType) { + if (nickname != null) { + this.nickname = nickname; + } + if (relationshipStatus != null) { + this.relationshipStatus = relationshipStatus; + } + if (personalityType != null) { + this.personalityType = personalityType; + } + if (otherPersonalityType != null) { + this.otherPersonalityType = otherPersonalityType; + } } public void updateLoveType(LoveTypeCategory loveTypeCategory, float avoidanceRate, float anxietyRate) { diff --git a/src/main/java/makeus/cmc/malmo/domain/service/ChatRoomDomainService.java b/src/main/java/makeus/cmc/malmo/domain/service/ChatRoomDomainService.java index aadc4036..cc320acb 100644 --- a/src/main/java/makeus/cmc/malmo/domain/service/ChatRoomDomainService.java +++ b/src/main/java/makeus/cmc/malmo/domain/service/ChatRoomDomainService.java @@ -4,8 +4,11 @@ import makeus.cmc.malmo.domain.model.chat.ChatRoom; import makeus.cmc.malmo.domain.value.id.ChatRoomId; import makeus.cmc.malmo.domain.value.id.MemberId; +import makeus.cmc.malmo.domain.value.type.SenderType; import org.springframework.stereotype.Component; +import java.time.LocalDateTime; + @Component public class ChatRoomDomainService { @@ -20,4 +23,12 @@ public ChatMessage createUserMessage(ChatRoomId chatRoomId, int level, int detai public ChatMessage createAiMessage(ChatRoomId chatRoomId, int level, int detailedLevel, String content) { return ChatMessage.createAssistantTextMessage(chatRoomId, level, detailedLevel, content); } + + public ChatMessage createAiMessage(ChatRoomId chatRoomId, int level, int detailedLevel, String content, LocalDateTime createdAt) { + return ChatMessage.createAssistantTextMessage(chatRoomId, level, detailedLevel, content, createdAt); + } + + public ChatMessage createSystemMessage(ChatRoomId chatRoomId, int level, int detailedLevel, String content) { + return ChatMessage.createSystemTextMessage(chatRoomId, level, detailedLevel, content); + } } diff --git a/src/main/java/makeus/cmc/malmo/domain/value/type/RelationshipStatus.java b/src/main/java/makeus/cmc/malmo/domain/value/type/RelationshipStatus.java new file mode 100644 index 00000000..ebbdeae4 --- /dev/null +++ b/src/main/java/makeus/cmc/malmo/domain/value/type/RelationshipStatus.java @@ -0,0 +1,5 @@ +package makeus.cmc.malmo.domain.value.type; + +public enum RelationshipStatus { + IN_RELATIONSHIP, SEEING_SOMEONE, BREAKUP +} diff --git a/src/main/java/makeus/cmc/malmo/util/GlobalConstants.java b/src/main/java/makeus/cmc/malmo/util/GlobalConstants.java index 46ee9898..ab4768a9 100644 --- a/src/main/java/makeus/cmc/malmo/util/GlobalConstants.java +++ b/src/main/java/makeus/cmc/malmo/util/GlobalConstants.java @@ -6,13 +6,28 @@ public class GlobalConstants { // 채팅방 관련 상수 public static final int INIT_CHATROOM_LEVEL = 1; - public static final String INIT_CHAT_MESSAGE = " 안녕! 나는 연애 고민 상담사 모모야.\n" + - "나와의 대화를 마무리하고 싶다면 종료하기 버튼을 눌러줘! 대화 종료 후에는 대화 요약 리포트를 보여줄게.\n" + - "오늘은 어떤 고민 때문에 나를 찾아왔어?"; + public static final String INIT_CHAT_MESSAGE_FIRST = " 안녕!"; + public static final String INIT_CHAT_MESSAGE_SECOND_PREFIX = "나는 연애 고민 상담사 모모야.\n" + + "나와의 대화를 마무리하고 싶다면 종료하기 버튼을 눌러줘! 대화 종료 후에는 대화 요약 리포트를 보여줄게.\n"; + + public static final String INIT_CHAT_MESSAGE_SECOND_SEEING_SOMEONE = + INIT_CHAT_MESSAGE_SECOND_PREFIX + + "오늘은 어떤 고민 때문에 나를 찾아왔어? 마음에 두고 있는 상대와 있었던 상황을 이야기해 주면 내가 같이 고민해볼게!"; + + public static final String INIT_CHAT_MESSAGE_SECOND_IN_RELATIONSHIP = + INIT_CHAT_MESSAGE_SECOND_PREFIX + + "오늘은 어떤 고민 때문에 나를 찾아왔어? 먼저 연인과 있었던 갈등 상황을 이야기해 주면 내가 같이 고민해볼게!"; + + public static final String INIT_CHAT_MESSAGE_SECOND_BREAKUP = + INIT_CHAT_MESSAGE_SECOND_PREFIX + + "오늘은 어떤 고민 때문에 나를 찾아왔어? 이별 전후로 마음에 남아 있는 상황을 이야기해 주면 내가 같이 고민해볼게!"; public static final String OPENAI_CHAT_URL = "https://api.openai.com/v1"; public static final String OPENAI_STATUS_URL = "https://status.openai.com/api/v2/status.json"; + + public static final String ATTACHMENT_TYPE_PROMPT_MESSAGE = + "잠깐! 애착유형 테스트를 하면, 더 정확한 상담이 가능해! 그대로 진행하면 바로 상담해줄게"; // 커플 복구 관련 상수 public static final int COUPLE_RECOVERY_LIMIT_DAYS = 30; diff --git a/src/test/java/makeus/cmc/malmo/application/service/chat/ChatRoomManagementServiceTest.java b/src/test/java/makeus/cmc/malmo/application/service/chat/ChatRoomManagementServiceTest.java new file mode 100644 index 00000000..fd663ac1 --- /dev/null +++ b/src/test/java/makeus/cmc/malmo/application/service/chat/ChatRoomManagementServiceTest.java @@ -0,0 +1,98 @@ +package makeus.cmc.malmo.application.service.chat; + +import makeus.cmc.malmo.application.helper.chat_room.ChatRoomCommandHelper; +import makeus.cmc.malmo.application.helper.member.MemberQueryHelper; +import makeus.cmc.malmo.domain.service.ChatRoomDomainService; +import makeus.cmc.malmo.domain.value.type.RelationshipStatus; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static makeus.cmc.malmo.util.GlobalConstants.*; +import static org.assertj.core.api.Assertions.assertThat; + +@ExtendWith(MockitoExtension.class) +@DisplayName("ChatRoomManagementService 단위 테스트") +class ChatRoomManagementServiceTest { + + @Mock + private ChatRoomDomainService chatRoomDomainService; + + @Mock + private MemberQueryHelper memberQueryHelper; + + @Mock + private ChatRoomCommandHelper chatRoomCommandHelper; + + @InjectMocks + private ChatRoomManagementService chatRoomManagementService; + + @Nested + @DisplayName("getSecondMessageByRelationshipStatus") + class GetSecondMessageByRelationshipStatus { + + @Test + @DisplayName("SEEING_SOMEONE 상태이면 마음에 두고 있는 상대 메시지를 반환한다") + void whenSeeingSomeone_thenReturnSeeingSomeoneMessage() { + // when + String result = chatRoomManagementService.getSecondMessageByRelationshipStatus(RelationshipStatus.SEEING_SOMEONE); + + // then + assertThat(result).isEqualTo(INIT_CHAT_MESSAGE_SECOND_SEEING_SOMEONE); + assertThat(result).contains("마음에 두고 있는 상대와 있었던 상황"); + } + + @Test + @DisplayName("IN_RELATIONSHIP 상태이면 연인 갈등 메시지를 반환한다") + void whenInRelationship_thenReturnInRelationshipMessage() { + // when + String result = chatRoomManagementService.getSecondMessageByRelationshipStatus(RelationshipStatus.IN_RELATIONSHIP); + + // then + assertThat(result).isEqualTo(INIT_CHAT_MESSAGE_SECOND_IN_RELATIONSHIP); + assertThat(result).contains("먼저 연인과 있었던 갈등 상황"); + } + + @Test + @DisplayName("BREAKUP 상태이면 이별 메시지를 반환한다") + void whenBreakup_thenReturnBreakupMessage() { + // when + String result = chatRoomManagementService.getSecondMessageByRelationshipStatus(RelationshipStatus.BREAKUP); + + // then + assertThat(result).isEqualTo(INIT_CHAT_MESSAGE_SECOND_BREAKUP); + assertThat(result).contains("이별 전후로 마음에 남아 있는 상황"); + } + + @Test + @DisplayName("null 상태이면 SEEING_SOMEONE과 동일한 메시지를 반환한다") + void whenNull_thenReturnSeeingSomeoneMessage() { + // when + String result = chatRoomManagementService.getSecondMessageByRelationshipStatus(null); + + // then + assertThat(result).isEqualTo(INIT_CHAT_MESSAGE_SECOND_SEEING_SOMEONE); + assertThat(result).contains("마음에 두고 있는 상대와 있었던 상황"); + } + + @Test + @DisplayName("모든 메시지는 공통 prefix를 포함한다") + void allMessages_containCommonPrefix() { + // when + String seeingSomeoneMsg = chatRoomManagementService.getSecondMessageByRelationshipStatus(RelationshipStatus.SEEING_SOMEONE); + String inRelationshipMsg = chatRoomManagementService.getSecondMessageByRelationshipStatus(RelationshipStatus.IN_RELATIONSHIP); + String breakupMsg = chatRoomManagementService.getSecondMessageByRelationshipStatus(RelationshipStatus.BREAKUP); + String nullMsg = chatRoomManagementService.getSecondMessageByRelationshipStatus(null); + + // then + assertThat(seeingSomeoneMsg).contains(INIT_CHAT_MESSAGE_SECOND_PREFIX); + assertThat(inRelationshipMsg).contains(INIT_CHAT_MESSAGE_SECOND_PREFIX); + assertThat(breakupMsg).contains(INIT_CHAT_MESSAGE_SECOND_PREFIX); + assertThat(nullMsg).contains(INIT_CHAT_MESSAGE_SECOND_PREFIX); + } + } +} diff --git a/src/test/java/makeus/cmc/malmo/integration_test/ChatRoomIntegrationTest.java b/src/test/java/makeus/cmc/malmo/integration_test/ChatRoomIntegrationTest.java index f13ac238..41b89c20 100644 --- a/src/test/java/makeus/cmc/malmo/integration_test/ChatRoomIntegrationTest.java +++ b/src/test/java/makeus/cmc/malmo/integration_test/ChatRoomIntegrationTest.java @@ -16,6 +16,8 @@ import makeus.cmc.malmo.domain.value.state.MemberState; import makeus.cmc.malmo.domain.value.type.MemberRole; import makeus.cmc.malmo.domain.value.type.Provider; +import makeus.cmc.malmo.domain.value.type.LoveTypeCategory; +import makeus.cmc.malmo.domain.value.type.RelationshipStatus; import makeus.cmc.malmo.domain.value.type.SenderType; import makeus.cmc.malmo.integration_test.dto_factory.ChatRoomRequestDtoFactory; import org.assertj.core.api.Assertions; @@ -92,6 +94,8 @@ private MemberEntity createAndSaveMember(String nickname, String email, String i .nickname(nickname) .email(email) .inviteCodeEntityValue(InviteCodeEntityValue.of(inviteCode)) + .loveTypeCategory(LoveTypeCategory.STABLE_TYPE) + .relationshipStatus(RelationshipStatus.IN_RELATIONSHIP) .build(); em.persist(memberEntity); return memberEntity; @@ -107,6 +111,7 @@ private MemberEntity createAndSaveDeletedMember(String nickname, String email, S .startLoveDate(LocalDate.of(2023, 1, 1)) .email(email) .inviteCodeEntityValue(InviteCodeEntityValue.of(inviteCode)) + .relationshipStatus(RelationshipStatus.IN_RELATIONSHIP) .build(); em.persist(deletedMember); return deletedMember; @@ -131,11 +136,12 @@ class CreateChatRoom { Assertions.assertThat(chatRooms).hasSize(1); Assertions.assertThat(chatRooms.get(0).getChatRoomState()).isEqualTo(ChatRoomState.BEFORE_INIT); - List messages = em.createQuery("SELECT m FROM ChatMessageEntity m WHERE m.chatRoomEntityId.value = :chatRoomId", ChatMessageEntity.class) + List messages = em.createQuery("SELECT m FROM ChatMessageEntity m WHERE m.chatRoomEntityId.value = :chatRoomId ORDER BY m.createdAt ASC", ChatMessageEntity.class) .setParameter("chatRoomId", chatRooms.get(0).getId()) .getResultList(); - Assertions.assertThat(messages).hasSize(1); - Assertions.assertThat(messages.get(0).getContent()).contains(INIT_CHAT_MESSAGE); + Assertions.assertThat(messages).hasSize(2); + Assertions.assertThat(messages.get(0).getContent()).contains(INIT_CHAT_MESSAGE_FIRST); + Assertions.assertThat(messages.get(1).getContent()).contains(INIT_CHAT_MESSAGE_SECOND_PREFIX); } @Test @@ -690,6 +696,196 @@ class GetChatRoomMessages { } } + @Nested + @DisplayName("애착유형 프롬프트 시스템 메시지") + class AttachmentTypePromptSystemMessage { + + private MemberEntity memberWithoutLoveType; + private MemberEntity memberWithLoveType; + private String tokenWithoutLoveType; + private String tokenWithLoveType; + + @BeforeEach + void setupMembers() { + // 애착유형 없는 멤버 + memberWithoutLoveType = MemberEntity.builder() + .provider(Provider.KAKAO) + .providerId("no_love_type@email.com") + .memberRole(MemberRole.MEMBER) + .memberState(MemberState.ALIVE) + .startLoveDate(LocalDate.of(2023, 1, 1)) + .nickname("noLoveType") + .email("no_love_type@email.com") + .inviteCodeEntityValue(InviteCodeEntityValue.of("invite_nolt")) + .loveTypeCategory(null) // 애착유형 없음 + .relationshipStatus(RelationshipStatus.IN_RELATIONSHIP) + .build(); + em.persist(memberWithoutLoveType); + + // 애착유형 있는 멤버 + memberWithLoveType = MemberEntity.builder() + .provider(Provider.KAKAO) + .providerId("with_love_type@email.com") + .memberRole(MemberRole.MEMBER) + .memberState(MemberState.ALIVE) + .startLoveDate(LocalDate.of(2023, 1, 1)) + .nickname("withLoveType") + .email("with_love_type@email.com") + .inviteCodeEntityValue(InviteCodeEntityValue.of("invite_wlt")) + .loveTypeCategory(LoveTypeCategory.STABLE_TYPE) // 애착유형 있음 + .relationshipStatus(RelationshipStatus.IN_RELATIONSHIP) + .build(); + em.persist(memberWithLoveType); + em.flush(); + + tokenWithoutLoveType = generateTokenPort.generateToken(memberWithoutLoveType.getId(), memberWithoutLoveType.getMemberRole()).getAccessToken(); + tokenWithLoveType = generateTokenPort.generateToken(memberWithLoveType.getId(), memberWithLoveType.getMemberRole()).getAccessToken(); + } + + @Test + @DisplayName("애착유형이 없고 유저 메시지가 없으면 시스템 메시지가 포함된다") + void 애착유형_없고_유저메시지_없으면_시스템메시지_포함() throws Exception { + // given - 채팅방 생성 (ASSISTANT 메시지만 있음) + ChatRoomEntity chatRoom = ChatRoomEntity.builder() + .memberEntityId(MemberEntityId.of(memberWithoutLoveType.getId())) + .chatRoomState(ChatRoomState.ALIVE) + .level(1) + .detailedLevel(1) + .build(); + em.persist(chatRoom); + + // ASSISTANT 메시지만 추가 (USER 메시지 없음) + em.persist(ChatMessageEntity.builder() + .chatRoomEntityId(ChatRoomEntityId.of(chatRoom.getId())) + .level(1) + .senderType(SenderType.ASSISTANT) + .content("안녕하세요") + .createdAt(LocalDateTime.now().minusMinutes(1)) + .build()); + em.flush(); + + // when & then + mockMvc.perform(get("/chatrooms/{chatRoomId}/messages", chatRoom.getId()) + .header("Authorization", "Bearer " + tokenWithoutLoveType) + .param("page", "0").param("size", "10")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data.list").isArray()) + .andExpect(jsonPath("$.data.list[0].senderType").value("ASSISTANT")) + .andExpect(jsonPath("$.data.list[1].senderType").value("SYSTEM")) + .andExpect(jsonPath("$.data.list[1].content").value(ATTACHMENT_TYPE_PROMPT_MESSAGE)) + .andExpect(jsonPath("$.data.list[1].messageId").isEmpty()); + } + + @Test + @DisplayName("애착유형이 있으면 시스템 메시지가 포함되지 않는다") + void 애착유형_있으면_시스템메시지_미포함() throws Exception { + // given - 채팅방 생성 (USER 메시지 없음) + ChatRoomEntity chatRoom = ChatRoomEntity.builder() + .memberEntityId(MemberEntityId.of(memberWithLoveType.getId())) + .chatRoomState(ChatRoomState.ALIVE) + .level(1) + .detailedLevel(1) + .build(); + em.persist(chatRoom); + + // ASSISTANT 메시지만 추가 + em.persist(ChatMessageEntity.builder() + .chatRoomEntityId(ChatRoomEntityId.of(chatRoom.getId())) + .level(1) + .senderType(SenderType.ASSISTANT) + .content("안녕하세요") + .createdAt(LocalDateTime.now().minusMinutes(1)) + .build()); + em.flush(); + + // when & then - SYSTEM 메시지가 포함되지 않아야 함 + mockMvc.perform(get("/chatrooms/{chatRoomId}/messages", chatRoom.getId()) + .header("Authorization", "Bearer " + tokenWithLoveType) + .param("page", "0").param("size", "10")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data.totalCount").value(1)) + .andExpect(jsonPath("$.data.list[0].senderType").value("ASSISTANT")) + .andExpect(jsonPath("$.data.list.length()").value(1)); + } + + @Test + @DisplayName("유저 메시지가 있으면 시스템 메시지가 포함되지 않는다") + void 유저메시지_있으면_시스템메시지_미포함() throws Exception { + // given - 채팅방 생성 + ChatRoomEntity chatRoom = ChatRoomEntity.builder() + .memberEntityId(MemberEntityId.of(memberWithoutLoveType.getId())) + .chatRoomState(ChatRoomState.ALIVE) + .level(1) + .detailedLevel(1) + .build(); + em.persist(chatRoom); + + // USER 메시지 추가 (이미 메시지를 보낸 상태) + em.persist(ChatMessageEntity.builder() + .chatRoomEntityId(ChatRoomEntityId.of(chatRoom.getId())) + .level(1) + .senderType(SenderType.USER) + .content("안녕하세요") + .createdAt(LocalDateTime.now().minusMinutes(1)) + .build()); + em.flush(); + + // when & then - SYSTEM 메시지가 포함되지 않아야 함 + mockMvc.perform(get("/chatrooms/{chatRoomId}/messages", chatRoom.getId()) + .header("Authorization", "Bearer " + tokenWithoutLoveType) + .param("page", "0").param("size", "10")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data.totalCount").value(1)) + .andExpect(jsonPath("$.data.list[0].senderType").value("USER")) + .andExpect(jsonPath("$.data.list.length()").value(1)); + } + + @Test + @DisplayName("첫 메시지 전송 시 시스템 메시지가 먼저 저장된다") + void 첫_메시지_전송시_시스템메시지_저장됨() throws Exception { + // given - 빈 채팅방 생성 + ChatRoomEntity chatRoom = ChatRoomEntity.builder() + .memberEntityId(MemberEntityId.of(memberWithoutLoveType.getId())) + .chatRoomState(ChatRoomState.ALIVE) + .level(1) + .detailedLevel(1) + .build(); + em.persist(chatRoom); + em.flush(); + em.clear(); + + // when - 첫 메시지 전송 + mockMvc.perform(post("/chatrooms/{chatRoomId}/messages", chatRoom.getId()) + .header("Authorization", "Bearer " + tokenWithoutLoveType) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(ChatRoomRequestDtoFactory.createSendChatMessageRequestDto("첫 번째 메시지")))) + .andExpect(status().isOk()); + + // then - DB에서 메시지 확인 + List messages = em.createQuery( + "SELECT m FROM ChatMessageEntity m WHERE m.chatRoomEntityId.value = :chatRoomId ORDER BY m.createdAt ASC", + ChatMessageEntity.class) + .setParameter("chatRoomId", chatRoom.getId()) + .getResultList(); + + // 시스템 메시지가 먼저, 유저 메시지가 나중에 저장되어야 함 + Assertions.assertThat(messages).hasSize(2); + Assertions.assertThat(messages.get(0).getSenderType()).isEqualTo(SenderType.SYSTEM); + Assertions.assertThat(messages.get(0).getContent()).isEqualTo(ATTACHMENT_TYPE_PROMPT_MESSAGE); + Assertions.assertThat(messages.get(1).getSenderType()).isEqualTo(SenderType.USER); + Assertions.assertThat(messages.get(1).getContent()).isEqualTo("첫 번째 메시지"); + + // 다시 메시지 조회 시 SYSTEM 메시지가 동적으로 추가되지 않아야 함 (이미 저장됨) + mockMvc.perform(get("/chatrooms/{chatRoomId}/messages", chatRoom.getId()) + .header("Authorization", "Bearer " + tokenWithoutLoveType) + .param("page", "0").param("size", "10")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data.totalCount").value(2)) + .andExpect(jsonPath("$.data.list[0].senderType").value("SYSTEM")) + .andExpect(jsonPath("$.data.list[1].senderType").value("USER")); + } + } + @Nested @DisplayName("채팅방 요약 조회") class GetChatRoomSummary { diff --git a/src/test/java/makeus/cmc/malmo/integration_test/MemberIntegrationTest.java b/src/test/java/makeus/cmc/malmo/integration_test/MemberIntegrationTest.java index 8fa45967..8961b611 100644 --- a/src/test/java/makeus/cmc/malmo/integration_test/MemberIntegrationTest.java +++ b/src/test/java/makeus/cmc/malmo/integration_test/MemberIntegrationTest.java @@ -822,6 +822,10 @@ public static class MemberResponseDto { float anxietyRate; String nickname; String email; + + String relationshipStatus; + String personalityType; + String otherPersonalityType; } @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) diff --git a/src/test/java/makeus/cmc/malmo/mapper/MemberMapperTest.java b/src/test/java/makeus/cmc/malmo/mapper/MemberMapperTest.java index 7a2502bd..07c32db3 100644 --- a/src/test/java/makeus/cmc/malmo/mapper/MemberMapperTest.java +++ b/src/test/java/makeus/cmc/malmo/mapper/MemberMapperTest.java @@ -159,6 +159,9 @@ private Member createCompleteMember() { LocalDate.now(), "oauth_token", CoupleId.of(100L), + null, // relationshipStatus + null, // personalityType + null, // otherPersonalityType now, now, null diff --git a/src/test/java/makeus/cmc/malmo/service/AppleNotificationServiceTest.java b/src/test/java/makeus/cmc/malmo/service/AppleNotificationServiceTest.java index fc1f531d..aeaac1a3 100644 --- a/src/test/java/makeus/cmc/malmo/service/AppleNotificationServiceTest.java +++ b/src/test/java/makeus/cmc/malmo/service/AppleNotificationServiceTest.java @@ -89,6 +89,9 @@ private Member createTestMember(String providerId, String oauthToken) { null, oauthToken, null, + null, // relationshipStatus + null, // personalityType + null, // otherPersonalityType null, null, null