LCOV - code coverage report

Current view: | top level - lib/services - event_service.dart |  |  | Coverage | Total | Hit
Test: | lcov.info |  | Lines: | 65.1 % | 304 | 198
Test Date: | 2025-08-12 03:21:51 |  | Functions: | - | 0 | 0

                Line data    Source code

           1              : import 'package:flutter/foundation.dart';
           2              : import 'package:shared_preferences/shared_preferences.dart';
           3              :
           4              : import '../config/api_config.dart';
           5              : import '../models/event_model.dart';
           6              : import '../models/participant_model.dart';
           7              : import '../models/score_model.dart';
           8              : import '../models/team_model.dart';
           9              : import './api_service.dart';
          10              :
          11              : class EventService with ChangeNotifier {
          12              :   List<Event> _events = [];
          13              :   Event? _currentEvent;
          14              :   List<Participant> _participants = [];
          15              :   List<Score> _scores = [];
          16              :   List<Team> _teams = [];
          17              :   bool _isLoading = false;
          18              :   String? _token;
          19              :   ApiService _apiService;
          20              :   String? _clubId;
          21              :
          22              :   // 기본 생성자
          23            0 :   EventService() : _apiService = ApiService();
          24              :
          25              :   // 테스트용 생성자
          26            3 :   EventService.forTest(this._apiService);
          27              :
          28            9 :   List<Event> get events => [..._events];
          29            0 :   Event? get currentEvent => _currentEvent;
          30            6 :   List<Participant> get participants => [..._participants];
          31            6 :   List<Score> get scores => [..._scores];
          32            3 :   List<Team> get teams => [..._teams];
          33            0 :   bool get isLoading => _isLoading;
          34              :
          35              :   // 초기화 함수
          36            3 :   Future<void> initialize(String token) async {
          37            3 :     _token = token;
          38            6 :     _apiService.setToken(token);
          39              :   }
          40              :
          41              :   // 클럽 ID 설정
          42            3 :   void setClubId(String clubId) {
          43            3 :     _clubId = clubId;
          44            3 :     notifyListeners();
          45              :   }
          46              :
          47              :   // 클럽의 모든 이벤트 가져오기
          48            3 :   Future<void> fetchClubEvents() async {
          49            9 :     print('fetchClubEvents 호출됨: token=$_token');
          50              :
          51            3 :     _isLoading = true;
          52            3 :     notifyListeners();
          53              :
          54              :     try {
          55              :       // 클럽 ID 가져오기
          56            3 :       final prefs = await SharedPreferences.getInstance();
          57            3 :       final clubId = prefs.getString(ApiConfig.clubIdKey);
          58              :
          59              :       if (clubId == null) {
          60            0 :         throw Exception('선택된 클럽이 없습니다');
          61              :       }
          62              :
          63            6 :       final data = await _apiService.post(
          64              :         '${ApiConfig.clubs}/events',
          65            3 :         data: {'clubId': clubId},
          66              :       );
          67              :
          68              :       // 응답 데이터가 리스트 형태로 직접 왔는지 확인
          69            3 :       if (data is List) {
          70              :         final List<dynamic> eventsData = data;
          71            1 :         _events = eventsData
          72            3 :             .map((eventData) => Event.fromJson(eventData))
          73            1 :             .toList();
          74              :       } else {
          75              :         // 응답 데이터가 객체 형태로 왔을 경우 events 키를 통해 접근
          76            2 :         final List<dynamic> eventsData = data['events'] ?? [];
          77            2 :         _events = eventsData
          78            6 :             .map((eventData) => Event.fromJson(eventData))
          79            2 :             .toList();
          80              :       }
          81              :
          82            3 :       _isLoading = false;
          83            3 :       notifyListeners();
          84              :     } catch (e) {
          85            1 :       _isLoading = false;
          86            1 :       notifyListeners();
          87            2 :       throw Exception('이벤트 목록을 불러오는데 실패했습니다: $e');
          88              :     }
          89              :   }
          90              :
          91              :   // ID로 이벤트 정보 가져오기
          92            2 :   Future<Event> fetchEventById(String eventId) async {
          93            4 :     if (_token == null || _clubId == null) {
          94            0 :       throw Exception('인증 또는 클럽 정보가 필요합니다');
          95              :     }
          96              :
          97              :     try {
          98            4 :       final data = await _apiService.post(
          99              :         '${ApiConfig.clubs}/events/detail',
         100            2 :         data: {'eventId': eventId},
         101              :       );
         102              :
         103            4 :       return Event.fromJson(data['event']);
         104              :     } catch (e) {
         105            2 :       throw Exception('이벤트 정보를 불러오는데 실패했습니다: $e');
         106              :     }
         107              :   }
         108              :
         109              :   // 이벤트 생성
         110            2 :   Future<Event> createEvent(Map<String, dynamic> eventData) async {
         111            4 :     if (_token == null || _clubId == null) {
         112            0 :       throw Exception('인증 또는 클럽 정보가 필요합니다');
         113              :     }
         114              :
         115            2 :     _isLoading = true;
         116            2 :     notifyListeners();
         117              :
         118              :     try {
         119            4 :       final data = await _apiService.post(
         120              :         '${ApiConfig.clubs}/events',
         121              :         data: eventData,
         122              :       );
         123              :
         124            4 :       final newEvent = Event.fromJson(data['event']);
         125              :
         126            4 :       _events.add(newEvent);
         127              :
         128            2 :       _isLoading = false;
         129            2 :       notifyListeners();
         130              :
         131              :       return newEvent;
         132              :     } catch (e) {
         133            0 :       _isLoading = false;
         134            0 :       notifyListeners();
         135            0 :       throw Exception('이벤트 생성에 실패했습니다: $e');
         136              :     }
         137              :   }
         138              :
         139              :   // 이벤트 정보 업데이트
         140            3 :   Future<Event> updateEvent(
         141              :     String eventId,
         142              :     Map<String, dynamic> updates,
         143              :   ) async {
         144            6 :     if (_token == null || _clubId == null) {
         145            0 :       throw Exception('인증 또는 클럽 정보가 필요합니다');
         146              :     }
         147              :
         148            3 :     _isLoading = true;
         149            3 :     notifyListeners();
         150              :
         151              :     try {
         152            6 :       final data = await _apiService.put(
         153            3 :         '${ApiConfig.clubs}/events/$eventId',
         154              :         data: updates,
         155              :       );
         156              :
         157            6 :       final updatedEvent = Event.fromJson(data['event']);
         158              :
         159              :       // 이벤트 목록 업데이트
         160            9 :       final index = _events.indexWhere((event) => event.id == eventId);
         161            3 :       if (index >= 0) {
         162            2 :         _events[index] = updatedEvent;
         163              :       }
         164              :
         165            3 :       _isLoading = false;
         166            3 :       notifyListeners();
         167              :
         168              :       return updatedEvent;
         169              :     } catch (e) {
         170            0 :       _isLoading = false;
         171            0 :       notifyListeners();
         172            0 :       throw Exception('이벤트 정보 업데이트에 실패했습니다: $e');
         173              :     }
         174              :   }
         175              :
         176              :   // 이벤트 삭제
         177            3 :   Future<bool> deleteEvent(String eventId) async {
         178            6 :     if (_token == null || _clubId == null) {
         179            0 :       throw Exception('인증 또는 클럽 정보가 필요합니다');
         180              :     }
         181              :
         182            3 :     _isLoading = true;
         183            3 :     notifyListeners();
         184              :
         185              :     try {
         186            9 :       await _apiService.delete('${ApiConfig.clubs}/events/$eventId');
         187              :
         188              :       // 이벤트 목록에서 삭제
         189            9 :       _events.removeWhere((event) => event.id == eventId);
         190              :
         191            3 :       _isLoading = false;
         192            3 :       notifyListeners();
         193              :
         194              :       return true;
         195              :     } catch (e) {
         196            0 :       _isLoading = false;
         197            0 :       notifyListeners();
         198            0 :       throw Exception('이벤트 삭제에 실패했습니다: $e');
         199              :     }
         200              :   }
         201              :
         202              :   // 참가자 관리 기능
         203              :   // 이벤트 참가자 목록 가져오기
         204            2 :   Future<List<Participant>> fetchEventParticipants(String eventId) async {
         205            4 :     if (_token == null || _clubId == null) {
         206            0 :       throw Exception('인증 또는 클럽 정보가 필요합니다');
         207              :     }
         208              :
         209            2 :     _isLoading = true;
         210            2 :     notifyListeners();
         211              :
         212              :     try {
         213            4 :       final data = await _apiService.post(
         214              :         '${ApiConfig.clubs}/events/participants',
         215            2 :         data: {'eventId': eventId},
         216              :       );
         217              :
         218            2 :       final List<dynamic> participantsData = data['participants'] ?? [];
         219            2 :       _participants = participantsData
         220            6 :           .map((participantData) => Participant.fromJson(participantData))
         221            2 :           .toList();
         222              :
         223            2 :       _isLoading = false;
         224            2 :       notifyListeners();
         225              :
         226            2 :       return _participants;
         227              :     } catch (e) {
         228            0 :       _isLoading = false;
         229            0 :       notifyListeners();
         230            0 :       throw Exception('참가자 목록을 불러오는데 실패했습니다: $e');
         231              :     }
         232              :   }
         233              :
         234              :   // 참가자 추가
         235            2 :   Future<Participant> addParticipant(
         236              :     String eventId,
         237              :     Map<String, dynamic> participantData,
         238              :   ) async {
         239            4 :     if (_token == null || _clubId == null) {
         240            0 :       throw Exception('인증 또는 클럽 정보가 필요합니다');
         241              :     }
         242              :
         243            2 :     _isLoading = true;
         244            2 :     notifyListeners();
         245              :
         246              :     try {
         247            4 :       final data = await _apiService.post(
         248            2 :         '${ApiConfig.clubs}/events/$eventId/participants',
         249              :         data: participantData,
         250              :       );
         251              :
         252            4 :       final newParticipant = Participant.fromJson(data['participant']);
         253              :
         254            4 :       _participants.add(newParticipant);
         255              :
         256            2 :       _isLoading = false;
         257            2 :       notifyListeners();
         258              :
         259              :       return newParticipant;
         260              :     } catch (e) {
         261            0 :       _isLoading = false;
         262            0 :       notifyListeners();
         263            0 :       throw Exception('참가자 추가에 실패했습니다: $e');
         264              :     }
         265              :   }
         266              :
         267              :   // 참가자 정보 업데이트
         268            2 :   Future<Participant> updateParticipant(
         269              :     String eventId,
         270              :     String participantId,
         271              :     Map<String, dynamic> updates,
         272              :   ) async {
         273            4 :     if (_token == null || _clubId == null) {
         274            0 :       throw Exception('인증 또는 클럽 정보가 필요합니다');
         275              :     }
         276              :
         277            2 :     _isLoading = true;
         278            2 :     notifyListeners();
         279              :
         280              :     try {
         281            4 :       final data = await _apiService.put(
         282            2 :         '${ApiConfig.clubs}/events/$eventId/participants/$participantId',
         283              :         data: updates,
         284              :       );
         285              :
         286            4 :       final updatedParticipant = Participant.fromJson(data['participant']);
         287              :
         288              :       // 참가자 목록 업데이트
         289            4 :       final index = _participants.indexWhere(
         290            3 :         (participant) => participant.id == participantId,
         291              :       );
         292            2 :       if (index >= 0) {
         293            2 :         _participants[index] = updatedParticipant;
         294              :       }
         295              :
         296            2 :       _isLoading = false;
         297            2 :       notifyListeners();
         298              :
         299              :       return updatedParticipant;
         300              :     } catch (e) {
         301            0 :       _isLoading = false;
         302            0 :       notifyListeners();
         303            0 :       throw Exception('참가자 정보 업데이트에 실패했습니다: $e');
         304              :     }
         305              :   }
         306              :
         307              :   // 참가자 삭제
         308            2 :   Future<bool> removeParticipant(String eventId, String participantId) async {
         309            4 :     if (_token == null || _clubId == null) {
         310            0 :       throw Exception('인증 또는 클럽 정보가 필요합니다');
         311              :     }
         312              :
         313            2 :     _isLoading = true;
         314            2 :     notifyListeners();
         315              :
         316              :     try {
         317            4 :       await _apiService.delete(
         318            2 :         '${ApiConfig.clubs}/events/$eventId/participants/$participantId',
         319              :       );
         320              :
         321              :       // 참가자 목록에서 삭제
         322            4 :       _participants.removeWhere(
         323            3 :         (participant) => participant.id == participantId,
         324              :       );
         325              :
         326            2 :       _isLoading = false;
         327            2 :       notifyListeners();
         328              :
         329              :       return true;
         330              :     } catch (e) {
         331            0 :       _isLoading = false;
         332            0 :       notifyListeners();
         333            0 :       throw Exception('참가자 삭제에 실패했습니다: $e');
         334              :     }
         335              :   }
         336              :
         337              :   // 참가자 상태 업데이트
         338            0 :   Future<Participant> updateParticipantStatus(
         339              :     String eventId,
         340              :     String participantId,
         341              :     String status,
         342              :   ) async {
         343            0 :     return updateParticipant(eventId, participantId, {'status': status});
         344              :   }
         345              :
         346              :   // 점수 관리 기능
         347              :   // 이벤트 점수 목록 가져오기
         348            2 :   Future<List<Score>> fetchEventScores(String eventId) async {
         349            4 :     if (_token == null || _clubId == null) {
         350            0 :       throw Exception('인증 또는 클럽 정보가 필요합니다');
         351              :     }
         352              :
         353            2 :     _isLoading = true;
         354            2 :     notifyListeners();
         355              :
         356              :     try {
         357            4 :       final data = await _apiService.post(
         358              :         '${ApiConfig.clubs}/events/scores',
         359            2 :         data: {'eventId': eventId},
         360              :       );
         361              :
         362            2 :       final List<dynamic> scoresData = data['scores'] ?? [];
         363            2 :       _scores = scoresData
         364            6 :           .map((scoreData) => Score.fromJson(scoreData))
         365            2 :           .toList();
         366              :
         367            2 :       _isLoading = false;
         368            2 :       notifyListeners();
         369              :
         370            2 :       return _scores;
         371              :     } catch (e) {
         372            0 :       _isLoading = false;
         373            0 :       notifyListeners();
         374            0 :       throw Exception('점수 목록을 불러오는데 실패했습니다: $e');
         375              :     }
         376              :   }
         377              :
         378              :   // 점수 추가
         379            2 :   Future<Score> addScore(String eventId, Map<String, dynamic> scoreData) async {
         380            4 :     if (_token == null || _clubId == null) {
         381            0 :       throw Exception('인증 또는 클럽 정보가 필요합니다');
         382              :     }
         383              :
         384            2 :     _isLoading = true;
         385            2 :     notifyListeners();
         386              :
         387              :     try {
         388            4 :       final data = await _apiService.post(
         389            2 :         '${ApiConfig.clubs}/events/$eventId/scores',
         390              :         data: scoreData,
         391              :       );
         392              :
         393            4 :       final newScore = Score.fromJson(data['score']);
         394              :
         395            4 :       _scores.add(newScore);
         396              :
         397            2 :       _isLoading = false;
         398            2 :       notifyListeners();
         399              :
         400              :       return newScore;
         401              :     } catch (e) {
         402            0 :       _isLoading = false;
         403            0 :       notifyListeners();
         404            0 :       throw Exception('점수 추가에 실패했습니다: $e');
         405              :     }
         406              :   }
         407              :
         408              :   // 점수 업데이트
         409            1 :   Future<Score> updateScore(
         410              :     String eventId,
         411              :     String scoreId,
         412              :     Map<String, dynamic> updates,
         413              :   ) async {
         414            2 :     if (_token == null || _clubId == null) {
         415            0 :       throw Exception('인증 또는 클럽 정보가 필요합니다');
         416              :     }
         417              :
         418            1 :     _isLoading = true;
         419            1 :     notifyListeners();
         420              :
         421              :     try {
         422            2 :       final data = await _apiService.put(
         423            1 :         '${ApiConfig.clubs}/events/$eventId/scores/$scoreId',
         424              :         data: updates,
         425              :       );
         426              :
         427            2 :       final updatedScore = Score.fromJson(data['score']);
         428              :
         429              :       // 점수 목록 업데이트
         430            2 :       final index = _scores.indexWhere((score) => score.id == scoreId);
         431            1 :       if (index >= 0) {
         432            0 :         _scores[index] = updatedScore;
         433              :       }
         434              :
         435            1 :       _isLoading = false;
         436            1 :       notifyListeners();
         437              :
         438              :       return updatedScore;
         439              :     } catch (e) {
         440            0 :       _isLoading = false;
         441            0 :       notifyListeners();
         442            0 :       throw Exception('점수 업데이트에 실패했습니다: $e');
         443              :     }
         444              :   }
         445              :
         446              :   // 점수 삭제
         447            1 :   Future<bool> deleteScore(String eventId, String scoreId) async {
         448            2 :     if (_token == null || _clubId == null) {
         449            0 :       throw Exception('인증 또는 클럽 정보가 필요합니다');
         450              :     }
         451              :
         452            1 :     _isLoading = true;
         453            1 :     notifyListeners();
         454              :
         455              :     try {
         456            2 :       await _apiService.delete(
         457            1 :         '${ApiConfig.clubs}/events/$eventId/scores/$scoreId',
         458              :       );
         459              :
         460              :       // 점수 목록에서 삭제
         461            2 :       _scores.removeWhere((score) => score.id == scoreId);
         462              :
         463            1 :       _isLoading = false;
         464            1 :       notifyListeners();
         465              :
         466              :       return true;
         467              :     } catch (e) {
         468            0 :       _isLoading = false;
         469            0 :       notifyListeners();
         470            0 :       throw Exception('점수 삭제에 실패했습니다: $e');
         471              :     }
         472              :   }
         473              :
         474              :   // 팀 관리 기능
         475              :   // 이벤트 팀 목록 가져오기
         476            1 :   Future<List<Team>> fetchEventTeams(String eventId) async {
         477            1 :     if (_token == null) {
         478            0 :       throw Exception('인증 정보가 필요합니다');
         479              :     }
         480              :
         481              :     try {
         482            2 :       final data = await _apiService.post(
         483              :         '${ApiConfig.events}/teams',
         484            1 :         data: {'eventId': eventId},
         485              :       );
         486              :
         487            1 :       final List<dynamic> teamsData = data['teams'] ?? [];
         488            1 :       _teams = teamsData
         489            3 :           .map((teamData) => Team.fromJson(teamData))
         490            1 :           .toList();
         491              :
         492            1 :       notifyListeners();
         493            1 :       return _teams;
         494              :     } catch (e) {
         495            0 :       throw Exception('팀 목록을 불러오는데 실패했습니다: $e');
         496              :     }
         497              :   }
         498              :
         499              :   // 이벤트에 팀이 있는지 확인 (간략 조회)
         500            0 :   Future<bool> hasEventTeams(String eventId) async {
         501            0 :     if (_token == null) {
         502            0 :       throw Exception('인증 정보가 필요합니다');
         503              :     }
         504              :
         505              :     try {
         506            0 :       final data = await _apiService.post(
         507              :         '${ApiConfig.events}/teams',
         508            0 :         data: {'eventId': eventId},
         509              :       );
         510              :
         511            0 :       final List<dynamic> teamsData = data['teams'] ?? [];
         512            0 :       return teamsData.isNotEmpty;
         513              :     } catch (e) {
         514            0 :       print('팀 확인 실패: $e');
         515              :       return false;
         516              :     }
         517              :   }
         518              :
         519              :   // 팀 생성
         520            0 :   Future<List<Team>> generateTeams(
         521              :     String eventId,
         522              :     Map<String, dynamic> teamConfig,
         523              :   ) async {
         524            0 :     if (_token == null || _clubId == null) {
         525            0 :       throw Exception('인증 또는 클럽 정보가 필요합니다');
         526              :     }
         527              :
         528            0 :     _isLoading = true;
         529            0 :     notifyListeners();
         530              :
         531              :     try {
         532            0 :       final data = await _apiService.post(
         533            0 :         '${ApiConfig.clubs}/events/$eventId/teams/generate',
         534              :         data: teamConfig,
         535              :       );
         536              :
         537            0 :       final List<dynamic> teamsData = data['teams'] ?? [];
         538            0 :       _teams = teamsData.map((teamData) => Team.fromJson(teamData)).toList();
         539              :
         540            0 :       _isLoading = false;
         541            0 :       notifyListeners();
         542              :
         543            0 :       return _teams;
         544              :     } catch (e) {
         545            0 :       _isLoading = false;
         546            0 :       notifyListeners();
         547            0 :       throw Exception('팀 생성에 실패했습니다: $e');
         548              :     }
         549              :   }
         550              :
         551              :   // 팀 저장
         552            1 :   Future<bool> saveTeams(String eventId, List<Team> teams) async {
         553            2 :     if (_token == null || _clubId == null) {
         554            0 :       throw Exception('인증 또는 클럽 정보가 필요합니다');
         555              :     }
         556              :
         557            1 :     _isLoading = true;
         558            1 :     notifyListeners();
         559              :
         560              :     try {
         561            2 :       await _apiService.post(
         562            1 :         '${ApiConfig.clubs}/events/$eventId/teams/save',
         563            5 :         data: {'teams': teams.map((team) => team.toJson()).toList()},
         564              :       );
         565              :
         566            1 :       _teams = teams;
         567              :
         568            1 :       _isLoading = false;
         569            1 :       notifyListeners();
         570              :
         571              :       return true;
         572              :     } catch (e) {
         573            0 :       _isLoading = false;
         574            0 :       notifyListeners();
         575            0 :       throw Exception('팀 저장에 실패했습니다: $e');
         576              :     }
         577              :   }
         578              :
         579              :   // 파일에서 이벤트 일괄 생성
         580            0 :   Future<List<Event>> createEventsFromFile(
         581              :     List<Map<String, dynamic>> eventsData,
         582              :   ) async {
         583            0 :     if (_token == null || _clubId == null) {
         584            0 :       throw Exception('인증 또는 클럽 정보가 필요합니다');
         585              :     }
         586              :
         587            0 :     _isLoading = true;
         588            0 :     notifyListeners();
         589              :
         590              :     try {
         591            0 :       final List<Event> createdEvents = [];
         592              :
         593              :       // 각 이벤트 데이터에 클럽 ID 추가
         594            0 :       for (var eventData in eventsData) {
         595            0 :         eventData['clubId'] = _clubId;
         596              :
         597              :         // null 값 처리 - 빈 문자열을 명시적 null로 변환
         598            0 :         eventData.forEach((key, value) {
         599            0 :           if (value is String && value.isEmpty) {
         600            0 :             eventData[key] = null;
         601              :           }
         602              :         });
         603              :
         604              :         // 이벤트 생성 API 호출
         605            0 :         final data = await _apiService.post(
         606              :           '${ApiConfig.clubs}/events',
         607              :           data: eventData,
         608              :         );
         609              :
         610            0 :         final newEvent = Event.fromJson(data['event']);
         611            0 :         createdEvents.add(newEvent);
         612            0 :         _events.add(newEvent);
         613              :       }
         614              :
         615            0 :       _isLoading = false;
         616            0 :       notifyListeners();
         617              :
         618              :       return createdEvents;
         619              :     } catch (e) {
         620            0 :       _isLoading = false;
         621            0 :       notifyListeners();
         622            0 :       throw Exception('파일에서 이벤트 생성에 실패했습니다: $e');
         623              :     }
         624              :   }
         625              :
         626              :   // 이벤트 복제
         627            1 :   Future<Event> cloneEvent(String eventId, {String? newName}) async {
         628            2 :     if (_token == null || _clubId == null) {
         629            0 :       throw Exception('인증 또는 클럽 정보가 필요합니다');
         630              :     }
         631              :
         632            1 :     _isLoading = true;
         633            1 :     notifyListeners();
         634              :
         635              :     try {
         636              :       // 원본 이벤트 정보 가져오기
         637            1 :       final originalEvent = await fetchEventById(eventId);
         638              :
         639              :       // 복제할 이벤트 데이터 준비
         640            1 :       final Map<String, dynamic> cloneData = {
         641            1 :         'clubId': _clubId,
         642            0 :         'title': newName ?? '${originalEvent.title} (복사본)',
         643            1 :         'description': originalEvent.description,
         644            1 :         'location': originalEvent.location,
         645            1 :         'type': originalEvent.type,
         646              :         'status': 'draft', // 복제된 이벤트는 초안 상태로 시작
         647            2 :         'startDate': originalEvent.startDate.toIso8601String(),
         648            1 :         'endDate': originalEvent.endDate?.toIso8601String(),
         649            1 :         'maxParticipants': originalEvent.maxParticipants,
         650            1 :         'participantFee': originalEvent.participantFee,
         651            1 :         'gameCount': originalEvent.gameCount,
         652            1 :         'publicHash': originalEvent.publicHash,
         653            1 :         'accessPassword': originalEvent.accessPassword,
         654              :         'isActive': true,
         655              :       };
         656              :
         657              :       // 이벤트 생성 API 호출
         658            2 :       final data = await _apiService.post(
         659              :         '${ApiConfig.clubs}/events',
         660              :         data: cloneData,
         661              :       );
         662              :
         663            2 :       final newEvent = Event.fromJson(data['event']);
         664            2 :       _events.add(newEvent);
         665              :
         666            1 :       _isLoading = false;
         667            1 :       notifyListeners();
         668              :
         669              :       return newEvent;
         670              :     } catch (e) {
         671            0 :       _isLoading = false;
         672            0 :       notifyListeners();
         673            0 :       throw Exception('이벤트 복제에 실패했습니다: $e');
         674              :     }
         675              :   }
         676              : }

Generated by: LCOV version 2.3.1-1