Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
Expand All @@ -17,19 +18,25 @@
@Tag(name = "CMS Auth", description = "CMS 인증 API")
public interface CMSAuthControllerDocs {

@Parameter(name = "X-App-Subdomain", in = ParameterIn.HEADER, required = true,
description = "요청 대상 CMS 앱의 서브도메인")
@Operation(summary = "CMS 로그인", description = "CMS 계정으로 로그인하여 액세스/리프레시 토큰을 발급합니다.")
@ApiResponse(responseCode = "200", description = "로그인 성공",
content = @Content(schema = @Schema(implementation = TokenResponse.class)))
ResponseEntity<TokenResponse> signIn(@Parameter(hidden = true) HttpServletRequest request,
SignInRequest signInRequest,
@Parameter(hidden = true) Long redotAppId);

@Parameter(name = "X-App-Subdomain", in = ParameterIn.HEADER, required = true,
description = "요청 대상 CMS 앱의 서브도메인")
@Operation(summary = "CMS 토큰 재발급", description = "요청 쿠키에 포함된 리프레시 토큰으로 새 토큰을 발급합니다.")
@ApiResponse(responseCode = "200", description = "재발급 성공",
content = @Content(schema = @Schema(implementation = TokenResponse.class)))
ResponseEntity<TokenResponse> reissueToken(@Parameter(hidden = true) Long redotAppId,
@Parameter(hidden = true) HttpServletRequest request);

@Parameter(name = "X-App-Subdomain", in = ParameterIn.HEADER, required = true,
description = "요청 대상 CMS 앱의 서브도메인")
@Operation(summary = "현재 CMS 멤버 정보 조회", description = "인증된 CMS 멤버의 상세 정보를 조회합니다.")
@ApiResponse(responseCode = "200", description = "조회 성공",
content = @Content(schema = @Schema(implementation = CMSMemberResponse.class)))
Expand All @@ -40,6 +47,8 @@ ResponseEntity<CMSMemberResponse> getCurrentCMSMemberInfo(@Parameter(hidden = tr
@ApiResponse(responseCode = "204", description = "로그아웃 성공")
ResponseEntity<Void> signOut(@Parameter(hidden = true) HttpServletRequest request);

@Parameter(name = "X-App-Subdomain", in = ParameterIn.HEADER, required = true,
description = "요청 대상 CMS 앱의 서브도메인")
@Operation(summary = "CMS 비밀번호 재설정 확정", description = "발급받은 인증 코드로 비밀번호 재설정을 확정합니다.")
@ApiResponse(responseCode = "204", description = "재설정 완료")
ResponseEntity<Void> confirmPasswordReset(@Parameter(hidden = true) Long redotAppId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
Expand All @@ -18,18 +19,24 @@
@Tag(name = "CMS Inquiry", description = "CMS 문의 관리 API")
public interface RedotAppInquiryControllerDocs {

@Parameter(name = "X-App-Subdomain", in = ParameterIn.HEADER, required = true,
description = "요청 대상 CMS 앱의 서브도메인")
@Operation(summary = "문의 생성", description = "CMS 앱에 새 문의를 등록합니다.")
@ApiResponse(responseCode = "200", description = "생성 성공",
content = @Content(schema = @Schema(implementation = RedotAppInquiryResponse.class)))
ResponseEntity<RedotAppInquiryResponse> createInquiry(@Parameter(hidden = true) Long redotAppId,
RedotAppInquiryCreateRequest request);

@Parameter(name = "X-App-Subdomain", in = ParameterIn.HEADER, required = true,
description = "요청 대상 CMS 앱의 서브도메인")
@Operation(summary = "문의 단건 조회", description = "문의 ID로 상세 정보를 조회합니다.")
@ApiResponse(responseCode = "200", description = "조회 성공",
content = @Content(schema = @Schema(implementation = RedotAppInquiryResponse.class)))
ResponseEntity<RedotAppInquiryResponse> getInquiry(@Parameter(hidden = true) Long redotAppId,
@Parameter(description = "문의 ID", example = "1") Long inquiryId);

@Parameter(name = "X-App-Subdomain", in = ParameterIn.HEADER, required = true,
description = "요청 대상 CMS 앱의 서브도메인")
@Operation(summary = "문의 목록 조회", description = "`status`, `inquiryNumber`, `title`, `inquirerName`, `startDate`, `endDate` 검색 조건과 `page`/`size`/`sort=createdAt,desc` 쿼리 파라미터로 조회합니다.")
@ApiResponse(responseCode = "200", description = "조회 성공",
content = @Content(schema = @Schema(implementation = PageResponse.class)))
Expand All @@ -38,12 +45,16 @@ ResponseEntity<PageResponse<RedotAppInquiryResponse>> getAllInquiries(@Parameter
@Parameter(description = "기본 정렬은 createdAt DESC 입니다.")
@ParameterObject Pageable pageable);

@Parameter(name = "X-App-Subdomain", in = ParameterIn.HEADER, required = true,
description = "요청 대상 CMS 앱의 서브도메인")
@Operation(summary = "문의 처리 완료", description = "문의 상태를 완료로 변경합니다.")
@ApiResponse(responseCode = "200", description = "상태 변경 완료")
ResponseEntity<Void> markInquiryAsCompleted(@Parameter(hidden = true) Long redotAppId,
@Parameter(description = "문의 ID", example = "1") Long inquiryId,
@Parameter(hidden = true) JwtPrincipal jwtPrincipal);

@Parameter(name = "X-App-Subdomain", in = ParameterIn.HEADER, required = true,
description = "요청 대상 CMS 앱의 서브도메인")
@Operation(summary = "문의 재오픈", description = "완료된 문의를 다시 열어 진행합니다.")
@ApiResponse(responseCode = "200", description = "재오픈 완료")
ResponseEntity<Void> reopenInquiry(@Parameter(hidden = true) Long redotAppId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
Expand All @@ -23,18 +24,24 @@
@Tag(name = "CMS Member", description = "CMS 멤버 관리 API")
public interface CMSMemberControllerDocs {

@Parameter(name = "X-App-Subdomain", in = ParameterIn.HEADER, required = true,
description = "요청 대상 CMS 앱의 서브도메인")
@Operation(summary = "CMS 멤버 생성", description = "CMS 앱에 새로운 멤버를 추가합니다.")
@ApiResponse(responseCode = "200", description = "생성 성공",
content = @Content(schema = @Schema(implementation = CMSMemberResponse.class)))
ResponseEntity<CMSMemberResponse> createCMSMember(@Parameter(hidden = true) Long redotAppId,
CMSMemberCreateRequest request);

@Parameter(name = "X-App-Subdomain", in = ParameterIn.HEADER, required = true,
description = "요청 대상 CMS 앱의 서브도메인")
@Operation(summary = "CMS 멤버 단건 조회", description = "멤버 ID 기준으로 정보를 조회합니다.")
@ApiResponse(responseCode = "200", description = "조회 성공",
content = @Content(schema = @Schema(implementation = CMSMemberResponse.class)))
ResponseEntity<CMSMemberResponse> getCMSMemberInfo(@Parameter(hidden = true) Long redotAppId,
@Parameter(description = "멤버 ID", example = "1") Long memberId);

@Parameter(name = "X-App-Subdomain", in = ParameterIn.HEADER, required = true,
description = "요청 대상 CMS 앱의 서브도메인")
@Operation(summary = "CMS 멤버 목록 조회", description = "`name`, `email`, `role` 검색 조건과 `page`/`size`/`sort=createdAt,desc` 파라미터로 멤버를 조회합니다.")
@ApiResponse(responseCode = "200", description = "조회 성공",
content = @Content(schema = @Schema(implementation = PageResponse.class)))
Expand All @@ -43,32 +50,42 @@ ResponseEntity<PageResponse<CMSMemberResponse>> getCMSMemberList(@Parameter(hidd
@Parameter(description = "기본 정렬 createdAt DESC")
@ParameterObject Pageable pageable);

@Parameter(name = "X-App-Subdomain", in = ParameterIn.HEADER, required = true,
description = "요청 대상 CMS 앱의 서브도메인")
@Operation(summary = "CMS 멤버 권한 변경", description = "멤버 권한을 관리자/멤버로 변경합니다.")
@ApiResponse(responseCode = "200", description = "변경 성공",
content = @Content(schema = @Schema(implementation = CMSMemberResponse.class)))
ResponseEntity<CMSMemberResponse> changeCMSMemberRole(@Parameter(hidden = true) Long redotAppId,
@Parameter(description = "멤버 ID", example = "1") Long memberId,
CMSMemberRoleRequest request);

@Parameter(name = "X-App-Subdomain", in = ParameterIn.HEADER, required = true,
description = "요청 대상 CMS 앱의 서브도메인")
@Operation(summary = "CMS 멤버 정보 수정", description = "본인 정보를 수정합니다.")
@ApiResponse(responseCode = "200", description = "수정 성공",
content = @Content(schema = @Schema(implementation = CMSMemberResponse.class)))
ResponseEntity<CMSMemberResponse> updateCMSMember(@Parameter(hidden = true) Long redotAppId,
@Parameter(hidden = true) JwtPrincipal jwtPrincipal,
CMSMemberUpdateRequest request);

@Parameter(name = "X-App-Subdomain", in = ParameterIn.HEADER, required = true,
description = "요청 대상 CMS 앱의 서브도메인")
@Operation(summary = "CMS 멤버 삭제", description = "특정 멤버를 삭제합니다.")
@ApiResponse(responseCode = "204", description = "삭제 완료")
ResponseEntity<Void> deleteCMSMember(@Parameter(hidden = true) Long redotAppId,
@Parameter(hidden = true) JwtPrincipal jwtPrincipal,
@Parameter(description = "멤버 ID", example = "1") Long memberId);

@Parameter(name = "X-App-Subdomain", in = ParameterIn.HEADER, required = true,
description = "요청 대상 CMS 앱의 서브도메인")
@Operation(summary = "현재 CMS 멤버 탈퇴", description = "본인 계정을 삭제하고 토큰 쿠키를 제거합니다.")
@ApiResponse(responseCode = "204", description = "탈퇴 완료")
ResponseEntity<Void> deleteCurrentCMSMember(@Parameter(hidden = true) HttpServletRequest request,
@Parameter(hidden = true) Long redotAppId,
@Parameter(hidden = true) JwtPrincipal jwtPrincipal);

@Parameter(name = "X-App-Subdomain", in = ParameterIn.HEADER, required = true,
description = "요청 대상 CMS 앱의 서브도메인")
@Operation(summary = "CMS 멤버 프로필 이미지 업로드", description = "CMS 멤버 이미지 파일을 업로드합니다.")
@ApiResponse(responseCode = "200", description = "업로드 성공",
content = @Content(schema = @Schema(implementation = UploadedImageUrlResponse.class)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
Expand All @@ -13,6 +14,8 @@
@Tag(name = "CMS Menu", description = "CMS 메뉴 관리 API")
public interface CMSMenuControllerDocs {

@Parameter(name = "X-App-Subdomain", in = ParameterIn.HEADER, required = true,
description = "요청 대상 CMS 앱의 서브도메인")
@Operation(summary = "CMS 메뉴 목록 조회", description = "선택한 앱의 메뉴 구성을 조회합니다.")
@ApiResponse(responseCode = "200", description = "조회 성공",
content = @Content(array = @ArraySchema(schema = @Schema(implementation = CMSMenuResponse.class))))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package redot.redot_server.domain.cms.site.page.controller;

import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import redot.redot_server.domain.cms.site.page.controller.docs.CMSSitePageControllerDocs;
import redot.redot_server.domain.cms.site.page.dto.request.AppVersionCreateRequest;
import redot.redot_server.domain.cms.site.page.dto.response.AppVersionSummaryResponse;
import redot.redot_server.domain.cms.site.page.service.CMSSitePageService;
import redot.redot_server.domain.site.page.dto.response.AppPageResponse;
import redot.redot_server.domain.site.page.entity.AppVersionStatus;
import redot.redot_server.global.redotapp.resolver.annotation.CurrentRedotApp;
import redot.redot_server.global.util.dto.response.PageResponse;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/app/cms/pages")
public class CMSSitePageController implements CMSSitePageControllerDocs {

private final CMSSitePageService cmsSitePageService;

@GetMapping("/versions")
@Override
public ResponseEntity<PageResponse<AppVersionSummaryResponse>> getAppVersions(@CurrentRedotApp Long redotAppId,
@RequestParam(name = "status", required = false) AppVersionStatus status,
@PageableDefault(sort = "createdAt", direction = Sort.Direction.DESC)
Pageable pageable) {
return ResponseEntity.ok(cmsSitePageService.getAppVersions(redotAppId, status, pageable));
}

@GetMapping("/{pageId}")
@Override
public ResponseEntity<AppPageResponse> getPage(@CurrentRedotApp Long redotAppId,
@PathVariable(name = "pageId") Long pageId) {
return ResponseEntity.ok(cmsSitePageService.getPage(redotAppId, pageId));
}

@PostMapping("/versions")
@Override
public ResponseEntity<AppVersionSummaryResponse> createVersion(@CurrentRedotApp Long redotAppId,
@Valid @RequestBody AppVersionCreateRequest request) {
return ResponseEntity.ok(cmsSitePageService.createAppVersion(redotAppId, request));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package redot.redot_server.domain.cms.site.page.controller.docs;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.data.domain.Pageable;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.http.ResponseEntity;
import redot.redot_server.domain.cms.site.page.dto.request.AppVersionCreateRequest;
import redot.redot_server.domain.cms.site.page.dto.response.AppVersionSummaryResponse;
import redot.redot_server.domain.site.page.dto.response.AppPageResponse;
import redot.redot_server.domain.site.page.entity.AppVersionStatus;
import redot.redot_server.global.util.dto.response.PageResponse;

@Tag(name = "CMS Site Page", description = "CMS 페이지/버전 관리 API")
public interface CMSSitePageControllerDocs {

@Parameter(name = "X-App-Subdomain", in = ParameterIn.HEADER, required = true,
description = "요청 대상 CMS 앱의 서브도메인")
@Operation(summary = "페이지 버전 목록 조회",
description = "최신순으로 CMS 페이지 버전을 조회하며 status 파라미터로 PUBLISHED/DRAFT만 필터링할 수 있습니다.")
@ApiResponse(responseCode = "200", description = "조회 성공",
content = @Content(schema = @Schema(implementation = PageResponse.class)))
ResponseEntity<PageResponse<AppVersionSummaryResponse>> getAppVersions(@Parameter(hidden = true) Long redotAppId,
@Parameter(description = "필터링할 버전 상태", example = "PUBLISHED") AppVersionStatus status,
@ParameterObject Pageable pageable);

@Parameter(name = "X-App-Subdomain", in = ParameterIn.HEADER, required = true,
description = "요청 대상 CMS 앱의 서브도메인")
@Operation(summary = "특정 페이지 조회", description = "앱 내 분리된 페이지 정보를 조회합니다.")
@ApiResponse(responseCode = "200", description = "조회 성공",
content = @Content(schema = @Schema(implementation = AppPageResponse.class)))
ResponseEntity<AppPageResponse> getPage(@Parameter(hidden = true) Long redotAppId,
@Parameter(name = "pageId", in = ParameterIn.PATH, description = "페이지 ID", example = "1", required = true)
Long pageId);

@Parameter(name = "X-App-Subdomain", in = ParameterIn.HEADER, required = true,
description = "요청 대상 CMS 앱의 서브도메인")
@Operation(summary = "페이지 버전 생성", description = "기존 페이지 유지 + 신규 페이지 추가로 새로운 DRAFT/PUBLISHED 버전을 생성합니다.")
@ApiResponse(responseCode = "200", description = "생성 성공",
content = @Content(schema = @Schema(implementation = AppVersionSummaryResponse.class)))
ResponseEntity<AppVersionSummaryResponse> createVersion(@Parameter(hidden = true) Long redotAppId,
AppVersionCreateRequest request);
}
Loading