Spaces:
Sleeping
Sleeping
File size: 5,936 Bytes
ce8f04a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | """Pre-gen data completeness gate."""
from __future__ import annotations
from core.projects.data_completeness import (
STATUS_MISSING,
STATUS_READY,
STATUS_STRUCTURE,
apply_project_facts,
evaluate_data_completeness,
)
from core.projects.instrument_schema import build_instrument_schema
def test_eurogranty_missing_target_blocks():
schema = build_instrument_schema(program_name="Granty na Eurogranty FENG.02.12")
r = evaluate_data_completeness(
external_context={
"company_data": {
"nip": "8721990161",
"name": "AUTOPROCES",
"pkd_codes": ["28.29.Z"],
"msp_status": "mikro",
"de_minimis": 2738,
"closed_financial_year": True,
"revenue_3y": [1, 2, 3],
"employment_fte": 2,
},
"grounding_mode": "regulation",
"program_dossier": {"readiness": {"level": "partial"}},
},
instrument_schema=schema,
description="Przygotowanie do aplikacji UE",
)
assert r["status"] == STATUS_MISSING
assert r["full_autopilot_allowed"] is False
fields = {m["field"] for m in r["missing_fields"]}
assert "eurogrant_call" in fields or "eurogrant_programme" in fields
def test_structure_only_allows_generate():
r = evaluate_data_completeness(
external_context={
"grounding_mode": "structure_only",
# complete eligibility so structure-only is not blocked by spine
"company_data": {
"nip": "8721990161",
"msp_status": "mikro",
"de_minimis_manual_eur": 1000,
},
},
grounding_mode="structure_only",
)
assert r["status"] == STATUS_STRUCTURE
assert r["ready_to_generate"] is True
assert r["full_autopilot_allowed"] is True
assert r.get("eligibility_spine_enforced") is True
def test_structure_only_still_gates_full_autopilot_on_large_firm(monkeypatch):
"""structure_only must not fail-open Full Autopilot past eligibility spine."""
monkeypatch.setenv("ENABLE_ELIGIBILITY_SPINE", "true")
r = evaluate_data_completeness(
external_context={
"grounding_mode": "structure_only",
"company_data": {
"nip": "8721990161",
"msp_status": "duza",
"de_minimis_manual_eur": 1000,
},
},
grounding_mode="structure_only",
)
assert r["status"] == STATUS_STRUCTURE
assert r["ready_to_generate"] is True # structural consent retained
assert r["full_autopilot_allowed"] is False
assert r.get("eligibility_spine_enforced") is True
assert any("duża" in b.lower() or "duza" in b.lower() for b in (r.get("eligibility") or {}).get("blockers") or []) or any(
"duż" in w.lower() or "duza" in w.lower() or "large" in w.lower() or "MŚP" in w or "duża" in w
for w in (r.get("warnings") or [])
)
def test_structure_only_gates_exhausted_de_minimis(monkeypatch):
monkeypatch.setenv("ENABLE_ELIGIBILITY_SPINE", "true")
r = evaluate_data_completeness(
external_context={
"grounding_mode": "structure_only",
"company_data": {
"nip": "8721990161",
"msp_status": "mikro",
"sudop": {"configured": True, "de_minimis_total_eur": 300_000},
},
},
grounding_mode="structure_only",
)
assert r["ready_to_generate"] is True
assert r["full_autopilot_allowed"] is False
assert (r.get("eligibility") or {}).get("de_minimis", {}).get("exhausted") is True
def test_structure_only_gates_unknown_de_minimis(monkeypatch):
monkeypatch.setenv("ENABLE_ELIGIBILITY_SPINE", "true")
r = evaluate_data_completeness(
external_context={
"grounding_mode": "structure_only",
"company_data": {
"nip": "8721990161",
"msp_status": "mikro",
# no sudop / manual de minimis
},
},
grounding_mode="structure_only",
)
assert r["full_autopilot_allowed"] is False
assert r.get("eligibility_spine_enforced") is True
def test_apply_facts_then_ready_eurogranty():
schema = build_instrument_schema(program_name="Granty na Eurogranty")
ext = {
"company_data": {
"nip": "8721990161",
"name": "AUTOPROCES",
"pkd_codes": ["28.29.Z"],
"msp_status": "mikro",
"de_minimis": 1000,
"closed_financial_year": True,
"revenue_3y": {"2023": 1, "2024": 2, "2025": 3},
"employment_fte": 3,
},
"grounding_mode": "regulation",
"program_dossier": {"readiness": {"level": "ready"}},
}
ext = apply_project_facts(
ext,
{
"eurogrant_programme": "Horizon Europe Cluster 4",
"eurogrant_call": "HORIZON-CL4-2026-AI-MANUFACTURING",
"eurogrant_role": "samodzielny",
"specialist_analysis_yes_no": "tak — analiza partnerów i stanu techniki",
"lump_sum_amount_pln": 110852,
},
)
r = evaluate_data_completeness(
external_context=ext,
instrument_schema=schema,
description="Przygotowanie wniosku Horizon dla AI in manufacturing",
)
assert r["status"] == STATUS_READY
assert r["full_autopilot_allowed"] is True
assert not r["missing_fields"]
def test_missing_nip_blocks():
schema = build_instrument_schema(program_type="SMART", program_name="SMART")
r = evaluate_data_completeness(
external_context={"company_data": {}, "grounding_mode": "regulation"},
instrument_schema=schema,
description="Projekt innowacyjny",
)
assert r["full_autopilot_allowed"] is False
assert any(m["field"] == "nip" for m in r["missing_fields"])
|