Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
cbde362
refactor: update application configuration files for logging and envi…
jbh010204 Aug 7, 2025
fe516dc
refactor: update application configuration files for logging and envi…
jbh010204 Aug 7, 2025
b9e1687
refactor: add default value for Discord webhook URL and prevent notif…
jbh010204 Aug 8, 2025
7c3b84a
feat: add LuaScriptsFunctionalRegistrar to ApplicationContextInitiali…
polyglot-k Aug 8, 2025
546d6ce
feat: rename Lua script files for clarity and consistency
polyglot-k Aug 8, 2025
9d6003d
feat: add AtomicOperatorAutoRegistrar for dynamic registration of Cac…
polyglot-k Aug 8, 2025
6c4dcd2
feat: add LuaScriptsFunctionalRegistrar for dynamic loading of Lua sc…
polyglot-k Aug 8, 2025
8db0333
feat: refactor AtomicExamQuota operators to use dynamic Lua script lo…
polyglot-k Aug 8, 2025
7c0d2b7
feat: add @Lazy annotation to examQuotaCacheAtomicOperatorMap injecti…
polyglot-k Aug 8, 2025
fb7a598
Merge branch 'develop' of https://github.com/mosu-dev/mosu-server int…
polyglot-k Aug 8, 2025
e5076ec
chore: add .gitkeep files to maintain empty directory structure
polyglot-k Aug 8, 2025
211511b
feat: ensure Redis scripts for quota operations are not null
polyglot-k Aug 8, 2025
1daba52
fix: correct index calculation for script path in LuaScriptsFunctiona…
polyglot-k Aug 8, 2025
4233ed8
Merge pull request #260 from mosu-dev/refactor/enhanced-redis
polyglot-k Aug 8, 2025
795a6e9
chore: dev.mosuedu.com:3000 cors 설정 추가
toothlessdev Aug 9, 2025
6ea148a
feat: update self-deploy workflow to include JDK 21 setup and Docker …
polyglot-k Aug 9, 2025
9e44526
MOSU fix: 회원가입 정보 추가
wlgns12370 Aug 9, 2025
b61bb05
MOSU-258 refactor: 경합이 발생할 수 있는 상황을 방지하기 위해 filter 로직 수정
jbh010204 Aug 9, 2025
50cba22
MOSU-258 refactor: RequestCounter 객체 내애서 AtomicInteger사용
jbh010204 Aug 9, 2025
553dd16
MOSU-258 refactor: LEVEL_0 Duration 값 변경
jbh010204 Aug 9, 2025
5bc6c38
MOSU-258 test: IP 차단 로직 동시성 안전성 확보 및 LEVEL_0 페널티 시간 조정
jbh010204 Aug 9, 2025
6341200
MOSU-258 refactor: 리뷰 내용 반영
jbh010204 Aug 9, 2025
921b2ef
MOSU feat: 이용약관 정보 추가
wlgns12370 Aug 9, 2025
5d7fb7b
Merge pull request #263 from mosu-dev/refactor/mosu-258
jbh010204 Aug 9, 2025
46e7c7a
MOSU-264 refactor: Dirty Checking을 위한 Transaction 분리
wlgns12370 Aug 9, 2025
34a04b5
MOSU-264 test: 마케팅 동의 여부 파싱 테스트
wlgns12370 Aug 9, 2025
6bd062b
MOSU-264 test: 테스트 중복 로직 삭제
wlgns12370 Aug 9, 2025
caa0723
MOSU-264 refactor: null 검증 로직 제거
wlgns12370 Aug 9, 2025
df0354e
MOSU-264 test: @Nested 제거
wlgns12370 Aug 9, 2025
572ddb0
MOSU-264 feat: DDL 구현
wlgns12370 Aug 9, 2025
b680c70
Merge pull request #265 from mosu-dev/refactor/mosu-264
wlgns12370 Aug 9, 2025
bc7d613
MOSU-267 feat: cache 적용할 도메인들 enum으로 정의
jbh010204 Aug 9, 2025
40f61d0
MOSU-267 feat: LocalCacheManager 구현
jbh010204 Aug 9, 2025
a0a4473
MOSU fix: DDL 삭제
wlgns12370 Aug 9, 2025
c5be4ad
MOSU-267 fix: 변수명 오타 수정
jbh010204 Aug 10, 2025
a0fd7db
MOSU-267 feat: 공지 도메인 캐싱 적용
jbh010204 Aug 10, 2025
6a43347
MOSU feat: data.sql 추가
wlgns12370 Aug 10, 2025
53b4e11
feat: update s3Key column definition to TEXT in File entity
polyglot-k Aug 10, 2025
1d40637
feat: remove CUSTOMER_KEY_CHECK endpoint from Whitelist
polyglot-k Aug 10, 2025
febbe32
refactor: remove unnecessary @NotBlank annotation from PhoneNumberPat…
jbh010204 Aug 10, 2025
e784335
Merge branch 'develop' into refactor/mosu-267
jbh010204 Aug 10, 2025
50915bc
Merge pull request #269 from mosu-dev/refactor/mosu-267
jbh010204 Aug 10, 2025
24f6e2e
Merge branch 'feat/mosu-249' of https://github.com/mosu-dev/mosu-serv…
polyglot-k Aug 10, 2025
03357a6
feat: reorganize application configuration files and add base profile
polyglot-k Aug 10, 2025
affed22
feat: update deployment scripts to use base environment variables and…
polyglot-k Aug 10, 2025
7f0bf73
feat: implement updateInquiry method for modifying existing inquiries
polyglot-k Aug 10, 2025
3dbbf21
feat: initialize DiscordNotifier with webhook URL and prevent notific…
polyglot-k Aug 10, 2025
da95311
feat: update DiscordNotifier to use blank check for webhook URL confi…
polyglot-k Aug 10, 2025
3f0a973
feat: increase title size limit in InquiryUpdateRequest to 300 charac…
polyglot-k Aug 10, 2025
08a58cd
feat: update logging configuration to specify log file path in applic…
polyglot-k Aug 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .github/workflows/docker-depoly.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,16 @@ jobs:
script: |
cd /home/ubuntu/mosu

