@@ -223,6 +223,89 @@ def sync_from_leaguepedia
223223 } , status : :service_unavailable
224224 end
225225
226+ # GET /api/v1/competitive/pro-matches/diagnose-missing
227+ # Cross-reference Leaguepedia Cargo API with our DB to find missing games.
228+ # Bypasses the ProStaff Scraper — queries Leaguepedia directly.
229+ #
230+ # @param overview_page [String] required — Leaguepedia OverviewPage
231+ # @param our_team [String] required — team name as in Leaguepedia
232+ def diagnose_missing
233+ overview_page = params . require ( :overview_page )
234+ our_team = params [ :our_team ] . presence
235+ raise ActionController ::ParameterMissing . new ( :our_team ) if our_team . blank?
236+
237+ service = ::Competitive ::Services ::LeaguepediaRecoveryService . new ( current_organization )
238+ games = service . diagnose_missing ( overview_page : overview_page , our_team : our_team )
239+
240+ missing = games . reject { |g | g [ :present_in_db ] }
241+ present = games . select { |g | g [ :present_in_db ] }
242+
243+ render json : {
244+ message : "Diagnosis complete for #{ our_team } " ,
245+ data : {
246+ overview_page : overview_page ,
247+ our_team : our_team ,
248+ total_in_leaguepedia : games . size ,
249+ present_in_db : present . size ,
250+ missing_count : missing . size ,
251+ missing_games : missing ,
252+ present_games : present
253+ }
254+ }
255+ rescue ActionController ::ParameterMissing => e
256+ render json : { error : { code : 'MISSING_PARAM' , message : e . message } } ,
257+ status : :unprocessable_entity
258+ rescue StandardError => e
259+ Rails . logger . error "[ProMatches#diagnose_missing] #{ e . message } "
260+ render json : { error : { code : 'LEAGUEPEDIA_ERROR' , message : e . message } } ,
261+ status : :service_unavailable
262+ end
263+
264+ # POST /api/v1/competitive/pro-matches/recover-missing
265+ # Recover missing games by querying Leaguepedia Cargo API directly.
266+ # Bypasses the ProStaff Scraper — no SCRAPER_API_KEY required.
267+ #
268+ # Flow:
269+ # 1. Fetch all ScoreboardGames for the overview_page from Leaguepedia
270+ # 2. Filter to games involving our_team
271+ # 3. Skip games already present in the DB (by external_match_id)
272+ # 4. For each missing game, fetch ScoreboardPlayers and import
273+ #
274+ # @param overview_page [String] required — Leaguepedia OverviewPage
275+ # @param our_team [String] required — team name as in Leaguepedia
276+ # @param stage [String] optional — filter to a specific stage
277+ def recover_missing
278+ overview_page = params . require ( :overview_page )
279+ our_team = params [ :our_team ] . presence
280+ raise ActionController ::ParameterMissing . new ( :our_team ) if our_team . blank?
281+
282+ stage = params [ :stage ] . presence
283+
284+ service = ::Competitive ::Services ::LeaguepediaRecoveryService . new ( current_organization )
285+ result = service . recover_missing (
286+ overview_page : overview_page ,
287+ our_team : our_team ,
288+ stage : stage
289+ )
290+
291+ render json : {
292+ message : "Recovery complete for #{ our_team } in #{ overview_page } " ,
293+ data : {
294+ overview_page : overview_page ,
295+ our_team : our_team ,
296+ stage : stage ,
297+ stats : result
298+ }
299+ } , status : :ok
300+ rescue ActionController ::ParameterMissing => e
301+ render json : { error : { code : 'MISSING_PARAM' , message : e . message } } ,
302+ status : :unprocessable_entity
303+ rescue StandardError => e
304+ Rails . logger . error "[ProMatches#recover_missing] #{ e . message } "
305+ render json : { error : { code : 'LEAGUEPEDIA_ERROR' , message : e . message } } ,
306+ status : :service_unavailable
307+ end
308+
226309 # POST /api/v1/competitive/pro-matches/import
227310 # Import a match from PandaScore to our database
228311 def import
0 commit comments