feat:동기화 페이지에 글로벌/테넌트 필터 추가

- 환경 탭 앞에 글로벌/테넌트 토글 버튼 추가
- 글로벌: tenant_id가 NULL인 코드/카테고리만 표시
- 테넌트: 현재 선택된 테넌트의 데이터만 표시
- Push/Pull API에 type 파라미터 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-29 01:06:33 +09:00
parent 50f9fa2fd3
commit 1e70d2edbf
4 changed files with 198 additions and 119 deletions

View File

@@ -49,9 +49,10 @@ public function index(Request $request): View|Response
$environments = $this->getEnvironments();
$selectedEnv = $request->get('env', 'dev');
$selectedType = $request->get('type', 'global'); // global or tenant
// 로컬 코드 조회
$localCodes = $this->getCodeList();
// 로컬 코드 조회 (타입 필터 적용)
$localCodes = $this->getCodeList($selectedType);
// 원격 코드 조회
$remoteCodes = [];
@@ -59,7 +60,7 @@ public function index(Request $request): View|Response
if (! empty($environments[$selectedEnv]['url'])) {
try {
$remoteCodes = $this->fetchRemoteCodes($environments[$selectedEnv]);
$remoteCodes = $this->fetchRemoteCodes($environments[$selectedEnv], $selectedType);
} catch (\Exception $e) {
$remoteError = $e->getMessage();
}
@@ -71,6 +72,7 @@ public function index(Request $request): View|Response
return view('common-codes.sync', [
'environments' => $environments,
'selectedEnv' => $selectedEnv,
'selectedType' => $selectedType,
'localCodes' => $localCodes,
'remoteCodes' => $remoteCodes,
'remoteError' => $remoteError,
@@ -91,7 +93,8 @@ public function export(Request $request): JsonResponse
return response()->json(['error' => 'Unauthorized'], 401);
}
$codes = $this->getCodeList();
$type = $request->get('type', 'all'); // global, tenant, or all
$codes = $this->getCodeList($type);
return response()->json([
'success' => true,
@@ -168,6 +171,7 @@ public function push(Request $request): JsonResponse
{
$validated = $request->validate([
'env' => 'required|string|in:dev,prod',
'type' => 'required|string|in:global,tenant',
'code_keys' => 'required|array|min:1',
'code_keys.*' => 'string',
]);
@@ -179,8 +183,8 @@ public function push(Request $request): JsonResponse
return response()->json(['error' => '환경 설정이 없습니다.'], 400);
}
// 선택된 코드 조회
$localCodes = $this->getCodeList();
// 선택된 코드 조회 (타입 필터 적용)
$localCodes = $this->getCodeList($validated['type']);
$selectedCodes = array_filter($localCodes, function ($code) use ($validated) {
$key = $this->makeCodeKey($code);
return in_array($key, $validated['code_keys']);
@@ -223,6 +227,7 @@ public function pull(Request $request): JsonResponse
{
$validated = $request->validate([
'env' => 'required|string|in:dev,prod',
'type' => 'required|string|in:global,tenant',
'code_keys' => 'required|array|min:1',
'code_keys.*' => 'string',
]);
@@ -234,9 +239,9 @@ public function pull(Request $request): JsonResponse
return response()->json(['error' => '환경 설정이 없습니다.'], 400);
}
// 원격 코드 조회
// 원격 코드 조회 (타입 필터 적용)
try {
$remoteCodes = $this->fetchRemoteCodes($env);
$remoteCodes = $this->fetchRemoteCodes($env, $validated['type']);
} catch (\Exception $e) {
return response()->json(['error' => $e->getMessage()], 500);
}
@@ -289,52 +294,56 @@ public function pull(Request $request): JsonResponse
}
/**
* 코드 목록 조회 (글로벌 + 테넌트)
* 코드 목록 조회
* @param string $type 'global', 'tenant', or 'all'
*/
private function getCodeList(): array
private function getCodeList(string $type = 'all'): array
{
$tenantId = $this->getTenantId();
// 글로벌 코드 (tenant_id IS NULL)
$globalCodes = CommonCode::query()
->whereNull('tenant_id')
->orderBy('code_group')
->orderBy('sort_order')
->get();
// 테넌트 코드
$tenantCodes = CommonCode::query()
->where('tenant_id', $tenantId)
->orderBy('code_group')
->orderBy('sort_order')
->get();
$codes = [];
foreach ($globalCodes as $code) {
$codes[] = [
'tenant_id' => null,
'code_group' => $code->code_group,
'code' => $code->code,
'name' => $code->name,
'sort_order' => $code->sort_order,
'attributes' => $code->attributes,
'is_active' => $code->is_active,
'is_global' => true,
];
// 글로벌 코드 (tenant_id IS NULL)
if ($type === 'global' || $type === 'all') {
$globalCodes = CommonCode::query()
->whereNull('tenant_id')
->orderBy('code_group')
->orderBy('sort_order')
->get();
foreach ($globalCodes as $code) {
$codes[] = [
'tenant_id' => null,
'code_group' => $code->code_group,
'code' => $code->code,
'name' => $code->name,
'sort_order' => $code->sort_order,
'attributes' => $code->attributes,
'is_active' => $code->is_active,
'is_global' => true,
];
}
}
foreach ($tenantCodes as $code) {
$codes[] = [
'tenant_id' => $code->tenant_id,
'code_group' => $code->code_group,
'code' => $code->code,
'name' => $code->name,
'sort_order' => $code->sort_order,
'attributes' => $code->attributes,
'is_active' => $code->is_active,
'is_global' => false,
];
// 테넌트 코드
if ($type === 'tenant' || $type === 'all') {
$tenantCodes = CommonCode::query()
->where('tenant_id', $tenantId)
->orderBy('code_group')
->orderBy('sort_order')
->get();
foreach ($tenantCodes as $code) {
$codes[] = [
'tenant_id' => $code->tenant_id,
'code_group' => $code->code_group,
'code' => $code->code,
'name' => $code->name,
'sort_order' => $code->sort_order,
'attributes' => $code->attributes,
'is_active' => $code->is_active,
'is_global' => false,
];
}
}
return $codes;
@@ -343,12 +352,14 @@ private function getCodeList(): array
/**
* 원격 코드 조회
*/
private function fetchRemoteCodes(array $env): array
private function fetchRemoteCodes(array $env, string $type = 'all'): array
{
$response = Http::withHeaders([
'X-Menu-Sync-Key' => $env['api_key'],
'Accept' => 'application/json',
])->timeout(10)->get(rtrim($env['url'], '/') . '/common-code-sync/export');
])->timeout(10)->get(rtrim($env['url'], '/') . '/common-code-sync/export', [
'type' => $type,
]);
if (! $response->successful()) {
throw new \Exception('API 오류: HTTP ' . $response->status());