find($tenantId); if (! $tenant || ! $tenant->isDemoTenant()) { // 프로덕션 테넌트 → 즉시 통과 (기존 동작 유지) return $next($request); } // 1. 만료 체크 (파트너 데모, 고객 체험) if ($tenant->isDemoExpired()) { return response()->json([ 'success' => false, 'message' => '체험 기간이 만료되었습니다. 정식 계약을 진행해 주세요.', 'error_code' => 'DEMO_EXPIRED', ], 403); } // 2. 쇼케이스 → 읽기 전용 (GET, HEAD, OPTIONS만 허용) if ($tenant->isDemoShowcase() && ! $request->isMethodSafe()) { return response()->json([ 'success' => false, 'message' => '데모 환경에서는 조회만 가능합니다.', 'error_code' => 'DEMO_READ_ONLY', ], 403); } // 3. 읽기전용 옵션이 설정된 데모 테넌트 if ($tenant->isDemoReadOnly() && ! $request->isMethodSafe()) { return response()->json([ 'success' => false, 'message' => '데모 환경에서는 조회만 가능합니다.', 'error_code' => 'DEMO_READ_ONLY', ], 403); } // 4. 차단 기능 체크 (바로빌, 이카운트 등 외부 연동) if ($this->isBlockedRoute($request)) { return response()->json([ 'success' => false, 'message' => '데모 환경에서 사용할 수 없는 기능입니다. 정식 계약 후 이용 가능합니다.', 'error_code' => 'DEMO_FEATURE_BLOCKED', ], 403); } return $next($request); } private function isBlockedRoute(Request $request): bool { $path = $request->path(); foreach (self::BLOCKED_ROUTE_PREFIXES as $prefix) { if (str_starts_with($path, $prefix)) { return true; } } return false; } }