feat(market-intel): add opportunity evidence plan preview
All checks were successful
CD Pipeline / deploy (push) Successful in 1m4s
All checks were successful
CD Pipeline / deploy (push) Successful in 1m4s
This commit is contained in:
@@ -464,6 +464,12 @@ def test_market_intel_preview_template_uses_safe_fetch_false_endpoint():
|
||||
assert "data-market-intel-opportunity-scoring-thresholds" in template
|
||||
assert "data-market-intel-opportunity-scoring-evidence" in template
|
||||
assert "data-market-intel-opportunity-scoring-sequence" in template
|
||||
assert "data-market-intel-opportunity-evidence" in template
|
||||
assert "data-market-intel-opportunity-evidence-checks" in template
|
||||
assert "data-market-intel-opportunity-evidence-sections" in template
|
||||
assert "data-market-intel-opportunity-evidence-escalation" in template
|
||||
assert "data-market-intel-opportunity-evidence-tables" in template
|
||||
assert "data-market-intel-opportunity-evidence-sequence" in template
|
||||
assert "data-market-intel-migration" in template
|
||||
assert "data-market-intel-migration-tables" in template
|
||||
assert "data-market-intel-approval" in template
|
||||
@@ -485,6 +491,7 @@ def test_market_intel_preview_template_uses_safe_fetch_false_endpoint():
|
||||
assert "market_intel.market_intel_match_review_plan" in template
|
||||
assert "market_intel.market_intel_opportunity_plan" in template
|
||||
assert "market_intel.market_intel_opportunity_scoring_plan" in template
|
||||
assert "market_intel.market_intel_opportunity_evidence_plan" in template
|
||||
assert "market_intel.market_intel_migration_blueprint" in template
|
||||
assert "market_intel.market_intel_write_approval_runbook" in template
|
||||
assert "market_intel.market_intel_deployment_readiness" in template
|
||||
@@ -510,7 +517,7 @@ def test_legacy_source_bridge_default_is_planned_only():
|
||||
bridge = MarketIntelService().build_legacy_source_bridge()
|
||||
|
||||
assert bridge["mode"] == "legacy_source_bridge_planned"
|
||||
assert bridge["phase"] == "phase_36_opportunity_scoring_plan_preview"
|
||||
assert bridge["phase"] == "phase_37_opportunity_evidence_plan_preview"
|
||||
assert bridge["execute_requested"] is False
|
||||
assert bridge["read_only_query_executed"] is False
|
||||
assert bridge["database_connection_opened"] is False
|
||||
@@ -668,7 +675,7 @@ def test_mcp_tool_contract_preview_is_read_only_and_whitelisted():
|
||||
contract = MarketIntelService().build_mcp_tool_contract()
|
||||
|
||||
assert contract["mode"] == "mcp_tool_contract_preview"
|
||||
assert contract["phase"] == "phase_36_opportunity_scoring_plan_preview"
|
||||
assert contract["phase"] == "phase_37_opportunity_evidence_plan_preview"
|
||||
assert contract["caller"] == "market_intel"
|
||||
assert contract["contract_ready"] is True
|
||||
assert contract["blocked_reasons"] == []
|
||||
@@ -801,7 +808,7 @@ def test_mcp_activation_runbook_route_is_preview_only():
|
||||
|
||||
assert response.status_code == 200
|
||||
assert data["mode"] == "mcp_activation_runbook_preview"
|
||||
assert data["phase"] == "phase_36_opportunity_scoring_plan_preview"
|
||||
assert data["phase"] == "phase_37_opportunity_evidence_plan_preview"
|
||||
assert data["deployment_actions_executed"] is False
|
||||
assert data["docker_command_executed"] is False
|
||||
assert data["ssh_command_executed"] is False
|
||||
@@ -814,7 +821,7 @@ def test_mcp_fetch_gate_default_blocks_external_fetch():
|
||||
gate = MarketIntelService().build_mcp_fetch_gate(fetch_requested=True)
|
||||
|
||||
assert gate["mode"] == "mcp_fetch_gate_planned"
|
||||
assert gate["phase"] == "phase_36_opportunity_scoring_plan_preview"
|
||||
assert gate["phase"] == "phase_37_opportunity_evidence_plan_preview"
|
||||
assert gate["fetch_requested"] is True
|
||||
assert gate["manual_fetch_gate_open"] is False
|
||||
assert gate["network_request_allowed"] is False
|
||||
@@ -884,7 +891,7 @@ def test_mcp_fetch_gate_route_is_preview_only():
|
||||
|
||||
assert response.status_code == 200
|
||||
assert data["mode"] == "mcp_fetch_gate_planned"
|
||||
assert data["phase"] == "phase_36_opportunity_scoring_plan_preview"
|
||||
assert data["phase"] == "phase_37_opportunity_evidence_plan_preview"
|
||||
assert data["fetch_requested"] is False
|
||||
assert data["network_request_allowed"] is False
|
||||
assert data["external_network_executed"] is False
|
||||
@@ -896,7 +903,7 @@ def test_scheduler_plan_preview_blocks_job_attachment():
|
||||
plan = MarketIntelService().build_scheduler_plan()
|
||||
|
||||
assert plan["mode"] == "scheduler_attach_plan_preview"
|
||||
assert plan["phase"] == "phase_36_opportunity_scoring_plan_preview"
|
||||
assert plan["phase"] == "phase_37_opportunity_evidence_plan_preview"
|
||||
assert plan["ready_to_attach_scheduler"] is False
|
||||
assert plan["scheduler_attached"] is False
|
||||
assert plan["scheduler_registration_executed"] is False
|
||||
@@ -934,7 +941,7 @@ def test_scheduler_plan_route_is_preview_only():
|
||||
|
||||
assert response.status_code == 200
|
||||
assert data["mode"] == "scheduler_attach_plan_preview"
|
||||
assert data["phase"] == "phase_36_opportunity_scoring_plan_preview"
|
||||
assert data["phase"] == "phase_37_opportunity_evidence_plan_preview"
|
||||
assert data["scheduler_registration_executed"] is False
|
||||
assert data["crawler_job_started"] is False
|
||||
assert data["external_network_executed"] is False
|
||||
@@ -945,7 +952,7 @@ def test_match_review_plan_preview_blocks_auto_confirm():
|
||||
plan = MarketIntelService().build_match_review_plan()
|
||||
|
||||
assert plan["mode"] == "match_review_plan_preview"
|
||||
assert plan["phase"] == "phase_36_opportunity_scoring_plan_preview"
|
||||
assert plan["phase"] == "phase_37_opportunity_evidence_plan_preview"
|
||||
assert plan["ready_for_review_queue"] is False
|
||||
assert plan["review_queue_created"] is False
|
||||
assert plan["auto_match_executed"] is False
|
||||
@@ -981,7 +988,7 @@ def test_match_review_plan_route_is_preview_only():
|
||||
|
||||
assert response.status_code == 200
|
||||
assert data["mode"] == "match_review_plan_preview"
|
||||
assert data["phase"] == "phase_36_opportunity_scoring_plan_preview"
|
||||
assert data["phase"] == "phase_37_opportunity_evidence_plan_preview"
|
||||
assert data["review_queue_created"] is False
|
||||
assert data["auto_confirm_executed"] is False
|
||||
assert data["external_network_executed"] is False
|
||||
@@ -992,7 +999,7 @@ def test_opportunity_plan_preview_blocks_alerts_and_ai_summary():
|
||||
plan = MarketIntelService().build_opportunity_plan()
|
||||
|
||||
assert plan["mode"] == "opportunity_plan_preview"
|
||||
assert plan["phase"] == "phase_36_opportunity_scoring_plan_preview"
|
||||
assert plan["phase"] == "phase_37_opportunity_evidence_plan_preview"
|
||||
assert plan["ready_for_opportunity_queue"] is False
|
||||
assert plan["opportunity_queue_created"] is False
|
||||
assert plan["threat_alert_dispatched"] is False
|
||||
@@ -1033,7 +1040,7 @@ def test_opportunity_plan_route_is_preview_only():
|
||||
|
||||
assert response.status_code == 200
|
||||
assert data["mode"] == "opportunity_plan_preview"
|
||||
assert data["phase"] == "phase_36_opportunity_scoring_plan_preview"
|
||||
assert data["phase"] == "phase_37_opportunity_evidence_plan_preview"
|
||||
assert data["opportunity_queue_created"] is False
|
||||
assert data["threat_alert_dispatched"] is False
|
||||
assert data["ai_summary_generated"] is False
|
||||
@@ -1044,7 +1051,7 @@ def test_opportunity_scoring_plan_preview_blocks_scoring_and_alerts():
|
||||
plan = MarketIntelService().build_opportunity_scoring_plan()
|
||||
|
||||
assert plan["mode"] == "opportunity_scoring_plan_preview"
|
||||
assert plan["phase"] == "phase_36_opportunity_scoring_plan_preview"
|
||||
assert plan["phase"] == "phase_37_opportunity_evidence_plan_preview"
|
||||
assert plan["ready_for_scoring_job"] is False
|
||||
assert plan["scoring_job_created"] is False
|
||||
assert plan["score_calculation_executed"] is False
|
||||
@@ -1092,7 +1099,7 @@ def test_opportunity_scoring_plan_route_is_preview_only():
|
||||
|
||||
assert response.status_code == 200
|
||||
assert data["mode"] == "opportunity_scoring_plan_preview"
|
||||
assert data["phase"] == "phase_36_opportunity_scoring_plan_preview"
|
||||
assert data["phase"] == "phase_37_opportunity_evidence_plan_preview"
|
||||
assert data["scoring_job_created"] is False
|
||||
assert data["score_calculation_executed"] is False
|
||||
assert data["sample_scores_generated"] is False
|
||||
@@ -1100,6 +1107,65 @@ def test_opportunity_scoring_plan_route_is_preview_only():
|
||||
assert data["external_network_executed"] is False
|
||||
|
||||
|
||||
def test_opportunity_evidence_plan_preview_blocks_queries_and_alerts():
|
||||
plan = MarketIntelService().build_opportunity_evidence_plan()
|
||||
|
||||
assert plan["mode"] == "opportunity_evidence_plan_preview"
|
||||
assert plan["phase"] == "phase_37_opportunity_evidence_plan_preview"
|
||||
assert plan["ready_for_evidence_bundle"] is False
|
||||
assert plan["evidence_bundle_created"] is False
|
||||
assert plan["evidence_query_executed"] is False
|
||||
assert plan["sample_evidence_generated"] is False
|
||||
assert plan["alert_candidate_created"] is False
|
||||
assert plan["telegram_dispatched"] is False
|
||||
assert plan["ai_summary_generated"] is False
|
||||
assert plan["database_session_created"] is False
|
||||
assert plan["database_write_executed"] is False
|
||||
assert plan["database_commit_executed"] is False
|
||||
assert plan["external_network_executed"] is False
|
||||
assert plan["scheduler_attached"] is False
|
||||
assert plan["writes_executed"] is False
|
||||
assert plan["would_write_database"] is False
|
||||
assert plan["section_count"] == 5
|
||||
assert {item["key"] for item in plan["sections"]} == {
|
||||
"campaign_context",
|
||||
"market_product_snapshot",
|
||||
"match_review_state",
|
||||
"momo_reference",
|
||||
"scoring_trace",
|
||||
}
|
||||
assert "confirmed_match_evidence_available" in plan["blocked_reasons"]
|
||||
assert "scoring_trace_available" in plan["blocked_reasons"]
|
||||
assert "manual_operator_approval" in plan["blocked_reasons"]
|
||||
assert "do_not_query_database_from_evidence_preview" in plan["safe_boundaries"]
|
||||
assert "do_not_generate_placeholder_evidence" in plan["safe_boundaries"]
|
||||
assert plan["bundle_contract"]["freshness_window_hours"] == 24
|
||||
|
||||
|
||||
def test_opportunity_evidence_plan_route_is_preview_only():
|
||||
from routes.market_intel_routes import market_intel_bp
|
||||
|
||||
app = Flask(__name__)
|
||||
app.secret_key = "test-secret"
|
||||
app.register_blueprint(market_intel_bp)
|
||||
client = app.test_client()
|
||||
with client.session_transaction() as session:
|
||||
session["logged_in"] = True
|
||||
|
||||
response = client.get("/api/market_intel/opportunity_evidence_plan")
|
||||
data = response.get_json()
|
||||
|
||||
assert response.status_code == 200
|
||||
assert data["mode"] == "opportunity_evidence_plan_preview"
|
||||
assert data["phase"] == "phase_37_opportunity_evidence_plan_preview"
|
||||
assert data["evidence_bundle_created"] is False
|
||||
assert data["evidence_query_executed"] is False
|
||||
assert data["sample_evidence_generated"] is False
|
||||
assert data["alert_candidate_created"] is False
|
||||
assert data["database_write_executed"] is False
|
||||
assert data["external_network_executed"] is False
|
||||
|
||||
|
||||
def test_mcp_deploy_preflight_blocks_without_required_env():
|
||||
preflight = build_mcp_deploy_preflight_plan(env={})
|
||||
|
||||
@@ -1163,7 +1229,7 @@ def test_mcp_deploy_preflight_route_is_preview_only():
|
||||
|
||||
assert response.status_code == 200
|
||||
assert data["mode"] == "mcp_external_deploy_preflight_preview"
|
||||
assert data["phase"] == "phase_36_opportunity_scoring_plan_preview"
|
||||
assert data["phase"] == "phase_37_opportunity_evidence_plan_preview"
|
||||
assert data["deployment_actions_executed"] is False
|
||||
assert data["docker_command_executed"] is False
|
||||
assert data["ssh_command_executed"] is False
|
||||
@@ -1178,7 +1244,7 @@ def test_mcp_readiness_default_is_planned_only(monkeypatch):
|
||||
readiness = MarketIntelService().build_mcp_readiness()
|
||||
|
||||
assert readiness["mode"] == "mcp_readiness_planned"
|
||||
assert readiness["phase"] == "phase_36_opportunity_scoring_plan_preview"
|
||||
assert readiness["phase"] == "phase_37_opportunity_evidence_plan_preview"
|
||||
assert readiness["execute_requested"] is False
|
||||
assert readiness["router_enabled"] is False
|
||||
assert readiness["external_mcp_complete"] is False
|
||||
@@ -1569,6 +1635,7 @@ def test_deployment_readiness_reports_app_only_release_gate():
|
||||
assert readiness["checks"]["match_review_plan_preview_safe"] is True
|
||||
assert readiness["checks"]["opportunity_plan_preview_safe"] is True
|
||||
assert readiness["checks"]["opportunity_scoring_plan_preview_safe"] is True
|
||||
assert readiness["checks"]["opportunity_evidence_plan_preview_safe"] is True
|
||||
assert readiness["checks"]["writer_plan_dry_run_only"] is True
|
||||
assert readiness["writer_plan_summary"]["writes_executed"] is False
|
||||
assert "readiness_checks_not_all_passed" not in readiness["blocked_reasons"]
|
||||
@@ -1593,6 +1660,7 @@ def test_deployment_readiness_reports_app_only_release_gate():
|
||||
assert "/api/market_intel/match_review_plan" in readiness["production_smoke_targets"]
|
||||
assert "/api/market_intel/opportunity_plan" in readiness["production_smoke_targets"]
|
||||
assert "/api/market_intel/opportunity_scoring_plan" in readiness["production_smoke_targets"]
|
||||
assert "/api/market_intel/opportunity_evidence_plan" in readiness["production_smoke_targets"]
|
||||
assert readiness["write_approval_runbook"]["ready_for_real_write"] is False
|
||||
assert readiness["write_approval_runbook"]["writes_executed"] is False
|
||||
assert readiness["migration_blueprint"]["migration_executed"] is False
|
||||
@@ -1623,6 +1691,9 @@ def test_deployment_readiness_reports_app_only_release_gate():
|
||||
assert readiness["opportunity_scoring_plan"]["scoring_job_created"] is False
|
||||
assert readiness["opportunity_scoring_plan"]["score_calculation_executed"] is False
|
||||
assert readiness["opportunity_scoring_plan"]["database_write_executed"] is False
|
||||
assert readiness["opportunity_evidence_plan"]["evidence_bundle_created"] is False
|
||||
assert readiness["opportunity_evidence_plan"]["evidence_query_executed"] is False
|
||||
assert readiness["opportunity_evidence_plan"]["database_write_executed"] is False
|
||||
|
||||
|
||||
def test_write_approval_runbook_is_read_only_and_blocks_real_write():
|
||||
|
||||
Reference in New Issue
Block a user