echo "${{ secrets.ENV_BLUE }}" > .env.blue
echo "${{ secrets.ENV_GREEN }}" > .env.green
echo "${{ secrets.ENV_BASE }}" > .env
echo "${{ secrets.ENV_BASE }}" > .env.blue
echo "${{ secrets.ENV_BASE }}" > .env.green

echo "${{ secrets.ENV }}" >> .env
echo "${{ secrets.ENV }}" >> .env.blue
echo "${{ secrets.ENV }}" >> .env.green

echo "APP_IMAGE_VERSION=${{ github.sha }}" >> .env
echo "APP_IMAGE_VERSION=${{ github.sha }}" >> .env.blue
echo "APP_IMAGE_VERSION=${{ github.sha }}" >> .env.green

./deploy.sh
54 changes: 51 additions & 3 deletions .github/workflows/self-depoly.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,68 @@ name: Docker CI/CD - Deploy
on:
workflow_dispatch:
branches:
- test
- develop
jobs:
deploy:
runs-on: self-hosted

steps:
- name: Checkout source
uses: actions/checkout@v3

- name: Set up JDK 21
uses: actions/setup-java@v3
with:
java-version: '21'
distribution: 'temurin'

Comment on lines +12 to +20
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Update deprecated action versions (checkout/setup-java/cache)

actionlint flags these actions as too old. Upgrade to v4 for better support and security fixes.

Apply:

-uses: actions/checkout@v3
+uses: actions/checkout@v4
...
-uses: actions/setup-java@v3
+uses: actions/setup-java@v4
...
-uses: actions/cache@v3
+uses: actions/cache@v4

Also applies to: 21-30

🧰 Tools
🪛 actionlint (1.7.7)

