find($groupId); } /** * [GET] 옵션 값 목록 * params: active_only?(bool) */ public static function index(int $groupId, array $params = []) { $tenantId = self::tenantId(); if (!$tenantId) { return ['error' => '활성 테넌트가 없습니다.', 'code' => 400]; } $group = self::loadGroup($tenantId, $groupId); if (!$group) { return ['error' => '옵션 그룹을 찾을 수 없습니다.', 'code' => 404]; } $q = TenantOptionValue::where('group_id', $group->id) ->orderBy('sort_order') ->orderBy('value_label'); if (!empty($params['active_only'])) { $q->where('is_active', 1); } $list = $q->get(); return $list; } /** * [POST] 옵션 값 생성 */ public static function store(int $groupId, array $params = []) { $tenantId = self::tenantId(); if (!$tenantId) { return ['error' => '활성 테넌트가 없습니다.', 'code' => 400]; } $group = self::loadGroup($tenantId, $groupId); if (!$group) { return ['error' => '옵션 그룹을 찾을 수 없습니다.', 'code' => 404]; } $v = Validator::make($params, [ 'value_key' => [ 'required','string','max:64','alpha_dash', Rule::unique('tenant_option_values', 'value_key') ->where(fn ($q) => $q->where('group_id', $group->id)), ], 'value_label' => ['required','string','max:100'], 'sort_order' => ['nullable','integer'], 'is_active' => ['nullable','boolean'], ]); if ($v->fails()) { return ['error' => $v->errors()->first(), 'code' => 422]; } $data = $v->validated(); $data['group_id'] = $group->id; $item = TenantOptionValue::create($data); return $item->toArray(); } /** * [GET] 옵션 값 단건 조회 */ public static function show(int $groupId, int $id) { $tenantId = self::tenantId(); if (!$tenantId) { return ['error' => '활성 테넌트가 없습니다.', 'code' => 400]; } $group = self::loadGroup($tenantId, $groupId); if (!$group) { return ['error' => '옵션 그룹을 찾을 수 없습니다.', 'code' => 404]; } $item = TenantOptionValue::where('group_id', $group->id)->find($id); if (!$item) { return ['error' => '옵션 값을 찾을 수 없습니다.', 'code' => 404]; } return $item->toArray(); } /** * [PATCH] 옵션 값 수정 */ public static function update(int $groupId, int $id, array $params = []) { $tenantId = self::tenantId(); if (!$tenantId) { return ['error' => '활성 테넌트가 없습니다.', 'code' => 400]; } $group = self::loadGroup($tenantId, $groupId); if (!$group) { return ['error' => '옵션 그룹을 찾을 수 없습니다.', 'code' => 404]; } $item = TenantOptionValue::where('group_id', $group->id)->find($id); if (!$item) { return ['error' => '옵션 값을 찾을 수 없습니다.', 'code' => 404]; } $v = Validator::make($params, [ 'value_key' => [ 'sometimes','string','max:64','alpha_dash', Rule::unique('tenant_option_values', 'value_key') ->where(fn ($q) => $q->where('group_id', $group->id)) ->ignore($item->id), ], 'value_label' => ['sometimes','string','max:100'], 'sort_order' => ['nullable','integer'], 'is_active' => ['nullable','boolean'], ]); if ($v->fails()) { return ['error' => $v->errors()->first(), 'code' => 422]; } $data = $v->validated(); if (empty($data)) { return ['error' => '수정할 항목이 없습니다.', 'code' => 422]; } $item->fill($data)->save(); return $item->toArray(); } /** * [DELETE] 옵션 값 삭제 * - TODO: 실제 프로필/필드설정에서 value_key 참조 여부 체크가 필요하면 여기서 차단 */ public static function destroy(int $groupId, int $id) { $tenantId = self::tenantId(); if (!$tenantId) { return ['error' => '활성 테넌트가 없습니다.', 'code' => 400]; } $group = self::loadGroup($tenantId, $groupId); if (!$group) { return ['error' => '옵션 그룹을 찾을 수 없습니다.', 'code' => 404]; } $item = TenantOptionValue::where('group_id', $group->id)->find($id); if (!$item) { return ['error' => '옵션 값을 찾을 수 없습니다.', 'code' => 404]; } // TODO: 참조 무결성 검사(필요 시 구현) $item->delete(); return ['deleted' => true]; } /** * [PATCH] 정렬 순서 일괄 변경 * params: items: [{id, sort_order}, ...] */ public static function reorder(int $groupId, array $params = []) { $tenantId = self::tenantId(); if (!$tenantId) { return ['error' => '활성 테넌트가 없습니다.', 'code' => 400]; } $group = self::loadGroup($tenantId, $groupId); if (!$group) { return ['error' => '옵션 그룹을 찾을 수 없습니다.', 'code' => 404]; } $v = Validator::make($params, [ 'items' => ['required','array','min:1'], 'items.*.id' => ['required','integer'], 'items.*.sort_order' => ['required','integer'], ]); if ($v->fails()) { return ['error' => $v->errors()->first(), 'code' => 422]; } $rows = $v->validated()['items']; try { DB::transaction(function () use ($group, $rows) { foreach ($rows as $r) { TenantOptionValue::where('group_id', $group->id) ->where('id', $r['id']) ->update(['sort_order' => (int) $r['sort_order']]); } }); } catch (\Throwable $e) { return ['error' => '정렬 순서 저장 중 오류가 발생했습니다.', 'code' => 500]; } return ['reordered' => true]; } }