"""Lepsza odpowiedź Matcher AI gdy baza naborów jest pusta.""" import logging from fastapi import Depends, HTTPException from endpoints.grants import router, MatchRequest, get_nabory, run_advanced_match_core, MATCH_FALLBACK_QUESTIONS, _rule_based_advanced_match_fallback from endpoints.projects import get_db from core.subscription.middleware import verify_token from core.projects.models import Project logger = logging.getLogger(__name__) _orig_route = None def apply_match_fix(): global _orig_route for route in list(router.routes): if getattr(route, "path", "") == "/match" and "POST" in getattr(route, "methods", set()): router.routes.remove(route) _orig_route = route break @router.post("/match") async def match_grants_fixed( request: MatchRequest, token_data: dict = Depends(verify_token), db=Depends(get_db), ): clerk_id = token_data.get("sub") project = db.query(Project).filter( Project.id == request.project_id, Project.clerk_user_id == clerk_id, ).first() if not project: raise HTTPException(status_code=404, detail="Projekt nie istnieje lub brak dostępu") nabory_list: list = [] try: nabory_resp = await get_nabory(force_refresh=False, db=db) nabory_list = nabory_resp.get("nabory", []) stats = nabory_resp.get("count", 0) if not nabory_list: return { "status": "ok", "project_id": request.project_id, "needs_more_info": True, "clarifying_questions": [ "Baza naborów jest pusta. Uruchom import: POST /api/admin/grants/import-wyszukiwarka " "lub skrypt scripts/import_wyszukiwarka.py z plikiem WYSZUKIWARKA." ], "matches": [], "catalog_empty": True, "hint": "Ustaw WYSZUKIWARKA_JSON=/ścieżka/do/dotacje-2026-06-21.json i zaimportuj katalog.", } result = await run_advanced_match_core( title=project.title or "", description=project.description or "Brak opisu", estimated_value=project.estimated_value or 0.0, external_context=project.external_context or {}, industry=project.industry if hasattr(project, "industry") else "", user_answers=request.user_answers or [], nabory_list=nabory_list, ) if not result.needs_more_info: external_context = project.external_context or {} external_context["ai_matches"] = [m.model_dump() for m in result.matches] if request.user_answers: external_context["ai_matches_qa_history"] = [ qa.model_dump() for qa in request.user_answers ] project.external_context = external_context db.commit() return { "status": "ok", "project_id": request.project_id, "needs_more_info": result.needs_more_info, "clarifying_questions": result.clarifying_questions, "matches": [m.model_dump() for m in result.matches], "nabory_in_catalog": stats, } except Exception as e: logger.error("Error in match_grants for project %s: %s", request.project_id, e, exc_info=True) try: fallback = _rule_based_advanced_match_fallback( project.title or "", project.description or "", project.external_context or {}, request.user_answers or [], nabory_list, ) return { "status": "ok", "project_id": request.project_id, "needs_more_info": fallback.needs_more_info, "clarifying_questions": fallback.clarifying_questions, "matches": [m.model_dump() for m in fallback.matches], "fallback_mode": "rule_based", "detail": str(e)[:200], } except Exception: return { "status": "error", "detail": f"Błąd generowania dopasowań przez AI: {str(e)}", "needs_more_info": True, "clarifying_questions": MATCH_FALLBACK_QUESTIONS, "matches": [], } logger.info("[grants_match_fix] POST /match patched with catalog-empty handling.")