233 lines
13 KiB
PHP
233 lines
13 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Swagger\v1;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @OA\Tag(name="Menu", description="메뉴 관리(목록/조회/등록/수정/삭제/정렬/토글)")
|
||
|
|
*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @OA\Schema(
|
||
|
|
* schema="Menu",
|
||
|
|
* type="object",
|
||
|
|
* description="메뉴 상세",
|
||
|
|
* required={"id","name"},
|
||
|
|
* @OA\Property(property="id", type="integer", example=12),
|
||
|
|
* @OA\Property(property="tenant_id", type="integer", nullable=true, example=1, description="null=공용"),
|
||
|
|
* @OA\Property(property="parent_id", type="integer", nullable=true, example=null),
|
||
|
|
* @OA\Property(property="name", type="string", example="메뉴 관리"),
|
||
|
|
* @OA\Property(property="slug", type="string", nullable=true, example="menu.manage"),
|
||
|
|
* @OA\Property(property="url", type="string", nullable=true, example="/admin/menus"),
|
||
|
|
* @OA\Property(property="is_active", type="integer", example=1),
|
||
|
|
* @OA\Property(property="sort_order", type="integer", example=10),
|
||
|
|
* @OA\Property(property="hidden", type="integer", example=0),
|
||
|
|
* @OA\Property(property="is_external", type="integer", example=0),
|
||
|
|
* @OA\Property(property="external_url", type="string", nullable=true, example=null),
|
||
|
|
* @OA\Property(property="icon", type="string", nullable=true, example="list"),
|
||
|
|
* @OA\Property(property="created_at", type="string", format="date-time", example="2025-08-15 10:00:00"),
|
||
|
|
* @OA\Property(property="updated_at", type="string", format="date-time", example="2025-08-15 10:00:00"),
|
||
|
|
* @OA\Property(property="deleted_at", type="string", format="date-time", nullable=true, example=null)
|
||
|
|
* )
|
||
|
|
*
|
||
|
|
* @OA\Schema(
|
||
|
|
* schema="MenuBrief",
|
||
|
|
* type="object",
|
||
|
|
* description="메뉴 요약",
|
||
|
|
* required={"id","name"},
|
||
|
|
* @OA\Property(property="id", type="integer", example=12),
|
||
|
|
* @OA\Property(property="parent_id", type="integer", nullable=true, example=null),
|
||
|
|
* @OA\Property(property="name", type="string", example="메뉴 관리"),
|
||
|
|
* @OA\Property(property="slug", type="string", nullable=true, example="menu.manage"),
|
||
|
|
* @OA\Property(property="url", type="string", nullable=true, example="/admin/menus"),
|
||
|
|
* @OA\Property(property="is_active", type="integer", example=1),
|
||
|
|
* @OA\Property(property="sort_order", type="integer", example=10),
|
||
|
|
* @OA\Property(property="hidden", type="integer", example=0),
|
||
|
|
* @OA\Property(property="is_external", type="integer", example=0),
|
||
|
|
* @OA\Property(property="external_url", type="string", nullable=true, example=null),
|
||
|
|
* @OA\Property(property="icon", type="string", nullable=true, example="list")
|
||
|
|
* )
|
||
|
|
*
|
||
|
|
* @OA\Schema(
|
||
|
|
* schema="MenuList",
|
||
|
|
* type="array",
|
||
|
|
* @OA\Items(ref="#/components/schemas/MenuBrief")
|
||
|
|
* )
|
||
|
|
*
|
||
|
|
* @OA\Schema(
|
||
|
|
* schema="MenuCreateRequest",
|
||
|
|
* type="object",
|
||
|
|
* required={"name"},
|
||
|
|
* @OA\Property(property="parent_id", type="integer", nullable=true, example=null, description="상위 메뉴 ID"),
|
||
|
|
* @OA\Property(property="name", type="string", example="새 메뉴", description="메뉴명"),
|
||
|
|
* @OA\Property(property="slug", type="string", nullable=true, example="menu.new", description="권한 키로도 활용"),
|
||
|
|
* @OA\Property(property="url", type="string", nullable=true, example="/admin/new"),
|
||
|
|
* @OA\Property(property="is_active", type="boolean", example=true),
|
||
|
|
* @OA\Property(property="sort_order", type="integer", example=0),
|
||
|
|
* @OA\Property(property="hidden", type="boolean", example=false),
|
||
|
|
* @OA\Property(property="is_external", type="boolean", example=false),
|
||
|
|
* @OA\Property(property="external_url", type="string", nullable=true, example=null),
|
||
|
|
* @OA\Property(property="icon", type="string", nullable=true, example="plus")
|
||
|
|
* )
|
||
|
|
*
|
||
|
|
* @OA\Schema(
|
||
|
|
* schema="MenuUpdateRequest",
|
||
|
|
* type="object",
|
||
|
|
* @OA\Property(property="parent_id", type="integer", nullable=true, example=null),
|
||
|
|
* @OA\Property(property="name", type="string", example="메뉴명 변경"),
|
||
|
|
* @OA\Property(property="slug", type="string", nullable=true, example="menu.changed"),
|
||
|
|
* @OA\Property(property="url", type="string", nullable=true, example="/admin/changed"),
|
||
|
|
* @OA\Property(property="is_active", type="boolean", example=true),
|
||
|
|
* @OA\Property(property="sort_order", type="integer", example=5),
|
||
|
|
* @OA\Property(property="hidden", type="boolean", example=false),
|
||
|
|
* @OA\Property(property="is_external", type="boolean", example=false),
|
||
|
|
* @OA\Property(property="external_url", type="string", nullable=true, example=null),
|
||
|
|
* @OA\Property(property="icon", type="string", nullable=true, example="edit")
|
||
|
|
* )
|
||
|
|
*/
|
||
|
|
class MenuApi
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* @OA\Get(
|
||
|
|
* path="/api/v1/menus",
|
||
|
|
* summary="메뉴 목록 조회",
|
||
|
|
* description="테넌트 범위 내(또는 공용) 메뉴 목록을 반환합니다. parent_id/is_active/hidden 필터 지원.",
|
||
|
|
* tags={"Menu"},
|
||
|
|
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||
|
|
* @OA\Parameter(name="parent_id", in="query", required=false, @OA\Schema(type="integer", example=0)),
|
||
|
|
* @OA\Parameter(name="is_active", in="query", required=false, @OA\Schema(type="integer", example=1)),
|
||
|
|
* @OA\Parameter(name="hidden", in="query", required=false, @OA\Schema(type="integer", example=0)),
|
||
|
|
* @OA\Response(response=200, description="목록 조회 성공",
|
||
|
|
* @OA\JsonContent(allOf={@OA\Schema(ref="#/components/schemas/ApiResponse"), @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/MenuList"))})
|
||
|
|
* ),
|
||
|
|
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||
|
|
* @OA\Response(response=403, description="권한 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||
|
|
* @OA\Response(response=500, description="서버 에러", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||
|
|
* )
|
||
|
|
*/
|
||
|
|
public function index() {}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @OA\Get(
|
||
|
|
* path="/api/v1/menus/{id}",
|
||
|
|
* summary="메뉴 단건 조회",
|
||
|
|
* description="ID로 메뉴 상세 정보를 조회합니다.",
|
||
|
|
* tags={"Menu"},
|
||
|
|
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||
|
|
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer", example=12)),
|
||
|
|
* @OA\Response(response=200, description="단건 조회 성공",
|
||
|
|
* @OA\JsonContent(allOf={@OA\Schema(ref="#/components/schemas/ApiResponse"), @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/Menu"))})
|
||
|
|
* ),
|
||
|
|
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||
|
|
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||
|
|
* @OA\Response(response=403, description="권한 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||
|
|
* @OA\Response(response=500, description="서버 에러", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||
|
|
* )
|
||
|
|
*/
|
||
|
|
public function show() {}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @OA\Post(
|
||
|
|
* path="/api/v1/menus",
|
||
|
|
* summary="메뉴 등록",
|
||
|
|
* description="새로운 메뉴를 등록합니다.",
|
||
|
|
* tags={"Menu"},
|
||
|
|
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||
|
|
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/MenuCreateRequest")),
|
||
|
|
* @OA\Response(response=200, description="등록 성공",
|
||
|
|
* @OA\JsonContent(allOf={@OA\Schema(ref="#/components/schemas/ApiResponse"), @OA\Schema(@OA\Property(property="data", type="object", @OA\Property(property="id", type="integer", example=12)))})
|
||
|
|
* ),
|
||
|
|
* @OA\Response(response=400, description="파라미터 오류", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||
|
|
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||
|
|
* @OA\ResponsE(response=403, description="권한 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||
|
|
* @OA\Response(response=500, description="서버 에러", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||
|
|
* )
|
||
|
|
*/
|
||
|
|
public function store() {}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @OA\Patch(
|
||
|
|
* path="/api/v1/menus/{id}",
|
||
|
|
* summary="메뉴 수정",
|
||
|
|
* description="기존 메뉴 정보를 수정합니다(부분 수정).",
|
||
|
|
* tags={"Menu"},
|
||
|
|
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||
|
|
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer", example=12)),
|
||
|
|
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/MenuUpdateRequest")),
|
||
|
|
* @OA\Response(response=200, description="수정 성공",
|
||
|
|
* @OA\JsonContent(allOf={@OA\Schema(ref="#/components/schemas/ApiResponse"), @OA\Schema(@OA\Property(property="data", type="object", @OA\Property(property="id", type="integer", example=12)))})
|
||
|
|
* ),
|
||
|
|
* @OA\Response(response=400, description="파라미터 오류", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||
|
|
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||
|
|
* @OA\Response(response=403, description="권한 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||
|
|
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||
|
|
* @OA\Response(response=500, description="서버 에러", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||
|
|
* )
|
||
|
|
*/
|
||
|
|
public function update() {}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @OA\Delete(
|
||
|
|
* path="/api/v1/menus/{id}",
|
||
|
|
* summary="메뉴 삭제(소프트 삭제)",
|
||
|
|
* description="지정한 메뉴를 소프트 삭제합니다.",
|
||
|
|
* tags={"Menu"},
|
||
|
|
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||
|
|
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer", example=12)),
|
||
|
|
* @OA\Response(response=200, description="삭제 성공",
|
||
|
|
* @OA\JsonContent(allOf={@OA\Schema(ref="#/components/schemas/ApiResponse"), @OA\Schema(@OA\Property(property="data", type="object", @OA\Property(property="id", type="integer", example=12), @OA\Property(property="deleted", type="boolean", example=true)))})
|
||
|
|
* ),
|
||
|
|
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||
|
|
* @OA\Response(response=403, description="권한 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||
|
|
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||
|
|
* @OA\Response(response=500, description="서버 에러", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||
|
|
* )
|
||
|
|
*/
|
||
|
|
public function destroy() {}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @OA\Post(
|
||
|
|
* path="/api/v1/menus/reorder",
|
||
|
|
* summary="메뉴 정렬 변경",
|
||
|
|
* description="여러 메뉴의 sort_order를 일괄 변경합니다.",
|
||
|
|
* tags={"Menu"},
|
||
|
|
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||
|
|
* @OA\RequestBody(required=true, @OA\JsonContent(
|
||
|
|
* type="array",
|
||
|
|
* @OA\Items(type="object",
|
||
|
|
* @OA\Property(property="id", type="integer", example=12),
|
||
|
|
* @OA\Property(property="sort_order", type="integer", example=1)
|
||
|
|
* )
|
||
|
|
* )),
|
||
|
|
* @OA\Response(response=200, description="정렬 변경 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse")),
|
||
|
|
* @OA\Response(response=400, description="파라미터 오류", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||
|
|
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||
|
|
* @OA\Response(response=403, description="권한 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||
|
|
* @OA\Response(response=500, description="서버 에러", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||
|
|
* )
|
||
|
|
*/
|
||
|
|
public function reorder() {}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @OA\Post(
|
||
|
|
* path="/api/v1/menus/{id}/toggle",
|
||
|
|
* summary="메뉴 상태 토글",
|
||
|
|
* description="is_active / hidden / is_external 중 하나 이상을 토글합니다.",
|
||
|
|
* tags={"Menu"},
|
||
|
|
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
|
||
|
|
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer", example=12)),
|
||
|
|
* @OA\RequestBody(required=true, @OA\JsonContent(type="object",
|
||
|
|
* @OA\Property(property="is_active", type="boolean", nullable=true, example=true),
|
||
|
|
* @OA\Property(property="hidden", type="boolean", nullable=true, example=false),
|
||
|
|
* @OA\Property(property="is_external", type="boolean", nullable=true, example=false)
|
||
|
|
* )),
|
||
|
|
* @OA\Response(response=200, description="토글 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse")),
|
||
|
|
* @OA\Response(response=400, description="파라미터 오류", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||
|
|
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||
|
|
* @OA\Response(response=403, description="권한 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||
|
|
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
|
||
|
|
* @OA\Response(response=500, description="서버 에러", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
|
||
|
|
* )
|
||
|
|
*/
|
||
|
|
public function toggle() {}
|
||
|
|
}
|