Skip to content

가게 개별 테이블 이미지 등록/삭제 API 구현#83

Merged
sonjunkyu merged 9 commits intodevelopfrom
feature/table-image
Jan 30, 2026
Merged

가게 개별 테이블 이미지 등록/삭제 API 구현#83
sonjunkyu merged 9 commits intodevelopfrom
feature/table-image

Conversation

@sonjunkyu
Copy link
Contributor

@sonjunkyu sonjunkyu commented Jan 28, 2026

💡 작업 개요

1. S3 저장 경로

stores/{storeId}/tables/{tableId}/

2. 테이블 이미지 등록 (POST)

  • POST /api/v1/stores/{storeId}/tables/{tableId}/image
  • 테이블 이미지를 AWS S3에 업로드
  • 기존에 이미지가 존재할 경우 삭제 후 새로운 이미지 등록
  • 응답 DTO 반환 시 S3 Key -> URL로 변환

3. 테이블 이미지 삭제 (DELETE)

  • DELETE /api/v1/stores/{storeId}/tables/{tableId}/image
  • 서비스 로직에서 이미지가 존재하는지 확인 후 삭제
  • Soft delete가 아닌 Hard delete

4. 테이블 상세 조회 시 테이블 이미지 URL 반환 (REFACTOR)

  • Entity에는 S3 Key만 저장되어 있음
  • 따라서 null 아니면 S3 Key를 반환
  • 서비스 로직에서 S3 Key -> URL 반환하도록 개선

✅ 작업 내용

  • 기능 개발
  • 버그 수정
  • 리팩토링
  • 주석/포맷 정리
  • 기타 설정

🧪 테스트 내용

  • 로컬 환경에서 빌드 정상 실행 확인
  • API 테스트는 CD 후 배포 서버에서 Swagger 기반으로 진행 예정

📝 기타 참고 사항

Summary by CodeRabbit

  • New Features
    • Table image uploads: Store owners can now upload images for individual dining tables, allowing customers to view table details before booking
    • Image management: Delete existing table images and upload replacements to keep content current
    • Enhanced table presentation: Images are automatically stored and retrieved with table information

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 28, 2026

📝 Walkthrough

Walkthrough

The PR implements table image upload and delete functionality for individual store tables. Two new endpoints are added to manage table images in S3, with supporting DTOs, converters, and service implementations. The table detail query flow is updated to include converted image URLs.

Changes

Cohort / File(s) Summary
Controller & Documentation
src/main/java/com/eatsfine/eatsfine/domain/storetable/controller/StoreTableController.java, StoreTableControllerDocs.java
Added POST/DELETE endpoints for table image operations; uploadTableImage accepts multipart file and returns upload DTO with status; deleteTableImage removes image and returns deletion DTO.
Response DTOs
src/main/java/com/eatsfine/eatsfine/domain/storetable/dto/res/StoreTableResDto.java
Introduced UploadTableImageDto (tableId, tableImageUrl) and DeleteTableImageDto (tableId) as nested records with @Builder annotation.
Converter
src/main/java/com/eatsfine/eatsfine/domain/storetable/converter/StoreTableConverter.java
Updated toTableDetailDto signature to accept tableImageUrl parameter; added toUploadTableImageDto and toDeleteTableImageDto converter methods.
Entity
src/main/java/com/eatsfine/eatsfine/domain/storetable/entity/StoreTable.java
Added updateTableImage(String imageKey) and deleteTableImage() mutation methods.
Service Interface & Implementation
src/main/java/com/eatsfine/eatsfine/domain/storetable/service/StoreTableCommandService.java, StoreTableCommandServiceImpl.java
Added uploadTableImage and deleteTableImage methods; implementation includes store/table validation, S3 file operations via injected S3Service, and entity updates.
Query Service
src/main/java/com/eatsfine/eatsfine/domain/storetable/service/StoreTableQueryServiceImpl.java
Integrated S3Service dependency to convert table image keys to URLs in getTableDetail flow.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Controller as StoreTableController
    participant Service as StoreTableCommandServiceImpl
    participant Entity as StoreTable
    participant S3 as S3Service
    participant DB as Database

    Client->>Controller: POST /stores/{storeId}/tables/{tableId}/table-image<br/>(multipart file)
    activate Controller
    
    Controller->>Service: uploadTableImage(storeId, tableId, file)
    activate Service
    
    Service->>DB: findStore(storeId)
    activate DB
    DB-->>Service: Store
    deactivate DB
    
    Service->>DB: findTable(tableId)
    activate DB
    DB-->>Service: StoreTable
    deactivate DB
    
    alt Existing Image
        Service->>S3: deleteImage(existingImageKey)
        activate S3
        S3-->>Service: deleted
        deactivate S3
    end
    
    Service->>S3: uploadImage(file, stores/{storeId}/tables/{tableId}/)
    activate S3
    S3-->>Service: imageKey
    deactivate S3
    
    Service->>Entity: updateTableImage(imageKey)
    activate Entity
    Entity->>DB: save(updatedTable)
    activate DB
    DB-->>Entity: saved
    deactivate DB
    deactivate Entity
    
    Service->>Service: toUploadTableImageDto(tableId, imageUrl)
    Service-->>Controller: UploadTableImageDto
    deactivate Service
    
    Controller-->>Client: ApiResponse<UploadTableImageDto> 200
    deactivate Controller
