Files
sam-api/app/Swagger/v1/DepartmentApi.php
kent 73d06e03b0 fix : 권한관리 기능 추가 (각 기능 확인 필요)
- 메뉴관리
- 역할관리
- 부서관리
- 메뉴, 부서, 역할, 유저 - 권한 연동
2025-08-16 03:25:50 +09:00

384 lines
20 KiB
PHP

<?php
namespace App\Swagger\v1;
/**
* @OA\Tag(
* name="Department",
* description="부서 관리(목록/조회/등록/수정/삭제) + 부서원 관리 + 부서 권한 매핑"
* )
*/
/**
* =========================
* Schemas
* =========================
*/
/**
* @OA\Schema(
* schema="Department",
* type="object",
* description="부서 상세",
* required={"id","name"},
* @OA\Property(property="id", type="integer", example=7),
* @OA\Property(property="tenant_id", type="integer", example=1),
* @OA\Property(property="code", type="string", nullable=true, example="OPS"),
* @OA\Property(property="name", type="string", example="운영팀"),
* @OA\Property(property="description", type="string", nullable=true, example="서비스 운영 총괄"),
* @OA\Property(property="is_active", type="integer", example=1),
* @OA\Property(property="sort_order", type="integer", example=10),
* @OA\Property(property="created_at", type="string", format="date-time", example="2025-08-16 10:00:00"),
* @OA\Property(property="updated_at", type="string", format="date-time", example="2025-08-16 10:00:00")
* )
*
* @OA\Schema(
* schema="DepartmentBrief",
* type="object",
* description="부서 요약",
* required={"id","name"},
* @OA\Property(property="id", type="integer", example=7),
* @OA\Property(property="code", type="string", nullable=true, example="OPS"),
* @OA\Property(property="name", type="string", example="운영팀"),
* @OA\Property(property="is_active", type="integer", example=1),
* @OA\Property(property="sort_order", type="integer", example=10)
* )
*
* @OA\Schema(
* schema="DepartmentList",
* type="array",
* @OA\Items(ref="#/components/schemas/DepartmentBrief")
* )
*
* @OA\Schema(
* schema="DepartmentCreateRequest",
* type="object",
* required={"name"},
* @OA\Property(property="code", type="string", nullable=true, example="OPS"),
* @OA\Property(property="name", type="string", example="운영팀"),
* @OA\Property(property="description", type="string", nullable=true, example="서비스 운영 총괄"),
* @OA\Property(property="is_active", type="integer", enum={0,1}, example=1),
* @OA\Property(property="sort_order", type="integer", example=0)
* )
*
* @OA\Schema(
* schema="DepartmentUpdateRequest",
* type="object",
* @OA\Property(property="code", type="string", nullable=true, example="OPS2"),
* @OA\Property(property="name", type="string", example="운영기획팀"),
* @OA\Property(property="description", type="string", nullable=true, example="운영 기획/성과 관리"),
* @OA\Property(property="is_active", type="integer", enum={0,1}, example=1),
* @OA\Property(property="sort_order", type="integer", example=5)
* )
*
* @OA\Schema(
* schema="DepartmentUserAttachRequest",
* type="object",
* required={"user_id"},
* @OA\Property(property="user_id", type="integer", example=12),
* @OA\Property(property="is_primary", type="integer", enum={0,1}, nullable=true, example=0)
* )
*
* @OA\Schema(
* schema="DepartmentPermissionUpsertRequest",
* type="object",
* required={"permission_id"},
* @OA\Property(property="permission_id", type="integer", example=25),
* @OA\Property(property="menu_id", type="integer", nullable=true, example=101, description="특정 메뉴에 한정하려면 지정"),
* @OA\Property(property="is_allowed", type="integer", enum={0,1}, example=1, description="1=ALLOW, 0=DENY(차단)")
* )
*
* @OA\Schema(
* schema="UserBrief",
* type="object",
* description="부서원 요약",
* required={"id","name","email"},
* @OA\Property(property="id", type="integer", example=12),
* @OA\Property(property="name", type="string", example="홍길동"),
* @OA\Property(property="email", type="string", format="email", example="hong@example.com"),
* @OA\Property(property="phone", type="string", nullable=true, example="010-1234-5678"),
* @OA\Property(property="is_active", type="integer", example=1)
* )
*/
class DepartmentApi
{
/**
* @OA\Get(
* path="/api/v1/departments",
* summary="부서 목록 조회",
* description="테넌트 범위 내 부서 목록을 페이징으로 반환합니다. (q로 이름/코드 검색)",
* tags={"Department"},
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
* @OA\Parameter(name="page", in="query", required=false, @OA\Schema(type="integer", example=1)),
* @OA\Parameter(name="per_page", in="query", required=false, @OA\Schema(type="integer", example=10)),
* @OA\Parameter(name="q", in="query", required=false, @OA\Schema(type="string", example="운영")),
* @OA\Parameter(name="is_active", in="query", required=false, @OA\Schema(type="integer", enum={0,1}, example=1)),
* @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="current_page", type="integer", example=1),
* @OA\Property(property="per_page", type="integer", example=10),
* @OA\Property(property="total", type="integer", example=2),
* @OA\Property(property="data", ref="#/components/schemas/DepartmentList")
* ))
* }
* )
* ),
* @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/departments/{id}",
* summary="부서 단건 조회",
* description="ID로 부서 상세를 조회합니다.",
* tags={"Department"},
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer", example=7)),
* @OA\Response(response=200, description="단건 조회 성공",
* @OA\JsonContent(
* allOf={
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/Department"))
* }
* )
* ),
* @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/departments",
* summary="부서 생성",
* description="새 부서를 생성합니다.",
* tags={"Department"},
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/DepartmentCreateRequest")),
* @OA\Response(response=200, description="생성 성공",
* @OA\JsonContent(
* allOf={
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/Department"))
* }
* )
* ),
* @OA\Response(response=422, 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/departments/{id}",
* summary="부서 수정",
* description="기존 부서 정보를 부분 수정합니다.",
* tags={"Department"},
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer", example=7)),
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/DepartmentUpdateRequest")),
* @OA\Response(response=200, description="수정 성공",
* @OA\JsonContent(
* allOf={
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(@OA\Property(property="data", ref="#/components/schemas/Department"))
* }
* )
* ),
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
* @OA\Response(response=422, 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 update() {}
/**
* @OA\Delete(
* path="/api/v1/departments/{id}",
* summary="부서 삭제",
* description="지정한 부서를 삭제합니다(소프트 삭제 권장).",
* tags={"Department"},
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer", example=7)),
* @OA\Response(response=200, description="삭제 성공",
* @OA\JsonContent(ref="#/components/schemas/ApiResponse")
* ),
* @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 destroy() {}
/**
* @OA\Get(
* path="/api/v1/departments/{id}/users",
* summary="부서 사용자 목록",
* description="해당 부서에 속한 사용자 목록을 페이징으로 반환합니다.",
* tags={"Department"},
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer", example=7)),
* @OA\Parameter(name="page", in="query", required=false, @OA\Schema(type="integer", example=1)),
* @OA\Parameter(name="per_page", in="query", required=false, @OA\Schema(type="integer", example=20)),
* @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="current_page", type="integer", example=1),
* @OA\Property(property="per_page", type="integer", example=20),
* @OA\Property(property="total", type="integer", example=1),
* @OA\Property(property="data", type="array", @OA\Items(ref="#/components/schemas/UserBrief"))
* ))
* }
* )
* ),
* @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"))
* )
*/
public function users() {}
/**
* @OA\Post(
* path="/api/v1/departments/{id}/users",
* summary="부서 사용자 배정(단건)",
* description="특정 사용자 한 명을 해당 부서에 배정합니다.",
* tags={"Department"},
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer", example=7)),
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/DepartmentUserAttachRequest")),
* @OA\Response(response=200, description="배정 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse")),
* @OA\Response(response=409, description="이미 배정됨", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
* @OA\Response(response=422, 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"))
* )
*/
public function attachUser() {}
/**
* @OA\Delete(
* path="/api/v1/departments/{id}/users/{user}",
* summary="부서 사용자 해제(단건)",
* description="해당 부서에서 특정 사용자를 제거합니다.",
* tags={"Department"},
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer", example=7)),
* @OA\Parameter(name="user", in="path", required=true, @OA\Schema(type="integer", example=12)),
* @OA\Response(response=200, description="해제 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse")),
* @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"))
* )
*/
public function detachUser() {}
/**
* @OA\Patch(
* path="/api/v1/departments/{id}/users/{user}/primary",
* summary="주부서 설정/해제",
* description="부서 사용자 주부서 여부를 설정 또는 해제합니다.",
* tags={"Department"},
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer", example=7)),
* @OA\Parameter(name="user", in="path", required=true, @OA\Schema(type="integer", example=12)),
* @OA\RequestBody(
* required=true,
* @OA\JsonContent(
* @OA\Property(property="is_primary", type="integer", enum={0,1}, example=1)
* )
* ),
* @OA\Response(response=200, description="설정 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse")),
* @OA\Response(response=404, description="데이터 없음", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
* @OA\Response(response=422, 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"))
* )
*/
public function setPrimary() {}
/**
* @OA\Get(
* path="/api/v1/departments/{id}/permissions",
* summary="부서 권한 목록",
* description="부서에 매핑된 권한(메뉴 한정 포함)을 조회합니다.",
* tags={"Department"},
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer", example=7)),
* @OA\Response(response=200, description="조회 성공",
* @OA\JsonContent(
* allOf={
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(@OA\Property(
* property="data",
* type="array",
* @OA\Items(type="object",
* @OA\Property(property="permission_id", type="integer", example=25),
* @OA\Property(property="menu_id", type="integer", nullable=true, example=101),
* @OA\Property(property="is_allowed", type="integer", example=1)
* )
* ))
* }
* )
* ),
* @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"))
* )
*/
public function listPermissions() {}
/**
* @OA\Post(
* path="/api/v1/departments/{id}/permissions",
* summary="부서 권한 부여/차단(단건 Upsert)",
* description="permission_id 기준으로 ALLOW(1) 또는 DENY(0) 처리합니다. menu_id 지정 시 해당 메뉴 범위로 제한됩니다.",
* tags={"Department"},
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer", example=7)),
* @OA\RequestBody(required=true, @OA\JsonContent(ref="#/components/schemas/DepartmentPermissionUpsertRequest")),
* @OA\Response(response=200, description="적용 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse")),
* @OA\Response(response=422, 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"))
* )
*/
public function upsertPermission() {}
/**
* @OA\Delete(
* path="/api/v1/departments/{id}/permissions/{permission}",
* summary="부서 권한 해제(단건)",
* description="지정 권한을 부서 매핑에서 제거합니다. (menu_id 쿼리 파라미터로 특정 메뉴 범위를 지정 가능)",
* tags={"Department"},
* security={{"ApiKeyAuth": {}},{"BearerAuth": {}}},
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer", example=7)),
* @OA\Parameter(name="permission", in="path", required=true, @OA\Schema(type="integer", example=25)),
* @OA\Parameter(name="menu_id", in="query", required=false, @OA\Schema(type="integer", example=101)),
* @OA\Response(response=200, description="해제 성공", @OA\JsonContent(ref="#/components/schemas/ApiResponse")),
* @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"))
* )
*/
public function revokePermission() {}
}