feat(search): add role-aware backend search and truthful n8n status

Two new endpoints. GET /api/v1/search returns bounded typed results
(vehicle, booking, data-quality-issue, application section) instead of the
frontend guessing routes from regex patterns against public-ref prefixes;
data-quality and manager-only sections are filtered server-side by role,
and customers are deliberately never returned since no customer detail
route exists in this PoC.

GET /api/v1/integrations/status aggregates outbox delivery counts
(pending/delivering/succeeded/failed) into a single truthful n8n state
(disabled/unavailable/degraded/operational/no_evidence) instead of the UI
showing whichever status the single most recent event happened to be in --
a vehicle_status_conflict-style bug where one stale failure or one lucky
success could misreport the dispatcher's actual health.

Also fixes a real config gap this surfaced: MCP_HUB_REGISTRATION_ENABLED
was documented in .env.example but had no corresponding Settings field, so
it was silently ignored by pydantic-settings' extra="ignore" and never
actually read anywhere in the codebase.
This commit is contained in:
NuklearRabbit
2026-08-02 06:41:56 +02:00
parent 4bc3e33953
commit 4437b8792a
11 changed files with 596 additions and 46 deletions
+34
View File
@@ -163,6 +163,40 @@ class ApplyRecommendedStatusResult(BaseModel):
reason: str
class SearchResultItem(BaseModel):
type: Literal["vehicle", "booking", "data_quality_issue", "section"]
label: str
detail: str
link: str
class SearchResponse(BaseModel):
query: str
results: list[SearchResultItem]
class N8nIntegrationStatus(BaseModel):
configured: bool
dispatch_enabled: bool
state: Literal["disabled", "unavailable", "degraded", "operational", "no_evidence"]
pending: int
delivering: int
failed: int
succeeded: int
latest_success_at: datetime | None
latest_failure_at: datetime | None
class McpHubIntegrationStatus(BaseModel):
registration_enabled: bool
state: Literal["not_configured", "configured"]
class IntegrationStatusOut(BaseModel):
n8n: N8nIntegrationStatus
mcp_hub: McpHubIntegrationStatus
class VehicleDetailOut(VehicleOut):
bookings: list[BookingSummaryOut] = Field(default_factory=list)
inspections: list[InspectionOut] = Field(default_factory=list)