Loading
sequenceDiagram
    participant Client
    participant Controller as StoreTableController
    participant Service as StoreTableCommandServiceImpl
    participant Entity as StoreTable
    participant S3 as S3Service
    participant DB as Database

    Client->>Controller: DELETE /stores/{storeId}/tables/{tableId}/table-image
    activate Controller
    
    Controller->>Service: deleteTableImage(storeId, tableId)
    activate Service
    
    Service->>DB: findStore(storeId)
    activate DB
    DB-->>Service: Store
    deactivate DB
    
    Service->>DB: findTable(tableId)
    activate DB
    DB-->>Service: StoreTable
    deactivate DB
    
    alt Image Exists
        Service->>S3: deleteImage(imageKey)
        activate S3
        S3-->>Service: deleted
        deactivate S3
        
        Service->>Entity: deleteTableImage()
        activate Entity
        Entity->>DB: save(updatedTable)
        activate DB
        DB-->>Entity: saved
        deactivate DB
        deactivate Entity
    end
    
    Service->>Service: toDeleteTableImageDto(tableId)
    Service-->>Controller: DeleteTableImageDto
    deactivate Service
    
    Controller-->>Client: ApiResponse<DeleteTableImageDto> 200
    deactivate Controller
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • CokaNuri
  • SungMinju
  • zerochani
  • twodo0

Poem

🐰 A rabbit hops through S3 skies,
Uploading table images with careful eyes,
Delete with care, update with grace,
Each photo finds its perfect place!
Tables shine in detail now so bright,
Fluffy paws make everything right. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.77% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: implementing table image upload/delete APIs for individual store tables.
Description check ✅ Passed The PR description covers all required template sections including overview, work items, testing approach, and references the related issue.
Linked Issues check ✅ Passed Code changes fully implement the requirements from issue #79: table image upload/delete APIs, S3 storage path configuration, and service layer URL conversion.
Out of Scope Changes check ✅ Passed All code changes are directly related to implementing table image upload/delete functionality and the refactored table detail query with image URLs.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In
`@src/main/java/com/eatsfine/eatsfine/domain/storetable/controller/StoreTableController.java`:
- Around line 85-91: The Delete endpoint mapping in StoreTableController is
using the wrong path segment and missing the `@Override` annotation; update the
`@DeleteMapping` on the deleteTableImage method to use
"/stores/{storeId}/tables/{tableId}/image" (matching the upload endpoint and API
spec) and add the `@Override` annotation above the deleteTableImage method to
indicate it implements the interface, leaving the return logic
(ApiResponse.of(..., storeTableCommandService.deleteTableImage(storeId,
tableId))) and TableImageSuccessStatus reference unchanged.
- Around line 73-83: The controller method uploadTableImage currently maps to
"/stores/{storeId}/tables/{tableId}/table-image" and may be missing an
`@Override`; change the `@PostMapping` path to
"/stores/{storeId}/tables/{tableId}/image" to match the API spec/issue `#79` and
add the `@Override` annotation above uploadTableImage if this method implements
the signature from StoreTableControllerDocs; update any related references to
the mapping constant if used so the endpoint path stays consistent.
🧹 Nitpick comments (2)
src/main/java/com/eatsfine/eatsfine/domain/storetable/service/StoreTableCommandServiceImpl.java (1)

168-196: Consider operation ordering for resilience against partial failures.

The current sequence deletes the old S3 image (line 185), then uploads the new one (line 188), then updates the entity (line 190). Since S3 operations are outside the transaction:

  1. If upload fails after delete, the old image is lost with no replacement.
  2. If the transaction rolls back after S3 operations succeed, an orphan file remains in S3.

A safer approach is to upload the new image first, update the entity, then delete the old image after the transaction commits (or asynchronously). This ensures:

  • On upload failure: old image remains intact.
  • On transaction failure: only an orphan new file, which can be cleaned up.
♻️ Suggested ordering
-        // 기존 이미지가 존재할 경우 삭제
-        if (table.getTableImageUrl() != null && !table.getTableImageUrl().isBlank()) {
-            s3Service.deleteByKey(table.getTableImageUrl());
-        }
-
-        String key = s3Service.upload(tableImage, "stores/" + storeId + "/tables/" + tableId);
+        // 기존 이미지 키 보존 (나중에 삭제)
+        String oldImageKey = table.getTableImageUrl();
+
+        // 새 이미지 먼저 업로드
+        String key = s3Service.upload(tableImage, "stores/" + storeId + "/tables/" + tableId);

         table.updateTableImage(key);

         // URL 변환 및 응답
         String tableImageUrl = s3Service.toUrl(key);

+        // 기존 이미지가 존재할 경우 삭제 (새 이미지 업로드 성공 후)
+        if (oldImageKey != null && !oldImageKey.isBlank()) {
+            s3Service.deleteByKey(oldImageKey);
+        }
+
         return StoreTableConverter.toUploadTableImageDto(tableId, tableImageUrl);
