Conversation
|
""" Walkthrough이 PR은 채팅, 크롤링 일자리, 잡포스팅 등 주요 도메인에서 Redis 기반의 데이터 처리와 시퀀스 기반 메시지 읽기/쓰기 등 새로운 기능을 도입하며, 관련 서비스, 컨트롤러, DTO, 레포지토리, 배치 잡 구성을 대대적으로 리팩터링합니다. 여러 API 시그니처와 데이터 모델이 변경되고, Redis를 활용한 지오스페이셜 쿼리 및 채팅 읽음 처리, 메시지 시퀀스 관리가 추가되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant ChatSocketController
participant ChatFacadeService
participant ChatMessageService
participant ChatRedisRepository
participant ChatRoomService
Client->>ChatSocketController: send(request, userId, isCarer)
ChatSocketController->>ChatFacadeService: send(request, userId, isCarer)
ChatFacadeService->>ChatRoomService: getById(chatRoomId)
ChatFacadeService->>ChatRedisRepository: getChatRoomSequence(chatRoomId)
ChatFacadeService->>ChatMessageService: save(request, userId, sequence)
ChatFacadeService->>ChatRedisRepository: addUnreadChatRoom(receiverId, chatRoomId)
ChatFacadeService->>ChatRedisRepository: updateReadSequence(chatRoomId, sequence, senderId)
ChatFacadeService->>ChatRedisRepository: publish(ChatMessage)
ChatFacadeService->>ChatFacadeService: sendNotification(...)
ChatFacadeService-->>ChatSocketController: (no return)
sequenceDiagram
participant Client
participant ChatSocketController
participant ChatFacadeService
participant ChatRedisRepository
Client->>ChatSocketController: read(request, userId, isCarer)
ChatSocketController->>ChatFacadeService: read(request, userId, isCarer)
ChatFacadeService->>ChatRedisRepository: removeUnreadChatRoom(userId, chatRoomId)
ChatFacadeService->>ChatRedisRepository: updateReadSequence(chatRoomId, sequence, userId)
ChatFacadeService->>ChatRedisRepository: publish(ReadMessage)
ChatFacadeService-->>ChatSocketController: (no return)
sequenceDiagram
participant Client
participant CrawlingPostingFacadeService
participant CrawlingJobPostingService
participant RedisJobPostingRepository
Client->>CrawlingPostingFacadeService: getCrawlingPostingsInRange(request)
CrawlingPostingFacadeService->>CrawlingJobPostingService: findAllInRange(next, location, distance, limit)
CrawlingJobPostingService->>RedisJobPostingRepository: findByLocationAndDistance(location, distance, limit, next)
RedisJobPostingRepository-->>CrawlingJobPostingService: List<postingIds>
CrawlingJobPostingService->>CrawlingJobPostingService: get postings by IDs, map to DTOs
CrawlingJobPostingService-->>CrawlingPostingFacadeService: List<DTOs>
CrawlingPostingFacadeService-->>Client: CrawlingJobPostingScrollResponse
Possibly related PRs
Suggested labels
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
Docstrings generation was requested by @mjj111. * #275 (comment) The following files were modified: * `idle-application/src/main/kotlin/com/swm/idle/application/chat/domain/ChatMessageService.kt` * `idle-application/src/main/kotlin/com/swm/idle/application/chat/domain/ChatRoomService.kt` * `idle-application/src/main/kotlin/com/swm/idle/application/chat/facade/ChatFacadeService.kt` * `idle-application/src/main/kotlin/com/swm/idle/application/common/converter/PointConverter.kt` * `idle-application/src/main/kotlin/com/swm/idle/application/jobposting/domain/CrawlingJobPostingService.kt` * `idle-application/src/main/kotlin/com/swm/idle/application/jobposting/facade/CarerPostingFacadeService.kt` * `idle-application/src/main/kotlin/com/swm/idle/application/jobposting/facade/CenterPostingFacadeService.kt` * `idle-application/src/main/kotlin/com/swm/idle/application/jobposting/facade/CrawlingPostingFacadeService.kt` * `idle-application/src/main/kotlin/com/swm/idle/application/user/carer/domain/CarerService.kt` * `idle-application/src/main/kotlin/com/swm/idle/application/user/center/service/domain/CenterService.kt` * `idle-batch/src/main/kotlin/com/swm/idle/batch/common/launcher/CrawlingJobLauncher.kt` * `idle-batch/src/main/kotlin/com/swm/idle/batch/crawler/WorknetPageParser.kt` * `idle-batch/src/main/kotlin/com/swm/idle/batch/job/JobConfig.kt` * `idle-batch/src/main/kotlin/com/swm/idle/batch/step/PostingReader.kt` * `idle-batch/src/main/kotlin/com/swm/idle/batch/step/PostingWriter.kt` * `idle-domain/src/main/kotlin/com/swm/idle/domain/chat/event/ChatRedisTemplate.kt` * `idle-domain/src/main/kotlin/com/swm/idle/domain/chat/repository/ChatMessageRepository.kt` * `idle-domain/src/main/kotlin/com/swm/idle/domain/chat/repository/ChatRoomRepository.kt` * `idle-domain/src/main/kotlin/com/swm/idle/domain/chat/vo/ChatRoomSummaryInfo.kt` * `idle-domain/src/main/kotlin/com/swm/idle/domain/chat/vo/ChatRoomSummaryInfoProjection.kt` * `idle-domain/src/main/kotlin/com/swm/idle/domain/jobposting/repository/redis/RedisJobPostingRepository.kt` * `idle-presentation/src/main/kotlin/com/swm/idle/presentation/batch/api/BatchApi.kt` * `idle-presentation/src/main/kotlin/com/swm/idle/presentation/batch/controller/BatchController.kt` * `idle-presentation/src/main/kotlin/com/swm/idle/presentation/chat/api/ChatCarerApi.kt` * `idle-presentation/src/main/kotlin/com/swm/idle/presentation/chat/api/ChatCenterApi.kt` * `idle-presentation/src/main/kotlin/com/swm/idle/presentation/chat/controller/ChatCarerController.kt` * `idle-presentation/src/main/kotlin/com/swm/idle/presentation/chat/controller/ChatCenterController.kt` * `idle-presentation/src/main/kotlin/com/swm/idle/presentation/chat/controller/ChatSocketController.kt` * `idle-presentation/src/main/kotlin/com/swm/idle/presentation/chat/handler/ChatHandler.kt` * `idle-presentation/src/main/kotlin/com/swm/idle/presentation/jobposting/api/CrawlingJobPostingApi.kt` * `idle-presentation/src/main/kotlin/com/swm/idle/presentation/jobposting/controller/CarerJobPostingController.kt` * `idle-presentation/src/main/kotlin/com/swm/idle/presentation/jobposting/controller/CenterJobPostingController.kt` * `idle-presentation/src/main/kotlin/com/swm/idle/presentation/jobposting/controller/CrawlingJobPostingController.kt` * `idle-support/transfer/src/main/kotlin/com/swm/idle/support/transfer/jobposting/carer/CrawlingJobPostingScrollResponse.kt` * `idle-support/transfer/src/main/kotlin/com/swm/idle/support/transfer/jobposting/common/CrawlingJobPostingResponse.kt`
|



1. 📄 Summary
📦 공고 수집 및 조회 개선 (IDLE-578, IDLE-580)
💬 채팅 기능 개선 (IDLE-581, IDLE-582, IDLE-584)
🧹 기타 리팩토링 및 안정화
2. 🤔 고민했던 점
이번 작업에서는 Redis를 어떻게 활용할지에 대한 고민이 많았습니다. 단순한 캐시로만 사용할지, 아니면 데이터 흐름의 핵심 일부로 적극 활용할지를 두고 여러 방향을 검토했습니다. 특히, 위치 기반 공고 조회나 채팅 시퀀스 관리처럼 실시간성과 데이터 정합성이 중요한 기능에서는 Redis가 단순 캐시를 넘어서 핵심 저장소로써 어떤 역할을 해야 할지 판단이 필요했습니다. TTL을 설정할 때에도 만료 이후의 처리 로직이나, 예상치 못한 삭제로 인한 fallback 전략이 함께 고려되어야 했습니다. Redis 특성상 빠른 속도와 유연함을 제공하지만, 반대로 운영 중 발생할 수 있는 예외 상황에 대한 고민도 함께 이루어졌습니다.
3. 💡 알게된 점
이번 경험을 통해 Redis가 단순히 자주 조회되는 데이터를 캐시하는 용도만이 아니라, 시퀀스 저장소나 사용자별 상태(예: 안 읽은 메시지 상태) 관리 등 실시간성을 요구하는 로직에서 핵심적인 역할을 할 수 있다는 점을 새롭게 인식하게 되었습니다. 또한 TTL을 활용한 데이터 보존 전략이 실제 서비스에서 어떤 의미를 가지는지, 그리고 데이터가 만료되었을 때의 처리 방안이 얼마나 중요한지도 체감할 수 있었습니다. Redis와 RDB 간의 정합성 유지 문제나, 캐시가 아닌 준-영속 저장소로 사용할 때 생길 수 있는 데이터 소실 위험에 대해서도 더 깊이 공부할 필요성을 느꼈습니다. 특히 채팅처럼 데이터 순서와 정확성이 중요한 기능에서는 Redis를 어떻게 안전하게 설계하고 운영할지에 대한 고민이 앞으로도 계속 이어질 것 같습니다.
Summary by CodeRabbit
신규 기능
기능 개선
버그 수정
DB 마이그레이션
리팩터링/정리
문서화