100, 'max_orders' => 50, 'max_productions' => 30, 'max_users' => 5, 'max_storage_gb' => 1, 'max_ai_tokens' => 100000, ]; /** * 사용 가능한 프리셋 목록 */ private const AVAILABLE_PRESETS = [ 'manufacturing', // 제조업 기본 // 향후 추가 예정: // 'blinds', // 블라인드/스크린 // 'construction', // 시공/건설 // 'distribution', // 유통/도소매 ]; /** * 파트너 데모 테넌트 생성 (Tier 2) * 파트너 승인 시 호출 */ public function createPartnerDemo(int $partnerId, string $preset = 'manufacturing'): Tenant { $tenant = new Tenant; $tenant->forceFill([ 'company_name' => '파트너데모_'.$partnerId, 'code' => 'DEMO_P_'.$partnerId, 'email' => 'demo-partner-'.$partnerId.'@codebridge-x.com', 'tenant_st_code' => 'active', 'tenant_type' => Tenant::TYPE_DEMO_PARTNER, 'demo_source_partner_id' => $partnerId, 'options' => [ Tenant::OPTION_DEMO_PRESET => $preset, Tenant::OPTION_DEMO_LIMITS => self::DEFAULT_DEMO_LIMITS, ], ]); $tenant->save(); Log::info('파트너 데모 테넌트 생성', [ 'tenant_id' => $tenant->id, 'partner_id' => $partnerId, 'preset' => $preset, ]); return $tenant; } /** * 고객 체험 테넌트 생성 (Tier 3) * 파트너가 요청 → 본사 승인 후 호출 */ public function createTrialDemo( int $partnerId, string $companyName, string $email, int $durationDays = 30, string $preset = 'manufacturing' ): Tenant { $tenant = new Tenant; $tenant->forceFill([ 'company_name' => $companyName, 'code' => 'DEMO_T_'.strtoupper(substr(md5(uniqid()), 0, 8)), 'email' => $email, 'tenant_st_code' => 'trial', 'tenant_type' => Tenant::TYPE_DEMO_TRIAL, 'demo_expires_at' => now()->addDays($durationDays), 'demo_source_partner_id' => $partnerId, 'options' => [ Tenant::OPTION_DEMO_PRESET => $preset, Tenant::OPTION_DEMO_LIMITS => self::DEFAULT_DEMO_LIMITS, ], ]); $tenant->save(); Log::info('고객 체험 테넌트 생성', [ 'tenant_id' => $tenant->id, 'partner_id' => $partnerId, 'company_name' => $companyName, 'expires_at' => $tenant->demo_expires_at->toDateString(), ]); return $tenant; } /** * 체험 기간 연장 (최대 1회, 30일) */ public function extendTrial(Tenant $tenant, int $days = 30): bool { if (! $tenant->isDemoTrial()) { return false; } // 이미 연장한 이력이 있는지 체크 (options에 기록) if ($tenant->getOption('demo_extended', false)) { return false; } $newExpiry = ($tenant->demo_expires_at ?? now())->addDays($days); $tenant->forceFill(['demo_expires_at' => $newExpiry]); $tenant->setOption('demo_extended', true); $tenant->save(); Log::info('고객 체험 기간 연장', [ 'tenant_id' => $tenant->id, 'new_expires_at' => $newExpiry->toDateString(), ]); return true; } /** * 데모 → 정식 전환 */ public function convertToProduction(Tenant $tenant): void { $tenant->convertToProduction(); Log::info('데모 → 정식 테넌트 전환', [ 'tenant_id' => $tenant->id, 'company_name' => $tenant->company_name, ]); } /** * 사용 가능한 프리셋 목록 */ public function getAvailablePresets(): array { return self::AVAILABLE_PRESETS; } /** * 만료된 체험 테넌트 조회 */ public function getExpiredTrials(): \Illuminate\Database\Eloquent\Collection { return Tenant::withoutGlobalScopes() ->where('tenant_type', Tenant::TYPE_DEMO_TRIAL) ->whereNotNull('demo_expires_at') ->where('demo_expires_at', '<', now()) ->get(); } }