src/main/java/com/eatsfine/eatsfine/domain/storetable/controller/StoreTableController.java (1)

80-80: Consider adding validation for the uploaded file.

The MultipartFile parameter has no validation. Consider adding checks for empty files or file type validation to prevent invalid uploads from reaching the service layer.

Optional: Add validation annotation or check

You could use a custom validator or add a simple check in the service layer. For controller-level validation:

`@RequestPart`("tableImage") `@NotNull` MultipartFile tableImage

Or ensure the service layer validates:

  • File is not empty (!tableImage.isEmpty())
  • Content type is an image (tableImage.getContentType().startsWith("image/"))
  • File size is within acceptable limits

Comment on lines +73 to +83
@PostMapping(
value = "/stores/{storeId}/tables/{tableId}/table-image",
consumes = MediaType.MULTIPART_FORM_DATA_VALUE
)
public ApiResponse<StoreTableResDto.UploadTableImageDto> uploadTableImage(
@PathVariable Long storeId,
@PathVariable Long tableId,
@RequestPart("tableImage") MultipartFile tableImage
) {
return ApiResponse.of(TableImageSuccessStatus._STORE_TABLE_IMAGE_UPLOAD_SUCCESS, storeTableCommandService.uploadTableImage(storeId, tableId, tableImage));
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

URL path inconsistency with requirements.

The PR description and issue #79 specify the endpoint path as /api/v1/stores/{storeId}/tables/{tableId}/image, but the implementation uses /table-image. Consider aligning with the documented API specification.

Additionally, the @Override annotation appears to be missing if this method is declared in StoreTableControllerDocs.

Suggested path alignment
     `@PostMapping`(
-            value = "/stores/{storeId}/tables/{tableId}/table-image",
+            value = "/stores/{storeId}/tables/{tableId}/image",
             consumes = MediaType.MULTIPART_FORM_DATA_VALUE
     )
+    `@Override`
     public ApiResponse<StoreTableResDto.UploadTableImageDto> uploadTableImage(
🤖 Prompt for AI Agents
In
`@src/main/java/com/eatsfine/eatsfine/domain/storetable/controller/StoreTableController.java`
around lines 73 - 83, The controller method uploadTableImage currently maps to
"/stores/{storeId}/tables/{tableId}/table-image" and may be missing an
`@Override`; change the `@PostMapping` path to
"/stores/{storeId}/tables/{tableId}/image" to match the API spec/issue `#79` and
add the `@Override` annotation above uploadTableImage if this method implements
the signature from StoreTableControllerDocs; update any related references to
the mapping constant if used so the endpoint path stays consistent.

Comment on lines +85 to +91
@DeleteMapping("/stores/{storeId}/tables/{tableId}/table-image")
public ApiResponse<StoreTableResDto.DeleteTableImageDto> deleteTableImage(
@PathVariable Long storeId,
@PathVariable Long tableId
) {
return ApiResponse.of(TableImageSuccessStatus._STORE_TABLE_IMAGE_DELETE_SUCCESS, storeTableCommandService.deleteTableImage(storeId, tableId));
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Same path inconsistency and missing annotation.

Same observations as the upload endpoint - the path uses /table-image instead of /image per the API specification, and @Override annotation should be added for interface implementation consistency.

Suggested fix
-    `@DeleteMapping`("/stores/{storeId}/tables/{tableId}/table-image")
+    `@Override`
+    `@DeleteMapping`("/stores/{storeId}/tables/{tableId}/image")
     public ApiResponse<StoreTableResDto.DeleteTableImageDto> deleteTableImage(
🤖 Prompt for AI Agents
In
`@src/main/java/com/eatsfine/eatsfine/domain/storetable/controller/StoreTableController.java`
around lines 85 - 91, The Delete endpoint mapping in StoreTableController is
using the wrong path segment and missing the `@Override` annotation; update the
`@DeleteMapping` on the deleteTableImage method to use
"/stores/{storeId}/tables/{tableId}/image" (matching the upload endpoint and API
spec) and add the `@Override` annotation above the deleteTableImage method to
indicate it implements the interface, leaving the return logic
(ApiResponse.of(..., storeTableCommandService.deleteTableImage(storeId,
tableId))) and TableImageSuccessStatus reference unchanged.

@sonjunkyu sonjunkyu merged commit 3e99e07 into develop Jan 30, 2026
2 checks passed
CokaNuri added a commit that referenced this pull request Jan 31, 2026
* Initial commit

* [CHORE]: CI 스크립트 작성

* [CHORE]: CI 배포 프로필 구성

* [FEAT]: HealthCheck API 구현 및 테스트 추가

* [FEAT]: Docker 빌드 환경 구성

* [FEAT]: CD 배포 파이프라인 구성

* [FIX]: 도커 이미지 풀링 및 컨테이너 실행 부분 수정

* [FIX]: 헬스체크 실패 방지를 위한 앱 기동 대기 추가

* [FIX]: invalid duration 문자열 추가

* [FEAT]: 의존성 추가

* [FIX]: 대문자를 소문자로 변경

* [FIX]: 경로 대소문자 에러 수정

* [FIX]: CI 파이프라인 수정

* [FIX]: CI 파이프라인 원래대로 다시 수정

* [FIX]: 스크립트 수정

* [FIX]: 도커파일 수정

* [FIX]: 도커파일 수정

* [chore] 빌드 및 패키지 설정 변경

* [chore] 빌드 및 패키지 설정 변경

* [chore] 빌드 및 패키지 설정 변경

* [chore] 빌드 및 패키지 설정 변경

* [FEAT]: 로컬 개발 환경 구성을 위한 Docker Compose 및 설정 추가

* [FEAT]: BaseEntity 추가

* [FEAT]: 예약 도메인 엔티티(Booking) 기본 설정

* [FIX]: Entity에 식별자 추가

* [FIX]: 불필요한 import문 제거

* [FEAT]: BusinessHours 요일 enum 정의

* [FEAT]: BusinessHours 엔티티 초기 세팅

* [FEAT]: Region 엔티티 설계

* [FEAT]: TableImage 엔티티 초기 세팅

* [REFACTOR]: BusinessHours isClosed 필드를 isHoliday로 변경

* [REFACTOR]: BusinessHours Store 연관관계 적용 및 BaseEntity 상속

* [FEAT]: 가게 승인 상태 enum 추가

* [FEAT]: 가게 카테고리 enum 추가

* [FEAT]: Store 엔티티 설계

* [REFACTOR]: TableImage Store 연관관계 적용 및 BaseEntity 상속

* [FEAT]: StoreRepository 세팅

* [FEAT]: TableImageRepository 세팅

* [FEAT]: BusinessHoursRepository 세팅

* [FEAT]: RegionRepository 세팅

* [CHORE]: yml 파일 수정

* [REFACTOR]: Store와 BusinessHours 양방향 연관관계 및 편의 메서드 추가

* [FIX]: StoreTable 연관관계 주석처리

* [REFACTOR]: Store와 TableImage 양방향 연관관계 및 편의 메서드 추가

* [REFACTOR]: Store-TableImage 양방향 연관관계 삭제 편의 메서드 추가 및 생명주기 관리 설정

* [REFACTOR]: ApiResponse 실패 응답을 BaseErrorCode 기반으로 통합

* [FEAT]: HTTPS 적용 및 NGINX Blue-Green 무중단 배포 전환 로직 수정

* [FEAT]: HTTPS 적용 및 NGINX Blue-Green 무중단 배포 전환 로직 수정

* [FEAT] 예약 가능 시간대 및 테이블 조회 DTO 개발

* [FEAT] 예약 가능 시간대,테이블 조회 컨트롤러 개발 및 스웨거 설정

* [FEAT] BookingTable 엔티티 개발

* [FIX] Booking 엔티티 수정 (BookingTable 연관관계 고려)

* [FEAT] BookingRepository- findReservedTableIds 메서드 구현

* [FIX] Store 엔티티 businessHours,tableImages 필드에 @Builder.Default 애노테이션 추가

* [FEAT] StoreTable 엔티티 기본 설정

* [FEAT] 예약 가능 시간 조회 시 '나눠 앉기' 동의 여부 로직 추가

* [FEAT] 테이블 유형 enum 추가

* [FEAT] TableLayout 엔티티 기본 설정 및 Store, StoreTable 연관관계 수정

* [FEAT] BusinessHours의 DayofWeek을 커스텀 enum이 아닌java.time 으로 변경

* [FIX] BusinessHours의 DayofWeek @Enumerated추가

* [FIX] rows 필드 db에서 오류 -> lows로 수정

* [FEAT] GET /api/v1/stores/{storeId}/bookings/available-times 구현

* [FEAT] GeneralException 구현

* [FIX] 로컬 개발 환경에서 https->http 사용

* [FEAT] User 엔티티 기본 설정

* [FEAT]: 식당 상세 조회 DTO 및 BusinessHours 변환 로직 추가

* [FEAT]: StoreSuccessStatus, StoreErrorStatus 추가

* [FEAT]: GeneralException(프로젝트 exception) 세팅

* [FEAT]: StoreException 세팅

* [FEAT]: 식당 상세 조회 API (Controller/Service) 구현

* [FEAT]: 전역 예외 핸들러(GeneralExceptionAdvice) 구현

* [REFACTOR]: BusinessHours 응답 DTO 및 컨버터 휴무 처리 단순화

* [FEAT] 예약 시간대 설정 후 테이블 조회 DTO 개발

* [FEAT] StoreTable에 Table의 위치 필드 추가

* [FEAT] 시간대 설정 후 예약 가능한 테이블 조회 서비스 구현

* [FEAT] 테이블 분리 허용 여부에 따라 테이블 조회 로직 수정

* [FEAT] GET /api/v1/stores/{storeId}/bookings/available-tables 구현

* [CHORE] Swagger 버전 변경 2.3.0 -> 2.8.1

* [FEAT] BookingException 및 ErrorStatus 추가

* [FEAT] 에러 핸들러 구현

* [FEAT] BookingController에 BookingException 포함

* 예전 테스트 코드 제거

* [REFACTOR] : BookingErrorStatus를 공통 ErrorStatus에서 Booking 도메인으로 분리

* [REFACTOR]: 전역 예외 핸들러 제거

* [REFACTOR]: BusinessHoursResDto.summary 응답 시간 포맷(HH:mm) 적용

* [REFACTOR]: BusinessHours 응답 DTO isClosed로 필드명 변경

* [FIX]: NGINX Blue-Green 자동 전환 배포 로직 수정

* [FIX]: NGINX Blue-Green 자동 전환 배포 로직 수정 (다시 복구)

* Update database password in application-local.yml

* [FEAT] : 예약 생성 DTO 개발

* [FIX]: NGINX Blue-Green 존재 여부 확인 후 stop 하도록 로직 수정

* [REFACTOR] : 예약 조회 DTO, 컨트롤러 구조 변경

* [FEAT] : BookingErrorStatus 추가

* [FEAT] : CreateBookingDTO에 isSplitAccepted 필드 추가

* [FEAT] : createdAt JPA 자동 설정 가능하게 애노테이션 추가

* [FEAT] : 비관적 락 적용해 테이블 조회하는 메서드 개발

* [FIX] : Post 방식 API ModelAttribute->RequestBody 변경

* [FIX] : boolingTables 필드에 @Builder.Default 애노테이션 추가

* [FEAT] : 예약 생성 비즈니스 로직 개발

* [FIX]: 배포 대상 판단 로직을 nginx upstream 기준으로 수정

* [FIX]: deploy.yml 로직 약간수정

* [FIX]: 기존으로 복구 및 로그 추가

* [FIX]: 기존으로 복구

* [FIX]: 배포 스크립트 Nginx 리로드 경로

* [FIX]: HTTPS 환경에서 깨지던 blue-green 배포 판단 로직 수정

* [FIX]: 로직 순서 수정

* [FIX]: 로직 순서 수정

* [FIX]: 코드 약간 수정

* [FIX]: 코드 약간 수정

* [FIX]: 코드 약간 수정

* [FIX]: 코드 약간 수정

* [FIX]: 코드 약간 수정

* [BUILD]: QueryDSL 설정 추가 (.gitignore, build.gradle)

* [CHORE] : DB_PASSWORD 환경변수로 관리

* [FEAT] : UserRepository 임시 사용

* [FEAT] : BookingErrorStatus 추가

* [FEAT] : 결제 요청 관련 DTO 개발

* [FEAT] : StoreErrorStatus 추가

* [REFACTOR] : Swagger 테스트용 @ParameterObject 애노테이션 추가

* [REFACTOR] : 영업시간 정보 없을 시 예외 처리 로직 추가

* [FEAT] : Booking 엔티티에 depositAmount 필드 추가 및 confirm 메서드 추가

* [FIX] : 예약 상태가 PENDING 혹은 CONFIRMED인 테이블을 조회하도록 수정

* [FEAT] : 결제 완료 처리 API 개발

* [FIX] : JpaAuditing 설정 변경

* [FEAT] Swagger 운영 도메인 등록

* [FEAT]: 결제 요청 API 구현 및 Booking 연동

* [FEAT]: 가게 등록 및 Region 예외 추가

* [REFACTOR]: Store 엔티티 초기 구조 보정

* [FEAT]: StoreConverter 추가

* [FEAT]: Store/Region 성공 상태 코드 추가

* [FEAT]: 가게 등록 및 영업시간 요청 처리

* [FEAT]: 영업시간 검증 및 예외처리

* [REFACTOR]: 영업시간 및 이미지 필드 수정

* [FEAT]: 가게 검색 기본 구조 추가

* [FEAT]: QueryDSL 기반 가게 검색 구현

* [FEAT]: 실시간 영업 여부 체크 로직 구현

* [FEAT]: 가게 검색에 키워드 검색, 지역 필터 기능 추가

* [FEAT]: 가게별 예약금 로직 추가

* [FEAT]: 가게 테이블(StoreTable) 도메인 엔티티 설계 (#51)

- StoreTable: Soft Delete 적용, 좌석 인원(min/max) 필드 세분화
- TableLayout: Soft Delete 적용, 배치도 활성/비활성 로직, Cascade 옵션 적용
- TableBlock: 예약 차단 시간 관리를 위한 엔티티 설계
- SlotStatus: 예약 시간대 상태 관리를 위한 Enum 및 DTO 구조 설계
- Common: DB 스키마 정합성을 위한 @column 제약조건 명시

* [FIX]: 간편결제만 놔두기

* [FEAT]: 토스페이먼츠 결제위젯 연동 및 승인 프로세스 구현

* [FEAT]: 독립적인 테스트 환경 구성을 위한 H2 DB 및 설정 추가해서 빌드 실패 해결

* [FIX]: username 삭제

* Feature/payment (#54)

* [FIX]: 간편결제만 놔두기

* [FEAT]: 토스페이먼츠 결제위젯 연동 및 승인 프로세스 구현

* [FEAT]: 독립적인 테스트 환경 구성을 위한 H2 DB 및 설정 추가해서 빌드 실패 해결

* [FIX]: username 삭제

* [FEAT]: 식당 기본 정보, 영업시간 수정, 브레이크타임 설정 API 개발  (#55)

* [FEAT]: 가게 기본 정보 수정 DTO 추가

* [FEAT]: StoreSuccessStatus에 가게 기본 정보 수정 성공 응답 추가

* [FEAT]: Store 엔티티에 가게 기본 정보 수정 메서드 추가

* [FEAT]: 가게 기본 정보 수정 로직 개발

* [FEAT]: StoreController에 가게 기본 정보 수정 API 추가

* [FEAT]: 영업시간 검증 메서드(생성용/수정용) 분리

* [FEAT]: 영업시간 수정 DTO 추가

* [FEAT]: 응답 컨버터 및 상태코드 추가

* [FEAT]: 영업 시간 수정 로직 개발

* [REFACTOR]: 영업시간 변경 응답 7일 모두 내려주도록 수정 및 필드명 변경

* [FEAT]: 브레이크타임 설정 DTO 및 응답코드 추가

* [FEAT]: 요청된 브레이크타임 유효성 검증 로직 개발

* [FEAT]: 브레이크타임 설정 로직 구현

* [FEAT]: 상세조회 응답에 브레이크타임 추가

* [FEAT]: 결제 승인 결과(성공/실패) 처리

* [REFACTOR]: Payment 예외 처리 리팩토링

* [FEAT]: 결제 취소(환불) API 구현

* [FEAT]: 결제 내역 조회 및 상세 조회 API 구현

* [FEAT]: 테이블 배치도 생성, 조회 API 구현 (#56)

* [REFACTOR]: TableLayout SQLDelete 쿼리문 수정 및 Builder.Default 추가

* [FEAT]: TableLayoutException 세팅

* [FEAT]: TableLayout 성공/실패 응답코드 추가

* [FEAT]: Controller에 배치도 생성 API 추가

* [FEAT]: 배치도 DTO, Converter 추가

* [FEAT]: 테이블 배치도 생성 로직 개발

* [REFACTOR]: StoreTable SQLDelete 쿼리문 수정

* [REFACTOR]: TableLayout - StoreTable 연관관계 Cascade.REMOVE 추가

* [FEAT]: 테이블 배치도 조회 API 추가

* [FEAT]: 테이블 배치도 조회 로직 개발

* [REFACTOR]: 테이블 배치도 조회 응답 DTO, Converter에 reviewCount 필드 추가

* [FEAT]: 가게 이미지, 테이블 이미지(S3) 업로드/조회/삭제 기능 구현 (#61)

* [REFACTOR]: url -> key로 변수명 변경 및 imageOrder 필드 추가

* [BUILD]: AWS S3 관련 의존성 추가

* [FEAT]: S3Config, S3Service 추가

* [FEAT]: 이미지 업로드 관련 예외 및 에러 상태코드 추가

* [FEAT]: 가게 메인 이미지 등록 응답 DTO 및 성공 상태코드 추가

* [FEAT]: 가게 메인 이미지 등록 로직 구현

* [FEAT]: 가게 매인 이미지 조회 응답 DTO 및 성공 상태코드 추가

* [FEAT]: 가게 메인 이미지 조회 로직 구현

* [FEAT]: 테이블 이미지 등록 응답 DTO 및 성공 상태코드 추가

* [FEAT]: 가게 테이블 이미지(TableImage) 등록 로직 구현

* [FEAT]: 가게 테이블 이미지(TableImage) 조회 로직 구현

* [REFACTOR]: 테이블 이미지 등록 및 조회 성공 코드 수정

* [FEAT]: 테이블 이미지 삭제 응답 DTO 및 성공 상태코드 추가

* [FEAT]: 가게 테이블 이미지(TableImage) 삭제 로직 구현

* [CHORE]: application.yml에 AWS S3 설정 추가

* [FIX]: StoreSuccessStatus 충돌 해결

* [FIX]: 에러 상태코드 중복 수정

* [CHORE]: application-test.yml에 aws s3 설정 추가

* [FIX]: S3 설정 위치 수정

* [REFACTOR]: AWS S3 설정값 환경변수 처리

* [FEAT]: 가게 테이블 생성 API 구현 (#62)

* [FEAT]: StoreTableException 세팅

* [FEAT]: 테이블 생성 성공/실패 응답코드 추가

* [FEAT]: StoreTableController 가게 테이블 생성 API 및 명세 추가

* [FEAT]: 테이블 생성 DTO, Converter 추가

* [FEAT]: 테이블 생성 검증 로직 추가

* [FEAT]: 테이블 생성 검증 서비스 로직 추가

* [FIX]: 무중단 배포 구조 스크립트에서 단일 컨테이너 배포 구조 스크립트로 변경

* [FIX]: EC2 SSH 배포 방식 수정 및 GitHub Actions 안정화

* [FIX]: GitHub Actions SSH 포트 임시 오픈/회수 로직 정리

* [FIX]: 배포 워크플로우 main으로 변경

* [CHORE]: 불필요 도커 이미지 및 컨테이너 정리

* [FEAT]: 테이블 예약 시간대 목록 조회, 관리 API 구현 (#69)

* [REFACTOR]: 테이블 슬롯 조회 생성/실패 응답 코드 추가 및 에러코드 통일

* [FEAT]: StoreTableController에 가게 슬롯 조회 API 및 명세 추가

* [FEAT]: TableBlockRepository 생성

* [FEAT]: BookingRepository에 JPQL 메소드 추가

* [FEAT]: 테이블 슬롯 조회 응답 DTO, Converter 추가

* [FEAT]: 테이블 슬롯 계산, 검증 로직 추가

* [FEAT]: 테이블 슬롯 조회 서비스 로직 추가

* [FEAT]: 테이블 슬롯 상태 변경 성공/실패 에러 핸들러 추가

* [FEAT]: TableBlockController에 테이블 슬롯 상태 변경 API 및 명세 추가

* [FEAT]: TableBlockRepository 특정 테이블 차단 내역 조회 메소드 추가

* [FEAT]: BookingRepository 테이블 예약 여부 조회 메소드 추가

* [FEAT]: 테이블 상태 변경 요청/응답 DTO, Converter 추가

* [FEAT]: 테이블 상태 변경시 검증 로직 추가

* [FEAT]: 테이블 상태 변경 서비스 로직 추가

* [FEAT]: 가게 등록 시 사업자번호 검증 추가 및 Region 엔티티 구조 변경 (#75)

* [REFACTOR]: 주소(Region) 저장 체계 변경

* [FEAT]: 사업자번호 검증 API 관련 의존성 및 설정파일 추가

* [FEAT]: 사업자번호 검증 로직 추가

* [FEAT]: 가게 등록 요청 시 사업자번호 검증부 추가

* [REFACTOR]: WebClient -> RestClient로 변경

* [FEAT]: Real, Mock으로 사업자번호 검증 분리

* [CHORE]: 사업자번호 검증 성공 로그 추가

* [FEAT]: application.yml에 사업자번호 검증 api key 설정부 추가

* [REFACTOR]: 사업자번호 검증 코드 패키지명 변경

* [FIX]: test의 application.yml에 더미 키값 추가

* [CHORE]: 멈춰있는 컨테이너 전부 삭제 명령어 제거

* [FEAT]: DTO 분리 및 필드명 변경

* [REFACTOR]: 결제 승인 로직 개선 및 DTO 적용

* [REFACTOR]: / 붙여줌

* [FEAT]: 메뉴 엔티티 설계 (#82)

* [FEAT]: 가게 테이블 상세 조회/수정/삭제 API 구현 (#77)

* [FEAT]: 테이블 상세 정보 조회 성공 응답 코드 추가

* [FEAT]: 테이블 상세 정보 조회 api 및 명세 추가

* [FEAT]: 테이블 상세 정보 조회 응답 DTO, Converter 추가

* [FEAT]: 테이블 상세 정보 조회 서비스 로직 추가

* [FEAT]: 테이블 정보 수정 성공/실패 응답 코드 추가

* [FEAT]: 테이블 정보 수정 api 및 명세 추가

* [FEAT]: StoreTable 엔티티 편의 메소드 추가

* [FEAT]: 테이블 정보 수정 요청/응답 DTO, Converter 추가

* [FEAT]: 테이블 정보 수정 서비스 로직 구현
- 테이블 번호 수정
- 테이블 좌석 수 변경
- 테이블 유형 변경

* [FEAT]: 테이블 삭제 성공/실패 응답 코드 추가

* [FEAT]: 테이블 삭제 api 및 명세 추가

* [FEAT]: 테이블 삭제 응답 DTO, Converter 추가

* [FEAT]: 테이블 삭제 서비스 로직 구현
- 삭제 시 현재 시간을 기준으로 예약 존재 여부 확인
- 삭제 시 soft delete

* 가게 개별 테이블 이미지 등록/삭제 API 구현 (#83)

* [FEAT]: 테이블 이미지 업로드 API 및 명세 추가

* [FEAT]: StoreTable 이미지 업로드 메소드 추가

* [FEAT]: 테이블 이미지 업로드 응답 DTO, Converter 추가

* [FEAT]: 테이블 이미지 업로드 서비스 로직 추가

* [REFACTOR]: 테이블 상세 조회 시 테이블 이미지 URL을 포함하도록 수정

* [FEAT]: 테이블 이미지 삭제 API 및 명세 추가

* [FEAT]: StoreTable 테이블 이미지 삭제 메소드 추가

* [FEAT]: 테이블 이미지 삭제 응답 DTO, Converter 추가

* [FEAT]: 테이블 이미지 삭제 서비스 로직 추가

* [FEAT] : 예약 취소 API 개발 / 마이페이지 예약 조회 API 개발  (#85)

* [FEAT] : 예약 취소 DTO 개발

* [FEAT] : 예약 취소 DTO 개발

* [FEAT] : 예약 취소 성공,실패 상태 추가

* [FIX] : 예약 상태 이름 변경

* [FEAT] : Booking 엔티티에 cancel 비지니스 메서드 추가

* [FEAT] : 예약 취소 API 구현

* [FEAT] : Booking 엔티티 취소 이유 필드와 취소 메서드 구현

* [FEAT] : BookingConverter 구현

* [FEAT] : 예약생성 응답 DTO에 paymentID, orderID 추가

* [CHORE] : 결제 요청 API 스웨거 설명 수정

* [REFACTOR] : 결제 승인 API에서 예약 상태도 변경하도록 코드 구조 변경

* [CHORE] : 결제 완료 처리 api 스웨거 설정 변경

* [REFACTOR] : 예약 생성 api에서 내부적으로 결제 요청 로직까지 진행하도록 코드 변경

* [FEAT] : 예약 엔티티에서 결제 완료된 결제키를 찾는 편의 메서드 개발

* [FEAT] : 예약 취소시 환불까지 연동되는 비즈니스로직 개발

* [FEAT] : 예약 조회 응답 DTO 개발

* [FEAT] : 예약 조회 Repository 개발

* [FEAT] : 예약 조회 Service 개발

* [FEAT] : 예약 조회 Controller 개발

* [CHORE] : application-local.yml 파일 설정 추가

* [FEAT] : BookingMenu 엔티티 개발

* [FEAT] : 예약 생성 요청 DTO 변경

* [FEAT] : 예약 생성 서비스 로직 변경(메뉴 고려)

* [FIX] : 예약금, 결제금액 타입 Integer->Decimal로 변경

* [FIX] : 예약 조회 기본 페이지 1로 변경

* [FIX] : 불필요한 예약 완료 처리 api 삭제

* [REFACTOR] : 존재하지 않는 테이블을 포함해 에약을 생성하는 예외 처리

* [CHORE] : PAYMENT 컨트롤러 SWAGGER 설정 복원

* [FEAT] : 예약 취소 로직 예외 처리 추가

* [FIX] : 결제 금액 타입 Integer -> BigDecimal로 변경

* [FEAT]: 메뉴 관리 CRUD 구현 및 S3 수명주기 추가 (#87)

* [FEAT]: 메뉴 도메인 DTO 추가

* [FEAT]: 메뉴 API 상태코드 추가

* [FEAT]: 메뉴, 메뉴 이미지 등록, 삭제 로직 추가

* [FEAT]: 메뉴 수정 DTO 추가

* [FEAT]: 메뉴 수정 성공 응답코드 추가

* [FEAT]: 메뉴 수정 로직 추가

* [REFACTOR]: S3 예외처리 세분화

* [FEAT]: 메뉴 조회 DTO 및 성공 응답코드 추가

* [FEAT]: 메뉴 조회 로직 추가

* [FEAT]: 메뉴 조회 시 N+1 방지를 위해 fetch join 쿼리 추가

* [FEAT]: 품절여부 변경 DTO 및 성공 응답코드 추가

* [FEAT]: 메뉴 품절여부 변경 로직 추가

* [FEAT]: 메뉴 삭제 시 soft delete 설정

* [FEAT]: @Valid, @RequestParam, @PathVaraible 유효성 검사 실패 시 에러 메시지 보이도록 메서드 추가

* [FEAT]: 이미지 선 업로드에 따른 S3 수명 주기 연동 로직 구현

* [REFACTOR]: 이미지 Url 리턴하도록 수정

* [FEAT]: 품절 여부 수정 요청이 기존과 동일하다면 바로 리턴하도록 조건 추가

* [REFACTOR]: 이미지 삭제 API를 이미 등록된 이미지 삭제하는 것으로 역할 수정

* [REFACTOR]: soft delete된 Menu는 안 가져오도록 쿼리 수정

* [REFACTOR]: @where -> @SQLRestriction 으로 수정

* [FIX]: isSuccess(false)로 수정

* [REFACTOR]: 예약금 정책 변경에 따라 minPrice 필드 삭제 및 로직 삭제

* [REFACTOR]: 남아있던 minPrice 사용하는 로직들 수정

* [FEAT]: 사용하지 않는 removeMenu 메서드 삭제

* [REFACTOR]: 메뉴가 없는 가게도 조회될 수 있도록 쿼리 조건 수정

* [REFACTOR]: 트랜잭션 커밋 이후에 S3에 접근할 수 있도록 로직 수정

* [FEAT]: moveObject()에서 이동 경로가 동일한 경우 예외처리 추가

* [FIX] : QClass 관련 빌드 에러 수정

---------

Co-authored-by: CHAN <150508884+zerochani@users.noreply.github.com>
Co-authored-by: SungMinju <minju2928@naver.com>
Co-authored-by: J_lisa&& <155425927+SungMinju@users.noreply.github.com>
Co-authored-by: twodo0 <dopal0426@gmail.com>
Co-authored-by: 손준규 <144649271+sonjunkyu@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT]: 가게 개별 테이블 이미지 등록/삭제 API 구현

3 participants