From db2f52f7b8173abcc592409e534bfd14441f331d Mon Sep 17 00:00:00 2001 From: sonjunkyu Date: Sat, 17 Jan 2026 23:00:40 +0900 Subject: [PATCH 01/11] =?UTF-8?q?[REFACTOR]:=20TableLayout=20SQLDelete=20?= =?UTF-8?q?=EC=BF=BC=EB=A6=AC=EB=AC=B8=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20?= =?UTF-8?q?Builder.Default=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eatsfine/domain/table_layout/entity/TableLayout.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/entity/TableLayout.java b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/entity/TableLayout.java index 7231dce..087e563 100644 --- a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/entity/TableLayout.java +++ b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/entity/TableLayout.java @@ -17,7 +17,7 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor @Builder -@SQLDelete(sql = "UPDATE table_layout SET is_deleted = true WHERE id = ?") +@SQLDelete(sql = "UPDATE table_layout SET is_deleted = true, is_active = false, deleted_at = CURRENT_TIMESTAMP WHERE id = ?") @SQLRestriction("is_deleted = false") @Table(name = "table_layout") public class TableLayout extends BaseEntity { @@ -46,6 +46,7 @@ public class TableLayout extends BaseEntity { @Column(name = "deleted_at") private LocalDateTime deletedAt; + @Builder.Default @OneToMany(mappedBy = "tableLayout", cascade = {CascadeType.PERSIST, CascadeType.MERGE}) private List tables = new ArrayList<>(); From 8b828dd2f56e16aa7167449c3f9577e682bddef3 Mon Sep 17 00:00:00 2001 From: sonjunkyu Date: Sun, 18 Jan 2026 00:39:23 +0900 Subject: [PATCH 02/11] =?UTF-8?q?[FEAT]:=20TableLayoutException=20?= =?UTF-8?q?=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../table_layout/exception/TableLayoutException.java | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/main/java/com/eatsfine/eatsfine/domain/table_layout/exception/TableLayoutException.java diff --git a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/exception/TableLayoutException.java b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/exception/TableLayoutException.java new file mode 100644 index 0000000..ee893b5 --- /dev/null +++ b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/exception/TableLayoutException.java @@ -0,0 +1,10 @@ +package com.eatsfine.eatsfine.domain.table_layout.exception; + +import com.eatsfine.eatsfine.global.apiPayload.code.BaseErrorCode; +import com.eatsfine.eatsfine.global.apiPayload.exception.GeneralException; + +public class TableLayoutException extends GeneralException { + public TableLayoutException(BaseErrorCode code) { + super(code); + } +} From 703620d573650949397cce8fb50fb00ae3a6a3e5 Mon Sep 17 00:00:00 2001 From: sonjunkyu Date: Sun, 18 Jan 2026 13:39:30 +0900 Subject: [PATCH 03/11] =?UTF-8?q?[FEAT]:=20TableLayout=20=EC=84=B1?= =?UTF-8?q?=EA=B3=B5/=EC=8B=A4=ED=8C=A8=20=EC=9D=91=EB=8B=B5=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../status/TableLayoutErrorStatus.java | 40 ++++++++++++++++++ .../status/TableLayoutSuccessStatus.java | 42 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 src/main/java/com/eatsfine/eatsfine/domain/table_layout/exception/status/TableLayoutErrorStatus.java create mode 100644 src/main/java/com/eatsfine/eatsfine/domain/table_layout/exception/status/TableLayoutSuccessStatus.java diff --git a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/exception/status/TableLayoutErrorStatus.java b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/exception/status/TableLayoutErrorStatus.java new file mode 100644 index 0000000..c0d02e4 --- /dev/null +++ b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/exception/status/TableLayoutErrorStatus.java @@ -0,0 +1,40 @@ +package com.eatsfine.eatsfine.domain.table_layout.exception.status; + +import com.eatsfine.eatsfine.global.apiPayload.code.BaseErrorCode; +import com.eatsfine.eatsfine.global.apiPayload.code.ErrorReasonDto; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor +public enum TableLayoutErrorStatus implements BaseErrorCode { + + _LAYOUT_NOT_FOUND(HttpStatus.NOT_FOUND, "LAYOUT404", "배치도를 찾을 수 없습니다."), + + _LAYOUT_FORBIDDEN(HttpStatus.FORBIDDEN, "LAYOUT403", "해당 가게의 소유자만 접근 가능합니다."), + ; + + private final HttpStatus httpStatus; + private final String code; + private final String message; + + @Override + public ErrorReasonDto getReason() { + return ErrorReasonDto.builder() + .isSuccess(false) + .code(code) + .message(message) + .build(); + } + + @Override + public ErrorReasonDto getReasonHttpStatus() { + return ErrorReasonDto.builder() + .httpStatus(httpStatus) + .isSuccess(false) + .code(code) + .message(message) + .build(); + } +} diff --git a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/exception/status/TableLayoutSuccessStatus.java b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/exception/status/TableLayoutSuccessStatus.java new file mode 100644 index 0000000..beb03ef --- /dev/null +++ b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/exception/status/TableLayoutSuccessStatus.java @@ -0,0 +1,42 @@ +package com.eatsfine.eatsfine.domain.table_layout.exception.status; + +import com.eatsfine.eatsfine.global.apiPayload.code.BaseCode; +import com.eatsfine.eatsfine.global.apiPayload.code.ReasonDto; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor +public enum TableLayoutSuccessStatus implements BaseCode { + + _LAYOUT_CREATED(HttpStatus.CREATED, "LAYOUT201", "성공적으로 배치도를 생성했습니다."), + + _LAYOUT_FOUND(HttpStatus.OK, "LAYOUT200", "성공적으로 배치도를 조회했습니다."), + + _LAYOUT_NO_CONTENT(HttpStatus.NO_CONTENT, "LAYOUT204", "조회된 배치도가 없습니다."), + ; + + private final HttpStatus httpStatus; + private final String code; + private final String message; + + @Override + public ReasonDto getReason() { + return ReasonDto.builder() + .isSuccess(true) + .message(message) + .code(code) + .build(); + } + + @Override + public ReasonDto getReasonHttpStatus() { + return ReasonDto.builder() + .isSuccess(true) + .httpStatus(httpStatus) + .message(message) + .code(code) + .build(); + } +} From fc422c8290411b44977ec1e08c22a449423f8c6c Mon Sep 17 00:00:00 2001 From: sonjunkyu Date: Sun, 18 Jan 2026 13:47:56 +0900 Subject: [PATCH 04/11] =?UTF-8?q?[FEAT]:=20Controller=EC=97=90=20=EB=B0=B0?= =?UTF-8?q?=EC=B9=98=EB=8F=84=20=EC=83=9D=EC=84=B1=20API=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/TableLayoutController.java | 26 +++++++++++++++ .../controller/TableLayoutControllerDocs.java | 33 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 src/main/java/com/eatsfine/eatsfine/domain/table_layout/controller/TableLayoutController.java create mode 100644 src/main/java/com/eatsfine/eatsfine/domain/table_layout/controller/TableLayoutControllerDocs.java diff --git a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/controller/TableLayoutController.java b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/controller/TableLayoutController.java new file mode 100644 index 0000000..34a29a8 --- /dev/null +++ b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/controller/TableLayoutController.java @@ -0,0 +1,26 @@ +package com.eatsfine.eatsfine.domain.table_layout.controller; + +import com.eatsfine.eatsfine.domain.table_layout.dto.req.TableLayoutReqDto; +import com.eatsfine.eatsfine.domain.table_layout.dto.res.TableLayoutResDto; +import com.eatsfine.eatsfine.domain.table_layout.exception.status.TableLayoutSuccessStatus; +import com.eatsfine.eatsfine.domain.table_layout.service.TableLayoutCommandService; +import com.eatsfine.eatsfine.global.apiPayload.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +@Tag(name = "TableLayout", description = "테이블 배치도 조회 및 관리 API") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/v1") +public class TableLayoutController implements TableLayoutControllerDocs{ + private final TableLayoutCommandService tableLayoutCommandService; + + @PostMapping("stores/{storeId}/layouts") + public ApiResponse createLayout( + @PathVariable Long storeId, + @RequestBody TableLayoutReqDto.LayoutCreateDto dto + ) { + return ApiResponse.of(TableLayoutSuccessStatus._LAYOUT_CREATED, tableLayoutCommandService.createLayout(storeId, dto)); + } +} diff --git a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/controller/TableLayoutControllerDocs.java b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/controller/TableLayoutControllerDocs.java new file mode 100644 index 0000000..df57f01 --- /dev/null +++ b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/controller/TableLayoutControllerDocs.java @@ -0,0 +1,33 @@ +package com.eatsfine.eatsfine.domain.table_layout.controller; + +import com.eatsfine.eatsfine.domain.table_layout.dto.req.TableLayoutReqDto; +import com.eatsfine.eatsfine.domain.table_layout.dto.res.TableLayoutResDto; +import com.eatsfine.eatsfine.global.apiPayload.ApiResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.parameters.RequestBody; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import jakarta.validation.Valid; + +public interface TableLayoutControllerDocs { + @Operation( + summary = "테이블 배치도 생성", + description = """ + 사장 회원이 가게의 테이블 배치도를 생성합니다. + + - 그리드 크기는 1x1 ~ 10x10 범위 내에서 설정 가능합니다. + - 가게당 활성 배치도는 1개만 존재하며, 새 배치도 생성 시 기존 배치도는 자동으로 비활성화됩니다. + - 생성된 배치도는 빈 상태로 생성되며, 이후 테이블 추가 API를 통해 테이블을 배치할 수 있습니다. + """ + ) + @ApiResponses({ + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "배치도 생성 성공"), + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "잘못된 요청 (그리드 크기 범위 초과 등)"), + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "가게를 찾을 수 없음") + }) + ApiResponse createLayout( + @Parameter(description = "가게 ID", required = true, example = "1") + Long storeId, + @RequestBody @Valid TableLayoutReqDto.LayoutCreateDto dto + ); +} From 13467d1e5c9a9e574dad5b530a4433727a54b20c Mon Sep 17 00:00:00 2001 From: sonjunkyu Date: Sun, 18 Jan 2026 13:57:33 +0900 Subject: [PATCH 05/11] =?UTF-8?q?[FEAT]:=20=EB=B0=B0=EC=B9=98=EB=8F=84=20D?= =?UTF-8?q?TO,=20Converter=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../converter/TableLayoutConverter.java | 41 +++++++++++++++++++ .../dto/req/TableLayoutReqDto.java | 21 ++++++++++ .../dto/res/TableLayoutResDto.java | 35 ++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 src/main/java/com/eatsfine/eatsfine/domain/table_layout/converter/TableLayoutConverter.java create mode 100644 src/main/java/com/eatsfine/eatsfine/domain/table_layout/dto/req/TableLayoutReqDto.java create mode 100644 src/main/java/com/eatsfine/eatsfine/domain/table_layout/dto/res/TableLayoutResDto.java diff --git a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/converter/TableLayoutConverter.java b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/converter/TableLayoutConverter.java new file mode 100644 index 0000000..4140aef --- /dev/null +++ b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/converter/TableLayoutConverter.java @@ -0,0 +1,41 @@ +package com.eatsfine.eatsfine.domain.table_layout.converter; + +import com.eatsfine.eatsfine.domain.storetable.entity.StoreTable; +import com.eatsfine.eatsfine.domain.table_layout.dto.res.TableLayoutResDto; +import com.eatsfine.eatsfine.domain.table_layout.entity.TableLayout; + +public class TableLayoutConverter { + // TableLayout Entity를 생성 응답 DTO로 변환 + public static TableLayoutResDto.LayoutDetailDto toLayoutDetailDto(TableLayout layout) { + return TableLayoutResDto.LayoutDetailDto.builder() + .layoutId(layout.getId()) + .totalTableCount(layout.getTables().size()) + .gridInfo( + TableLayoutResDto.GridInfo.builder() + .gridCol(layout.getCols()) + .gridRow(layout.getLows()) + .build() + ) + .tables( + layout.getTables().stream() + .map(TableLayoutConverter::toTableInfo) + .toList() + ) + .build(); + } + + // StoreTable Entity를 TableInfo DTO로 변환 + private static TableLayoutResDto.TableInfo toTableInfo(StoreTable table) { + return TableLayoutResDto.TableInfo.builder() + .tableId(table.getId()) + .tableNumber(table.getTableNumber()) + .seatsType(table.getSeatsType()) + .minSeatCount(table.getMinSeatCount()) + .maxSeatCount(table.getMaxSeatCount()) + .gridX(table.getGridX()) + .gridY(table.getGridY()) + .widthSpan(table.getWidthSpan()) + .heightSpan(table.getHeightSpan()) + .build(); + } +} diff --git a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/dto/req/TableLayoutReqDto.java b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/dto/req/TableLayoutReqDto.java new file mode 100644 index 0000000..1acda58 --- /dev/null +++ b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/dto/req/TableLayoutReqDto.java @@ -0,0 +1,21 @@ +package com.eatsfine.eatsfine.domain.table_layout.dto.req; + +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.Builder; + +public class TableLayoutReqDto { + @Builder + public record LayoutCreateDto( + @NotNull(message = "Column 크기는 필수입니다.") + @Min(value = 1, message = "가로 크기는 최소 1이어야 합니다.") + @Max(value = 10, message = "가로 크기는 최대 10이어야 합니다.") + Integer gridCol, + + @NotNull(message = "Row 크기는 필수입니다.") + @Min(value = 1, message = "세로 크기는 최소 1이어야 합니다.") + @Max(value = 10, message = "세로 크기는 최대 10이어야 합니다.") + Integer gridRow + ) {} +} diff --git a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/dto/res/TableLayoutResDto.java b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/dto/res/TableLayoutResDto.java new file mode 100644 index 0000000..12f76fa --- /dev/null +++ b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/dto/res/TableLayoutResDto.java @@ -0,0 +1,35 @@ +package com.eatsfine.eatsfine.domain.table_layout.dto.res; + +import com.eatsfine.eatsfine.domain.storetable.enums.SeatsType; +import lombok.Builder; + +import java.util.List; + +public class TableLayoutResDto { + @Builder + public record LayoutDetailDto( + Long layoutId, + Integer totalTableCount, + GridInfo gridInfo, + List tables + ) {} + + @Builder + public record GridInfo( + Integer gridCol, + Integer gridRow + ) {} + + @Builder + public record TableInfo( + Long tableId, + String tableNumber, + SeatsType seatsType, + Integer minSeatCount, + Integer maxSeatCount, + Integer gridX, + Integer gridY, + Integer widthSpan, + Integer heightSpan + ) {} +} From bddcc711b5d2b0b07bed2ed788c2df1019f89134 Mon Sep 17 00:00:00 2001 From: sonjunkyu Date: Sun, 18 Jan 2026 13:57:45 +0900 Subject: [PATCH 06/11] =?UTF-8?q?[FEAT]:=20=ED=85=8C=EC=9D=B4=EB=B8=94=20?= =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=8F=84=20=EC=83=9D=EC=84=B1=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/TableLayoutCommandService.java | 8 +++ .../TableLayoutCommandServiceImpl.java | 50 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/main/java/com/eatsfine/eatsfine/domain/table_layout/service/TableLayoutCommandService.java create mode 100644 src/main/java/com/eatsfine/eatsfine/domain/table_layout/service/TableLayoutCommandServiceImpl.java diff --git a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/service/TableLayoutCommandService.java b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/service/TableLayoutCommandService.java new file mode 100644 index 0000000..3e7840b --- /dev/null +++ b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/service/TableLayoutCommandService.java @@ -0,0 +1,8 @@ +package com.eatsfine.eatsfine.domain.table_layout.service; + +import com.eatsfine.eatsfine.domain.table_layout.dto.req.TableLayoutReqDto; +import com.eatsfine.eatsfine.domain.table_layout.dto.res.TableLayoutResDto; + +public interface TableLayoutCommandService { + TableLayoutResDto.LayoutDetailDto createLayout(Long storeId, TableLayoutReqDto.LayoutCreateDto dto); +} diff --git a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/service/TableLayoutCommandServiceImpl.java b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/service/TableLayoutCommandServiceImpl.java new file mode 100644 index 0000000..3eeb906 --- /dev/null +++ b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/service/TableLayoutCommandServiceImpl.java @@ -0,0 +1,50 @@ +package com.eatsfine.eatsfine.domain.table_layout.service; + +import com.eatsfine.eatsfine.domain.store.entity.Store; +import com.eatsfine.eatsfine.domain.store.exception.StoreException; +import com.eatsfine.eatsfine.domain.store.repository.StoreRepository; +import com.eatsfine.eatsfine.domain.store.status.StoreErrorStatus; +import com.eatsfine.eatsfine.domain.table_layout.converter.TableLayoutConverter; +import com.eatsfine.eatsfine.domain.table_layout.dto.req.TableLayoutReqDto; +import com.eatsfine.eatsfine.domain.table_layout.dto.res.TableLayoutResDto; +import com.eatsfine.eatsfine.domain.table_layout.entity.TableLayout; +import com.eatsfine.eatsfine.domain.table_layout.repository.TableLayoutRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional +public class TableLayoutCommandServiceImpl implements TableLayoutCommandService { + private final StoreRepository storeRepository; + private final TableLayoutRepository tableLayoutRepository; + + // 테이블 배치도 생성 + @Override + public TableLayoutResDto.LayoutDetailDto createLayout(Long storeId, TableLayoutReqDto.LayoutCreateDto dto) { + Store store = storeRepository.findById(storeId) + .orElseThrow(() -> new StoreException(StoreErrorStatus._STORE_NOT_FOUND)); + + deactivateExistingLayout(store); + + // 새 배치도 생성 + TableLayout newLayout = TableLayout.builder() + .store(store) + .lows(dto.gridRow()) + .cols(dto.gridCol()) + .isActive(true) + .isDeleted(false) + .build(); + + TableLayout savedLayout = tableLayoutRepository.save(newLayout); + + return TableLayoutConverter.toLayoutDetailDto(savedLayout); + } + + // 기존 테이블 배치도 비활성화 + private void deactivateExistingLayout(Store store) { + tableLayoutRepository.findByStoreIdAndIsActiveTrue(store.getId()) + .ifPresent(tableLayoutRepository::delete); + } +} From accd33a91a5bb5204c25b1051f68affede58968b Mon Sep 17 00:00:00 2001 From: sonjunkyu Date: Sun, 18 Jan 2026 15:43:32 +0900 Subject: [PATCH 07/11] =?UTF-8?q?[REFACTOR]:=20StoreTable=20SQLDelete=20?= =?UTF-8?q?=EC=BF=BC=EB=A6=AC=EB=AC=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eatsfine/eatsfine/domain/storetable/entity/StoreTable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eatsfine/eatsfine/domain/storetable/entity/StoreTable.java b/src/main/java/com/eatsfine/eatsfine/domain/storetable/entity/StoreTable.java index 7b16850..bec6bc7 100644 --- a/src/main/java/com/eatsfine/eatsfine/domain/storetable/entity/StoreTable.java +++ b/src/main/java/com/eatsfine/eatsfine/domain/storetable/entity/StoreTable.java @@ -17,7 +17,7 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor @Getter -@SQLDelete(sql = "UPDATE store_table SET is_deleted = true WHERE id = ?") +@SQLDelete(sql = "UPDATE store_table SET is_deleted = true, deleted_at = CURRENT_TIMESTAMP WHERE id = ?") @SQLRestriction("is_deleted = false") @Table(name = "store_table") public class StoreTable extends BaseEntity { From 1ee12cf7d335050386c9606d34afbe547086d61b Mon Sep 17 00:00:00 2001 From: sonjunkyu Date: Sun, 18 Jan 2026 15:45:21 +0900 Subject: [PATCH 08/11] =?UTF-8?q?[REFACTOR]:=20TableLayout=20-=20StoreTabl?= =?UTF-8?q?e=20=EC=97=B0=EA=B4=80=EA=B4=80=EA=B3=84=20Cascade.REMOVE=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eatsfine/domain/table_layout/entity/TableLayout.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/entity/TableLayout.java b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/entity/TableLayout.java index 087e563..4d45ea4 100644 --- a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/entity/TableLayout.java +++ b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/entity/TableLayout.java @@ -47,7 +47,7 @@ public class TableLayout extends BaseEntity { private LocalDateTime deletedAt; @Builder.Default - @OneToMany(mappedBy = "tableLayout", cascade = {CascadeType.PERSIST, CascadeType.MERGE}) + @OneToMany(mappedBy = "tableLayout", cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}) private List tables = new ArrayList<>(); } From c18a2b1ca96494298d4ccc1642a413a204656c6c Mon Sep 17 00:00:00 2001 From: sonjunkyu Date: Sun, 18 Jan 2026 15:51:21 +0900 Subject: [PATCH 09/11] =?UTF-8?q?[FEAT]:=20=ED=85=8C=EC=9D=B4=EB=B8=94=20?= =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=8F=84=20=EC=A1=B0=ED=9A=8C=20API=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/TableLayoutController.java | 13 ++++++++++++ .../controller/TableLayoutControllerDocs.java | 20 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/controller/TableLayoutController.java b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/controller/TableLayoutController.java index 34a29a8..b96960d 100644 --- a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/controller/TableLayoutController.java +++ b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/controller/TableLayoutController.java @@ -4,6 +4,7 @@ import com.eatsfine.eatsfine.domain.table_layout.dto.res.TableLayoutResDto; import com.eatsfine.eatsfine.domain.table_layout.exception.status.TableLayoutSuccessStatus; import com.eatsfine.eatsfine.domain.table_layout.service.TableLayoutCommandService; +import com.eatsfine.eatsfine.domain.table_layout.service.TableLayoutQueryService; import com.eatsfine.eatsfine.global.apiPayload.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; @@ -15,6 +16,7 @@ @RequestMapping("/api/v1") public class TableLayoutController implements TableLayoutControllerDocs{ private final TableLayoutCommandService tableLayoutCommandService; + private final TableLayoutQueryService tableLayoutQueryService; @PostMapping("stores/{storeId}/layouts") public ApiResponse createLayout( @@ -23,4 +25,15 @@ public ApiResponse createLayout( ) { return ApiResponse.of(TableLayoutSuccessStatus._LAYOUT_CREATED, tableLayoutCommandService.createLayout(storeId, dto)); } + + @GetMapping("stores/{storeId}/layouts") + public ApiResponse getActiveLayout(@PathVariable Long storeId) { + TableLayoutResDto.LayoutDetailDto result = tableLayoutQueryService.getActiveLayout(storeId); + + if (result == null) { + return ApiResponse.of(TableLayoutSuccessStatus._LAYOUT_NO_CONTENT, null); + } + + return ApiResponse.of(TableLayoutSuccessStatus._LAYOUT_FOUND, result); + } } diff --git a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/controller/TableLayoutControllerDocs.java b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/controller/TableLayoutControllerDocs.java index df57f01..4a84567 100644 --- a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/controller/TableLayoutControllerDocs.java +++ b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/controller/TableLayoutControllerDocs.java @@ -30,4 +30,24 @@ ApiResponse createLayout( Long storeId, @RequestBody @Valid TableLayoutReqDto.LayoutCreateDto dto ); + + @Operation( + summary = "테이블 배치도 조회", + description = """ + 가게의 활성화된 테이블 배치도를 조회합니다. + + - isActive = true인 배치도만 조회됩니다. + - 배치된 테이블 목록도 함께 반환됩니다. (삭제된 테이블은 제외) + - 활성 배치도가 없는 경우 204 응답을 반환합니다. + """ + ) + @ApiResponses({ + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "배치도 조회 성공"), + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "204", description = "조회는 성공했지만 가게 배치도가 없음"), + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "가게를 찾을 수 없음") + }) + ApiResponse getActiveLayout( + @Parameter(description = "가게 ID", required = true, example = "1") + Long storeId + ); } From 05584505260663aec57c68c9df058aa54eeeef42 Mon Sep 17 00:00:00 2001 From: sonjunkyu Date: Sun, 18 Jan 2026 15:52:42 +0900 Subject: [PATCH 10/11] =?UTF-8?q?[FEAT]:=20=ED=85=8C=EC=9D=B4=EB=B8=94=20?= =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=8F=84=20=EC=A1=B0=ED=9A=8C=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/TableLayoutQueryService.java | 7 +++++ .../service/TableLayoutQueryServiceImpl.java | 31 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 src/main/java/com/eatsfine/eatsfine/domain/table_layout/service/TableLayoutQueryService.java create mode 100644 src/main/java/com/eatsfine/eatsfine/domain/table_layout/service/TableLayoutQueryServiceImpl.java diff --git a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/service/TableLayoutQueryService.java b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/service/TableLayoutQueryService.java new file mode 100644 index 0000000..ac83475 --- /dev/null +++ b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/service/TableLayoutQueryService.java @@ -0,0 +1,7 @@ +package com.eatsfine.eatsfine.domain.table_layout.service; + +import com.eatsfine.eatsfine.domain.table_layout.dto.res.TableLayoutResDto; + +public interface TableLayoutQueryService { + TableLayoutResDto.LayoutDetailDto getActiveLayout(Long storeId); +} diff --git a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/service/TableLayoutQueryServiceImpl.java b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/service/TableLayoutQueryServiceImpl.java new file mode 100644 index 0000000..b5ab0c6 --- /dev/null +++ b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/service/TableLayoutQueryServiceImpl.java @@ -0,0 +1,31 @@ +package com.eatsfine.eatsfine.domain.table_layout.service; + +import com.eatsfine.eatsfine.domain.store.exception.StoreException; +import com.eatsfine.eatsfine.domain.store.repository.StoreRepository; +import com.eatsfine.eatsfine.domain.store.status.StoreErrorStatus; +import com.eatsfine.eatsfine.domain.table_layout.converter.TableLayoutConverter; +import com.eatsfine.eatsfine.domain.table_layout.dto.res.TableLayoutResDto; +import com.eatsfine.eatsfine.domain.table_layout.repository.TableLayoutRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class TableLayoutQueryServiceImpl implements TableLayoutQueryService { + private final StoreRepository storeRepository; + private final TableLayoutRepository tableLayoutRepository; + + // 테이블 배치도 조회 + @Override + public TableLayoutResDto.LayoutDetailDto getActiveLayout(Long storeId) { + storeRepository.findById(storeId) + .orElseThrow(() -> new StoreException(StoreErrorStatus._STORE_NOT_FOUND)); + + // 배치도가 없을 시 null 반환 + return tableLayoutRepository.findByStoreIdAndIsActiveTrue(storeId) + .map(TableLayoutConverter::toLayoutDetailDto) + .orElse(null); + } +} From 115907ed8f7f61f134dd87be336f1256e00f0d65 Mon Sep 17 00:00:00 2001 From: sonjunkyu Date: Mon, 19 Jan 2026 00:53:10 +0900 Subject: [PATCH 11/11] =?UTF-8?q?[REFACTOR]:=20=ED=85=8C=EC=9D=B4=EB=B8=94?= =?UTF-8?q?=20=EB=B0=B0=EC=B9=98=EB=8F=84=20=EC=A1=B0=ED=9A=8C=20=EC=9D=91?= =?UTF-8?q?=EB=8B=B5=20DTO,=20Converter=EC=97=90=20reviewCount=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/table_layout/converter/TableLayoutConverter.java | 1 + .../eatsfine/domain/table_layout/dto/res/TableLayoutResDto.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/converter/TableLayoutConverter.java b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/converter/TableLayoutConverter.java index 4140aef..1dc6304 100644 --- a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/converter/TableLayoutConverter.java +++ b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/converter/TableLayoutConverter.java @@ -32,6 +32,7 @@ private static TableLayoutResDto.TableInfo toTableInfo(StoreTable table) { .seatsType(table.getSeatsType()) .minSeatCount(table.getMinSeatCount()) .maxSeatCount(table.getMaxSeatCount()) + .reviewCount(0) // 추후 리뷰 로직 구현 시 추가 .gridX(table.getGridX()) .gridY(table.getGridY()) .widthSpan(table.getWidthSpan()) diff --git a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/dto/res/TableLayoutResDto.java b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/dto/res/TableLayoutResDto.java index 12f76fa..1e1a4a0 100644 --- a/src/main/java/com/eatsfine/eatsfine/domain/table_layout/dto/res/TableLayoutResDto.java +++ b/src/main/java/com/eatsfine/eatsfine/domain/table_layout/dto/res/TableLayoutResDto.java @@ -27,6 +27,7 @@ public record TableInfo( SeatsType seatsType, Integer minSeatCount, Integer maxSeatCount, + Integer reviewCount, Integer gridX, Integer gridY, Integer widthSpan,