Repository: Team-ThinkBoo/ClubAccount-BE
Pull request #24: [TB-19] 링크를 통해 접속한 비회원에 대해 영수증 조회 허용
Author: login: baekjaehyuk
Labels: name: refactor
name: feat
Created: 2025-04-17T14:10:01Z | Merged: 2025-04-18T05:47:07Z

## 📌 작업 개요
* 로그인하지 않은 비회원일 경우, 해당 조직 내에 등록된 영수증을 조회가 가능하도록 로직 수정

---

## ✅ 작업 내용
1. 상세 조회 및 단일 조회에 대한 메서드명 수정
2. PathVariable로 해당 조직의 UUID를 판별하여 영수증을 조회가 가능하도록 로직 수정

---

## 📂 리뷰 요구사항
- 현재 User 엔티티 내 rink가 아닌 link로 수정이 필요할 듯 합니다.
---




Diff:
diff --git a/src/main/java/com/ClubAccount_BE/core/config/SecurityConfig.java b/src/main/java/com/ClubAccount_BE/core/config/SecurityConfig.java
index bdddb17..7c9615f 100644
--- a/src/main/java/com/ClubAccount_BE/core/config/SecurityConfig.java
+++ b/src/main/java/com/ClubAccount_BE/core/config/SecurityConfig.java
@@ -1,6 +1,10 @@
 package com.ClubAccount_BE.core.config;
 
-import com.ClubAccount_BE.auth.security.*;
+import com.ClubAccount_BE.auth.security.JwtAccessDeniedHandler;
+import com.ClubAccount_BE.auth.security.JwtAuthenticationEntryPoint;
+import com.ClubAccount_BE.auth.security.JwtAuthenticationProvider;
+import com.ClubAccount_BE.auth.security.TokenAuthenticationFilter;
+import com.ClubAccount_BE.auth.security.TokenProvider;
 import com.ClubAccount_BE.user.application.port.in.FindUserUseCase;
 import lombok.RequiredArgsConstructor;
 import org.springframework.context.annotation.Bean;
