Skip to content

Commit 66e3abf

Browse files
committed
📝 docs : menu & store 스웨거 명세 작성
1 parent 5b74962 commit 66e3abf

File tree

4 files changed

+290
-2
lines changed

4 files changed

+290
-2
lines changed
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
package com.example.Centralthon.domain.menu.web.controller;
2+
3+
import com.example.Centralthon.domain.menu.web.dto.MenuDetailsRes;
4+
import com.example.Centralthon.domain.menu.web.dto.MenuIdsReq;
5+
import com.example.Centralthon.domain.menu.web.dto.NearbyMenusRes;
6+
import com.example.Centralthon.domain.menu.web.dto.StoresByMenuRes;
7+
import com.example.Centralthon.global.response.SuccessResponse;
8+
import io.swagger.v3.oas.annotations.Operation;
9+
import io.swagger.v3.oas.annotations.Parameter;
10+
import io.swagger.v3.oas.annotations.media.Content;
11+
import io.swagger.v3.oas.annotations.media.ExampleObject;
12+
import io.swagger.v3.oas.annotations.media.Schema;
13+
import io.swagger.v3.oas.annotations.responses.ApiResponse;
14+
import io.swagger.v3.oas.annotations.tags.Tag;
15+
import jakarta.validation.Valid;
16+
import org.springframework.http.ResponseEntity;
17+
import org.springframework.web.bind.annotation.RequestBody;
18+
import org.springframework.web.bind.annotation.RequestParam;
19+
20+
import java.util.List;
21+
22+
@Tag(name = "Menus", description = "반찬 관련 API")
23+
public interface MenuApi {
24+
@Operation(
25+
summary = "맞춤 추천용 메뉴 목록 조회",
26+
description ="사용자 위치 기준 2km 이내에 가게에서 판매중인 반찬 매물을 반환합니다.<br>"+
27+
"중복을 제외하고 { 반찬명, 카테고리 }를 반환합니다.")
28+
@ApiResponse(
29+
responseCode = "200",
30+
description = "맞춤 추천용 메뉴 목록 조회 성공",
31+
content = @Content(
32+
mediaType = "application/json",
33+
schema = @Schema(implementation = SuccessResponse.class),
34+
examples = @ExampleObject(
35+
name = "SUCCESS_200",
36+
value = """
37+
{
38+
"timestamp": "2025-08-15 04:22:54",
39+
"code": "SUCCESS_200",
40+
"httpStatus": 200,
41+
"message": "호출에 성공하였습니다.",
42+
"data": [
43+
{
44+
"name": "진미채 볶음",
45+
"category" : "STIR_FRY"
46+
},
47+
{
48+
"name": "두부 조림",
49+
"category" : "BRAISED"
50+
}
51+
],
52+
"isSuccess": true
53+
}
54+
"""
55+
)
56+
)
57+
)
58+
ResponseEntity<SuccessResponse<List<NearbyMenusRes>>> nearbyMenus(
59+
@Parameter(name = "lat", description = "사용자 위도", example = "37.468355", required = true)
60+
@RequestParam("lat") Double lat,
61+
@Parameter(name = "lng", description = "사용자 경도", example = "127.039073", required = true)
62+
@RequestParam("lng") Double lng);
63+
64+
@Operation(
65+
summary = "특정 메뉴 판매 가게 조회",
66+
description = "반찬명을 기준으로 해당 메뉴를 판매하는 가게를 조회합니다. 공백까지 포함하여 동일 여부를 판단합니다.<br>"+
67+
"{ 메뉴Id값, 가게명, 사용자-가게 거리(km), 할인가, 수량}을 반환합니다.")
68+
@ApiResponse(
69+
responseCode = "200",
70+
description = "특정 메뉴 판매 가게 조회 성공",
71+
content = @Content(
72+
mediaType = "application/json",
73+
schema = @Schema(implementation = SuccessResponse.class),
74+
examples = @ExampleObject(
75+
name = "SUCCESS_200",
76+
value = """
77+
{
78+
"timestamp": "2025-08-15 04:22:54",
79+
"code": "SUCCESS_200",
80+
"httpStatus": 200,
81+
"message": "호출에 성공하였습니다.",
82+
"data": [
83+
{
84+
"menuId": 15,
85+
"storeName": "초록찬 비건키친",
86+
"distance": 1.7047542239779305,
87+
"salePrice": 4000,
88+
"quantity": 7
89+
},
90+
{
91+
"menuId": 1,
92+
"storeName": "우찬이네 반찬",
93+
"distance": 1.0348092111962985,
94+
"salePrice": 4200,
95+
"quantity": 10
96+
}
97+
],
98+
"isSuccess": true
99+
}
100+
"""
101+
)
102+
)
103+
)
104+
ResponseEntity<SuccessResponse<List<StoresByMenuRes>>> storesByMenu(
105+
@Parameter(name = "name", description = "메뉴 이름(공백 포함하여 완전일치)", example = "두부 조림", required = true)
106+
@RequestParam("name") String name,
107+
@Parameter(name = "lat", description = "사용자 위도", example = "37.468355", required = true)
108+
@RequestParam("lat") Double lat,
109+
@Parameter(name = "lng", description = "사용자 경도", example = "127.039073", required = true)
110+
@RequestParam("lng") Double lng);
111+
112+
@Operation(
113+
summary = "메뉴 상세 조회",
114+
description = "사용자가 추가한 각 메뉴들의 상세 정보를 반환합니다.<br>"+
115+
"{메뉴Id값, 메뉴 이름, 카테고리, 원가, 할인가, 할인율, 가게명}을 반환합니다."
116+
)
117+
@ApiResponse(
118+
responseCode = "200",
119+
description = "메뉴 상세 조회 성공",
120+
content = @Content(
121+
mediaType = "application/json",
122+
schema = @Schema(implementation = SuccessResponse.class),
123+
examples = @ExampleObject(
124+
name = "SUCCESS_200",
125+
value = """
126+
{
127+
"timestamp": "2025-08-15 04:22:54",
128+
"code": "SUCCESS_200",
129+
"httpStatus": 200,
130+
"message": "호출에 성공하였습니다.",
131+
"data": [
132+
{
133+
"menuId": 1,
134+
"name": "진미채 볶음",
135+
"category" : "STIR_FRY",
136+
"costPrice" : 3000,
137+
"salePrice" : 2400,
138+
"salePercent" : 20,
139+
"storeName" : "우찬이네 밥상"
140+
},
141+
{
142+
"menuId": 4,
143+
"name": "두부 조림",
144+
"category" : "BRAISED",
145+
"costPrice" : 5000,
146+
"salePrice" : 4000,
147+
"salePercent" : 20,
148+
"storeName" : "희망 식당"
149+
}
150+
],
151+
"isSuccess": true
152+
}
153+
"""
154+
)
155+
)
156+
)
157+
ResponseEntity<SuccessResponse<List<MenuDetailsRes>>> details(@RequestBody @Valid MenuIdsReq menus);
158+
}

