STATE-WP-0069 T04: meter workstream_id query-param aliases
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 3s

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.
This commit is contained in:
tegwick 2026-07-08 21:32:14 +02:00
parent b2b72b7327
commit 793a39a1a4
8 changed files with 181 additions and 15 deletions

View file

@ -3,7 +3,7 @@ from collections import defaultdict
from datetime import datetime
from typing import Any
from fastapi import APIRouter, Depends, HTTPException, Query, status
from fastapi import APIRouter, Depends, HTTPException, Query, Request, Response, status
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
@ -12,6 +12,7 @@ from api.models.managed_repo import ManagedRepo
from api.models.task import Task
from api.models.token_event import TokenEvent
from api.models.workplan import Workplan
from api.services.legacy_compat import meter_legacy_query_param
from api.schemas.token_event import (
RepoTokenSummary,
TokenAggregateRow,
@ -152,6 +153,7 @@ def _filter_query(
q,
*,
task_id: uuid.UUID | None = None,
workplan_id: uuid.UUID | None = None,
workstream_id: uuid.UUID | None = None,
repo_id: uuid.UUID | None = None,
ref_type: str | None = None,
@ -168,8 +170,9 @@ def _filter_query(
):
if task_id:
q = q.where(TokenEvent.task_id == task_id)
if workstream_id:
q = q.where(TokenEvent.workplan_id == workstream_id)
scope_id = workplan_id or workstream_id
if scope_id:
q = q.where(TokenEvent.workplan_id == scope_id)
if repo_id:
q = q.where(TokenEvent.repo_id == repo_id)
if ref_type:
@ -600,7 +603,10 @@ async def get_token_event(
@router.get("/", response_model=list[TokenEventRead])
async def list_token_events(
request: Request,
response: Response,
task_id: uuid.UUID | None = None,
workplan_id: uuid.UUID | None = None,
workstream_id: uuid.UUID | None = None,
repo_id: uuid.UUID | None = None,
ref_type: str | None = None,
@ -618,9 +624,19 @@ async def list_token_events(
limit: int = Query(100, le=1000),
session: AsyncSession = Depends(get_session),
) -> list[TokenEvent]:
if workstream_id is not None and workplan_id is None:
await meter_legacy_query_param(
session=session,
request=request,
response=response,
method="GET",
route="/token-events/",
replacement_ref="/token-events/?workplan_id=<workplan_id>",
)
q = _filter_query(
select(TokenEvent),
task_id=task_id,
workplan_id=workplan_id,
workstream_id=workstream_id,
repo_id=repo_id,
ref_type=ref_type,