Files
sam-api/app/Swagger/v1/UserInvitationApi.php

313 lines
12 KiB
PHP
Raw Normal View History

<?php
namespace App\Swagger\v1;
/**
* @OA\Tag(
* name="UserInvitation",
* description="사용자 초대 관리"
* )
*
* @OA\Schema(
* schema="UserInvitation",
* type="object",
* required={"id", "tenant_id", "email", "token", "status", "invited_by", "expires_at"},
*
* @OA\Property(property="id", type="integer", example=1),
* @OA\Property(property="tenant_id", type="integer", example=1),
* @OA\Property(property="email", type="string", format="email", example="user@example.com"),
* @OA\Property(property="role_id", type="integer", nullable=true, example=2),
* @OA\Property(property="message", type="string", nullable=true, example="회사에 합류해 주세요!"),
* @OA\Property(property="token", type="string", example="abc123..."),
* @OA\Property(property="status", type="string", enum={"pending", "accepted", "expired", "cancelled"}, example="pending"),
* @OA\Property(property="status_label", type="string", example="대기중"),
* @OA\Property(property="invited_by", type="integer", example=1),
* @OA\Property(property="expires_at", type="string", format="date-time"),
* @OA\Property(property="accepted_at", type="string", format="date-time", nullable=true),
* @OA\Property(property="created_at", type="string", format="date-time"),
* @OA\Property(property="updated_at", type="string", format="date-time"),
* @OA\Property(
* property="role",
* type="object",
* nullable=true,
* @OA\Property(property="id", type="integer"),
* @OA\Property(property="name", type="string")
* ),
* @OA\Property(
* property="inviter",
* type="object",
* @OA\Property(property="id", type="integer"),
* @OA\Property(property="name", type="string")
* )
* )
*
* @OA\Schema(
* schema="UserInvitationPagination",
* type="object",
*
* @OA\Property(
* property="data",
* type="array",
*
* @OA\Items(ref="#/components/schemas/UserInvitation")
* ),
*
* @OA\Property(property="current_page", type="integer", example=1),
* @OA\Property(property="last_page", type="integer", example=5),
* @OA\Property(property="per_page", type="integer", example=20),
* @OA\Property(property="total", type="integer", example=100)
* )
*
* @OA\Schema(
* schema="InviteUserRequest",
* type="object",
* required={"email"},
*
* @OA\Property(property="email", type="string", format="email", example="newuser@example.com", description="초대할 사용자 이메일"),
* @OA\Property(property="role", type="string", nullable=true, enum={"admin", "manager", "user"}, example="user", description="부여할 역할 (role 또는 role_id 중 하나만 사용)"),
* @OA\Property(property="role_id", type="integer", nullable=true, example=2, description="부여할 역할 ID (role 또는 role_id 중 하나만 사용)"),
* @OA\Property(property="message", type="string", nullable=true, example="SAM 시스템에 합류해 주세요!", description="초대 메시지"),
* @OA\Property(property="expires_days", type="integer", nullable=true, example=7, minimum=1, maximum=30, description="만료 기간(일)")
* )
*
* @OA\Schema(
* schema="AcceptInvitationRequest",
* type="object",
* required={"name", "password", "password_confirmation"},
*
* @OA\Property(property="name", type="string", example="홍길동", description="사용자 이름"),
* @OA\Property(property="password", type="string", format="password", example="password123", description="비밀번호 (8자 이상)"),
* @OA\Property(property="password_confirmation", type="string", format="password", example="password123", description="비밀번호 확인"),
* @OA\Property(property="phone", type="string", nullable=true, example="010-1234-5678", description="연락처")
* )
*/
class UserInvitationApi
{
/**
* @OA\Get(
* path="/api/v1/users/invitations",
* operationId="getUserInvitations",
* tags={"UserInvitation"},
* summary="초대 목록 조회",
* description="테넌트의 사용자 초대 목록을 조회합니다.",
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
*
* @OA\Parameter(
* name="status",
* in="query",
* description="상태 필터",
* required=false,
*
* @OA\Schema(type="string", enum={"pending", "accepted", "expired", "cancelled"})
* ),
*
* @OA\Parameter(
* name="search",
* in="query",
* description="이메일 검색",
* required=false,
*
* @OA\Schema(type="string")
* ),
*
* @OA\Parameter(
* name="sort_by",
* in="query",
* description="정렬 기준",
* required=false,
*
* @OA\Schema(type="string", enum={"created_at", "expires_at", "email"}, default="created_at")
* ),
*
* @OA\Parameter(
* name="sort_dir",
* in="query",
* description="정렬 방향",
* required=false,
*
* @OA\Schema(type="string", enum={"asc", "desc"}, default="desc")
* ),
*
* @OA\Parameter(
* name="per_page",
* in="query",
* description="페이지당 항목 수",
* required=false,
*
* @OA\Schema(type="integer", default=20, minimum=1, maximum=100)
* ),
*
* @OA\Response(
* response=200,
* description="성공",
*
* @OA\JsonContent(
*
* @OA\Property(property="success", type="boolean", example=true),
* @OA\Property(property="message", type="string", example="조회 완료"),
* @OA\Property(property="data", ref="#/components/schemas/UserInvitationPagination")
* )
* ),
*
* @OA\Response(response=401, description="인증 실패"),
* @OA\Response(response=403, description="권한 없음")
* )
*/
public function index() {}
/**
* @OA\Post(
* path="/api/v1/users/invite",
* operationId="inviteUser",
* tags={"UserInvitation"},
* summary="사용자 초대",
* description="새로운 사용자를 테넌트에 초대합니다. 초대 이메일이 발송됩니다.",
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
*
* @OA\RequestBody(
* required=true,
*
* @OA\JsonContent(ref="#/components/schemas/InviteUserRequest")
* ),
*
* @OA\Response(
* response=200,
* description="초대 발송 성공",
*
* @OA\JsonContent(
*
* @OA\Property(property="success", type="boolean", example=true),
* @OA\Property(property="message", type="string", example="초대가 발송되었습니다"),
* @OA\Property(property="data", ref="#/components/schemas/UserInvitation")
* )
* ),
*
* @OA\Response(response=400, description="이미 가입된 사용자 또는 대기 중인 초대 존재"),
* @OA\Response(response=401, description="인증 실패"),
* @OA\Response(response=422, description="유효성 검증 실패")
* )
*/
public function invite() {}
/**
* @OA\Post(
* path="/api/v1/users/invitations/{token}/accept",
* operationId="acceptInvitation",
* tags={"UserInvitation"},
* summary="초대 수락",
* description="초대를 수락하고 사용자 계정을 생성합니다. 인증 불필요.",
* security={{"ApiKeyAuth": {}}},
*
* @OA\Parameter(
* name="token",
* in="path",
* description="초대 토큰",
* required=true,
*
* @OA\Schema(type="string")
* ),
*
* @OA\RequestBody(
* required=true,
*
* @OA\JsonContent(ref="#/components/schemas/AcceptInvitationRequest")
* ),
*
* @OA\Response(
* response=200,
* description="초대 수락 성공",
*
* @OA\JsonContent(
*
* @OA\Property(property="success", type="boolean", example=true),
* @OA\Property(property="message", type="string", example="초대가 수락되었습니다"),
* @OA\Property(property="data", type="object",
* @OA\Property(property="id", type="integer"),
* @OA\Property(property="name", type="string"),
* @OA\Property(property="email", type="string")
* )
* )
* ),
*
* @OA\Response(response=400, description="만료된 초대 또는 잘못된 상태"),
* @OA\Response(response=404, description="초대를 찾을 수 없음"),
* @OA\Response(response=422, description="유효성 검증 실패")
* )
*/
public function accept() {}
/**
* @OA\Delete(
* path="/api/v1/users/invitations/{id}",
* operationId="cancelInvitation",
* tags={"UserInvitation"},
* summary="초대 취소",
* description="대기 중인 초대를 취소합니다.",
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
*
* @OA\Parameter(
* name="id",
* in="path",
* description="초대 ID",
* required=true,
*
* @OA\Schema(type="integer")
* ),
*
* @OA\Response(
* response=200,
* description="취소 성공",
*
* @OA\JsonContent(
*
* @OA\Property(property="success", type="boolean", example=true),
* @OA\Property(property="message", type="string", example="초대가 취소되었습니다"),
* @OA\Property(property="data", type="boolean", example=true)
* )
* ),
*
* @OA\Response(response=400, description="취소할 수 없는 상태"),
* @OA\Response(response=401, description="인증 실패"),
* @OA\Response(response=404, description="초대를 찾을 수 없음")
* )
*/
public function cancel() {}
/**
* @OA\Post(
* path="/api/v1/users/invitations/{id}/resend",
* operationId="resendInvitation",
* tags={"UserInvitation"},
* summary="초대 재발송",
* description="대기 중인 초대 이메일을 재발송합니다. 만료 기간이 연장됩니다.",
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
*
* @OA\Parameter(
* name="id",
* in="path",
* description="초대 ID",
* required=true,
*
* @OA\Schema(type="integer")
* ),
*
* @OA\Response(
* response=200,
* description="재발송 성공",
*
* @OA\JsonContent(
*
* @OA\Property(property="success", type="boolean", example=true),
* @OA\Property(property="message", type="string", example="초대가 재발송되었습니다"),
* @OA\Property(property="data", ref="#/components/schemas/UserInvitation")
* )
* ),
*
* @OA\Response(response=400, description="재발송할 수 없는 상태"),
* @OA\Response(response=401, description="인증 실패"),
* @OA\Response(response=404, description="초대를 찾을 수 없음")
* )
*/
public function resend() {}
}