- enhance_files_table: 이중 파일명 시스템 (display_name/stored_name), 폴더 관리, 문서 연결 지원
- create_folders_table: 동적 폴더 관리 시스템 (tenant별 커스터마이징 가능)
- 5개 stub 마이그레이션 생성 (file_share_links, file_deletion_logs, storage_usage_history, add_storage_columns_to_tenants)
- FolderSeeder stub 생성
- CURRENT_WORKS.md에 Phase 1 진행상황 문서화
fix: 파일 공유 및 삭제 기능 버그 수정
- ShareLinkRequest: PATH 파라미터 {id}를 file_id로 자동 병합
- routes/api.php: 공유 링크 다운로드를 auth.apikey 그룹 밖으로 이동 (인증 불필요)
- FileShareLink: File, Tenant 클래스 import 추가
- File 모델: softDeleteFile()에서 SoftDeletes의 delete() 메서드 사용
- FileStorageService: getTrash(), restoreFile(), permanentDelete()에서 onlyTrashed() 사용
- File 모델: Tenant 네임스페이스 수정 (App\Models\Tenants\Tenant)
refactor: Swagger 문서 정리 - File 태그를 Files로 통합
- FileApi.php의 모든 태그를 Files로 변경
- 구 파일 시스템 라우트 삭제 (prefix 'file')
- 구 FileController.php 삭제
- 신규 파일 저장소 시스템으로 완전 통합
fix: 모든 legacy 파일 컬럼 nullable 일괄 처리
- 5개 legacy 컬럼을 한 번에 nullable로 변경
* original_name, file_name, file_name_old (string)
* fileable_id, fileable_type (polymorphic)
- foreach 루프로 반복 작업 자동화
- 신규/기존 시스템 간 완전한 하위 호환성 확보
fix: legacy 파일 컬럼 nullable 처리 완료
- file_name, file_name_old 컬럼도 nullable로 변경
- 기존 시스템과 신규 시스템 간 완전한 하위 호환성 확보
- Legacy: original_name, file_name, file_name_old (nullable)
- New: display_name, stored_name (required)
fix: original_name 컬럼 nullable 처리
- original_name을 nullable로 변경하여 하위 호환성 유지
- 새 시스템에서는 display_name 사용, 기존 시스템은 original_name 사용 가능
fix: 파일 업로드 DB 컬럼 누락 및 메시지 구조 개선
- files 테이블에 감사 컬럼 추가 (created_by, updated_by, uploaded_by)
- ApiResponse::handle() 메시지 로직 개선 (접미사 제거)
- 다국어 지원을 위한 완성된 문장 구조 유지
- FileUploadRequest 파일 검증 규칙 수정
fix: 파일 저장소 버그 수정 및 신규 테넌트 폴더 자동 생성
- FolderSeeder 네임스페이스 수정 (App\Models\Tenant → App\Models\Tenants\Tenant)
- FileStorageController use 문 구문 오류 수정 (/ → \)
- TenantObserver에 신규 테넌트 기본 폴더 자동 생성 로직 추가
- 5개 기본 폴더 (생산관리, 품질관리, 회계, 인사, 일반)
- 에러 처리 및 로깅
- 회원가입 시 자동 실행
139 lines
7.3 KiB
PHP
139 lines
7.3 KiB
PHP
<?php
|
|
|
|
namespace App\Swagger\v1;
|
|
|
|
/**
|
|
* @OA\Post(
|
|
* path="/api/v1/register",
|
|
* tags={"Auth"},
|
|
* summary="회원가입 및 테넌트 생성",
|
|
* description="신규 회원가입과 동시에 새로운 테넌트(회사)를 생성합니다. 사용자는 자동으로 system_manager 역할이 부여되며 모든 테넌트 메뉴 권한을 갖습니다.",
|
|
* operationId="register",
|
|
* security={{"ApiKeyAuth": {}}},
|
|
*
|
|
* @OA\RequestBody(
|
|
* required=true,
|
|
* description="회원가입 정보",
|
|
*
|
|
* @OA\JsonContent(
|
|
* required={"user_id", "name", "email", "password", "password_confirmation", "company_name", "business_num"},
|
|
*
|
|
* @OA\Property(property="user_id", type="string", example="john_doe", description="사용자 아이디 (영문, 숫자, _, - 만 허용)"),
|
|
* @OA\Property(property="name", type="string", example="홍길동", description="사용자 이름"),
|
|
* @OA\Property(property="email", type="string", format="email", example="john@example.com", description="이메일 주소"),
|
|
* @OA\Property(property="phone", type="string", example="010-1234-5678", description="전화번호 (선택)", nullable=true),
|
|
* @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="position", type="string", example="개발팀장", description="직책 (선택)", nullable=true),
|
|
* @OA\Property(property="company_name", type="string", example="(주)테크컴퍼니", description="회사명"),
|
|
* @OA\Property(property="business_num", type="string", example="123-45-67890", description="사업자등록번호 (000-00-00000 형식)"),
|
|
* @OA\Property(property="company_scale", type="string", example="중소기업", description="회사 규모 (선택)", nullable=true),
|
|
* @OA\Property(property="industry", type="string", example="IT/소프트웨어", description="업종 (선택)", nullable=true)
|
|
* )
|
|
* ),
|
|
*
|
|
* @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="user",
|
|
* type="object",
|
|
* @OA\Property(property="id", type="integer", example=1),
|
|
* @OA\Property(property="user_id", type="string", example="john_doe"),
|
|
* @OA\Property(property="name", type="string", example="홍길동"),
|
|
* @OA\Property(property="email", type="string", example="john@example.com"),
|
|
* @OA\Property(property="phone", type="string", example="010-1234-5678", nullable=true),
|
|
* @OA\Property(
|
|
* property="options",
|
|
* type="object",
|
|
* @OA\Property(property="position", type="string", example="개발팀장"),
|
|
* nullable=true
|
|
* )
|
|
* ),
|
|
* @OA\Property(
|
|
* property="tenant",
|
|
* type="object",
|
|
* @OA\Property(property="id", type="integer", example=1),
|
|
* @OA\Property(property="company_name", type="string", example="(주)테크컴퍼니"),
|
|
* @OA\Property(property="business_num", type="string", example="123-45-67890"),
|
|
* @OA\Property(property="tenant_st_code", type="string", example="trial", description="테넌트 상태 (trial: 데모, active: 정식, none: 비활성)"),
|
|
* @OA\Property(
|
|
* property="options",
|
|
* type="object",
|
|
* @OA\Property(property="company_scale", type="string", example="중소기업"),
|
|
* @OA\Property(property="industry", type="string", example="IT/소프트웨어"),
|
|
* nullable=true
|
|
* )
|
|
* ),
|
|
* @OA\Property(
|
|
* property="menus",
|
|
* type="array",
|
|
* description="생성된 테넌트의 기본 메뉴 목록 (9개: 대시보드, 기초정보관리, 제품관리, 거래처관리, BOM관리, 시스템관리, 사용자관리, 권한관리, 부서관리)",
|
|
*
|
|
* @OA\Items(
|
|
* type="object",
|
|
*
|
|
* @OA\Property(property="id", type="integer", example=1, description="메뉴 ID"),
|
|
* @OA\Property(property="parent_id", type="integer", example=null, nullable=true, description="상위 메뉴 ID (최상위 메뉴는 null)"),
|
|
* @OA\Property(property="name", type="string", example="대시보드", description="메뉴명"),
|
|
* @OA\Property(property="url", type="string", example="/dashboard", description="메뉴 URL"),
|
|
* @OA\Property(property="icon", type="string", example="dashboard", description="메뉴 아이콘"),
|
|
* @OA\Property(property="sort_order", type="integer", example=1, description="정렬 순서"),
|
|
* @OA\Property(property="is_external", type="integer", example=0, description="외부 링크 여부 (0: 내부, 1: 외부)"),
|
|
* @OA\Property(property="external_url", type="string", example=null, nullable=true, description="외부 링크 URL")
|
|
* )
|
|
* )
|
|
* )
|
|
* )
|
|
* ),
|
|
*
|
|
* @OA\Response(
|
|
* response=422,
|
|
* description="유효성 검증 실패",
|
|
*
|
|
* @OA\JsonContent(
|
|
*
|
|
* @OA\Property(property="success", type="boolean", example=false),
|
|
* @OA\Property(property="message", type="string", example="유효성 검증에 실패했습니다"),
|
|
* @OA\Property(
|
|
* property="errors",
|
|
* type="object",
|
|
* @OA\Property(
|
|
* property="user_id",
|
|
* type="array",
|
|
*
|
|
* @OA\Items(type="string", example="이미 사용 중인 아이디입니다")
|
|
* ),
|
|
*
|
|
* @OA\Property(
|
|
* property="business_num",
|
|
* type="array",
|
|
*
|
|
* @OA\Items(type="string", example="사업자등록번호 형식이 올바르지 않습니다 (000-00-00000)")
|
|
* )
|
|
* )
|
|
* )
|
|
* ),
|
|
*
|
|
* @OA\Response(
|
|
* response=500,
|
|
* description="서버 오류",
|
|
*
|
|
* @OA\JsonContent(
|
|
*
|
|
* @OA\Property(property="success", type="boolean", example=false),
|
|
* @OA\Property(property="message", type="string", example="회원가입 처리 중 오류가 발생했습니다")
|
|
* )
|
|
* )
|
|
* )
|
|
*/
|
|
class RegisterApi {}
|