"""HTTP middleware: resolve registered Automation API surface (lab: no version 501). Historically this returned HTTP 501 when the hot-swapped catalog major was below a path's PATH_FLOOR. That blocked real lab data for Ansible/Terraform/apps. Catalog majors still filter the UI browse list; runtime always serves registered routes with deep handlers or DB-backed stubs. """ from __future__ import annotations from collections.abc import Callable from starlette.middleware.base import BaseHTTPMiddleware from starlette.requests import Request from starlette.responses import Response from app.vsphere.contracts.matrix import available_for_request class VsphereVersionGateMiddleware(BaseHTTPMiddleware): async def dispatch(self, request: Request, call_next: Callable) -> Response: path = request.url.path if not (path.startswith("/api/") or path.startswith("/rest/")): return await call_next(request) major = getattr(request.app.state, "vsphere_contract_major", 9) # Touch resolver so unknown paths still fall through to FastAPI 404 / # stub catch-all; registered paths are never version-blocked. available_for_request(request.method, path, int(major)) return await call_next(request)