LCOV - code coverage report
Current view: top level - lib/services - club_service.dart Coverage Total Hit
Test: lcov.info Lines: 78.6 % 103 81
Test Date: 2025-08-12 03:21:51 Functions: - 0 0

            Line data    Source code
       1              : import 'dart:convert';
       2              : import 'package:flutter/foundation.dart';
       3              : import 'package:shared_preferences/shared_preferences.dart';
       4              : 
       5              : import '../config/api_config.dart';
       6              : import '../models/club_model.dart';
       7              : import './api_service.dart';
       8              : import './event_bus.dart';
       9              : 
      10              : class ClubService with ChangeNotifier {
      11              :   List<Club> _clubs = [];
      12              :   Club? _currentClub;
      13              :   bool _isLoading = false;
      14              :   String? _token;
      15              :   ApiService _apiService;
      16              :   
      17              :   // 기본 생성자
      18            0 :   ClubService() : _apiService = ApiService();
      19              :   
      20              :   // 테스트용 생성자
      21            2 :   ClubService.forTest(this._apiService);
      22              : 
      23            6 :   List<Club> get clubs => [..._clubs];
      24            4 :   Club? get currentClub => _currentClub;
      25            0 :   bool get isLoading => _isLoading;
      26              : 
      27              :   // 초기화 함수
      28            2 :   Future<void> initialize(String token) async {
      29            2 :     _token = token;
      30            4 :     _apiService.setToken(token);
      31              :     
      32              :     // 저장된 현재 클럽 ID 가져오기
      33            2 :     final prefs = await SharedPreferences.getInstance();
      34            2 :     final clubId = prefs.getString(ApiConfig.clubIdKey);
      35              :     
      36              :     if (clubId != null) {
      37            2 :       await fetchClubById(clubId);
      38              :     }
      39              :   }
      40              : 
      41              :   // 사용자의 모든 클럽 가져오기
      42            2 :   Future<void> fetchUserClubs() async {
      43            2 :     if (_token == null) return;
      44              :     
      45            2 :     _isLoading = true;
      46            2 :     notifyListeners();
      47              :     
      48              :     try {
      49            4 :       final data = await _apiService.post('${ApiConfig.clubs}/user');
      50              : 
      51              :       final List<dynamic> clubsData = data;
      52              :       
      53           10 :       _clubs = clubsData.map((clubData) => Club.fromJson(clubData)).toList();
      54              :       
      55            2 :       _isLoading = false;
      56            2 :       notifyListeners();
      57              :     } catch (e) {
      58            0 :       _isLoading = false;
      59            0 :       notifyListeners();
      60            0 :       throw Exception('클럽 목록을 불러오는데 실패했습니다: $e');
      61              :     }
      62              :   }
      63              : 
      64              :   // ID로 클럽 정보 가져오기
      65            2 :   Future<void> fetchClubById(String clubId) async {
      66            2 :     if (_token == null) return;
      67              :     
      68            2 :     _isLoading = true;
      69            2 :     notifyListeners();
      70              :     
      71              :     try {
      72            4 :       final data = await _apiService.post(
      73              :         '${ApiConfig.clubs}',
      74            2 :         data: {'clubId': clubId},
      75              :       );
      76              : 
      77              :       // 백엔드에서는 club 키로 감싸지 않고 직접 클럽 객체를 반환합니다
      78            4 :       _currentClub = Club.fromJson(data);
      79              :       
      80              :       // 현재 클럽 ID 저장
      81            2 :       final prefs = await SharedPreferences.getInstance();
      82            2 :       await prefs.setString(ApiConfig.clubIdKey, clubId);
      83              :       
      84            2 :       _isLoading = false;
      85            2 :       notifyListeners();
      86              :     } catch (e) {
      87            1 :       _isLoading = false;
      88            1 :       notifyListeners();
      89            2 :       throw Exception('클럽 정보를 불러오는데 실패했습니다: $e');
      90              :     }
      91              :   }
      92              : 
      93              :   // 현재 클럽 설정
      94            2 :   Future<void> setCurrentClub(String clubId) async {
      95            2 :     await fetchClubById(clubId);
      96              :   }
      97              :   
      98              :   // 백엔드에 클럽 선택 요청 (세션에 clubId 저장)
      99            2 :   Future<void> selectClub(String clubId) async {
     100            2 :     if (_token == null) return;
     101              :     
     102            2 :     _isLoading = true;
     103            2 :     notifyListeners();
     104              :     
     105              :     try {
     106            4 :       await _apiService.post(
     107              :         '${ApiConfig.clubs}/select-club',
     108            2 :         data: {'clubId': clubId},
     109              :       );
     110              : 
     111              :       // 클럽 선택 성공 후 클럽 정보 가져오기
     112            2 :       await fetchClubById(clubId);
     113              :       
     114              :       // 클럽 ID를 로컬에 저장
     115            2 :       final prefs = await SharedPreferences.getInstance();
     116            2 :       await prefs.setString(ApiConfig.clubIdKey, clubId);
     117              :       
     118              :       // 클럽 데이터도 함께 저장
     119            2 :       if (_currentClub != null) {
     120            8 :         await prefs.setString('${ApiConfig.clubIdKey}_data', jsonEncode(_currentClub!.toJson()));
     121              :       }
     122              :       
     123              :       // 클럽 변경 이벤트 발생 - 다른 서비스들에게 알림
     124            6 :       EventBus().fire(ClubChangedEvent(clubId));
     125              :       
     126            2 :       _isLoading = false;
     127            2 :       notifyListeners();
     128              :     } catch (e) {
     129            0 :       _isLoading = false;
     130            0 :       notifyListeners();
     131            0 :       throw Exception('클럽 선택에 실패했습니다: $e');
     132              :     }
     133              :   }
     134              : 
     135              :   // 클럽 생성
     136            2 :   Future<Club> createClub(Club club) async {
     137            2 :     if (_token == null) {
     138            0 :       throw Exception('인증이 필요합니다');
     139              :     }
     140              :     
     141            2 :     _isLoading = true;
     142            2 :     notifyListeners();
     143              :     
     144              :     try {
     145            4 :       final data = await _apiService.post(
     146              :         '${ApiConfig.clubs}',
     147            2 :         data: club.toJson(),
     148              :       );
     149              : 
     150            4 :       final newClub = Club.fromJson(data['club']);
     151              :       
     152            4 :       _clubs.add(newClub);
     153            2 :       _currentClub = newClub;
     154              :       
     155              :       // 현재 클럽 ID 저장
     156            2 :       final prefs = await SharedPreferences.getInstance();
     157            4 :       await prefs.setString(ApiConfig.clubIdKey, newClub.id);
     158              :       
     159            2 :       _isLoading = false;
     160            2 :       notifyListeners();
     161              :       
     162              :       return newClub;
     163              :     } catch (e) {
     164            1 :       _isLoading = false;
     165            1 :       notifyListeners();
     166            2 :       throw Exception('클럽 생성에 실패했습니다: $e');
     167              :     }
     168              :   }
     169              : 
     170              :   // 클럽 정보 업데이트
     171            2 :   Future<Club> updateClub(String clubId, Map<String, dynamic> updates) async {
     172            2 :     if (_token == null) {
     173            0 :       throw Exception('인증이 필요합니다');
     174              :     }
     175              :     
     176            2 :     _isLoading = true;
     177            2 :     notifyListeners();
     178              :     
     179              :     try {
     180            4 :       final data = await _apiService.put(
     181              :         ApiConfig.clubs,
     182            2 :         data: {
     183            2 :           'clubId': clubId,
     184            2 :           ...updates,
     185              :         },
     186              :       );
     187              : 
     188              :       // 백엔드 응답 처리: 직접 클럽 객체가 반환되거나 {club: {...}} 형태로 반환될 수 있음
     189            4 :       final updatedClub = data is Map && data.containsKey('club') 
     190            4 :           ? Club.fromJson(data['club']) 
     191            1 :           : Club.fromJson(data);
     192              :       
     193              :       // 클럽 목록 업데이트
     194           10 :       final index = _clubs.indexWhere((club) => club.id == clubId);
     195            2 :       if (index >= 0) {
     196            4 :         _clubs[index] = updatedClub;
     197              :       }
     198              :       
     199              :       // 현재 클럽이 업데이트된 클럽인 경우 업데이트
     200            6 :       if (_currentClub?.id == clubId) {
     201            2 :         _currentClub = updatedClub;
     202              :       }
     203              :       
     204            2 :       _isLoading = false;
     205            2 :       notifyListeners();
     206              :       
     207              :       return updatedClub;
     208              :     } catch (e) {
     209            0 :       _isLoading = false;
     210            0 :       notifyListeners();
     211            0 :       throw Exception('클럽 정보 업데이트에 실패했습니다: $e');
     212              :     }
     213              :   }
     214              :   
     215              :   // 클럽 정보 가져오기 (ID로)
     216            0 :   Future<Club> fetchClub(String clubId) async {
     217            0 :     if (_token == null) {
     218            0 :       throw Exception('인증이 필요합니다');
     219              :     }
     220              :     
     221              :     try {
     222              :       // 현재 클럽이 요청한 클럽과 동일한 경우 캐시된 데이터 반환
     223            0 :       if (_currentClub != null && _currentClub!.id == clubId) {
     224            0 :         return _currentClub!;
     225              :       }
     226              :       
     227            0 :       final data = await _apiService.post(
     228              :         '${ApiConfig.clubs}',
     229            0 :         data: {'clubId': clubId},
     230              :       );
     231              : 
     232            0 :       final club = Club.fromJson(data);
     233              :       return club;
     234              :     } catch (e) {
     235            0 :       throw Exception('클럽 정보를 불러오는데 실패했습니다: $e');
     236              :     }
     237              :   }
     238              : }
        

Generated by: LCOV version 2.3.1-1