@@ -21,6 +25,7 @@
 @RequiredArgsConstructor
 @EnableWebSecurity
 public class SecurityConfig {
+
     public static final String API_V1_PREFIX = "/api/v1";
 
     private final TokenProvider tokenProvider;
@@ -30,43 +35,46 @@ public class SecurityConfig {
     @Bean
     public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
         http
-            .authorizeHttpRequests(auth -> auth
-                .requestMatchers(
-                    API_V1_PREFIX + "/users/sign-up/**",
-                    API_V1_PREFIX + "/auth/sign-in",
-                    API_V1_PREFIX + "/auth/token",
-                    API_V1_PREFIX + "/users/{student-number}/validate",
-                    API_V1_PREFIX + "/users/password",
-                    API_V1_PREFIX + "/health",
-                    API_V1_PREFIX + "/users/sign-up/check-duplicate-auth-id",
-                    API_V1_PREFIX + "/email/send",
-                    API_V1_PREFIX + "/email/verify",
-                    API_V1_PREFIX + "/auth/reset-password",
-                    "/api-docs",
-                    "/swagger-custom-ui.html",
-                    "/v3/api-docs",
-                    "/v3/api-docs/**",
-                    "/swagger-ui/**",
-                    "/api-docs/**",
-                    "/swagger-ui.html"
-                ).permitAll()
-                .anyRequest().authenticated()
-            )
-            .csrf(AbstractHttpConfigurer::disable)
-            .headers(AbstractHttpConfigurer::disable)
-            .formLogin(AbstractHttpConfigurer::disable)
-            .httpBasic(AbstractHttpConfigurer::disable)
-            .rememberMe(AbstractHttpConfigurer::disable)
-            .logout(AbstractHttpConfigurer::disable)
-            .exceptionHandling(ex -> ex
-                .accessDeniedHandler(jwtAccessDeniedHandler)
-                .authenticationEntryPoint(jwtAuthenticationEntryPoint)
-            )
-            .sessionManagement(sess -> sess
-                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
-            )
-            .cors(Customizer.withDefaults())
-            .addFilterBefore(tokenAuthenticationFilter(tokenProvider), UsernamePasswordAuthenticationFilter.class);
+                .authorizeHttpRequests(auth -> auth
+                        .requestMatchers(
+                                API_V1_PREFIX + "/users/sign-up/**",
+                                API_V1_PREFIX + "/auth/sign-in",
+                                API_V1_PREFIX + "/auth/token",
+                                API_V1_PREFIX + "/users/{student-number}/validate",
+                                API_V1_PREFIX + "/users/password",
+                                API_V1_PREFIX + "/health",
+                                API_V1_PREFIX + "/users/sign-up/check-duplicate-auth-id",
+                                API_V1_PREFIX + "/email/send",
+                                API_V1_PREFIX + "/email/verify",
+                                API_V1_PREFIX + "/auth/reset-password",
+                                API_V1_PREFIX + "{link}/receipts",
+                                API_V1_PREFIX + "{link}/receipts/{receiptId}",
+                                "/api-docs",
+                                "/swagger-custom-ui.html",
+                                "/v3/api-docs",
+                                "/v3/api-docs/**",
+                                "/swagger-ui/**",
+                                "/api-docs/**",
+                                "/swagger-ui.html"
+                        ).permitAll()
+                        .anyRequest().authenticated()
+                )
+                .csrf(AbstractHttpConfigurer::disable)
+                .headers(AbstractHttpConfigurer::disable)
+                .formLogin(AbstractHttpConfigurer::disable)
+                .httpBasic(AbstractHttpConfigurer::disable)
+                .rememberMe(AbstractHttpConfigurer::disable)
+                .logout(AbstractHttpConfigurer::disable)
+                .exceptionHandling(ex -> ex
+                        .accessDeniedHandler(jwtAccessDeniedHandler)
+                        .authenticationEntryPoint(jwtAuthenticationEntryPoint)
+                )
+                .sessionManagement(sess -> sess
+                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
+                )
+                .cors(Customizer.withDefaults())
+                .addFilterBefore(tokenAuthenticationFilter(tokenProvider),
+                        UsernamePasswordAuthenticationFilter.class);
 
         return http.build();
     }
@@ -78,7 +86,8 @@ public PasswordEncoder passwordEncoder() {
     }
 
     @Bean
-    public AuthenticationManager authenticationManager(JwtAuthenticationProvider jwtAuthenticationProvider) {
+    public AuthenticationManager authenticationManager(
+            JwtAuthenticationProvider jwtAuthenticationProvider) {
         return new ProviderManager(jwtAuthenticationProvider);
     }
 
diff --git a/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/FindReceiptController.java b/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/FindReceiptController.java
index ec6a6ba..f1e40a8 100644
--- a/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/FindReceiptController.java
+++ b/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/FindReceiptController.java
@@ -1,12 +1,11 @@
 package com.ClubAccount_BE.receipt.adapter.in.web;
 
-import com.ClubAccount_BE.core.meta.LoginUser;
 import com.ClubAccount_BE.core.response.PagingResponse;
 import com.ClubAccount_BE.receipt.adapter.in.web.api.FindReceiptApi;
 import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptDetailResponse;
 import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptResponse;
 import com.ClubAccount_BE.receipt.application.port.in.FindReceiptUseCase;
-import com.ClubAccount_BE.user.domain.User;
+import java.util.UUID;
 import lombok.RequiredArgsConstructor;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.domain.Sort;
@@ -18,24 +17,24 @@
 
 @RestController
 @RequiredArgsConstructor
-@RequestMapping("/api/v1/receipts")
+@RequestMapping("/api/v1")
 public class FindReceiptController implements FindReceiptApi {
 
     private final FindReceiptUseCase findReceiptUseCase;
 
-    @GetMapping
-    public PagingResponse<ReceiptResponse> getReceipts(
-            @LoginUser User user,
+    @GetMapping("{link}/receipts")
+    public PagingResponse<ReceiptResponse> getReceiptList(
+            @PathVariable(value = "link") UUID link,
             @PageableDefault(page = 1, sort = "createdAt", direction = Sort.Direction.ASC) Pageable pageable
     ) {
-        return findReceiptUseCase.getReceipts(user, pageable);
+        return findReceiptUseCase.getReceiptList(link, pageable);
     }
 
-    @GetMapping("/{receiptId}")
+    @GetMapping("{link}/receipts/{receiptId}")
     public ReceiptDetailResponse getReceipt(
-            @LoginUser User user,
+            @PathVariable(value = "link") UUID link,
             @PathVariable("receiptId") Long receiptId
     ) {
-        return findReceiptUseCase.getReceipt(user, receiptId);
+        return findReceiptUseCase.getReceipt(link, receiptId);
     }
 }
diff --git a/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/api/FindReceiptApi.java b/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/api/FindReceiptApi.java
index 923d137..ffff765 100644
--- a/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/api/FindReceiptApi.java
+++ b/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/api/FindReceiptApi.java
@@ -1,12 +1,11 @@
 package com.ClubAccount_BE.receipt.adapter.in.web.api;
 
-import com.ClubAccount_BE.core.meta.LoginUser;
 import com.ClubAccount_BE.core.response.PagingResponse;
 import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptDetailResponse;
 import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptResponse;
-import com.ClubAccount_BE.user.domain.User;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
+import java.util.UUID;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.domain.Sort;
 import org.springframework.data.web.PageableDefault;
@@ -16,14 +15,14 @@
 public interface FindReceiptApi {
 
     @Operation(summary = "영수증 목록 조회", description = "파싱된 영수증 정보를 조회한다.")
-    PagingResponse<ReceiptResponse> getReceipts(
-            @LoginUser User user,
+    PagingResponse<ReceiptResponse> getReceiptList(
+            @PathVariable(value = "link") UUID link,
             @PageableDefault(page = 1, sort = "createdAt", direction = Sort.Direction.ASC) Pageable pageable
     );
 
     @Operation(summary = "영수증 상세 목록 조회", description = "파싱된 영수증 정보를 조회한다.")
     ReceiptDetailResponse getReceipt(
-            @LoginUser User user,
+            @PathVariable(value = "link") UUID link,
             @PathVariable("receiptId") Long receiptId
     );
 }
diff --git a/src/main/java/com/ClubAccount_BE/receipt/adapter/out/ReceiptRepositoryAdapter.java b/src/main/java/com/ClubAccount_BE/receipt/adapter/out/ReceiptRepositoryAdapter.java
index bb1c1bd..c31c23c 100644
--- a/src/main/java/com/ClubAccount_BE/receipt/adapter/out/ReceiptRepositoryAdapter.java
+++ b/src/main/java/com/ClubAccount_BE/receipt/adapter/out/ReceiptRepositoryAdapter.java
@@ -32,7 +32,7 @@ public Long createReceipt(Receipt receipt, List<ReceiptItem> receiptItems) {
     }
 
     @Override
-    public Page<Receipt> getReceipts(User user, Pageable pageable) {
+    public Page<Receipt> getReceiptList(User user, Pageable pageable) {
         return receiptRepository
                 .findAllByUserId(user.getId(), pageable)
                 .map(ReceiptMapper::toDomain);
diff --git a/src/main/java/com/ClubAccount_BE/receipt/application/port/in/FindReceiptUseCase.java b/src/main/java/com/ClubAccount_BE/receipt/application/port/in/FindReceiptUseCase.java
index b6e502d..4d18531 100644
--- a/src/main/java/com/ClubAccount_BE/receipt/application/port/in/FindReceiptUseCase.java
+++ b/src/main/java/com/ClubAccount_BE/receipt/application/port/in/FindReceiptUseCase.java
@@ -3,12 +3,12 @@
 import com.ClubAccount_BE.core.response.PagingResponse;
 import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptDetailResponse;
 import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptResponse;
-import com.ClubAccount_BE.user.domain.User;
+import java.util.UUID;
 import org.springframework.data.domain.Pageable;
 
 public interface FindReceiptUseCase {
 
-    PagingResponse<ReceiptResponse> getReceipts(User user, Pageable pageable);
+    PagingResponse<ReceiptResponse> getReceiptList(UUID link, Pageable pageable);
 
-    ReceiptDetailResponse getReceipt(User user, Long receiptId);
+    ReceiptDetailResponse getReceipt(UUID link, Long receiptId);
 }
diff --git a/src/main/java/com/ClubAccount_BE/receipt/application/port/out/FindReceiptPort.java b/src/main/java/com/ClubAccount_BE/receipt/application/port/out/FindReceiptPort.java
index 82831a7..3bd622e 100644
--- a/src/main/java/com/ClubAccount_BE/receipt/application/port/out/FindReceiptPort.java
+++ b/src/main/java/com/ClubAccount_BE/receipt/application/port/out/FindReceiptPort.java
@@ -7,7 +7,7 @@
 
 public interface FindReceiptPort {
 
-    Page<Receipt> getReceipts(User user, Pageable pageable);
+    Page<Receipt> getReceiptList(User user, Pageable pageable);
 
     Receipt getReceipt(User user, Long receiptId);
 }
diff --git a/src/main/java/com/ClubAccount_BE/receipt/application/service/FindReceiptService.java b/src/main/java/com/ClubAccount_BE/receipt/application/service/FindReceiptService.java
index 1788b54..da59794 100644
--- a/src/main/java/com/ClubAccount_BE/receipt/application/service/FindReceiptService.java
+++ b/src/main/java/com/ClubAccount_BE/receipt/application/service/FindReceiptService.java
@@ -6,7 +6,9 @@
 import com.ClubAccount_BE.receipt.application.port.in.FindReceiptUseCase;
 import com.ClubAccount_BE.receipt.application.port.out.FindReceiptPort;
 import com.ClubAccount_BE.receipt.domain.Receipt;
+import com.ClubAccount_BE.user.application.port.out.FindUserPort;
 import com.ClubAccount_BE.user.domain.User;
+import java.util.UUID;
 import lombok.RequiredArgsConstructor;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
@@ -19,18 +21,23 @@
 public class FindReceiptService implements FindReceiptUseCase {
 
     private final FindReceiptPort findReceiptPort;
+    private final FindUserPort findUserPort;
 
     @Override
-    public PagingResponse<ReceiptResponse> getReceipts(User user, Pageable pageable) {
+    public PagingResponse<ReceiptResponse> getReceiptList(UUID link, Pageable pageable) {
+
+        User user = findUserPort.getUserByLink(link);
         Page<ReceiptResponse> page = findReceiptPort
-                .getReceipts(user, pageable)
+                .getReceiptList(user, pageable)
                 .map(ReceiptResponse::of);
 
         return PagingResponse.of(page);
     }
 
     @Override
-    public ReceiptDetailResponse getReceipt(User user, Long receiptId) {
+    public ReceiptDetailResponse getReceipt(UUID link, Long receiptId) {
+
+        User user = findUserPort.getUserByLink(link);
         Receipt receipt = findReceiptPort.getReceipt(user, receiptId);
         return ReceiptDetailResponse.of(receipt);
     }
diff --git a/src/main/java/com/ClubAccount_BE/user/adapter/out/persistence/UserPersistenceAdapter.java b/src/main/java/com/ClubAccount_BE/user/adapter/out/persistence/UserPersistenceAdapter.java
index c7d2666..5d824f3 100644
--- a/src/main/java/com/ClubAccount_BE/user/adapter/out/persistence/UserPersistenceAdapter.java
+++ b/src/main/java/com/ClubAccount_BE/user/adapter/out/persistence/UserPersistenceAdapter.java
@@ -9,12 +9,14 @@
 import com.ClubAccount_BE.user.application.service.update.UpdatePasswordPort;
 import com.ClubAccount_BE.user.domain.User;
 import com.ClubAccount_BE.user.mapper.UserMapper;
+import java.util.UUID;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Component;
 
 @Component
 @RequiredArgsConstructor
-public class UserPersistenceAdapter implements FindUserPort, SaveUserPort, CheckUserPort, FindUserByEmailPort, UpdatePasswordPort {
+public class UserPersistenceAdapter implements FindUserPort, SaveUserPort, CheckUserPort,
+        FindUserByEmailPort, UpdatePasswordPort {
 
     private final UserRepository userRepository;
 
@@ -39,6 +41,12 @@ public User getUserById(Long userId) {
                 .orElseThrow(() -> new IllegalArgumentException("해당 아이디의 사용자를 찾을 수 없습니다."));
     }
 
+    @Override
+    public User getUserByLink(UUID link) {
+        return userRepository.findByRink(link)
+                .map(UserMapper::toDomain)
+                .orElseThrow(() -> new IllegalArgumentException("해당 링크의 사용자를 찾을 수 없습니다."));
+    }
 
     @Override
     public boolean checkDuplicateAuthId(String authId) {
diff --git a/src/main/java/com/ClubAccount_BE/user/adapter/out/persistence/repository/UserRepository.java b/src/main/java/com/ClubAccount_BE/user/adapter/out/persistence/repository/UserRepository.java
index 15010e1..d410331 100644
--- a/src/main/java/com/ClubAccount_BE/user/adapter/out/persistence/repository/UserRepository.java
+++ b/src/main/java/com/ClubAccount_BE/user/adapter/out/persistence/repository/UserRepository.java
@@ -1,17 +1,21 @@
 package com.ClubAccount_BE.user.adapter.out.persistence.repository;
 
 import com.ClubAccount_BE.user.adapter.out.persistence.entity.UserEntity;
+import java.util.Optional;
+import java.util.UUID;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
 
-import java.util.Optional;
-
 @Repository
 public interface UserRepository extends JpaRepository<UserEntity, Long> {
 
     Optional<UserEntity> getByAuthId(String authId);
+
     Optional<UserEntity> findById(Long userId);
+
     boolean existsByAuthId(String authId);
+
     Optional<UserEntity> findByAuthId(String email);
 
+    Optional<UserEntity> findByRink(UUID rink);
 }
\ No newline at end of file
diff --git a/src/main/java/com/ClubAccount_BE/user/application/port/out/FindUserPort.java b/src/main/java/com/ClubAccount_BE/user/application/port/out/FindUserPort.java
index ab744a5..722ea25 100644
--- a/src/main/java/com/ClubAccount_BE/user/application/port/out/FindUserPort.java
+++ b/src/main/java/com/ClubAccount_BE/user/application/port/out/FindUserPort.java
@@ -1,9 +1,13 @@
 package com.ClubAccount_BE.user.application.port.out;
 
 import com.ClubAccount_BE.user.domain.User;
+import java.util.UUID;
 
 public interface FindUserPort {
+
     User getUserByAuthId(String email);
 
     User getUserById(Long userId);
+
+    User getUserByLink(UUID link);
 }


Reviews:
user: login: copilot-pull-request-reviewer[bot]
body: ## Pull Request Overview

This PR enables receipt lookup for non-members by allowing access via an organization-specific link. Key changes include:
- Renaming and updating the service and use-case methods to use a UUID 'link' instead of a User instance.
- Modifying the API and controller layers to accept the 'link' as a path variable, updating route mappings accordingly.

### Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

| File | Description |
| ---- | ----------- |
| src/main/java/com/ClubAccount_BE/receipt/application/service/FindReceiptService.java | Updated service methods to fetch a User using UUID link and renamed methods accordingly. |
| src/main/java/com/ClubAccount_BE/receipt/application/port/in/FindReceiptUseCase.java | Modified the interface to accept a UUID instead of a User and renamed method signatures. |
| src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/api/FindReceiptApi.java | Adjusted the API interface to receive the link as a path variable with updated method names. |
| src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/FindReceiptController.java | Revised controller mappings to incorporate the link in the URL path for receipt access. |


<details>
<summary>Comments suppressed due to low confidence (4)</summary>

**src/main/java/com/ClubAccount_BE/receipt/application/service/FindReceiptService.java:27**
* [nitpick] Consider updating the JavaDoc for this method to clearly describe the purpose of the 'link' parameter and its relation to non-member access.
```
public PagingResponse<ReceiptResponse> getReceiptList(UUID link, Pageable pageable) {
```
**src/main/java/com/ClubAccount_BE/receipt/application/port/in/FindReceiptUseCase.java:11**
* [nitpick] Ensure that any interface documentation and comments are updated to reflect that the method now uses a UUID 'link' parameter instead of a User object.
```
PagingResponse<ReceiptResponse> getReceiptList(UUID link, Pageable pageable);
```
**src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/api/FindReceiptApi.java:17**
* [nitpick] Verify that the API documentation (e.g., Swagger annotations) is consistent with the change from a User parameter to a UUID 'link' for non-member receipt access.
```
PagingResponse<ReceiptResponse> getReceiptList(@PathVariable(value = "link") UUID link,
```
**src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/FindReceiptController.java:25**
* [nitpick] Confirm that the new route structure incorporating the 'link' in the path aligns with your overall API routing conventions.
```
@GetMapping("{link}/receipts")
```
</details>


state: COMMENTED
author_association: NONE
submitted_at: 2025-04-17T14:10:28Z
user: login: tiemo0708
body: 고생하셨습니다!
코멘트 확인 부탁드려요!!
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-18T05:33:20Z

Review comments:
diff_hunk: @@ -18,24 +17,24 @@
 
 @RestController
 @RequiredArgsConstructor
-@RequestMapping("/api/v1/receipts")
+@RequestMapping("/api/v1")
 public class FindReceiptController implements FindReceiptApi {
path: src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/FindReceiptController.java
user: login: tiemo0708
body: 회원과 비회원을 나누지않고 link로 조회가 가능한건가요?
혹시 따로 나누지 않았을때 장점이 있을까요?
created_at: 2025-04-18T05:25:58Z
author_association: MEMBER
diff_hunk: @@ -18,24 +17,24 @@
 
 @RestController
 @RequiredArgsConstructor
-@RequestMapping("/api/v1/receipts")
+@RequestMapping("/api/v1")
 public class FindReceiptController implements FindReceiptApi {
 
     private final FindReceiptUseCase findReceiptUseCase;
 
-    @GetMapping
-    public PagingResponse<ReceiptResponse> getReceipts(
-            @LoginUser User user,
+    @GetMapping("{link}/receipts")
path: src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/FindReceiptController.java
user: login: tiemo0708
body: SecurityConfig에서 permitAll처리 해주어야하지 않나요?
created_at: 2025-04-18T05:32:16Z
author_association: MEMBER

PR comments:
user: login: codecov[bot]
created_at: 2025-04-17T14:11:24Z
body: ## [Codecov](https://app.codecov.io/gh/Team-ThinkBoo/ClubAccount-BE/pull/24?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Team-ThinkBoo) Report
Attention: Patch coverage is `0%` with `6 lines` in your changes missing coverage. Please review.
| [Files with missing lines](https://app.codecov.io/gh/Team-ThinkBoo/ClubAccount-BE/pull/24?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Team-ThinkBoo) | Patch % | Lines |
|---|---|---|
| [...eceipt/application/service/FindReceiptService.java](https://app.codecov.io/gh/Team-ThinkBoo/ClubAccount-BE/pull/24?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Team-ThinkBoo#diff-c3JjL21haW4vamF2YS9jb20vQ2x1YkFjY291bnRfQkUvcmVjZWlwdC9hcHBsaWNhdGlvbi9zZXJ2aWNlL0ZpbmRSZWNlaXB0U2VydmljZS5qYXZh) | 0.00% | [3 Missing :warning: ](https://app.codecov.io/gh/Team-ThinkBoo/ClubAccount-BE/pull/24?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Team-ThinkBoo) |
| [...dapter/out/persistence/UserPersistenceAdapter.java](https://app.codecov.io/gh/Team-ThinkBoo/ClubAccount-BE/pull/24?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Team-ThinkBoo#diff-c3JjL21haW4vamF2YS9jb20vQ2x1YkFjY291bnRfQkUvdXNlci9hZGFwdGVyL291dC9wZXJzaXN0ZW5jZS9Vc2VyUGVyc2lzdGVuY2VBZGFwdGVyLmphdmE=) | 0.00% | [3 Missing :warning: ](https://app.codecov.io/gh/Team-ThinkBoo/ClubAccount-BE/pull/24?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Team-ThinkBoo) |

:loudspeaker: Thoughts on this report? [Let us know!](https://github.com/codecov/feedback/issues/255)
author_association: NONE
user: login: sonarqubecloud[bot]
created_at: 2025-04-18T05:46:20Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=Club-Account_ClubAccount-BE&pullRequest=24) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=Club-Account_ClubAccount-BE&pullRequest=24&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=Club-Account_ClubAccount-BE&pullRequest=24&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=Club-Account_ClubAccount-BE&pullRequest=24&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=Club-Account_ClubAccount-BE&pullRequest=24&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=Club-Account_ClubAccount-BE&pullRequest=24&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=Club-Account_ClubAccount-BE&pullRequest=24)


author_association: NONE