Conversation
- Redis 의존성 추가로 캐시 계층 구현 지원 - 이후 DB 및 Elasticsearch 부하를 감소시키는 단계적 캐시 도입을 위한 기반 마련 - TTL 및 키 설계와 같은 캐시 정책 적용을 위한 사전 작업
- Docker Compose에 Redis 서비스 추가하여 로컬 개발 환경에서도 캐시 계층 테스트 가능 - Redis 컨테이너 healthcheck 설정으로 서비스 상태 점검 및 안정성 강화 - 데이터 지속성을 위해 redis_data 볼륨 마운트 설정 - Redis 설정에 appendonly 모드 활성화하여 데이터 보존 보장
- Spring 기반 Redis 설정 클래스 추가 - LettuceConnectionFactory 및 RedisTemplate 구성하여 Redis 연결 지원 - RedisSerializer 설정으로 키/값 직렬화 방식 정의 - 캐시 계층 도입을 위한 기반 작업으로, 이후 성능 최적화 및 부하 분산 목표
- RedisTemplate 설정 테스트 작성하여 Redis 연동 구성의 유효성 검증 - Spring Boot 기반 통합 테스트로 RedisTemplate 빈 등록 여부 확인 - 이후 캐시 계층 테스트 자동화 및 안정성 강화 목표
- 게시글 상세, 목록, 검색, 통계와 관련된 캐시 키 생성 유틸리티 추가 - 안정적이고 일관된 키 생성 방식 제공하여 캐시 조회와 무효화 로직 간소화 - 키 정규화, 유효성 검증, 해시 알고리즘(MD5) 적용으로 예외 처리와 확장성 고려 - Redis 캐시 계층 설계의 기반 코드로, 이후 성능 최적화 및 테스트 강화 목표 test(cache): add tests for PostCacheKey utility - PostCacheKey 클래스의 상세, 목록, 검색, 통계 키 생성 방식을 검증하는 테스트 추가 - 유효하지 않은 입력값에 대한 예외 처리 동작 확인 - 정상적인 키 형식 및 정규화 로직 검증으로 키 생성의 신뢰성 확보
- RedisTemplate 설정 및 키 스키마 정의에 관한 문서 추가 - 환경 설정, Redis 설정 클래스, 키 스키마 유틸리티 구현 절차를 상세히 기술 - TTL/설정 상수 관리 및 테스트/검증 방법 포함 - 캐시 계층 도입의 첫 번째 단계로, 이후 개발팀의 일관된 설계와 구현 지원 목적
WalkthroughRedis 의존성 및 Docker Compose 서비스가 추가되었고, Spring 빈으로 RedisTemplate 구성 클래스와 게시물 캐시 키 생성 유틸리티(PostCacheKey), 관련 단위/통합 테스트, Redis 사용 가이드 문서가 추가되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant App as 애플리케이션
participant Spring as 스프링 컨텍스트
participant Redis as Redis 서비스
App->>Spring: 컨텍스트 시작/빈 요청
Spring->>Spring: RedisConnectionFactory 생성 (Lettuce 등)
Spring->>Spring: RedisTemplate<String,String> 구성\n(StringRedisSerializer 설정)
Spring-->>App: RedisTemplate 빈 주입
Note over App: 캐시 키 생성
App->>App: PostCacheKey.detail(id) / publicList(...) / search(query,...)\n(정규화 · 검증 · MD5 해시)
Note over App,Redis: 캐시 연산 예시
App->>Redis: SET key value (TTL)
Redis-->>App: OK
App->>Redis: GET key
Redis-->>App: value
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (7)
build.gradle.kts (1)
50-50: Redis 의존성 추가 LGTM. 풀링·테스트 편의도 함께 고려해 주세요.
- 고동시 동시성이라면 Lettuce 풀링을 위해 commons-pool2 추가를 검토하세요(boot가 존재 시 자동 적용).
- 통합 테스트에서 실제 Redis 의존을 줄이려면 Testcontainers(redis) 도입을 권장합니다.
docker-compose.yml (1)
100-114: Redis 서비스 정의 좋습니다. 초기 기동 안정성과 보안을 약간 보강합시다.
- 컨테이너 초기화 시간 편차에 대비해 healthcheck에 start_period를 추가 권장.
- 비공개 환경이 아니라면 requirepass 설정도 고려하세요(앱 설정과 동기화 필요).
적용 예시:
redis: image: redis:7-alpine @@ healthcheck: test: ["CMD", "redis-cli", "ping"] + start_period: 5s interval: 10s timeout: 5s retries: 10(비밀번호 사용 시)
- command: ["redis-server", "--appendonly", "yes"] + command: ["redis-server", "--appendonly", "yes", "--requirepass", "see_password"]Also applies to: 118-118
src/test/java/dooya/see/adapter/integration/cache/RedisConfigTest.java (1)
9-15: 컨텍스트 범위를 슬림화하고 직렬화 설정까지 검증하세요.전체 앱 컨텍스트 로드는 무겁습니다. 설정 클래스만 대상으로 하고, String 직렬화가 적용됐는지도 함께 확인하세요.
예시 수정:
@@ -import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Import; +import org.springframework.data.redis.serializer.StringRedisSerializer; +import dooya.see.adapter.integration.cache.config.RedisConfig; @@ -@SpringBootTest -public record RedisConfigTest(RedisTemplate<String, String> redisTemplate) { +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = RedisConfig.class) +public record RedisConfigTest(RedisTemplate<String, String> redisTemplate) { @Test void RedisTemplate_설정_확인() { assertThat(redisTemplate).isNotNull(); + assertThat(redisTemplate.getKeySerializer()).isInstanceOf(StringRedisSerializer.class); + assertThat(redisTemplate.getValueSerializer()).isInstanceOf(StringRedisSerializer.class); } }src/test/java/dooya/see/adapter/integration/cache/key/PostCacheKeyTest.java (1)
8-48: 경계·정규화 케이스 테스트를 조금만 보강해 주세요.
- 카테고리 null 처리(normalize → "null") 케이스 추가.
- page < 0, size <= 0 등 허용/비허용 정책에 맞는 테스트를 명시하세요(허용 안 함이라면 유효성 검증도 구현 필요).
추가 예시:
@@ void 카테고리_목록_키는_대문자_카테고리와_페이지_정보를_포함한다() { String key = PostCacheKey.categoryList("tech", 1, 10); assertThat(key).isEqualTo("post:list:category:TECH:1:10"); } + + @Test + void 카테고리가_null이면_literal_null로_정규화된다() { + String key = PostCacheKey.categoryList(null, 0, 20); + assertThat(key).isEqualTo("post:list:category:null:0:20"); + } + + // 정책 결정에 따라 활성화: 음수 페이지/사이즈 검증 + // @Test + // void 음수_페이지나_비양수_사이즈면_예외() { + // assertThatThrownBy(() -> PostCacheKey.publicList(-1, 0)).isInstanceOf(IllegalArgumentException.class); + // assertThatThrownBy(() -> PostCacheKey.publicList(0, 0)).isInstanceOf(IllegalArgumentException.class); + // }src/main/java/dooya/see/adapter/integration/cache/config/RedisConfig.java (1)
19-29: RedisTemplate 직렬화 설정은 좋습니다. 몇 가지 미세 조정 제안
- afterPropertiesSet() 호출은 Bean 라이프사이클에서 자동 처리되는 편입니다(생략 가능).
- 문자열만 다룰 계획이면 StringRedisTemplate 사용도 간결합니다.
대체안:
- @Bean - RedisTemplate<String, String> redisTemplate(RedisConnectionFactory connectionFactory) { - RedisTemplate<String, String> template = new RedisTemplate<>(); - template.setConnectionFactory(connectionFactory); - template.setKeySerializer(new StringRedisSerializer()); - template.setValueSerializer(new StringRedisSerializer()); - template.setHashKeySerializer(new StringRedisSerializer()); - template.setHashValueSerializer(new StringRedisSerializer()); - template.afterPropertiesSet(); - return template; - } + @Bean + org.springframework.data.redis.core.StringRedisTemplate redisTemplate(RedisConnectionFactory cf) { + var template = new org.springframework.data.redis.core.StringRedisTemplate(); + template.setConnectionFactory(cf); + // 필요 시 추가 옵션만 설정 + return template; + }src/main/java/dooya/see/adapter/integration/cache/key/PostCacheKey.java (2)
20-26: 페이지네이션 매개변수 검증 추가를 권장합니다.
page와size매개변수에 대한 검증이 없어, 음수나 0 값이 캐시 키에 포함될 수 있습니다. 데이터 일관성을 위해 검증 로직 추가를 고려해주세요.검증 헬퍼 메서드를 추가하는 것을 고려해보세요:
private static void requireValidPagination(int page, int size) { if (page < 0) { throw new IllegalArgumentException("page must be non-negative"); } if (size <= 0) { throw new IllegalArgumentException("size must be positive"); } } public static String publicList(int page, int size) { requireValidPagination(page, size); return PREFIX + ":list:public:" + page + ":" + size; } public static String categoryList(String category, int page, int size) { requireValidPagination(page, size); return PREFIX + ":list:category:" + normalize(category) + ":" + page + ":" + size; }
28-31: 매개변수 이름 개선을 고려해보세요.매개변수 이름이
normalizedQuery인데, 메서드 내부에서 해시 처리되므로 "normalized"라는 이름이 다소 모호합니다.query또는searchQuery가 더 명확할 수 있습니다.-public static String search(String normalizedQuery, int page, int size) { - String hash = hashToHex(normalizedQuery); +public static String search(String query, int page, int size) { + String hash = hashToHex(query); return PREFIX + ":search:" + hash + ":" + page + ":" + size; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
.docs/cache-strategy.md(1 hunks).docs/redis-template-setup.md(1 hunks)build.gradle.kts(1 hunks)docker-compose.yml(1 hunks)src/main/java/dooya/see/adapter/integration/cache/config/RedisConfig.java(1 hunks)src/main/java/dooya/see/adapter/integration/cache/key/PostCacheKey.java(1 hunks)src/test/java/dooya/see/adapter/integration/cache/RedisConfigTest.java(1 hunks)src/test/java/dooya/see/adapter/integration/cache/key/PostCacheKeyTest.java(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/test/java/dooya/see/adapter/integration/cache/key/PostCacheKeyTest.java (1)
src/main/java/dooya/see/adapter/integration/cache/key/PostCacheKey.java (1)
PostCacheKey(9-64)
🪛 ast-grep (0.39.6)
src/main/java/dooya/see/adapter/integration/cache/key/PostCacheKey.java
[warning] 56-56: Triple DES (3DES or DESede) is considered deprecated. AES is the recommended cipher. Upgrade to use AES.
Context: MessageDigest.getInstance(HASH_ALGORITHM)
Note: [CWE-326]: Inadequate Encryption Strength [OWASP A03:2017]: Sensitive Data Exposure [OWASP A02:2021]: Cryptographic Failures [REFERENCES]
- https://find-sec-bugs.github.io/bugs.htm#TDES_USAGE
- https://csrc.nist.gov/News/2017/Update-to-Current-Use-and-Deprecation-of-TDEA
(desede-is-deprecated-java)
[warning] 56-56: Use of AES with ECB mode detected. ECB doesn't provide message confidentiality and is not semantically secure so should not be used. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.
Context: MessageDigest.getInstance(HASH_ALGORITHM)
Note: [CWE-327]: Use of a Broken or Risky Cryptographic Algorithm [OWASP A03:2017]: Sensitive Data Exposure [OWASP A02:2021]: Cryptographic Failures [REFERENCES]
- https://owasp.org/Top10/A02_2021-Cryptographic_Failures
- https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html
(use-of-aes-ecb-java)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: test
- GitHub Check: build-check
🔇 Additional comments (4)
.docs/cache-strategy.md (1)
60-60: 용어 수정 적절합니다.표현 명확해졌습니다. 추가 의견 없음.
src/main/java/dooya/see/adapter/integration/cache/key/PostCacheKey.java (3)
9-14: 클래스 구조가 올바릅니다.유틸리티 클래스 패턴이 정확하게 구현되었습니다. final 클래스와 private 생성자를 통해 인스턴스화와 상속을 방지하고 있습니다.
37-42: 정규화 로직이 적절합니다.null 카테고리를 "null" 문자열로 처리하는 것은 캐시 키 일관성을 위한 합리적인 선택입니다. 테스트 커버리지도 이 동작을 검증하고 있습니다.
52-63: MD5 해싱 사용이 적절하며, 정적 분석 경고는 오탐입니다.MD5를 해싱(암호화가 아님)에 사용하는 것은 캐시 키 생성 목적에 완전히 적합합니다. 정적 분석 도구의 DES/AES-ECB 경고는 암호화 관련 경고이지만, 이 코드는 암호화를 수행하지 않으므로 무시해도 됩니다.
null/blank 입력에 대해 "empty"를 반환하는 것은 이론적으로 충돌 가능성이 있지만, 실무에서는 문제가 되지 않을 것으로 보입니다.
| 1. Redis 접속 정보를 `application.yml` 또는 프로파일별 설정에 추가합니다. | ||
| - 예: `spring.data.redis.host`, `spring.data.redis.port`, `spring.data.redis.password`. | ||
| 2. 로컬·운영 환경에서 값을 어떻게 주입할지(환경 변수, docker-compose 등) 사전에 정리합니다. |
There was a problem hiding this comment.
프로퍼티 prefix가 잘못되었습니다. spring.redis.* 사용이 맞습니다.
Spring Boot 오토컨피그는 spring.redis.host|port|password를 사용합니다. 문서 예시를 수정해 주세요.
수정 예시:
- - 예: `spring.data.redis.host`, `spring.data.redis.port`, `spring.data.redis.password`.
+ - 예: `spring.redis.host`, `spring.redis.port`, `spring.redis.password`. 🤖 Prompt for AI Agents
.docs/redis-template-setup.md lines 6-8: the documented Redis property prefix is
incorrect; replace references to spring.data.redis.* with the correct Spring
Boot auto-config prefix spring.redis.* in the example and any descriptive text,
and update the sample keys to use spring.redis.host, spring.redis.port,
spring.redis.password so the docs match Spring Boot conventions.
| 2. `@Configuration` 클래스를 만들고 다음 빈을 등록합니다. | ||
| - `RedisConnectionFactory` (Lettuce 클라이언트 사용 권장) | ||
| - `RedisTemplate<String, ?>` (직렬화 전략 선택: `StringRedisSerializer`, `GenericJackson2JsonRedisSerializer` 등) | ||
| 3. 필요 시 `ObjectMapper` 등 공용 Bean을 주입하거나 별도 설정을 만듭니다. |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
RedisConnectionFactory 수동 등록은 피하고, 오토컨피그를 활용하세요.
수동 팩토리 빈을 정의하면 Boot의 spring.redis.* 바인딩이 무시될 수 있습니다. 연결 팩토리는 미정의(백오프)하고, 필요 시 RedisTemplate만 커스터마이즈하세요.
수정 예시(가이드 문구):
-2. `@Configuration` 클래스를 만들고 다음 빈을 등록합니다.
- - `RedisConnectionFactory` (Lettuce 클라이언트 사용 권장)
- - `RedisTemplate<String, ?>` (직렬화 전략 선택: `StringRedisSerializer`, `GenericJackson2JsonRedisSerializer` 등)
+2. `@Configuration` 클래스에서는 `RedisTemplate<String, ?>`만 커스터마이즈합니다.
+ - 연결 팩토리(`RedisConnectionFactory`)는 Spring Boot 오토컨피그에 맡깁니다(프로퍼티: `spring.redis.*`).
+ - 직렬화 전략만 명시적으로 설정(`StringRedisSerializer`, `GenericJackson2JsonRedisSerializer` 등). 📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| 2. `@Configuration` 클래스를 만들고 다음 빈을 등록합니다. | |
| - `RedisConnectionFactory` (Lettuce 클라이언트 사용 권장) | |
| - `RedisTemplate<String, ?>` (직렬화 전략 선택: `StringRedisSerializer`, `GenericJackson2JsonRedisSerializer` 등) | |
| 3. 필요 시 `ObjectMapper` 등 공용 Bean을 주입하거나 별도 설정을 만듭니다. | |
| 2. `@Configuration` 클래스에서는 `RedisTemplate<String, ?>`만 커스터마이즈합니다. | |
| - 연결 팩토리(`RedisConnectionFactory`)는 Spring Boot 오토컨피그에 맡깁니다(프로퍼티: `spring.redis.*`). | |
| - 직렬화 전략만 명시적으로 설정(`StringRedisSerializer`, `GenericJackson2JsonRedisSerializer` 등). | |
| 3. 필요 시 `ObjectMapper` 등 공용 Bean을 주입하거나 별도 설정을 만듭니다. |
🤖 Prompt for AI Agents
In .docs/redis-template-setup.md around lines 12 to 15, the guidance currently
suggests manually registering a RedisConnectionFactory which can override Spring
Boot's spring.redis.* binding; update the text to instruct readers to avoid
defining a RedisConnectionFactory bean and instead rely on Spring Boot
auto-configuration so spring.redis.* properties bind correctly, and advise that
if customization is needed they should define a RedisTemplate bean (or customize
serializers/ObjectMapper) while leaving the connection factory undefined to let
Boot back off.
src/main/java/dooya/see/adapter/integration/cache/config/RedisConfig.java
Outdated
Show resolved
Hide resolved
- Spring Boot의 자동 구성 기능 활용으로 LettuceConnectionFactory 제거 - `spring.data.redis.*` 설정을 기반으로 Redis 연결 자동 구성 지원 - 코드 단순화 및 중복 제거로 유지보수성 향상
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/main/java/dooya/see/adapter/integration/cache/config/RedisConfig.java(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build-check
- GitHub Check: test
🔇 Additional comments (3)
src/main/java/dooya/see/adapter/integration/cache/config/RedisConfig.java (3)
9-10: 설정 클래스 구조가 올바릅니다.패키지 구조와
@Configuration어노테이션이 적절하게 적용되었습니다.
11-22: 이전 리뷰에서 지적된 문제가 해결되었습니다.과거 리뷰에서 커스텀
redisConnectionFactory()빈이spring.redis.*프로퍼티를 무시한다는 크리티컬 이슈가 있었으나, 현재 코드에서는 해당 빈이 제거되고RedisConnectionFactory를 파라미터로 주입받아 Spring Boot의 자동 구성을 활용하고 있습니다. 이는 올바른 접근입니다.
16-19: 원본 리뷰 의견이 부정확합니다.
PostCacheKey구현을 검증한 결과, 모든 메서드(detail(),publicList(),categoryList(),search(),stats())가 String 타입의 키만 반환합니다. 또한RedisTemplate<String, String>으로 명시적으로 선언되어 있어, 컴파일 타임에 String만 저장됨이 보장됩니다. 따라서 복잡한 객체 직렬화가 필요하지 않으며,StringRedisSerializer사용은 현재 구현에 적절합니다.Likely an incorrect or invalid review comment.
| @Bean | ||
| RedisTemplate<String, String> redisTemplate(RedisConnectionFactory connectionFactory) { | ||
| RedisTemplate<String, String> template = new RedisTemplate<>(); | ||
| // Spring Boot auto-configures LettuceConnectionFactory based on spring.data.redis.* properties. |
There was a problem hiding this comment.
주석 위치를 조정하세요.
Line 14의 주석은 LettuceConnectionFactory의 자동 구성에 대해 설명하고 있지만, redisTemplate 메서드 내부에 위치해 있어 문맥상 어색합니다. 클래스 레벨 JavaDoc이나 메서드 상단으로 이동하는 것이 더 명확합니다.
다음과 같이 수정하는 것을 권장합니다:
+/**
+ * Redis configuration class.
+ * Spring Boot auto-configures LettuceConnectionFactory based on spring.data.redis.* properties.
+ */
@Configuration
public class RedisConfig {
@Bean
RedisTemplate<String, String> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, String> template = new RedisTemplate<>();
- // Spring Boot auto-configures LettuceConnectionFactory based on spring.data.redis.* properties.
template.setConnectionFactory(connectionFactory);🤖 Prompt for AI Agents
In src/main/java/dooya/see/adapter/integration/cache/config/RedisConfig.java
around line 14, the inline comment about Spring Boot auto-configuring
LettuceConnectionFactory is placed inside the redisTemplate method and reads
awkwardly in that context; move that comment to either the class-level JavaDoc
(above the class declaration) or immediately above the redisTemplate method
signature as a method-level comment, then remove the original inline comment
from inside the method so the documentation aligns with its intended scope and
improves readability.
- Spring Boot 자동 구성을 통해 LettuceConnectionFactory가 자동으로 설정됨을 기술한 주석 제거 - 코드 가독성 향상 및 불필요한 주석 관리 비용 감소 - Redis 설정 클래스 간결화로 유지보수성 개선
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/main/java/dooya/see/adapter/integration/cache/config/RedisConfig.java (1)
11-21: RedisTemplate 구성이 올바르게 구현되었습니다.
RedisConnectionFactory를 주입받아 사용하는 방식이 적절합니다StringRedisSerializer를 모든 시리얼라이저에 일관되게 적용하여RedisTemplate<String, String>타입과 일치합니다afterPropertiesSet()호출로 템플릿 초기화를 보장합니다선택적 개선 사항: 빈 메서드를
public으로 선언하면 일반적인 Spring 규칙과 더 일치하지만, 현재 구현도 정상 작동합니다.선택적으로 메서드를 public으로 변경할 수 있습니다:
@Bean - RedisTemplate<String, String> redisTemplate(RedisConnectionFactory connectionFactory) { + public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplate<String, String> template = new RedisTemplate<>();
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/main/java/dooya/see/adapter/integration/cache/config/RedisConfig.java(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: test
🔇 Additional comments (1)
src/main/java/dooya/see/adapter/integration/cache/config/RedisConfig.java (1)
9-10: 이전 리뷰 이슈가 모두 해결되었습니다. 깔끔한 구조입니다!커스텀
RedisConnectionFactory빈이 제거되어 Spring Boot의 자동 구성이spring.redis.*프로퍼티를 정상적으로 처리할 수 있게 되었습니다. 이는 권장되는 접근 방식이며 환경별 설정을 올바르게 지원합니다.
📌 Issue
🧐 현재 상황
🎯 목표
🛠 작업 내용
작업 할 내용을 입력해주세요.
RedisTemplate 설정 + 키 스키마 정의
테스트 작성
🚀 기타 사항
Summary by CodeRabbit
새로운 기능
문서
인프라
테스트