Repository: depromeet/kok-server
Pull request #53: ✨ [Feature/Room] Implement random profile generation
Author: login: yunyoung1819
Labels: name: ✨ Feature
description: new feature
name: 🥇 Urgency 1
description: 긴급도 높음
Created: 2025-03-06T11:58:40Z | Merged: 2025-03-08T15:34:12Z

## #️⃣ 연관된 이슈
- #52 

## 📝 작업 내용
- 랜덤 프로필 이미지 생성
- 랜덤 닉네임 생성


### ***📸 스크린샷 (선택)***


## ***💬 리뷰 요구사항(선택)***



Diff:
diff --git a/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/request/CreateRoomRequest.java b/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/request/CreateRoomRequest.java
index ce30a405..03c5cf38 100644
--- a/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/request/CreateRoomRequest.java
+++ b/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/request/CreateRoomRequest.java
@@ -13,11 +13,9 @@ public record CreateRoomRequest(
         @Min(value = 2, message = "참여 인원 수는 최소 2명 이상이어야 합니다.")
         Integer capacity,
 
+        @NotBlank(message = "프로필 이미지는 필수 입력 값입니다.")
         String hostProfile,
 
-        @NotBlank(message = "방장 이름(닉네임)은 필수 입력값입니다.")
-        String hostNickname,
-
-        @NotBlank(message = "비밀번호는 필수 입력값입니다.")
-        String password
+        @NotBlank(message = "닉네임은 필수 입력값입니다.")
+        String hostNickname
 ) {}
diff --git a/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/JoinRoomResponse.java b/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/JoinRoomResponse.java
new file mode 100644
index 00000000..43203c41
--- /dev/null
+++ b/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/JoinRoomResponse.java
@@ -0,0 +1,4 @@
+package com.kok.kokapi.room.adapter.in.dto.response;
+
+public record JoinRoomResponse(int participantCount, int memberId) {
+}
diff --git a/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/MemberResponse.java b/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/MemberResponse.java
index b02f0491..f6f4df08 100644
--- a/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/MemberResponse.java
+++ b/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/MemberResponse.java
@@ -1,11 +1,12 @@
 package com.kok.kokapi.room.adapter.in.dto.response;
 
 import com.kok.kokcore.room.domain.Member;
+import com.kok.kokcore.room.domain.vo.MemberRole;
 
 public record MemberResponse(
         String nickname,
         String profile,
-        String role
+        MemberRole role
 ) {
     public static MemberResponse from(Member member) {
         return new MemberResponse(member.getNickname(), member.getProfile(), member.getRole());
diff --git a/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/RandomProfileResponse.java b/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/RandomProfileResponse.java
new file mode 100644
index 00000000..4dd44a50
--- /dev/null
+++ b/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/RandomProfileResponse.java
@@ -0,0 +1,6 @@
+package com.kok.kokapi.room.adapter.in.dto.response;
+
+public record RandomProfileResponse(
+        String imageUrl,
+        String nickname
+){}
diff --git a/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/RoomCreateResponse.java b/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/RoomCreateResponse.java
new file mode 100644
index 00000000..0361af08
--- /dev/null
+++ b/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/RoomCreateResponse.java
@@ -0,0 +1,23 @@
+package com.kok.kokapi.room.adapter.in.dto.response;
+
+import com.kok.kokcore.room.domain.Room;
+
+public record RoomCreateResponse(
+        String id,
+        String roomName,
+        int capacity,
+        MemberResponse member,
+        int memberId,
+        int participantCount
+) {
+    public static RoomCreateResponse from(Room room, int memberId, int participantCount) {
+        return new RoomCreateResponse(
+                room.getId(),
+                room.getRoomName(),
+                room.getCapacity(),
+                MemberResponse.from(room.getMember()),
+                memberId,
+                participantCount
+        );
+    }
+}
\ No newline at end of file
diff --git a/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/RoomDetailResponse.java b/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/RoomDetailResponse.java
index 09d69628..df851571 100644
--- a/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/RoomDetailResponse.java
+++ b/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/RoomDetailResponse.java
@@ -13,7 +13,11 @@ public static RoomDetailResponse from(Room room) {
                 room.getId(),
                 room.getRoomName(),
                 room.getCapacity(),
-                MemberResponse.from(room.getMember())
+                getLeaderResponse(room)
         );
     }
+
+    private static MemberResponse getLeaderResponse(Room room) {
+        return MemberResponse.from(room.getMember());
+    }
 }
diff --git a/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/RoomMembersResponse.java b/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/RoomMembersResponse.java
index 0e957f3e..09057083 100644
--- a/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/RoomMembersResponse.java
+++ b/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/RoomMembersResponse.java
@@ -1,7 +1,9 @@
 package com.kok.kokapi.room.adapter.in.dto.response;
 
+import com.kok.kokcore.room.domain.vo.MemberRole;
+
 public record RoomMembersResponse(
         String profile,
         String nickname,
-        String role
+        MemberRole role
 ) {}
diff --git a/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/web/RoomController.java b/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/web/RoomController.java
index d4e941cc..475454d0 100644
--- a/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/web/RoomController.java
+++ b/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/web/RoomController.java
@@ -4,10 +4,12 @@
 import com.kok.kokapi.config.annotion.V1Controller;
 import com.kok.kokapi.room.adapter.in.dto.request.CreateRoomRequest;
 import com.kok.kokapi.room.adapter.in.dto.request.JoinRoomParticipantRequest;
+import com.kok.kokapi.room.adapter.in.dto.response.JoinRoomResponse;
+import com.kok.kokapi.room.adapter.in.dto.response.RoomCreateResponse;
 import com.kok.kokapi.room.adapter.in.dto.response.RoomMembersResponse;
 import com.kok.kokapi.room.adapter.in.dto.response.RoomDetailResponse;
 import com.kok.kokcore.room.domain.Member;