src/main/java/com/example/Centralthon/domain/menu/web/controller/MenuController.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.example.Centralthon.domain.menu.service.MenuService;
44

55
import com.example.Centralthon.domain.menu.web.dto.*;
6+
import com.example.Centralthon.domain.order.web.controller.OrderApi;
67
import com.example.Centralthon.global.response.SuccessResponse;
78
import jakarta.validation.Valid;
89

@@ -21,11 +22,12 @@
2122
@RestController
2223
@RequestMapping("/api/menus")
2324
@RequiredArgsConstructor
24-
public class MenuController {
25+
public class MenuController implements MenuApi {
2526
private final MenuService menuService;
2627

2728
//맞춤 추천용 메뉴 목록 조회
2829
@GetMapping("")
30+
@Override
2931
public ResponseEntity<SuccessResponse<List<NearbyMenusRes>>> nearbyMenus(
3032
@RequestParam("lat") Double lat,
3133
@RequestParam("lng") Double lng) {
@@ -37,6 +39,7 @@ public ResponseEntity<SuccessResponse<List<NearbyMenusRes>>> nearbyMenus(
3739

3840
//특정 메뉴를 판매 하는 가게 조회
3941
@GetMapping("/stores")
42+
@Override
4043
public ResponseEntity<SuccessResponse<List<StoresByMenuRes>>> storesByMenu(
4144
@RequestParam("name") String name,
4245
@RequestParam("lat") Double lat,
@@ -49,6 +52,7 @@ public ResponseEntity<SuccessResponse<List<StoresByMenuRes>>> storesByMenu(
4952

5053
//메뉴 상세 조회
5154
@PostMapping("/details")
55+
@Override
5256
public ResponseEntity<SuccessResponse<List<MenuDetailsRes>>> details(@RequestBody @Valid MenuIdsReq menus){
5357
List<MenuDetailsRes> menuList = menuService.details(menus);
5458

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package com.example.Centralthon.domain.store.web.controller;
2+
3+
import com.example.Centralthon.domain.order.web.dto.CompleteOrderReq;
4+
import com.example.Centralthon.domain.order.web.dto.CreateOrderReq;
5+
import com.example.Centralthon.domain.order.web.dto.CreateOrderRes;
6+
import com.example.Centralthon.domain.store.web.dto.NearbyStoresRes;
7+
import com.example.Centralthon.domain.store.web.dto.StoreMenusRes;
8+
import com.example.Centralthon.global.response.SuccessResponse;
9+
import io.swagger.v3.oas.annotations.Operation;
10+
import io.swagger.v3.oas.annotations.Parameter;
11+
import io.swagger.v3.oas.annotations.enums.ParameterIn;
12+
import io.swagger.v3.oas.annotations.media.Content;
13+
import io.swagger.v3.oas.annotations.media.ExampleObject;
14+
import io.swagger.v3.oas.annotations.media.Schema;
15+
import io.swagger.v3.oas.annotations.responses.ApiResponse;
16+
import io.swagger.v3.oas.annotations.tags.Tag;
17+
import org.springframework.http.ResponseEntity;
18+
import org.springframework.web.bind.annotation.PathVariable;
19+
import org.springframework.web.bind.annotation.RequestParam;
20+
21+
import java.util.List;
22+
23+
@Tag(name = "Stores", description = "가게 관련 API")
24+
public interface StoreApi {
25+
@Operation(
26+
summary = "근처 가게 위치 목록 조회",
27+
description = "사용자 위치 기준 2km 반경 내에 가게 목록을 조회합니다.<br> 가게들의 기본키와 좌표값(위도, 경도)을 반환합니다."
28+
)
29+
@ApiResponse(
30+
responseCode = "200",
31+
description = "근처 가게 조회 성공",
32+
content = @Content(
33+
mediaType = "application/json",
34+
schema = @Schema(implementation = SuccessResponse.class),
35+
examples = @ExampleObject(
36+
name = "SUCCESS_200",
37+
value = """
38+
{
39+
"timestamp": "2025-08-14 15:54:04",
40+
"code": "SUCCESS_200",
41+
"httpStatus": 200,
42+
"message": "호출에 성공하였습니다.",
43+
"data": [
44+
{
45+
"storeId": 1,
46+
"lat": 37.59,
47+
"lng": 127.0164
48+
},
49+
{
50+
"storeId": 2,
51+
"lat": 37.577,
52+
"lng": 127.0204
53+
}
54+
],
55+
"isSuccess": true
56+
}
57+
"""
58+
)
59+
)
60+
)
61+
ResponseEntity<SuccessResponse<List<NearbyStoresRes>>> nearbyStores(
62+
@Parameter(name = "lat", description = "사용자 위도", example = "37.468355", required = true)
63+
@RequestParam("lat") Double lat,
64+
@Parameter(name = "lng", description = "사용자 경도", example = "127.039073", required = true)
65+
@RequestParam("lng") Double lng);
66+
67+
@Operation(
68+
summary = "가게에서 판매 중인 메뉴 조회",
69+
description ="현재 재고가 있고 마감 기한을 넘지 않은 메뉴들의 목록을 반환합니다. distacne = 사용자와 가게간의 거리(km)<br>" +
70+
"{ 메뉴 Id값, 이름, 카테고리, 원가, 할인가, 할인율, 수량} 을 반환합니다.")
71+
@ApiResponse(
72+
responseCode = "200",
73+
description = "판매 메뉴 목록 조회 성공",
74+
content = @Content(
75+
mediaType = "application/json",
76+
schema = @Schema(implementation = SuccessResponse.class),
77+
examples = @ExampleObject(
78+
name = "SUCCESS_200",
79+
value = """
80+
{
81+
"timestamp": "2025-08-15 04:45:14",
82+
"code": "SUCCESS_200",
83+
"httpStatus": 200,
84+
"message": "호출에 성공하였습니다.",
85+
"data": {
86+
"name": "오색퓨전찬",
87+
"category": "FUSION_SIDE_DISH",
88+
"distance": 1.0419556581490452,
89+
"menus": [
90+
{
91+
"menuId": 4,
92+
"name": "진미채 볶음",
93+
"category": "STIR_FRY",
94+
"costPrice": 5000,
95+
"salePrice": 4500,
96+
"salePercent": 10,
97+
"quantity": 7
98+
},
99+
{
100+
"menuId": 6,
101+
"name": "순두부찌개",
102+
"category": "SOUP",
103+
"costPrice": 6200,
104+
"salePrice": 5900,
105+
"salePercent": 5,
106+
"quantity": 4
107+
}
108+
]
109+
},
110+
"isSuccess": true
111+
}
112+
"""
113+
)
114+
)
115+
)
116+
ResponseEntity<SuccessResponse<StoreMenusRes>> getStoreMenus(
117+
@Parameter(name = "storeId", in = ParameterIn.PATH, description = "가게 ID", example = "1", required = true)
118+
@PathVariable Long storeId,
119+
@Parameter(name = "lat", in = ParameterIn.QUERY, description = "사용자 위도", example = "37.468355", required = true)
120+
@RequestParam("lat") Double lat,
121+
@Parameter(name = "lng", in = ParameterIn.QUERY, description = "사용자 경도", example = "127.039073", required = true)
122+
@RequestParam("lng") Double lng);
123+
}

src/main/java/com/example/Centralthon/domain/store/web/controller/StoreController.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.example.Centralthon.domain.store.web.controller;
22

3+
import com.example.Centralthon.domain.order.web.controller.OrderApi;
34
import com.example.Centralthon.domain.store.service.StoreService;
45
import com.example.Centralthon.domain.store.web.dto.NearbyStoresRes;
56
import com.example.Centralthon.domain.store.web.dto.StoreMenusRes;
@@ -14,11 +15,12 @@
1415
@RestController
1516
@RequestMapping("/api/stores")
1617
@RequiredArgsConstructor
17-
public class StoreController {
18+
public class StoreController implements StoreApi {
1819
private final StoreService storeService;
1920

2021
// 근처 가게 위치 목록 조회
2122
@GetMapping("")
23+
@Override
2224
public ResponseEntity<SuccessResponse<List<NearbyStoresRes>>> nearbyStores(
2325
@RequestParam("lat") Double lat,
2426
@RequestParam("lng") Double lng){
@@ -30,6 +32,7 @@ public ResponseEntity<SuccessResponse<List<NearbyStoresRes>>> nearbyStores(
3032

3133
// 가게 판매 메뉴 목록 조회
3234
@GetMapping("/{storeId}/menus")
35+
@Override
3336
public ResponseEntity<SuccessResponse<StoreMenusRes>> getStoreMenus(
3437
@PathVariable Long storeId,
3538
@RequestParam("lat") Double lat,

0 commit comments

Comments
 (0)