diff --git a/app/Http/Controllers/Api/Admin/UserController.php b/app/Http/Controllers/Api/Admin/UserController.php index 2a27b70d..020680f4 100644 --- a/app/Http/Controllers/Api/Admin/UserController.php +++ b/app/Http/Controllers/Api/Admin/UserController.php @@ -19,18 +19,18 @@ public function __construct( /** * 사용자 목록 조회 */ - public function index(Request $request): JsonResponse + public function index(Request $request): JsonResponse|\Illuminate\Http\Response { $users = $this->userService->getUsers( $request->all(), $request->integer('per_page', 10) ); - // HTMX 요청인 경우 HTML 반환 + // HTMX 요청인 경우 HTML 직접 반환 if ($request->header('HX-Request')) { $html = view('users.partials.table', compact('users'))->render(); - return response()->json(['html' => $html]); + return response($html)->header('Content-Type', 'text/html'); } // 일반 API 요청인 경우 JSON 반환 diff --git a/app/Http/Controllers/DevTools/ApiExplorerController.php b/app/Http/Controllers/DevTools/ApiExplorerController.php index 1026d43a..d3b9286d 100644 --- a/app/Http/Controllers/DevTools/ApiExplorerController.php +++ b/app/Http/Controllers/DevTools/ApiExplorerController.php @@ -447,31 +447,50 @@ public function setDefaultEnvironment(int $id): JsonResponse /** * 현재 테넌트의 사용자 목록 + * 시스템 헤더에서 선택한 테넌트 기준 (session('selected_tenant_id')) + * 관리자는 자신이 속하지 않은 테넌트의 사용자도 볼 수 있어야 함 */ public function users(): JsonResponse { - // user_tenants 피벗 테이블에서 기본 테넌트 조회 - $defaultTenant = \DB::table('user_tenants') - ->where('user_id', auth()->id()) - ->where('is_default', true) - ->first(); + // 세션에서 직접 테넌트 ID 조회 (관리자가 선택한 테넌트) + $selectedTenantId = session('selected_tenant_id'); - if (!$defaultTenant) { + if (!$selectedTenantId) { + // 테넌트가 선택되지 않은 경우 로그인 사용자의 기본 테넌트 사용 + $currentTenant = auth()->user()->tenants() + ->where('is_default', true) + ->first() ?? auth()->user()->tenants()->first(); + + if (!$currentTenant) { + return response()->json([]); + } + + $selectedTenantId = $currentTenant->id; + } + + // Tenant 모델에서 직접 조회 (사용자의 테넌트 관계와 무관하게) + $tenant = \App\Models\Tenants\Tenant::find($selectedTenantId); + + if (!$tenant) { return response()->json([]); } - $tenantId = $defaultTenant->tenant_id; - // 해당 테넌트에 속한 사용자 목록 조회 - $users = \App\Models\User::whereHas('tenants', function ($query) use ($tenantId) { - $query->where('tenant_id', $tenantId); + $users = \App\Models\User::whereHas('tenants', function ($query) use ($selectedTenantId) { + $query->where('tenant_id', $selectedTenantId); }) ->select(['id', 'name', 'email']) ->orderBy('name') ->limit(100) ->get(); - return response()->json($users); + return response()->json([ + 'tenant' => [ + 'id' => $tenant->id, + 'name' => $tenant->company_name, + ], + 'users' => $users, + ]); } /** diff --git a/app/Http/Controllers/DevTools/FlowTesterController.php b/app/Http/Controllers/DevTools/FlowTesterController.php index 0f5ed537..2042a752 100644 --- a/app/Http/Controllers/DevTools/FlowTesterController.php +++ b/app/Http/Controllers/DevTools/FlowTesterController.php @@ -21,7 +21,7 @@ class FlowTesterController extends Controller */ public function index(): View { - $flows = AdminApiFlow::with(['runs' => fn ($q) => $q->latest()->limit(1)]) + $flows = AdminApiFlow::with('latestRun') ->orderByDesc('created_at') ->paginate(20); diff --git a/app/Models/Admin/AdminApiFlow.php b/app/Models/Admin/AdminApiFlow.php index 6aaf801d..05249a90 100644 --- a/app/Models/Admin/AdminApiFlow.php +++ b/app/Models/Admin/AdminApiFlow.php @@ -6,6 +6,7 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\Relations\HasOne; /** * API Flow Tester - 플로우 정의 모델 @@ -83,9 +84,22 @@ public function updater(): BelongsTo } /** - * 최근 실행 결과 조회 + * 관계: 최신 실행 기록 (서브쿼리 방식 - window function 회피) */ - public function latestRun(): ?AdminApiFlowRun + public function latestRun(): HasOne + { + return $this->hasOne(AdminApiFlowRun::class, 'flow_id') + ->whereIn('id', function ($query) { + $query->selectRaw('MAX(id)') + ->from('admin_api_flow_runs') + ->groupBy('flow_id'); + }); + } + + /** + * 최근 실행 결과 조회 (단일 조회용) + */ + public function getLatestRunResult(): ?AdminApiFlowRun { return $this->runs()->latest('created_at')->first(); } diff --git a/resources/views/api-logs/index.blade.php b/resources/views/api-logs/index.blade.php index 19c4b90a..c434d19b 100644 --- a/resources/views/api-logs/index.blade.php +++ b/resources/views/api-logs/index.blade.php @@ -7,6 +7,13 @@

API 요청 로그

+ +
@csrf
- -
- -
- - -
-
- - -
- - - @if($savedToken ?? false) -

✅ 세션에 저장된 토큰이 자동으로 입력되었습니다.

- @endif -
- - - - - + + @include('dev-tools.partials.auth-modal')
@@ -402,6 +320,9 @@ class="w-full border rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-blue-5 @endsection @push('scripts') +{{-- 공유 인증 스크립트 --}} +@include('dev-tools.partials.auth-scripts') + @endpush diff --git a/resources/views/dev-tools/partials/auth-modal.blade.php b/resources/views/dev-tools/partials/auth-modal.blade.php new file mode 100644 index 00000000..20d2f8d1 --- /dev/null +++ b/resources/views/dev-tools/partials/auth-modal.blade.php @@ -0,0 +1,89 @@ +{{-- + Dev Tools 공유 인증 모달 + 사용법: @include('dev-tools.partials.auth-modal') +--}} + + + diff --git a/resources/views/dev-tools/partials/auth-scripts.blade.php b/resources/views/dev-tools/partials/auth-scripts.blade.php new file mode 100644 index 00000000..d0452664 --- /dev/null +++ b/resources/views/dev-tools/partials/auth-scripts.blade.php @@ -0,0 +1,389 @@ +{{-- + Dev Tools 공유 인증 스크립트 + 사용법: @include('dev-tools.partials.auth-scripts') + + 제공 API: + - DevToolsAuth.openModal() : 인증 모달 열기 + - DevToolsAuth.closeModal() : 인증 모달 닫기 + - DevToolsAuth.getToken() : 현재 토큰 반환 + - DevToolsAuth.getUserId() : 현재 사용자 ID 반환 + - DevToolsAuth.isAuthenticated() : 인증 여부 반환 + - DevToolsAuth.getAuthPayload() : API 요청용 인증 페이로드 반환 + - DevToolsAuth.onAuthChange(callback) : 인증 상태 변경 콜백 등록 +--}} + + diff --git a/resources/views/users/index.blade.php b/resources/views/users/index.blade.php index 1710f741..4e66daef 100644 --- a/resources/views/users/index.blade.php +++ b/resources/views/users/index.blade.php @@ -61,13 +61,10 @@ class="bg-white rounded-lg shadow-sm overflow-hidden"> htmx.trigger('#user-table', 'filterSubmit'); }); - // HTMX 응답 처리 + // HTMX 응답 후 필요한 초기화 처리 document.body.addEventListener('htmx:afterSwap', function(event) { if (event.detail.target.id === 'user-table') { - const response = JSON.parse(event.detail.xhr.response); - if (response.html) { - event.detail.target.innerHTML = response.html; - } + // 필요시 테이블 로드 후 초기화 작업 } }); diff --git a/resources/views/users/partials/table.blade.php b/resources/views/users/partials/table.blade.php index e097942d..ea5a90cc 100644 --- a/resources/views/users/partials/table.blade.php +++ b/resources/views/users/partials/table.blade.php @@ -99,13 +99,13 @@ @if($user->deleted_at) @if($canModify) - @endif @if(auth()->user()?->is_super_admin) - @@ -115,7 +115,7 @@ class="text-red-600 hover:text-red-900"> @endif @elseif($canModify) - @else