"""Project creation helpers — eligibility, enrichment, early MSP analysis.""" from __future__ import annotations import logging from fastapi import HTTPException logger = logging.getLogger(__name__) def validate_grant_eligibility(external_context: dict) -> None: """Hard-block tworzenia projektu dla zamkniętych / przestarzałych naborów.""" if "selected_grant" not in external_context: return grant = external_context["selected_grant"] if grant.get("status") == "closed" or grant.get("is_outdated_warning"): logger.warning( "[Projects] Próba utworzenia wniosku dla wygasłego naboru: %s", grant.get("name"), ) raise HTTPException( status_code=400, detail=( "Ten nabór został oznaczony jako ZAMKNIĘTY lub PRZESTARZAŁY. " "Ze względów bezpieczeństwa nie można utworzyć projektu dla tego naboru." ), ) async def enrich_company_context_at_creation(enriched_context: dict, description: str | None) -> dict: """Pełne pobranie GUS/KRS + enrichment SUDOP/gaps na starcie projektu.""" if "company_data" not in enriched_context: return enriched_context if not enriched_context["company_data"].get("nip"): return enriched_context nip = enriched_context["company_data"]["nip"] try: from tools.company_search import fetch_regon_data from integrations.krs_client import KRSClient full_data = fetch_regon_data(nip) or {} full_data = {**full_data, "nip": nip} krs = full_data.get("krs") or full_data.get("numerKRS") if krs: try: odpis = KRSClient.get_odpis_aktualny(str(krs)) if odpis: krs_relations = KRSClient.extract_graph_relations(odpis) full_data["krs_full"] = krs_relations full_data["krs_zarzad"] = krs_relations.get("zarzad", []) full_data["krs_wspolnicy"] = krs_relations.get("wspolnicy", []) logger.info("[Projects] Pobrano pełny odpis KRS dla projektu (KRS: %s)", krs) except Exception as krs_e: logger.warning("[Projects] Nie udało się pobrać odpisu KRS: %s", krs_e) enriched_context["company_data"] = full_data logger.info("[Projects] Wzbogacono dane firmy na starcie projektu (NIP: %s)", nip) try: from core.registry_enrichment import enrich_company_profile enrichment = await enrich_company_profile( nip, project_description=description or "", include_web_intel=False, ) enriched_company = enrichment.get("company_data") or {} for krs_key in ("krs_full", "krs_zarzad", "krs_wspolnicy"): if krs_key in full_data and krs_key not in enriched_company: enriched_company[krs_key] = full_data[krs_key] enriched_context["company_data"] = {**full_data, **enriched_company} if enrichment.get("gaps"): enriched_context["gaps"] = enrichment["gaps"] if enrichment.get("risk_hints"): enriched_context["risk_hints"] = enrichment["risk_hints"] if enrichment.get("sudop"): enriched_context["sudop"] = enrichment["sudop"] logger.info( "[Projects] Enrichment SUDOP/gaps wykonany dla NIP %s (luki: %s)", nip, len(enrichment.get("gaps", [])), ) except Exception as enrich_e: logger.warning("[Projects] Pełny enrichment (SUDOP/gaps) nieudany: %s", enrich_e) except Exception as gus_e: logger.warning( "[Projects] Błąd wzbogacania danych GUS/KRS dla nowo tworzonego projektu: %s", gus_e, ) return enriched_context def apply_early_msp_analysis(enriched_context: dict) -> dict: """Wczesna analiza MSP/GraphRAG przy tworzeniu projektu.""" if "company_data" not in enriched_context: return enriched_context nip = enriched_context["company_data"].get("nip") if not nip: return enriched_context try: from core.graph_rag.sme_verifier import sme_verifier declared = enriched_context.get("declared_sme_status", "mikro") msp_result = sme_verifier.verify_sme_status(nip=nip, declared_status=declared) enriched_context["msp_analysis"] = msp_result logger.info("[Projects] Wczesna analiza MSP wykonana dla NIP %s przy tworzeniu projektu", nip) is_mock = msp_result.get("using_real_data") is False or "mock" in str( msp_result.get("msp_risk_note", "") ).lower() enriched_context["credibility_flags"] = { "msp_analysis_performed": True, "msp_using_real_data": msp_result.get("using_real_data", False), "msp_risk": bool(msp_result.get("msp_risk_note")), "gus_enriched": bool( enriched_context.get("company_data", {}).get("pkd") ), "overall_trust_level": ( "high" if msp_result.get("using_real_data") else "medium" if not is_mock else "low-mock" ), } except Exception as msp_e: logger.warning("[Projects] Nie udało się wykonać wczesnej analizy MSP: %s", msp_e) enriched_context["credibility_flags"] = { "msp_analysis_performed": False, "overall_trust_level": "unknown", } return enriched_context