13-13: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


16-16: the runner of "actions/setup-java@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🤖 Prompt for AI Agents
In .github/workflows/self-depoly.yaml around lines 12 to 30, the actions
'actions/checkout' and 'actions/setup-java' are using deprecated versions v3.
Update these actions to use version v4 by changing 'actions/checkout@v3' to
'actions/checkout@v4' and 'actions/setup-java@v3' to 'actions/setup-java@v4' to
ensure better support and security fixes.

- name: Cache Gradle files
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
gradle-${{ runner.os }}-

- name: Clone external repo with jar into libs/
run: |
mkdir -p libs
git clone https://x-access-token:${{ secrets.GH_PAT }}@github.com/mosu-dev/mosu-kmc-jar.git temp-jar
cp temp-jar/*.jar libs/

- name: Build with Gradle
run: ./gradlew build -x test

- name: Log in to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Build Docker image
run: docker build -t kangtaehyun1107/mosu-server:${{ github.sha }} .
working-directory:
- name: Push Docker image
Comment on lines +48 to +49
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix invalid empty 'working-directory' key

The empty value breaks workflow parsing (“string should not be empty”). Either set it explicitly or remove it.

Apply:

-        working-directory:
+        # working-directory: .
📝 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.

Suggested change
working-directory:
- name: Push Docker image
# working-directory: .
- name: Push Docker image
🧰 Tools
🪛 actionlint (1.7.7)

48-48: string should not be empty

(syntax-check)

🤖 Prompt for AI Agents
In .github/workflows/self-depoly.yaml at lines 48 to 49, the 'working-directory'
key is empty, causing a workflow parsing error. Remove the 'working-directory'
key entirely or set it to a valid non-empty string to fix the invalid empty key
issue.

run: docker push kangtaehyun1107/mosu-server:${{ github.sha }}

- name: Deploy via SSH
run: |
cd ~/mosu-server

echo "${{ secrets.TEST_ENV_BLUE }}" > .env.blue
echo "${{ secrets.TEST_ENV_GREEN }}" > .env.green
echo "${{ secrets.ENV_BASE }}" > .env
echo "${{ secrets.ENV_BASE }}" > .env.blue
echo "${{ secrets.ENV_BASE }}" > .env.green

echo "${{ secrets.ENV_TEST }}" >> .env
echo "${{ secrets.ENV_TEST }}" >> .env.blue
echo "${{ secrets.ENV_TEST }}" >> .env.green

echo "APP_IMAGE_VERSION=${{ github.sha }}" >> .env
echo "APP_IMAGE_VERSION=${{ github.sha }}" >> .env.blue
echo "APP_IMAGE_VERSION=${{ github.sha }}" >> .env.green

Comment on lines +56 to +67
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Safer multi-line secret writes and file permissions

Use printf and a restrictive umask to prevent permission leaks. Also keeps newline handling deterministic.

Apply:

-          echo "${{ secrets.ENV_BASE }}" > .env
-          echo "${{ secrets.ENV_BASE }}" > .env.blue
-          echo "${{ secrets.ENV_BASE }}" > .env.green
-          
-          echo "${{ secrets.ENV_TEST }}" >> .env
-          echo "${{ secrets.ENV_TEST }}" >> .env.blue
-          echo "${{ secrets.ENV_TEST }}" >> .env.green
-          
-          echo "APP_IMAGE_VERSION=${{ github.sha }}" >> .env
-          echo "APP_IMAGE_VERSION=${{ github.sha }}" >> .env.blue
-          echo "APP_IMAGE_VERSION=${{ github.sha }}" >> .env.green
+          umask 077
+          printf '%s\n' "${{ secrets.ENV_BASE }}" > .env
+          printf '%s\n' "${{ secrets.ENV_BASE }}" > .env.blue
+          printf '%s\n' "${{ secrets.ENV_BASE }}" > .env.green
+
+          printf '%s\n' "${{ secrets.ENV_TEST }}" >> .env
+          printf '%s\n' "${{ secrets.ENV_TEST }}" >> .env.blue
+          printf '%s\n' "${{ secrets.ENV_TEST }}" >> .env.green
+
+          printf '%s\n' "APP_IMAGE_VERSION=${{ github.sha }}" >> .env
+          printf '%s\n' "APP_IMAGE_VERSION=${{ github.sha }}" >> .env.blue
+          printf '%s\n' "APP_IMAGE_VERSION=${{ github.sha }}" >> .env.green
📝 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.

Suggested change
echo "${{ secrets.ENV_BASE }}" > .env
echo "${{ secrets.ENV_BASE }}" > .env.blue
echo "${{ secrets.ENV_BASE }}" > .env.green
echo "${{ secrets.ENV_TEST }}" >> .env
echo "${{ secrets.ENV_TEST }}" >> .env.blue
echo "${{ secrets.ENV_TEST }}" >> .env.green
echo "APP_IMAGE_VERSION=${{ github.sha }}" >> .env
echo "APP_IMAGE_VERSION=${{ github.sha }}" >> .env.blue
echo "APP_IMAGE_VERSION=${{ github.sha }}" >> .env.green
umask 077
printf '%s\n' "${{ secrets.ENV_BASE }}" > .env
printf '%s\n' "${{ secrets.ENV_BASE }}" > .env.blue
printf '%s\n' "${{ secrets.ENV_BASE }}" > .env.green
printf '%s\n' "${{ secrets.ENV_TEST }}" >> .env
printf '%s\n' "${{ secrets.ENV_TEST }}" >> .env.blue
printf '%s\n' "${{ secrets.ENV_TEST }}" >> .env.green
printf '%s\n' "APP_IMAGE_VERSION=${{ github.sha }}" >> .env
printf '%s\n' "APP_IMAGE_VERSION=${{ github.sha }}" >> .env.blue
printf '%s\n' "APP_IMAGE_VERSION=${{ github.sha }}" >> .env.green
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 59-59: trailing spaces

(trailing-spaces)


[error] 63-63: trailing spaces

(trailing-spaces)


[error] 67-67: trailing spaces

(trailing-spaces)

🤖 Prompt for AI Agents
In .github/workflows/self-depoly.yaml around lines 56 to 67, the current use of
echo to write multi-line secrets to .env files can cause permission leaks and
inconsistent newline handling. Replace echo commands with printf for
deterministic newlines and set a restrictive umask before writing to ensure the
created files have secure permissions. This will prevent accidental exposure of
sensitive environment variables.

sudo docker stop $(sudo docker ps -aq) || true
sudo docker rm $(sudo docker ps -aq) || true
echo "Stopping all containers..."
Expand Down
19 changes: 7 additions & 12 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,17 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
testImplementation 'org.projectlombok:lombok'
testImplementation 'org.projectlombok:lombok'
testCompileOnly 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testCompileOnly 'org.projectlombok:lombok'
testImplementation 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'

// 인증사 관련 의존성
implementation 'javax.servlet:jstl:1.2'
implementation "org.apache.tomcat.embed:tomcat-embed-jasper"
Expand Down Expand Up @@ -69,7 +70,6 @@ dependencies {
testImplementation 'org.testcontainers:junit-jupiter:1.19.3'
testImplementation 'org.testcontainers:mysql:1.20.0'


// security
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
Expand Down Expand Up @@ -103,11 +103,6 @@ dependencies {

runtimeOnly 'com.h2database:h2'

testImplementation 'org.springframework.boot:spring-boot-testcontainers:3.3.5'
testImplementation 'org.testcontainers:testcontainers:1.19.3'
testImplementation 'org.testcontainers:junit-jupiter:1.19.3'
testImplementation 'org.testcoscntainers:mysql:1.20.0'

annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"

implementation 'org.apache.commons:commons-pool2:2.12.1'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package life.mosu.mosuserver.application.caffeine;

import com.github.benmanes.caffeine.cache.Caffeine;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import life.mosu.mosuserver.domain.caffeine.CacheGroup;
import life.mosu.mosuserver.domain.caffeine.CacheType;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

@EnableCaching
@Configuration
public class LocalCacheConfig {

@Bean
public LocalCacheManager localCacheManager() {
List<Cache> caches = Arrays.stream(CacheGroup.values())
.filter(g -> g.getCacheType() == CacheType.LOCAL
|| g.getCacheType() == CacheType.COMPOSITE)
.map(g -> new CaffeineCache(
g.getCacheName(),
Caffeine.newBuilder()
.recordStats()
.expireAfterWrite(g.getExpiredAfterWrite())
.build()
)).collect(Collectors.toList());

return new LocalCacheManager(caches);
}

@Bean
@Primary
public CacheManager appCacheManager(LocalCacheManager localCacheManager) {
return localCacheManager;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package life.mosu.mosuserver.application.caffeine;

import jakarta.annotation.Nullable;
import jakarta.annotation.PostConstruct;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;

public class LocalCacheManager implements CacheManager, UpdatableCacheManager {

private final List<Cache> caches;
private Map<String, Cache> cacheMap = new ConcurrentHashMap<>();
private volatile Set<String> cacheNames = Collections.emptySet();

public LocalCacheManager(List<Cache> caches) {
this.caches = (caches != null) ? caches : Collections.emptyList();
}

@PostConstruct
public void init() {
Set<String> cacheNamesSet = new LinkedHashSet<>(caches.size());
Map<String, Cache> cacheMapTemp = new ConcurrentHashMap<>(16);

for (Cache cache : caches) {
String name = cache.getName();
cacheNamesSet.add(name);
cacheMapTemp.put(name, cache);
}
this.cacheMap = cacheMapTemp;
this.cacheNames = cacheNamesSet;
}

@Override
@Nullable
public Cache getCache(String name) {
return cacheMap.get(name);
}

@Override
public Collection<String> getCacheNames() {
return cacheNames;
}

@Override
public void putIfAbsent(Cache cache, String key, Object value) {
Cache localCache = getCache(cache.getName());
if (localCache != null) {
localCache.putIfAbsent(key, value);
}
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package life.mosu.mosuserver.application.caffeine;

import org.springframework.cache.Cache;

public interface UpdatableCacheManager {

void putIfAbsent(Cache cache, String key, Object value);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package life.mosu.mosuserver.application.exam.cache;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import life.mosu.mosuserver.global.exception.CustomRuntimeException;
import life.mosu.mosuserver.global.exception.ErrorCode;
import life.mosu.mosuserver.infra.persistence.redis.operator.VoidCacheAtomicOperator;
Expand All @@ -15,12 +17,17 @@ public class AtomicExamQuotaDecrementOperator implements VoidCacheAtomicOperator
private final RedisTemplate<String, Long> redisTemplate;
private final DefaultRedisScript<Long> decrementScript;


public AtomicExamQuotaDecrementOperator(
RedisTemplate<String, Long> redisTemplate,
@Qualifier("decrementExamQuotaScript") DefaultRedisScript<Long> decrementScript

@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@Qualifier("examLuaScripts")
Map<String, DefaultRedisScript<Long>> examLuaScripts
) {
this.redisTemplate = redisTemplate;
this.decrementScript = decrementScript;
this.decrementScript = Objects.requireNonNull(examLuaScripts.get("decrementQuota"),
"Redis script 'decrementQuota' not found");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
package life.mosu.mosuserver.application.exam.cache;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import life.mosu.mosuserver.global.exception.CustomRuntimeException;
import life.mosu.mosuserver.global.exception.ErrorCode;
import life.mosu.mosuserver.infra.persistence.redis.operator.VoidCacheAtomicOperator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class AtomicExamQuotaIncrementOperator implements VoidCacheAtomicOperator<String, Long> {

private final RedisTemplate<String, Long> redisTemplate;
private final DefaultRedisScript<Long> decrementScript;
private final DefaultRedisScript<Long> incrementScript;

public AtomicExamQuotaIncrementOperator(
RedisTemplate<String, Long> redisTemplate,
@Qualifier("incrementExamQuotaScript") DefaultRedisScript<Long> decrementScript

@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@Qualifier("examLuaScripts")
Map<String, DefaultRedisScript<Long>> examLuaScripts
) {
this.redisTemplate = redisTemplate;
this.decrementScript = decrementScript;
this.incrementScript = Objects.requireNonNull(examLuaScripts.get("incrementQuota"),
"Redis script 'incrementQuota' not found");
}

@Override
Expand All @@ -36,7 +44,7 @@ public String getActionName() {
@Override
public void execute(String key) {
try {
Long result = redisTemplate.execute(decrementScript, List.of(
Long result = redisTemplate.execute(incrementScript, List.of(
ExamQuotaPrefix.CURRENT_APPLICATIONS.with(key),
ExamQuotaPrefix.MAX_CAPACITY.with(key)
));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import life.mosu.mosuserver.infra.persistence.redis.operator.VoidCacheAtomicOperator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -29,7 +30,9 @@ public ExamQuotaCacheManager(
CacheWriter<String, Long> cacheWriter,
CacheReader<String, Long> cacheReader,

@Qualifier("examCacheAtomicOperatorMap")
@Lazy
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@Qualifier("examQuotaCacheAtomicOperatorMap")
Map<String, ? extends CacheAtomicOperator<String, Long>> cacheAtomicOperatorMap,
ExamJpaRepository examJpaRepository
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@
import life.mosu.mosuserver.domain.inquiry.entity.InquiryJpaEntity;
import life.mosu.mosuserver.domain.inquiry.entity.InquiryStatus;
import life.mosu.mosuserver.domain.inquiry.repository.InquiryJpaRepository;
import life.mosu.mosuserver.domain.inquiryAnswer.repository.InquiryAnswerJpaRepository;
import life.mosu.mosuserver.domain.user.entity.UserJpaEntity;
import life.mosu.mosuserver.domain.user.entity.UserRole;
import life.mosu.mosuserver.domain.user.repository.UserJpaRepository;
import life.mosu.mosuserver.global.exception.CustomRuntimeException;
import life.mosu.mosuserver.global.exception.ErrorCode;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryCreateRequest;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryDetailResponse;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryDetailResponse.InquiryAnswerDetailResponse;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryResponse;
import life.mosu.mosuserver.presentation.inquiry.dto.InquiryUpdateRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
Expand All @@ -26,11 +25,9 @@
@RequiredArgsConstructor
public class InquiryService {

private final UserJpaRepository userJpaRepository;
private final InquiryAttachmentService inquiryAttachmentService;
private final InquiryJpaRepository inquiryJpaRepository;
private final InquiryAnswerService inquiryAnswerService;
private final InquiryAnswerJpaRepository inquiryAnswerJpaRepository;

@Transactional
public void createInquiry(UserJpaEntity user, InquiryCreateRequest request) {
Expand Down Expand Up @@ -74,6 +71,17 @@ public void deleteInquiry(UserJpaEntity user, Long postId) {
inquiryJpaRepository.delete(inquiry);
}

@Transactional
public void updateInquiry(UserJpaEntity user, InquiryUpdateRequest request, Long postId) {
InquiryJpaEntity inquiry = getInquiry(postId);
hasPermission(inquiry.getUserId(), user);

inquiry.update(request.title(), request.content(), user.getName());
inquiryJpaRepository.save(inquiry);

inquiryAttachmentService.updateAttachment(request.attachments(), inquiry);
}

private InquiryDetailResponse toInquiryDetailResponse(InquiryJpaEntity inquiry) {
InquiryAnswerDetailResponse answer = inquiryAnswerService.getInquiryAnswerDetail(
inquiry.getId());
Expand Down
Loading