feat: Phase 4-1 테넌트 관리 백엔드 구현
- TenantService 생성 (CRUD, 통계, 복원/영구삭제) - API Controller 구현 (HTMX 요청 감지, HTML/JSON 이중 응답) - FormRequest 검증 (StoreTenantRequest, UpdateTenantRequest) - Tenant 모델 확장 (17개 필드, 관계 설정, accessor) - Department, Menu, Role 모델 복사 (admin → mng) - Web Controller 수정 (index/create/edit 화면) - MIGRATION_PLAN.md 작성 (HTMX + API 아키텍처)
This commit is contained in:
95
app/Http/Requests/StoreTenantRequest.php
Normal file
95
app/Http/Requests/StoreTenantRequest.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreTenantRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* 인증 확인
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* 유효성 검증 규칙
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
// 기본 정보 (필수)
|
||||
'company_name' => ['required', 'string', 'max:100'],
|
||||
'code' => ['required', 'string', 'max:50', 'unique:tenants,code'],
|
||||
'email' => ['nullable', 'email', 'max:100'],
|
||||
'phone' => ['nullable', 'string', 'max:20'],
|
||||
|
||||
// 회사 정보
|
||||
'business_num' => ['nullable', 'string', 'max:20'],
|
||||
'corp_reg_no' => ['nullable', 'string', 'max:20'],
|
||||
'ceo_name' => ['nullable', 'string', 'max:50'],
|
||||
'address' => ['nullable', 'string', 'max:255'],
|
||||
'homepage' => ['nullable', 'url', 'max:255'],
|
||||
'fax' => ['nullable', 'string', 'max:20'],
|
||||
|
||||
// 구독 정보
|
||||
'tenant_st_code' => ['required', 'string', 'in:trial,active,suspended,expired'],
|
||||
'billing_tp_code' => ['nullable', 'string', 'in:monthly,yearly,free'],
|
||||
'max_users' => ['nullable', 'integer', 'min:1'],
|
||||
'trial_ends_at' => ['nullable', 'date'],
|
||||
'expires_at' => ['nullable', 'date'],
|
||||
'last_paid_at' => ['nullable', 'date'],
|
||||
|
||||
// 관리 메모
|
||||
'admin_memo' => ['nullable', 'string'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 유효성 검증 메시지
|
||||
*/
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'company_name.required' => '회사명은 필수입니다.',
|
||||
'company_name.max' => '회사명은 최대 100자까지 입력 가능합니다.',
|
||||
'code.required' => '테넌트 코드는 필수입니다.',
|
||||
'code.unique' => '이미 사용 중인 테넌트 코드입니다.',
|
||||
'email.email' => '올바른 이메일 형식이 아닙니다.',
|
||||
'homepage.url' => '올바른 URL 형식이 아닙니다.',
|
||||
'tenant_st_code.required' => '상태는 필수입니다.',
|
||||
'tenant_st_code.in' => '올바른 상태를 선택해주세요.',
|
||||
'billing_tp_code.in' => '올바른 결제 유형을 선택해주세요.',
|
||||
'max_users.integer' => '최대 사용자 수는 숫자여야 합니다.',
|
||||
'max_users.min' => '최대 사용자 수는 최소 1명 이상이어야 합니다.',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 필드명 한글화
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'company_name' => '회사명',
|
||||
'code' => '테넌트 코드',
|
||||
'email' => '이메일',
|
||||
'phone' => '전화번호',
|
||||
'business_num' => '사업자등록번호',
|
||||
'corp_reg_no' => '법인등록번호',
|
||||
'ceo_name' => '대표자명',
|
||||
'address' => '주소',
|
||||
'homepage' => '홈페이지',
|
||||
'fax' => '팩스',
|
||||
'tenant_st_code' => '상태',
|
||||
'billing_tp_code' => '결제 유형',
|
||||
'max_users' => '최대 사용자 수',
|
||||
'trial_ends_at' => '트라이얼 종료일',
|
||||
'expires_at' => '구독 만료일',
|
||||
'last_paid_at' => '마지막 결제일',
|
||||
'admin_memo' => '관리자 메모',
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user