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