M54: harden operations and demo resilience
This commit is contained in:
@@ -9,16 +9,28 @@ from app.core.config import get_settings
|
||||
from app.models.audit import AuditEvent
|
||||
from app.models.booking import Booking
|
||||
from app.models.data_quality import DataQualityIssue
|
||||
from app.models.outbox import OutboxEvent
|
||||
from app.models.outbox import OutboxEvent, is_demo_scenario_failure
|
||||
from app.schemas import DemoIntegrationSummaryOut, DemoManifestOut, DemoScenarioOut
|
||||
from app.services.integration_status import derive_mcp_hub_status, derive_n8n_status
|
||||
from app.services.knowledge import get_knowledge_provider
|
||||
from app.services.knowledge import KnowledgeHealth, get_knowledge_provider
|
||||
|
||||
settings = get_settings()
|
||||
|
||||
_FAILED_DEMO_EVENT_ID = "00000000-0000-4000-8000-000000000020"
|
||||
|
||||
|
||||
def _knowledge_scenario_ready(health: KnowledgeHealth) -> bool:
|
||||
"""Require a reachable provider and independently verified indexed documents.
|
||||
|
||||
``source_document_count`` describes local Markdown files, while a sync report only
|
||||
describes an upload attempt. Neither proves that the active provider can retrieve a
|
||||
corpus, so an unavailable verification count remains honestly not ready.
|
||||
"""
|
||||
return bool(
|
||||
health.available and health.document_count is not None and health.document_count > 0
|
||||
)
|
||||
|
||||
|
||||
def _last_reset(db: Session) -> tuple[datetime | None, str | None]:
|
||||
marker = db.scalar(
|
||||
select(AuditEvent)
|
||||
@@ -49,7 +61,8 @@ def _scenarios(db: Session) -> list[DemoScenarioOut]:
|
||||
return_ready = bool(booking and booking.status == "active" and booking.end_odometer_km is None)
|
||||
duplicate_ready = bool(duplicate_issue and duplicate_issue.status == "open")
|
||||
overlap_ready = bool(overlap_issue and overlap_issue.status == "open")
|
||||
automation_ready = bool(failed_run and failed_run.delivery_status == "failed")
|
||||
automation_ready = bool(failed_run and is_demo_scenario_failure(failed_run))
|
||||
knowledge_ready = _knowledge_scenario_ready(knowledge_health)
|
||||
|
||||
return [
|
||||
DemoScenarioOut(
|
||||
@@ -119,8 +132,8 @@ def _scenarios(db: Session) -> list[DemoScenarioOut]:
|
||||
estimated_minutes=2,
|
||||
required_roles=["rental_employee", "operations_manager"],
|
||||
start_path="/knowledge",
|
||||
ready=knowledge_health.available,
|
||||
blocked_reason_code=None if knowledge_health.available else "knowledgeUnavailable",
|
||||
ready=knowledge_ready,
|
||||
blocked_reason_code=None if knowledge_ready else "knowledgeUnavailable",
|
||||
),
|
||||
]
|
||||
|
||||
@@ -145,9 +158,11 @@ def _integrations(db: Session) -> list[DemoIntegrationSummaryOut]:
|
||||
key="ragcore",
|
||||
status_code=(
|
||||
"operational"
|
||||
if knowledge_health.provider == "ragcore" and knowledge_health.available
|
||||
if knowledge_health.provider == "ragcore"
|
||||
and _knowledge_scenario_ready(knowledge_health)
|
||||
else "demoMode"
|
||||
if knowledge_health.provider == "demo" and knowledge_health.available
|
||||
if knowledge_health.provider == "demo"
|
||||
and _knowledge_scenario_ready(knowledge_health)
|
||||
else "unavailable"
|
||||
),
|
||||
detail_code=(
|
||||
@@ -169,9 +184,7 @@ def _integrations(db: Session) -> list[DemoIntegrationSummaryOut]:
|
||||
# "operational" -- same evidence rule the integration status page uses.
|
||||
status_code="operational" if mcp_hub.state == "operational" else "notConnected",
|
||||
detail_code=(
|
||||
"mcpDetailOperational"
|
||||
if mcp_hub.state == "operational"
|
||||
else "mcpDetailPrepared"
|
||||
"mcpDetailOperational" if mcp_hub.state == "operational" else "mcpDetailPrepared"
|
||||
),
|
||||
detail_params={},
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user