- 사업자등록번호 유효성 검사 API (바로빌 연동) - 회사 추가 신청/승인/반려 워크플로우 - 신청 승인 시 테넌트 자동 생성 및 사용자 연결 - 관리자용 신청 목록/상세 조회 - 사용자용 내 신청 목록 조회 - Swagger 문서 및 i18n 메시지 추가
420 lines
19 KiB
PHP
420 lines
19 KiB
PHP
<?php
|
|
|
|
namespace App\Swagger\v1;
|
|
|
|
/**
|
|
* @OA\Tag(name="Companies", description="회사 관리")
|
|
*
|
|
* @OA\Schema(
|
|
* schema="CompanyRequest",
|
|
* type="object",
|
|
* description="회사 추가 신청 정보",
|
|
*
|
|
* @OA\Property(property="id", type="integer", example=1, description="신청 ID"),
|
|
* @OA\Property(property="user_id", type="integer", example=1, description="신청자 ID"),
|
|
* @OA\Property(property="business_number", type="string", example="1234567890", description="사업자등록번호"),
|
|
* @OA\Property(property="formatted_business_number", type="string", example="123-45-67890", description="사업자등록번호 (포맷)"),
|
|
* @OA\Property(property="company_name", type="string", example="주식회사 테스트", description="회사명"),
|
|
* @OA\Property(property="ceo_name", type="string", nullable=true, example="홍길동", description="대표자명"),
|
|
* @OA\Property(property="address", type="string", nullable=true, example="서울시 강남구 테헤란로 123", description="주소"),
|
|
* @OA\Property(property="phone", type="string", nullable=true, example="02-1234-5678", description="전화번호"),
|
|
* @OA\Property(property="email", type="string", nullable=true, example="contact@test.com", description="이메일"),
|
|
* @OA\Property(property="status", type="string", enum={"pending","approved","rejected"}, example="pending", description="상태"),
|
|
* @OA\Property(property="status_label", type="string", example="대기중", description="상태 라벨"),
|
|
* @OA\Property(property="message", type="string", nullable=true, description="신청 메시지"),
|
|
* @OA\Property(property="reject_reason", type="string", nullable=true, description="반려 사유"),
|
|
* @OA\Property(property="barobill_response", type="object", nullable=true, description="바로빌 검증 응답"),
|
|
* @OA\Property(property="approved_by", type="integer", nullable=true, description="승인/반려 처리자 ID"),
|
|
* @OA\Property(property="created_tenant_id", type="integer", nullable=true, description="생성된 테넌트 ID"),
|
|
* @OA\Property(property="processed_at", type="string", format="date-time", nullable=true, description="처리일시"),
|
|
* @OA\Property(property="is_pending", type="boolean", example=true, description="대기중 여부"),
|
|
* @OA\Property(property="is_approved", type="boolean", example=false, description="승인됨 여부"),
|
|
* @OA\Property(property="is_rejected", type="boolean", example=false, description="반려됨 여부"),
|
|
* @OA\Property(property="user", type="object", nullable=true,
|
|
* @OA\Property(property="id", type="integer", example=1),
|
|
* @OA\Property(property="name", type="string", example="홍길동"),
|
|
* @OA\Property(property="email", type="string", example="user@example.com"),
|
|
* description="신청자 정보"
|
|
* ),
|
|
* @OA\Property(property="approver", type="object", nullable=true,
|
|
* @OA\Property(property="id", type="integer", example=1),
|
|
* @OA\Property(property="name", type="string", example="관리자"),
|
|
* @OA\Property(property="email", type="string", example="admin@example.com"),
|
|
* description="처리자 정보"
|
|
* ),
|
|
* @OA\Property(property="created_tenant", type="object", nullable=true,
|
|
* @OA\Property(property="id", type="integer", example=1),
|
|
* @OA\Property(property="company_name", type="string", example="주식회사 테스트"),
|
|
* @OA\Property(property="code", type="string", example="TEST0001"),
|
|
* description="생성된 테넌트 정보"
|
|
* ),
|
|
* @OA\Property(property="created_at", type="string", format="date-time"),
|
|
* @OA\Property(property="updated_at", type="string", format="date-time")
|
|
* )
|
|
*
|
|
* @OA\Schema(
|
|
* schema="BusinessNumberCheckResponse",
|
|
* type="object",
|
|
* description="사업자등록번호 검증 결과",
|
|
*
|
|
* @OA\Property(property="valid", type="boolean", example=true, description="유효 여부"),
|
|
* @OA\Property(property="status", type="string", example="01", description="상태 코드"),
|
|
* @OA\Property(property="status_label", type="string", example="사업중", description="상태 라벨"),
|
|
* @OA\Property(property="corp_name", type="string", nullable=true, example="주식회사 테스트", description="회사명 (바로빌 조회)"),
|
|
* @OA\Property(property="ceo_name", type="string", nullable=true, example="홍길동", description="대표자명 (바로빌 조회)"),
|
|
* @OA\Property(property="message", type="string", example="유효한 사업자등록번호입니다.", description="결과 메시지"),
|
|
* @OA\Property(property="already_exists", type="boolean", example=false, description="이미 등록된 회사 여부"),
|
|
* @OA\Property(property="existing_company_name", type="string", nullable=true, description="이미 등록된 회사명")
|
|
* )
|
|
*
|
|
* @OA\Schema(
|
|
* schema="CompanyRequestCreateRequest",
|
|
* type="object",
|
|
* required={"business_number", "company_name"},
|
|
* description="회사 추가 신청 요청",
|
|
*
|
|
* @OA\Property(property="business_number", type="string", example="1234567890", minLength=10, maxLength=13, description="사업자등록번호 (하이픈 포함/미포함 모두 가능)"),
|
|
* @OA\Property(property="company_name", type="string", example="주식회사 테스트", maxLength=200, description="회사명"),
|
|
* @OA\Property(property="ceo_name", type="string", example="홍길동", maxLength=50, nullable=true, description="대표자명"),
|
|
* @OA\Property(property="address", type="string", example="서울시 강남구 테헤란로 123", maxLength=300, nullable=true, description="주소"),
|
|
* @OA\Property(property="phone", type="string", example="02-1234-5678", maxLength=30, nullable=true, description="전화번호"),
|
|
* @OA\Property(property="email", type="string", format="email", example="contact@test.com", maxLength=100, nullable=true, description="이메일"),
|
|
* @OA\Property(property="message", type="string", example="신규 법인 등록 요청드립니다.", maxLength=1000, nullable=true, description="신청 메시지")
|
|
* )
|
|
*
|
|
* @OA\Schema(
|
|
* schema="CompanyRequestActionRequest",
|
|
* type="object",
|
|
* description="회사 추가 신청 처리 요청",
|
|
*
|
|
* @OA\Property(property="reason", type="string", example="서류 미비로 반려합니다.", maxLength=500, nullable=true, description="처리 사유 (반려 시 필수)")
|
|
* )
|
|
*
|
|
* @OA\Schema(
|
|
* schema="CompanyRequestPagination",
|
|
* type="object",
|
|
* description="회사 추가 신청 목록 (페이지네이션)",
|
|
*
|
|
* @OA\Property(property="data", type="array", @OA\Items(ref="#/components/schemas/CompanyRequest")),
|
|
* @OA\Property(property="links", type="object",
|
|
* @OA\Property(property="first", type="string"),
|
|
* @OA\Property(property="last", type="string"),
|
|
* @OA\Property(property="prev", type="string", nullable=true),
|
|
* @OA\Property(property="next", type="string", nullable=true)
|
|
* ),
|
|
* @OA\Property(property="meta", type="object",
|
|
* @OA\Property(property="current_page", type="integer", example=1),
|
|
* @OA\Property(property="from", type="integer", example=1),
|
|
* @OA\Property(property="last_page", type="integer", example=1),
|
|
* @OA\Property(property="per_page", type="integer", example=20),
|
|
* @OA\Property(property="to", type="integer", example=5),
|
|
* @OA\Property(property="total", type="integer", example=5)
|
|
* )
|
|
* )
|
|
*/
|
|
class CompanyApi
|
|
{
|
|
/**
|
|
* @OA\Post(
|
|
* path="/api/v1/companies/check",
|
|
* operationId="checkBusinessNumber",
|
|
* tags={"Companies"},
|
|
* summary="사업자등록번호 유효성 검사",
|
|
* description="사업자등록번호의 유효성을 검사합니다. 바로빌 API를 통해 휴폐업 여부를 확인하고, 이미 등록된 회사인지 확인합니다.",
|
|
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
|
|
*
|
|
* @OA\RequestBody(
|
|
* required=true,
|
|
* description="사업자등록번호",
|
|
*
|
|
* @OA\JsonContent(
|
|
* required={"business_number"},
|
|
*
|
|
* @OA\Property(property="business_number", type="string", example="1234567890", description="사업자등록번호 (10자리, 하이픈 제거)")
|
|
* )
|
|
* ),
|
|
*
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="검증 결과",
|
|
*
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
*
|
|
* @OA\Property(property="success", type="boolean", example=true),
|
|
* @OA\Property(property="message", type="string", example="검증이 완료되었습니다."),
|
|
* @OA\Property(property="data", ref="#/components/schemas/BusinessNumberCheckResponse")
|
|
* )
|
|
* ),
|
|
*
|
|
* @OA\Response(response=400, description="잘못된 요청"),
|
|
* @OA\Response(response=401, description="인증 실패")
|
|
* )
|
|
*/
|
|
public function check() {}
|
|
|
|
/**
|
|
* @OA\Post(
|
|
* path="/api/v1/companies/request",
|
|
* operationId="createCompanyRequest",
|
|
* tags={"Companies"},
|
|
* summary="회사 추가 신청",
|
|
* description="새로운 회사 추가를 신청합니다. 관리자 승인 후 테넌트가 생성됩니다.",
|
|
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
|
|
*
|
|
* @OA\RequestBody(
|
|
* required=true,
|
|
* description="회사 정보",
|
|
*
|
|
* @OA\JsonContent(ref="#/components/schemas/CompanyRequestCreateRequest")
|
|
* ),
|
|
*
|
|
* @OA\Response(
|
|
* response=201,
|
|
* description="신청 완료",
|
|
*
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
*
|
|
* @OA\Property(property="success", type="boolean", example=true),
|
|
* @OA\Property(property="message", type="string", example="회사 추가 신청이 완료되었습니다."),
|
|
* @OA\Property(property="data", ref="#/components/schemas/CompanyRequest")
|
|
* )
|
|
* ),
|
|
*
|
|
* @OA\Response(response=400, description="잘못된 요청 (중복 신청, 이미 등록된 회사 등)"),
|
|
* @OA\Response(response=401, description="인증 실패")
|
|
* )
|
|
*/
|
|
public function request() {}
|
|
|
|
/**
|
|
* @OA\Get(
|
|
* path="/api/v1/companies/requests",
|
|
* operationId="getCompanyRequests",
|
|
* tags={"Companies"},
|
|
* summary="회사 추가 신청 목록 (관리자용)",
|
|
* description="회사 추가 신청 목록을 조회합니다. 관리자 권한이 필요합니다.",
|
|
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
|
|
*
|
|
* @OA\Parameter(name="status", in="query", description="상태 필터",
|
|
*
|
|
* @OA\Schema(type="string", enum={"pending","approved","rejected"})
|
|
* ),
|
|
*
|
|
* @OA\Parameter(name="search", in="query", description="검색어 (사업자번호, 회사명, 신청자명)",
|
|
*
|
|
* @OA\Schema(type="string")
|
|
* ),
|
|
*
|
|
* @OA\Parameter(name="start_date", in="query", description="시작일",
|
|
*
|
|
* @OA\Schema(type="string", format="date")
|
|
* ),
|
|
*
|
|
* @OA\Parameter(name="end_date", in="query", description="종료일",
|
|
*
|
|
* @OA\Schema(type="string", format="date")
|
|
* ),
|
|
*
|
|
* @OA\Parameter(name="sort_by", in="query", description="정렬 기준",
|
|
*
|
|
* @OA\Schema(type="string", enum={"created_at","company_name","status","processed_at"})
|
|
* ),
|
|
*
|
|
* @OA\Parameter(name="sort_dir", in="query", description="정렬 방향",
|
|
*
|
|
* @OA\Schema(type="string", enum={"asc","desc"})
|
|
* ),
|
|
*
|
|
* @OA\Parameter(name="per_page", in="query", description="페이지당 항목 수",
|
|
*
|
|
* @OA\Schema(type="integer", minimum=1, maximum=100, default=20)
|
|
* ),
|
|
*
|
|
* @OA\Parameter(name="page", in="query", description="페이지 번호",
|
|
*
|
|
* @OA\Schema(type="integer", minimum=1)
|
|
* ),
|
|
*
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="신청 목록",
|
|
*
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
*
|
|
* @OA\Property(property="success", type="boolean", example=true),
|
|
* @OA\Property(property="message", type="string", example="조회되었습니다."),
|
|
* @OA\Property(property="data", ref="#/components/schemas/CompanyRequestPagination")
|
|
* )
|
|
* ),
|
|
*
|
|
* @OA\Response(response=401, description="인증 실패"),
|
|
* @OA\Response(response=403, description="권한 없음")
|
|
* )
|
|
*/
|
|
public function requests() {}
|
|
|
|
/**
|
|
* @OA\Get(
|
|
* path="/api/v1/companies/requests/{id}",
|
|
* operationId="getCompanyRequest",
|
|
* tags={"Companies"},
|
|
* summary="회사 추가 신청 상세",
|
|
* description="회사 추가 신청 상세 정보를 조회합니다.",
|
|
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
|
|
*
|
|
* @OA\Parameter(name="id", in="path", required=true, description="신청 ID",
|
|
*
|
|
* @OA\Schema(type="integer")
|
|
* ),
|
|
*
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="신청 상세",
|
|
*
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
*
|
|
* @OA\Property(property="success", type="boolean", example=true),
|
|
* @OA\Property(property="message", type="string", example="조회되었습니다."),
|
|
* @OA\Property(property="data", ref="#/components/schemas/CompanyRequest")
|
|
* )
|
|
* ),
|
|
*
|
|
* @OA\Response(response=401, description="인증 실패"),
|
|
* @OA\Response(response=404, description="신청 없음")
|
|
* )
|
|
*/
|
|
public function showRequest() {}
|
|
|
|
/**
|
|
* @OA\Post(
|
|
* path="/api/v1/companies/requests/{id}/approve",
|
|
* operationId="approveCompanyRequest",
|
|
* tags={"Companies"},
|
|
* summary="회사 추가 신청 승인",
|
|
* description="회사 추가 신청을 승인합니다. 승인 시 새로운 테넌트가 생성되고, 신청자가 해당 테넌트에 연결됩니다.",
|
|
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
|
|
*
|
|
* @OA\Parameter(name="id", in="path", required=true, description="신청 ID",
|
|
*
|
|
* @OA\Schema(type="integer")
|
|
* ),
|
|
*
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="승인 완료",
|
|
*
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
*
|
|
* @OA\Property(property="success", type="boolean", example=true),
|
|
* @OA\Property(property="message", type="string", example="승인되었습니다."),
|
|
* @OA\Property(property="data", ref="#/components/schemas/CompanyRequest")
|
|
* )
|
|
* ),
|
|
*
|
|
* @OA\Response(response=400, description="잘못된 요청 (이미 처리됨 등)"),
|
|
* @OA\Response(response=401, description="인증 실패"),
|
|
* @OA\Response(response=403, description="권한 없음"),
|
|
* @OA\Response(response=404, description="신청 없음")
|
|
* )
|
|
*/
|
|
public function approve() {}
|
|
|
|
/**
|
|
* @OA\Post(
|
|
* path="/api/v1/companies/requests/{id}/reject",
|
|
* operationId="rejectCompanyRequest",
|
|
* tags={"Companies"},
|
|
* summary="회사 추가 신청 반려",
|
|
* description="회사 추가 신청을 반려합니다.",
|
|
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
|
|
*
|
|
* @OA\Parameter(name="id", in="path", required=true, description="신청 ID",
|
|
*
|
|
* @OA\Schema(type="integer")
|
|
* ),
|
|
*
|
|
* @OA\RequestBody(
|
|
* description="반려 사유",
|
|
*
|
|
* @OA\JsonContent(ref="#/components/schemas/CompanyRequestActionRequest")
|
|
* ),
|
|
*
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="반려 완료",
|
|
*
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
*
|
|
* @OA\Property(property="success", type="boolean", example=true),
|
|
* @OA\Property(property="message", type="string", example="반려되었습니다."),
|
|
* @OA\Property(property="data", ref="#/components/schemas/CompanyRequest")
|
|
* )
|
|
* ),
|
|
*
|
|
* @OA\Response(response=400, description="잘못된 요청 (이미 처리됨 등)"),
|
|
* @OA\Response(response=401, description="인증 실패"),
|
|
* @OA\Response(response=403, description="권한 없음"),
|
|
* @OA\Response(response=404, description="신청 없음")
|
|
* )
|
|
*/
|
|
public function reject() {}
|
|
|
|
/**
|
|
* @OA\Get(
|
|
* path="/api/v1/companies/my-requests",
|
|
* operationId="getMyCompanyRequests",
|
|
* tags={"Companies"},
|
|
* summary="내 회사 추가 신청 목록",
|
|
* description="현재 사용자의 회사 추가 신청 목록을 조회합니다.",
|
|
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
|
|
*
|
|
* @OA\Parameter(name="status", in="query", description="상태 필터",
|
|
*
|
|
* @OA\Schema(type="string", enum={"pending","approved","rejected"})
|
|
* ),
|
|
*
|
|
* @OA\Parameter(name="sort_by", in="query", description="정렬 기준",
|
|
*
|
|
* @OA\Schema(type="string", enum={"created_at","company_name","status","processed_at"})
|
|
* ),
|
|
*
|
|
* @OA\Parameter(name="sort_dir", in="query", description="정렬 방향",
|
|
*
|
|
* @OA\Schema(type="string", enum={"asc","desc"})
|
|
* ),
|
|
*
|
|
* @OA\Parameter(name="per_page", in="query", description="페이지당 항목 수",
|
|
*
|
|
* @OA\Schema(type="integer", minimum=1, maximum=100, default=20)
|
|
* ),
|
|
*
|
|
* @OA\Parameter(name="page", in="query", description="페이지 번호",
|
|
*
|
|
* @OA\Schema(type="integer", minimum=1)
|
|
* ),
|
|
*
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="내 신청 목록",
|
|
*
|
|
* @OA\JsonContent(
|
|
* type="object",
|
|
*
|
|
* @OA\Property(property="success", type="boolean", example=true),
|
|
* @OA\Property(property="message", type="string", example="조회되었습니다."),
|
|
* @OA\Property(property="data", ref="#/components/schemas/CompanyRequestPagination")
|
|
* )
|
|
* ),
|
|
*
|
|
* @OA\Response(response=401, description="인증 실패")
|
|
* )
|
|
*/
|
|
public function myRequests() {}
|
|
}
|