state-hub/api/services/legacy_compat.py
tegwick 793a39a1a4
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 3s
STATE-WP-0069 T04: meter workstream_id query-param aliases
Add legacy_compat helper and Deprecation headers when callers filter
/tasks, /decisions, /token-events, or /execution/launch-requests with
workstream_id. Preferred workplan_id filters are unchanged. Route removal
remains gated on legacy-meter zero-usage windows.
2026-07-08 21:32:14 +02:00

52 lines
No EOL
1.6 KiB
Python

"""Shared legacy REST compat metering (routes and query params)."""
from __future__ import annotations
import logging
from fastapi import Request, Response
from sqlalchemy.ext.asyncio import AsyncSession
from api.services.legacy_meter import identity_from_request, record_legacy_usage
logger = logging.getLogger(__name__)
_LEGACY_OWNER = "state-hub.api"
def mark_legacy_response(response: Response | None, replacement_ref: str) -> None:
if response is None:
return
response.headers["Deprecation"] = "true"
response.headers["X-StateHub-Replacement"] = replacement_ref
response.headers.append("Link", f'<{replacement_ref}>; rel="successor-version"')
def legacy_query_param_key(method: str, route: str, param: str = "workstream_id") -> str:
return f"rest_api:{method} {route}?{param}"
async def meter_legacy_query_param(
*,
session: AsyncSession,
request: Request | None,
response: Response | None,
method: str,
route: str,
replacement_ref: str,
param: str = "workstream_id",
) -> None:
interface_key = legacy_query_param_key(method, route, param)
mark_legacy_response(response, replacement_ref)
try:
await record_legacy_usage(
session,
interface_key=interface_key,
interface_kind="rest_api",
replacement_ref=replacement_ref,
owner_component=_LEGACY_OWNER,
replacement_verified=True,
identity=identity_from_request(request),
)
except Exception:
await session.rollback()
logger.warning("legacy-meter failed to record %s", interface_key, exc_info=True)