-import com.kok.kokcore.room.domain.Room;
+import com.kok.kokcore.room.domain.vo.MemberRole;
 import com.kok.kokcore.room.usecase.CreateRoomUseCase;
 import com.kok.kokcore.room.usecase.GetRoomUseCase;
 import com.kok.kokcore.room.usecase.JoinRoomUseCase;
@@ -28,35 +30,35 @@ public class RoomController {
     private final CreateRoomUseCase createRoomUseCase;
     private final JoinRoomUseCase joinRoomUseCase;
 
-    @Operation(summary = "약속방 조회", description = "Retrieve detailed information for a room using its ID")
+    @Operation(summary = "약속방 조회", description = "약속방 ID를 통해 약속방을 조회합니다.")
     @GetMapping("/rooms/{roomId}")
     public ResponseEntity<ApiResponseDto<RoomDetailResponse>> getRoomDetail(@PathVariable String roomId) {
-        Room room = getRoomUseCase.findRoomById(roomId);
+        var room = getRoomUseCase.findRoomById(roomId);
         var response = RoomDetailResponse.from(room);
         return ResponseEntity.ok(ApiResponseDto.success(response));
     }
 
-    @Operation(summary = "약속방 생성", description = "Create a new room with the provided details.")
+    @Operation(summary = "약속방 생성", description = "새로운 약속방을 생성합니다.")
     @PostMapping("/rooms")
-    public ResponseEntity<ApiResponseDto<RoomDetailResponse>> createRoom(@Valid @RequestBody CreateRoomRequest request) {
-        Member host = new Member(request.hostNickname(), request.hostProfile(), "Leader");
-        Room room = createRoomUseCase.createRoom(
+    public ResponseEntity<ApiResponseDto<RoomCreateResponse>> createRoom(@Valid @RequestBody CreateRoomRequest request) {
+        var host = new Member(request.hostNickname(), request.hostProfile(), MemberRole.LEADER);
+        var room = createRoomUseCase.createRoom(
                 request.roomName(),
                 request.capacity(),
-                host,
-                request.password()
+                host
         );
 
-        var response = RoomDetailResponse.from(room);
+        var response = RoomCreateResponse.from(room, 1, 1);
+
         return ResponseEntity.status(HttpStatus.CREATED)
                 .body(ApiResponseDto.success(response));
     }
 
-    @Operation(summary = "약속방 참여자 프로필 목록 조회", description = "Retrieve the list of participant profiles for the room.")
+    @Operation(summary = "약속방 참여자 프로필 목록 조회", description = "약속방에 참여 중인 참여자들의 프로필 목록을 반환합니다.")
     @GetMapping("/rooms/{roomId}/participants")
     public ResponseEntity<ApiResponseDto<List<RoomMembersResponse>>> getParticipants(@PathVariable String roomId) {
-        Room room = getRoomUseCase.findRoomById(roomId);
-        List<Member> participants = getRoomUseCase.getParticipants(room.getId());
+        var room = getRoomUseCase.findRoomById(roomId);
+        var participants = getRoomUseCase.getParticipants(room.getId());
 
         var response = participants.stream()
                 .map(member -> new RoomMembersResponse(
@@ -67,13 +69,16 @@ public ResponseEntity<ApiResponseDto<List<RoomMembersResponse>>> getParticipants
         return ResponseEntity.ok(ApiResponseDto.success(response));
     }
 
-    @Operation(summary = "약속방 참여", description = "Register a new participant profile for the room.")
+    @Operation(summary = "약속방 참여", description = "사용자가 약속방에 참여합니다.")
     @PostMapping("/rooms/{roomId}/join")
-    public ResponseEntity<ApiResponseDto<String>> joinRoom(@PathVariable String roomId,
-                                                           @Valid @RequestBody JoinRoomParticipantRequest request) {
+    public ResponseEntity<ApiResponseDto<JoinRoomResponse>> joinRoom(@PathVariable String roomId,
+                                                                     @Valid @RequestBody JoinRoomParticipantRequest request) {
+
         getRoomUseCase.findRoomById(roomId);
-        Member participant = new Member(request.nickname(), request.profile(), "Follower");
-        joinRoomUseCase.joinRoom(roomId, participant);
-        return ResponseEntity.ok(ApiResponseDto.success("약속방 참여가 완료되었습니다."));
+        var participant = new Member(request.nickname(), request.profile(), MemberRole.FOLLOWER);
+        var participantCount = joinRoomUseCase.joinRoom(roomId, participant);
+        var memberId = participantCount;
+        JoinRoomResponse response = new JoinRoomResponse(participantCount, memberId);
+        return ResponseEntity.ok(ApiResponseDto.success(response));
     }
 }
diff --git a/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/web/RoomProfileController.java b/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/web/RoomProfileController.java
new file mode 100644
index 00000000..d70d18be
--- /dev/null
+++ b/kok-api/src/main/java/com/kok/kokapi/room/adapter/in/web/RoomProfileController.java
@@ -0,0 +1,46 @@
+package com.kok.kokapi.room.adapter.in.web;
+
+import com.kok.kokapi.common.response.ApiResponseDto;
+import com.kok.kokapi.config.annotion.V1Controller;
+import com.kok.kokapi.room.adapter.in.dto.response.RandomProfileResponse;
+import com.kok.kokcore.room.domain.Profile;
+import com.kok.kokcore.room.usecase.CreateRandomProfileUseCase;
+import com.kok.kokcore.room.usecase.GetMemberProfileUseCase;
+import io.swagger.v3.oas.annotations.Operation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+
+import java.util.List;
+
+@V1Controller
+@RequiredArgsConstructor
+public class RoomProfileController {
+
+    private final CreateRandomProfileUseCase createRandomProfileUseCase;
+    private final GetMemberProfileUseCase getMemberProfileUseCase;
+
+    @Operation(summary = "랜덤 프로필 및 닉네임 조회", description = "랜덤으로 생성한 프로필 이미지와 닉네임을 반환합니다.")
+    @GetMapping("/rooms/profile/random")
+    public ResponseEntity<ApiResponseDto<RandomProfileResponse>> getRandomProfile() {
+        Profile profile = createRandomProfileUseCase.createProfile();
+        RandomProfileResponse response = new RandomProfileResponse(
+                profile.getImageUrl(),
+                profile.getNickname()
+        );
+
+        return ResponseEntity.ok(ApiResponseDto.success(response));
+    }
+
+    @Operation(summary = "약속방 참여자의 프로필 조회", description = "약속방 참여자가 기존에 생성한 프로필 목록을 조회하며, 없을 경우 빈 값으로 반환합니다.")
+    @GetMapping("/rooms/{roomId}/profiles")
+    public ResponseEntity<ApiResponseDto<List<RandomProfileResponse>>> getMemberProfiles(@PathVariable String roomId) {
+        List<Profile> profiles = getMemberProfileUseCase.getProfilesByRoomId(roomId);
+        List<RandomProfileResponse> responseList = profiles.stream()
+                .map(profile -> new RandomProfileResponse(profile.getImageUrl(), profile.getNickname()))
+                .toList();
+
+        return ResponseEntity.ok(ApiResponseDto.success(responseList));
+    }
+}
diff --git a/kok-api/src/main/java/com/kok/kokapi/room/adapter/out/persistence/RoomParticipantQueryAdapter.java b/kok-api/src/main/java/com/kok/kokapi/room/adapter/out/persistence/RoomParticipantQueryAdapter.java
new file mode 100644
index 00000000..86770935
--- /dev/null
+++ b/kok-api/src/main/java/com/kok/kokapi/room/adapter/out/persistence/RoomParticipantQueryAdapter.java
@@ -0,0 +1,44 @@
+package com.kok.kokapi.room.adapter.out.persistence;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.kok.kokcore.room.application.port.out.LoadRoomParticipantsPort;
+import com.kok.kokcore.room.domain.Member;
+import com.kok.kokcore.room.domain.Profile;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+@RequiredArgsConstructor
+public class RoomParticipantQueryAdapter implements LoadRoomParticipantsPort {
+
+    private static final String PARTICIPANT_KEY_PREFIX = "room:participants:";
+    private final RedisTemplate<String, String> redisTemplate;
+    private final ObjectMapper objectMapper;
+
+    @Override
+    public List<Profile> getProfilesByRoomId(String roomId) {
+        String key = PARTICIPANT_KEY_PREFIX + roomId;
+        List<String> profileJson = redisTemplate.opsForList().range(key, 0, -1);
+
+        if (profileJson == null || profileJson.isEmpty()) {
+            return List.of();
+        }
+
+        return profileJson.stream()
+                .map(this::deserializeProfile)
+                .toList();
+    }
+
+    private Profile deserializeProfile(String profileJson) {
+        try {
+            Member member = objectMapper.readValue(profileJson, Member.class);
+            return new Profile(member.getProfile(), member.getNickname());
+        } catch (JsonProcessingException e) {
+            throw new RuntimeException("failed to deserialize profile");
+        }
+    }
+}
diff --git a/kok-api/src/main/java/com/kok/kokapi/room/adapter/out/persistence/RoomParticipantSaveAdapter.java b/kok-api/src/main/java/com/kok/kokapi/room/adapter/out/persistence/RoomParticipantSaveAdapter.java
new file mode 100644
index 00000000..8be7f9ae
--- /dev/null
+++ b/kok-api/src/main/java/com/kok/kokapi/room/adapter/out/persistence/RoomParticipantSaveAdapter.java
@@ -0,0 +1,33 @@
+package com.kok.kokapi.room.adapter.out.persistence;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.kok.kokcore.room.application.port.out.SaveRoomParticipantsPort;
+import com.kok.kokcore.room.domain.Member;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Repository;
+
+@Repository
+@RequiredArgsConstructor
+public class RoomParticipantSaveAdapter implements SaveRoomParticipantsPort {
+
+    private static final String PARTICIPANT_KEY_PREFIX = "room:participants:";
+    private final RedisTemplate<String, String> redisTemplate;
+    private final ObjectMapper objectMapper;
+
+    @Override
+    public int joinRoom(String roomId, Member member) {
+        String key = PARTICIPANT_KEY_PREFIX + roomId;
+
+        try {
+            String memberJson = objectMapper.writeValueAsString(member);
+            redisTemplate.opsForList().rightPush(key, memberJson);
+
+            Long participantCount = redisTemplate.opsForList().size(key);
+            return participantCount != null ? participantCount.intValue() : 0;
+        } catch (JsonProcessingException e) {
+            throw new RuntimeException("failed to serialize member");
+        }
+    }
+}
diff --git a/kok-api/src/main/java/com/kok/kokapi/room/application/service/RandomProfileService.java b/kok-api/src/main/java/com/kok/kokapi/room/application/service/RandomProfileService.java
new file mode 100644
index 00000000..7f80cc99
--- /dev/null
+++ b/kok-api/src/main/java/com/kok/kokapi/room/application/service/RandomProfileService.java
@@ -0,0 +1,46 @@
+package com.kok.kokapi.room.application.service;
+
+import com.kok.kokcore.room.domain.Profile;
+import com.kok.kokcore.room.usecase.CreateRandomProfileUseCase;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Random;
+
+@Service
+@RequiredArgsConstructor
+public class RandomProfileService implements CreateRandomProfileUseCase {
+
+    @Value("${ncp.object-storage-url}")
+    private String objectStorageUrl;
+
+    private static final List<String> ADJECTIVES = List.of(
+            "배고픈", "멋있는", "쿨한 ", "빠른", "친절한", "영리한", "행복한", "조용한", "강력한", "자유로운",
+            "스마트한", "잘생긴", "귀여운", "평화로운", "빛나는", "똑똑한", "신나는", "부드러운", "엉뚱한", "무서운"
+    );
+
+    private static final List<String> NOUNS = List.of(
+            "토미", "지미", "라이언", "루카스", "데이빗", "엠마", "올리버", "소피", "봉봉이", "피치",
+            "무지", "튜브", "프로도", "콘", "브라운", "코코", "프렌즈", "토끼", "펭수", "뽀로로"
+    );
+
+    @Override
+    public Profile createProfile() {
+        String imageUrl = getRandomImageUrl();
+        String nickname = generateRandomNickname();
+        return new Profile(imageUrl, nickname);
+    }
+
+    private String getRandomImageUrl() {
+        int randomImageIndex = new Random().nextInt(9) + 1;
+        return objectStorageUrl + "/profile_default/" + randomImageIndex + ".svg";
+    }
+
+    private String generateRandomNickname() {
+        String adjective = ADJECTIVES.get(new Random().nextInt(ADJECTIVES.size()));
+        String noun = NOUNS.get(new Random().nextInt(NOUNS.size()));
+        return adjective + " " + noun;
+    }
+}
diff --git a/kok-api/src/main/java/com/kok/kokapi/room/application/service/RoomCreationService.java b/kok-api/src/main/java/com/kok/kokapi/room/application/service/RoomCreationService.java
index 9fdb8b4b..23224550 100644
--- a/kok-api/src/main/java/com/kok/kokapi/room/application/service/RoomCreationService.java
+++ b/kok-api/src/main/java/com/kok/kokapi/room/application/service/RoomCreationService.java
@@ -16,8 +16,8 @@ public class RoomCreationService implements CreateRoomUseCase {
     private final JoinRoomUseCase joinRoomUseCase;
 
     @Override
-    public Room createRoom(String roomName, int capacity, Member host, String password) {
-        Room room = Room.create(roomName, capacity, host, password);
+    public Room createRoom(String roomName, int capacity, Member host) {
+        Room room = Room.create(roomName, capacity, host);
         Room savedRoom = saveRoomPort.save(room);
 
         joinRoomUseCase.joinRoom(savedRoom.getId(), savedRoom.getMember());
diff --git a/kok-api/src/main/java/com/kok/kokapi/room/application/service/RoomParticipantService.java b/kok-api/src/main/java/com/kok/kokapi/room/application/service/RoomParticipantService.java
index ef537fae..02b3d690 100644
--- a/kok-api/src/main/java/com/kok/kokapi/room/application/service/RoomParticipantService.java
+++ b/kok-api/src/main/java/com/kok/kokapi/room/application/service/RoomParticipantService.java
@@ -1,30 +1,31 @@
 package com.kok.kokapi.room.application.service;
 
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
+import com.kok.kokcore.room.application.port.out.LoadRoomParticipantsPort;
+import com.kok.kokcore.room.application.port.out.SaveRoomParticipantsPort;
 import com.kok.kokcore.room.domain.Member;
+import com.kok.kokcore.room.domain.Profile;
+import com.kok.kokcore.room.usecase.GetMemberProfileUseCase;
 import com.kok.kokcore.room.usecase.JoinRoomUseCase;
 import lombok.RequiredArgsConstructor;
-import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
+
 
 @Service
 @RequiredArgsConstructor
-public class RoomParticipantService implements JoinRoomUseCase {
+public class RoomParticipantService implements JoinRoomUseCase, GetMemberProfileUseCase {
+
+    private final LoadRoomParticipantsPort loadRoomParticipantsPort;
+    private final SaveRoomParticipantsPort saveRoomParticipantsPort;
 
-    private static final String PARTICIPANT_KEY_PREFIX = "room:participants:";
-    private final RedisTemplate<String, String> redisTemplate;
-    private final ObjectMapper objectMapper;
+    @Override
+    public int joinRoom(String roomId, Member member) {
+        return saveRoomParticipantsPort.joinRoom(roomId, member);
+    }
 
     @Override
-    public void joinRoom(String roomId, Member member) {
-        String key = PARTICIPANT_KEY_PREFIX + roomId;
-        try {
-            String memberJson = objectMapper.writeValueAsString(member);
-            redisTemplate.opsForList().rightPush(key, memberJson);
-        } catch (JsonProcessingException e) {
-            throw new RuntimeException("failed to serialize member");
-        }
+    public List<Profile> getProfilesByRoomId(String roomId) {
+        return loadRoomParticipantsPort.getProfilesByRoomId(roomId);
     }
 }
diff --git a/kok-api/src/main/resources/application-dev.yml b/kok-api/src/main/resources/application-dev.yml
index d9b931b5..035ae10c 100644
--- a/kok-api/src/main/resources/application-dev.yml
+++ b/kok-api/src/main/resources/application-dev.yml
@@ -36,7 +36,8 @@ station:
   format: json
   start-idx: 1
   end-idx: 1000
-
+ncp:
+  object-storage-url: ${OBJECT_STORAGE_URL}
 tmap:
   key: ${TMAP_KEY}
   url: "https://apis.openapi.sk.com/transit/routes/sub"
diff --git a/kok-api/src/main/resources/application-prod.yml b/kok-api/src/main/resources/application-prod.yml
index 42f9ef89..788f52d7 100644
--- a/kok-api/src/main/resources/application-prod.yml
+++ b/kok-api/src/main/resources/application-prod.yml
@@ -47,7 +47,8 @@ station:
   format: json
   start-idx: 1
   end-idx: 1000
-
+ncp:
+  object-storage-url: ${OBJECT_STORAGE_URL}
 tmap:
   key: ${TMAP_KEY}
   url: "https://apis.openapi.sk.com/transit/routes/sub"
diff --git a/kok-api/src/test/java/com/kok/kokapi/room/application/service/RoomCreationServiceTest.java b/kok-api/src/test/java/com/kok/kokapi/room/application/service/RoomCreationServiceTest.java
index fb70ba7a..2f2d6afb 100644
--- a/kok-api/src/test/java/com/kok/kokapi/room/application/service/RoomCreationServiceTest.java
+++ b/kok-api/src/test/java/com/kok/kokapi/room/application/service/RoomCreationServiceTest.java
@@ -7,6 +7,7 @@
 import com.kok.kokapi.common.template.ServiceTest;
 import com.kok.kokcore.room.domain.Member;
 import com.kok.kokcore.room.domain.Room;
+import com.kok.kokcore.room.domain.vo.MemberRole;
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -23,21 +24,19 @@ void createRoom() {
         int capacity = 4;
         String hostNickname = "test";
         String hostProfile = "hostProfile";
-        String password = "secret";
-        Member host = new Member(hostNickname, hostProfile, "Leader");
+        Member host = new Member(hostNickname, hostProfile, MemberRole.LEADER);
 
-        Room createdRoom = roomCreationService.createRoom(roomName, capacity, host, password);
+        Room createdRoom = roomCreationService.createRoom(roomName, capacity, host);
 
         assertAll("Room Create Test",
                 () -> assertNotNull(createdRoom, "Room 객체는 null이 아니어야 합니다."),
                 () -> assertNotNull(createdRoom.getId(), "약속방 ID는 null이 아니어야 합니다."),
                 () -> assertEquals(roomName, createdRoom.getRoomName(), "약속방 이름이 일치해야 합니다."),
                 () -> assertEquals(capacity, createdRoom.getCapacity(), "참여 인원 수가 일치해야 합니다."),
-                () -> assertEquals(password, createdRoom.getPassword(), "비밀번호가 일치해야 합니다."),
                 () -> assertNotNull(createdRoom.getMember(), "방장 정보는 null이 아니어야 합니다."),
                 () -> assertEquals(hostNickname, createdRoom.getMember().getNickname(), "방장 닉네임이 일치해야 합니다."),
                 () -> assertEquals(hostProfile, createdRoom.getMember().getProfile(), "방장 프로필이 일치해야 합니다."),
-                () -> assertEquals("Leader", createdRoom.getMember().getRole(), "방장 역할은 Leader여야 합니다.")
+                () -> assertEquals(MemberRole.LEADER, createdRoom.getMember().getRole(), "방장 역할은 Leader여야 합니다.")
         );
     }
 }
diff --git a/kok-api/src/test/java/com/kok/kokapi/room/application/service/RoomQueryServiceTest.java b/kok-api/src/test/java/com/kok/kokapi/room/application/service/RoomQueryServiceTest.java
index f16c8c3f..560c7f58 100644
--- a/kok-api/src/test/java/com/kok/kokapi/room/application/service/RoomQueryServiceTest.java
+++ b/kok-api/src/test/java/com/kok/kokapi/room/application/service/RoomQueryServiceTest.java
@@ -7,6 +7,7 @@
 import com.kok.kokcore.room.application.port.out.SaveRoomPort;
 import com.kok.kokcore.room.domain.Member;
 import com.kok.kokcore.room.domain.Room;
+import com.kok.kokcore.room.domain.vo.MemberRole;
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -22,8 +23,8 @@ class RoomQueryServiceTest extends ServiceTest {
     @Test
     void findRoomById() {
         // given
-        Member member = new Member("nickname", "image", "Leader");
-        Room room = saveRoomPort.save(Room.create("room", 2, member, "1234"));
+        Member member = new Member("nickname", "image", MemberRole.LEADER);
+        Room room = saveRoomPort.save(Room.create("room", 2, member));
 
         // when
         Room result = roomQueryService.findRoomById(room.getId());
diff --git a/kok-core/src/main/java/com/kok/kokcore/room/application/port/out/LoadRoomParticipantsPort.java b/kok-core/src/main/java/com/kok/kokcore/room/application/port/out/LoadRoomParticipantsPort.java
new file mode 100644
index 00000000..c0a8380b
--- /dev/null
+++ b/kok-core/src/main/java/com/kok/kokcore/room/application/port/out/LoadRoomParticipantsPort.java
@@ -0,0 +1,9 @@
+package com.kok.kokcore.room.application.port.out;
+
+import com.kok.kokcore.room.domain.Profile;
+
+import java.util.List;
+
+public interface LoadRoomParticipantsPort {
+    List<Profile> getProfilesByRoomId(String roomId);
+}
diff --git a/kok-core/src/main/java/com/kok/kokcore/room/application/port/out/SaveRoomParticipantsPort.java b/kok-core/src/main/java/com/kok/kokcore/room/application/port/out/SaveRoomParticipantsPort.java
new file mode 100644
index 00000000..b41a31d4
--- /dev/null
+++ b/kok-core/src/main/java/com/kok/kokcore/room/application/port/out/SaveRoomParticipantsPort.java
@@ -0,0 +1,7 @@
+package com.kok.kokcore.room.application.port.out;
+
+import com.kok.kokcore.room.domain.Member;
+
+public interface SaveRoomParticipantsPort {
+    int joinRoom(String roomId, Member member);
+}
diff --git a/kok-core/src/main/java/com/kok/kokcore/room/domain/Member.java b/kok-core/src/main/java/com/kok/kokcore/room/domain/Member.java
index d837b01e..cd57d779 100644
--- a/kok-core/src/main/java/com/kok/kokcore/room/domain/Member.java
+++ b/kok-core/src/main/java/com/kok/kokcore/room/domain/Member.java
@@ -1,5 +1,6 @@
 package com.kok.kokcore.room.domain;
 
+import com.kok.kokcore.room.domain.vo.MemberRole;
 import lombok.EqualsAndHashCode;
 import lombok.Getter;
 import lombok.ToString;
@@ -10,17 +11,14 @@
 public class Member {
     private final String nickname;
     private final String profile;
-    private final String role;
+    private final MemberRole role;
 
-    public Member(String nickname, String profile, String role) {
+    public Member(String nickname, String profile, MemberRole role) {
         if (nickname == null || nickname.trim().isEmpty()) {
             throw new IllegalArgumentException("Nickname is required");
         }
-        if (role == null || role.trim().isEmpty()) {
-            throw new IllegalArgumentException("Role is required");
-        }
         this.nickname = nickname.trim();
         this.profile = profile.trim();
-        this.role = role.trim();
+        this.role = role;
     }
 }
diff --git a/kok-core/src/main/java/com/kok/kokcore/room/domain/Profile.java b/kok-core/src/main/java/com/kok/kokcore/room/domain/Profile.java
new file mode 100644
index 00000000..86e5bd7a
--- /dev/null
+++ b/kok-core/src/main/java/com/kok/kokcore/room/domain/Profile.java
@@ -0,0 +1,18 @@
+package com.kok.kokcore.room.domain;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.ToString;
+
+@Getter
+@ToString
+@EqualsAndHashCode
+public class Profile {
+    private final String imageUrl;
+    private final String nickname;
+
+    public Profile(String imageUrl, String nickname) {
+        this.imageUrl = imageUrl;
+        this.nickname = nickname;
+    }
+}
diff --git a/kok-core/src/main/java/com/kok/kokcore/room/domain/Room.java b/kok-core/src/main/java/com/kok/kokcore/room/domain/Room.java
index d440f90a..d28cc226 100644
--- a/kok-core/src/main/java/com/kok/kokcore/room/domain/Room.java
+++ b/kok-core/src/main/java/com/kok/kokcore/room/domain/Room.java
@@ -11,27 +11,24 @@
 public class Room implements Serializable {
 
     public static final int REQUIRED_CAPACITY = 2;
-
     private final String id;               // 약속방 ID (UUID)
     private final String roomName;         // 약속방 이름
     private final int capacity;            // 참여인원 수 (최소 2명 이상)
-    private final String password;         // 방 비밀번호 (옵션)
-    private final Member member;             // 방 참여자
+    private final Member member;           // 방 참여자
 
-    private Room(String id, String roomName, int capacity, Member member, String password) {
+    private Room(String id, String roomName, int capacity, Member member) {
         this.id = id;
         this.roomName = roomName;
         this.capacity = capacity;
         this.member = member;
-        this.password = password;
     }
 
-    public static Room create(String roomName, int capacity, Member host, String password) {
+    public static Room create(String roomName, int capacity, Member member) {
         validateParameter(roomName, capacity);
 
         String roomId = UUID.randomUUID().toString();
 
-        return new Room(roomId, roomName, capacity, host, password);
+        return new Room(roomId, roomName, capacity, member);
     }
 
     private static void validateParameter(String roomName, int capacity) {
diff --git a/kok-core/src/main/java/com/kok/kokcore/room/domain/vo/MemberRole.java b/kok-core/src/main/java/com/kok/kokcore/room/domain/vo/MemberRole.java
new file mode 100644
index 00000000..40cbf6e5
--- /dev/null
+++ b/kok-core/src/main/java/com/kok/kokcore/room/domain/vo/MemberRole.java
@@ -0,0 +1,6 @@
+package com.kok.kokcore.room.domain.vo;
+
+public enum MemberRole {
+    LEADER,
+    FOLLOWER
+}
diff --git a/kok-core/src/main/java/com/kok/kokcore/room/usecase/CreateRandomProfileUseCase.java b/kok-core/src/main/java/com/kok/kokcore/room/usecase/CreateRandomProfileUseCase.java
new file mode 100644
index 00000000..1d9ac350
--- /dev/null
+++ b/kok-core/src/main/java/com/kok/kokcore/room/usecase/CreateRandomProfileUseCase.java
@@ -0,0 +1,7 @@
+package com.kok.kokcore.room.usecase;
+
+import com.kok.kokcore.room.domain.Profile;
+
+public interface CreateRandomProfileUseCase {
+    Profile createProfile();
+}
\ No newline at end of file
diff --git a/kok-core/src/main/java/com/kok/kokcore/room/usecase/CreateRoomUseCase.java b/kok-core/src/main/java/com/kok/kokcore/room/usecase/CreateRoomUseCase.java
index bdc75c5a..166e6a5a 100644
--- a/kok-core/src/main/java/com/kok/kokcore/room/usecase/CreateRoomUseCase.java
+++ b/kok-core/src/main/java/com/kok/kokcore/room/usecase/CreateRoomUseCase.java
@@ -4,5 +4,5 @@
 import com.kok.kokcore.room.domain.Room;
 
 public interface CreateRoomUseCase {
-    Room createRoom(String roomName, int capacity, Member host, String password);
-}
\ No newline at end of file
+    Room createRoom(String roomName, int capacity, Member host);
+}
diff --git a/kok-core/src/main/java/com/kok/kokcore/room/usecase/GetMemberProfileUseCase.java b/kok-core/src/main/java/com/kok/kokcore/room/usecase/GetMemberProfileUseCase.java
new file mode 100644
index 00000000..f881da75
--- /dev/null
+++ b/kok-core/src/main/java/com/kok/kokcore/room/usecase/GetMemberProfileUseCase.java
@@ -0,0 +1,9 @@
+package com.kok.kokcore.room.usecase;
+
+import com.kok.kokcore.room.domain.Profile;
+
+import java.util.List;
+
+public interface GetMemberProfileUseCase {
+    List<Profile> getProfilesByRoomId(String roomId);
+}
diff --git a/kok-core/src/main/java/com/kok/kokcore/room/usecase/JoinRoomUseCase.java b/kok-core/src/main/java/com/kok/kokcore/room/usecase/JoinRoomUseCase.java
index 958b7c1f..0044524d 100644
--- a/kok-core/src/main/java/com/kok/kokcore/room/usecase/JoinRoomUseCase.java
+++ b/kok-core/src/main/java/com/kok/kokcore/room/usecase/JoinRoomUseCase.java
@@ -3,5 +3,5 @@
 import com.kok.kokcore.room.domain.Member;
 
 public interface JoinRoomUseCase {
-    void joinRoom(String roomId, Member member);
+    int joinRoom(String roomId, Member member);
 }
diff --git a/kok-core/src/main/resources/application.properties b/kok-core/src/main/resources/application-prod.yml
similarity index 100%
rename from kok-core/src/main/resources/application.properties
rename to kok-core/src/main/resources/application-prod.yml
diff --git a/kok-core/src/test/java/com/kok/kokcore/room/domain/RoomTest.java b/kok-core/src/test/java/com/kok/kokcore/room/domain/RoomTest.java
index ba211bdf..e64a342e 100644
--- a/kok-core/src/test/java/com/kok/kokcore/room/domain/RoomTest.java
+++ b/kok-core/src/test/java/com/kok/kokcore/room/domain/RoomTest.java
@@ -1,5 +1,6 @@
 package com.kok.kokcore.room.domain;
 
+import com.kok.kokcore.room.domain.vo.MemberRole;
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Test;
 
@@ -16,10 +17,10 @@ void createRoom() {
         String hostProfile = "hostProfile";
         String hostNickname = "test";
         String password = "secret";
-        Member host = new Member(hostNickname, hostProfile, "Leader");
+        Member host = new Member(hostNickname, hostProfile, MemberRole.LEADER);
 
         // When
-        Room room = Room.create(roomName, capacity, host, password);
+        Room room = Room.create(roomName, capacity, host);
 
         // Then
         assertAll("약속방 생성",
@@ -28,8 +29,7 @@ void createRoom() {
                 () -> assertEquals(capacity, room.getCapacity(), "참여 인원 수가 일치해야 합니다."),
                 () -> assertEquals(hostNickname, room.getMember().getNickname(), "방장 닉네임이 일치해야 합니다."),
                 () -> assertEquals(hostProfile, room.getMember().getProfile(), "방장 프로필이 일치해야 합니다."),
-                () -> assertEquals("Leader", room.getMember().getRole(), "방장 역할은 Leader여야 합니다."),
-                () -> assertEquals(password, room.getPassword(), "비밀번호가 일치해야 합니다.")
+                () -> assertEquals(MemberRole.LEADER, room.getMember().getRole(), "방장 역할은 Leader여야 합니다.")
         );
     }
 
@@ -42,11 +42,11 @@ void createRoomWithEmptyRoomName() {
         String hostNickname = "hostNickname";
         String hostProfile = "hostProfile";
         String password = "secret";
-        Member host = new Member(hostNickname, hostProfile, "Leader");
+        Member host = new Member(hostNickname, hostProfile, MemberRole.LEADER);
 
         // When & Then
         IllegalArgumentException exception =
-                assertThrows(IllegalArgumentException.class, () -> Room.create(roomName, capacity, host, password));
+                assertThrows(IllegalArgumentException.class, () -> Room.create(roomName, capacity, host));
         assertTrue(exception.getMessage().contains("Room name is required"));
     }
 
@@ -58,12 +58,11 @@ void createRoomWithInvalidCapacity() {
         int capacity = 1;
         String hostNickname = "hostNickname";
         String hostProfile = "hostProfile";
-        String password = "secret";
-        Member host = new Member(hostNickname, hostProfile, "Leader");
+        Member host = new Member(hostNickname, hostProfile, MemberRole.LEADER);
 
         // When & Then
         IllegalArgumentException exception =
-                assertThrows(IllegalArgumentException.class, () -> Room.create(roomName, capacity, host, password));
+                assertThrows(IllegalArgumentException.class, () -> Room.create(roomName, capacity, host));
         assertTrue(exception.getMessage().contains("At least 2 participants are required"));
     }
 }


Reviews:
user: login: linirini
body: LGTM! 소소한 리뷰 조금씩 남겨보았습니다!
수고하셨어용><
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-08T11:44:45Z
user: login: yunyoung1819
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-08T12:11:25Z
user: login: yunyoung1819
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-08T13:00:37Z
user: login: minseokey
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-08T13:42:15Z
user: login: yunyoung1819
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-08T15:29:26Z

Review comments:
diff_hunk: @@ -6,16 +6,14 @@ public record RoomDetailResponse(
         String id,
         String roomName,
         int capacity,
-        MemberResponse member,
-        String roomLinkUrl
+        MemberResponse member
 ) {
     public static RoomDetailResponse from(Room room) {
         return new RoomDetailResponse(
                 room.getId(),
                 room.getRoomName(),
                 room.getCapacity(),
-                MemberResponse.from(room.getMember()),
-                room.getRoomLinkUrl()
+                MemberResponse.from(room.getMember())
path: kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/RoomDetailResponse.java
user: login: linirini
body: `Room에 속한 Member이니 Leader겠지?`라는 유추의 과정이 필요하다고 느껴졌어요!
메세지를 주는 메서드를 분리하면 어떨까요?
``
```suggestion
                MemberResponse.from(room.getLeader())
```
[소소한 인사이트(?) 공유><](https://developerfarm.wordpress.com/2012/02/01/object_calisthenics_10/)
created_at: 2025-03-08T11:15:13Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,43 @@
+package com.kok.kokapi.room.adapter.in.web;
+
+import com.kok.kokapi.common.response.ApiResponseDto;
+import com.kok.kokapi.config.annotion.V1Controller;
+import com.kok.kokapi.room.adapter.in.dto.response.RandomProfileResponse;
+import com.kok.kokcore.room.domain.Profile;
+import com.kok.kokcore.room.usecase.CreateRandomProfileUseCase;
+import com.kok.kokcore.room.usecase.GetMemberProfileUseCase;
+import io.swagger.v3.oas.annotations.Operation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+
+import java.util.List;
+
+@V1Controller
+@RequiredArgsConstructor
+public class RoomProfileController {
+
+    private final CreateRandomProfileUseCase createRandomProfileUseCase;
+    private final GetMemberProfileUseCase getMemberProfileUseCase;
+
+    @Operation(summary = "랜덤 프로필 및 닉네임 조회", description = "랜덤으로 생성한 프로필 이미지와 닉네임을 반환합니다.")
+    @GetMapping("/rooms/profile/random")
+    public ResponseEntity<ApiResponseDto<RandomProfileResponse>> getRandomProfile() {
+        Profile profile = createRandomProfileUseCase.crateProfile();
path: kok-api/src/main/java/com/kok/kokapi/room/adapter/in/web/RoomProfileController.java
user: login: linirini
body: 오타 발견!
```suggestion
        Profile profile = createRandomProfileUseCase.createProfile();
```
created_at: 2025-03-08T11:16:28Z
author_association: MEMBER
path: kok-api/src/main/java/com/kok/kokapi/room/adapter/out/persistence/RoomMemberQueryAdapter.java
user: login: linirini
body: 미사용 클래스!
created_at: 2025-03-08T11:39:16Z
author_association: MEMBER
path: kok-core/src/main/java/com/kok/kokcore/room/application/port/out/LoadRoomMemberPort.java
user: login: linirini
body: 미사용 클래스2!
created_at: 2025-03-08T11:40:12Z
author_association: MEMBER
path: kok-core/src/main/java/com/kok/kokcore/room/usecase/CreateRoomUseCase.java
user: login: linirini
body: EOL ㅎㅎㅎㅎ
created_at: 2025-03-08T11:40:46Z
author_association: MEMBER
diff_hunk: @@ -28,31 +28,30 @@ public class RoomController {
     private final CreateRoomUseCase createRoomUseCase;
     private final JoinRoomUseCase joinRoomUseCase;
 
-    @Operation(summary = "약속방 조회", description = "Retrieve detailed information for a room using its ID")
+    @Operation(summary = "약속방 조회", description = "약속방 ID를 통해 약속방을 조회합니다.")
path: kok-api/src/main/java/com/kok/kokapi/room/adapter/in/web/RoomController.java
user: login: linirini
body: 한국인은 한글이죠~ 👍👍
created_at: 2025-03-08T11:41:23Z
author_association: MEMBER
path: kok-api/src/main/java/com/kok/kokapi/room/adapter/out/persistence/RoomParticipantQueryAdapter.java
user: login: linirini
body: 👍👍👍😆
created_at: 2025-03-08T11:44:29Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,43 @@
+package com.kok.kokapi.room.adapter.in.web;
+
+import com.kok.kokapi.common.response.ApiResponseDto;
+import com.kok.kokapi.config.annotion.V1Controller;
+import com.kok.kokapi.room.adapter.in.dto.response.RandomProfileResponse;
+import com.kok.kokcore.room.domain.Profile;
+import com.kok.kokcore.room.usecase.CreateRandomProfileUseCase;
+import com.kok.kokcore.room.usecase.GetMemberProfileUseCase;
+import io.swagger.v3.oas.annotations.Operation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+
+import java.util.List;
+
+@V1Controller
+@RequiredArgsConstructor
+public class RoomProfileController {
+
+    private final CreateRandomProfileUseCase createRandomProfileUseCase;
+    private final GetMemberProfileUseCase getMemberProfileUseCase;
+
+    @Operation(summary = "랜덤 프로필 및 닉네임 조회", description = "랜덤으로 생성한 프로필 이미지와 닉네임을 반환합니다.")
+    @GetMapping("/rooms/profile/random")
+    public ResponseEntity<ApiResponseDto<RandomProfileResponse>> getRandomProfile() {
+        Profile profile = createRandomProfileUseCase.crateProfile();
path: kok-api/src/main/java/com/kok/kokapi/room/adapter/in/web/RoomProfileController.java
user: login: yunyoung1819
body: 굳! 수정했습니당
created_at: 2025-03-08T12:11:25Z
author_association: COLLABORATOR
diff_hunk: @@ -6,16 +6,14 @@ public record RoomDetailResponse(
         String id,
         String roomName,
         int capacity,
-        MemberResponse member,
-        String roomLinkUrl
+        MemberResponse member
 ) {
     public static RoomDetailResponse from(Room room) {
         return new RoomDetailResponse(
                 room.getId(),
                 room.getRoomName(),
                 room.getCapacity(),
-                MemberResponse.from(room.getMember()),
-                room.getRoomLinkUrl()
+                MemberResponse.from(room.getMember())
path: kok-api/src/main/java/com/kok/kokapi/room/adapter/in/dto/response/RoomDetailResponse.java
user: login: yunyoung1819
body: Good!
created_at: 2025-03-08T13:00:37Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,29 @@
+package com.kok.kokapi.room.adapter.out.persistence;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.kok.kokcore.room.application.port.out.SaveRoomParticipantsPort;
+import com.kok.kokcore.room.domain.Member;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Repository;
+
+@Repository
+@RequiredArgsConstructor
+public class RoomParticipantSaveAdapter implements SaveRoomParticipantsPort {
+
+    private static final String PARTICIPANT_KEY_PREFIX = "room:participants:";
+    private final RedisTemplate<String, String> redisTemplate;
+    private final ObjectMapper objectMapper;
+
+    @Override
+    public void joinRoom(String roomId, Member member) {
path: kok-api/src/main/java/com/kok/kokapi/room/adapter/out/persistence/RoomParticipantSaveAdapter.java
user: login: minseokey
body: 이 지점에서 memberId 를 리턴해주는것이 좋을것 같다는 의견입니다!
created_at: 2025-03-08T13:14:18Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,29 @@
+package com.kok.kokapi.room.adapter.out.persistence;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.kok.kokcore.room.application.port.out.SaveRoomParticipantsPort;
+import com.kok.kokcore.room.domain.Member;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Repository;
+
+@Repository
+@RequiredArgsConstructor
+public class RoomParticipantSaveAdapter implements SaveRoomParticipantsPort {
+
+    private static final String PARTICIPANT_KEY_PREFIX = "room:participants:";
+    private final RedisTemplate<String, String> redisTemplate;
+    private final ObjectMapper objectMapper;
+
+    @Override
+    public void joinRoom(String roomId, Member member) {
path: kok-api/src/main/java/com/kok/kokapi/room/adapter/out/persistence/RoomParticipantSaveAdapter.java
user: login: yunyoung1819
body: 우선 여기에서 memberId를 리턴하는 방식으로 수정했어요
created_at: 2025-03-08T15:29:26Z
author_association: COLLABORATOR

PR comments:
user: login: yunyoung1819
created_at: 2025-03-08T07:44:03Z
body: 편하실때 리뷰 부탁드려요~!
author_association: COLLABORATOR
user: login: yunyoung1819
created_at: 2025-03-08T15:34:10Z
body: 다 수정했어요
author_association: COLLABORATOR