fix(tradein/audit): exclude /api/v1/admin/* from api_request events
All checks were successful
CI Trade-In / changes (pull_request) Successful in 7s
CI / changes (pull_request) Successful in 7s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 4m52s

Admin viewing the audit/analytics dashboards hits /api/v1/admin/* which the
request-audit middleware logged as api_request — polluting top_paths and
activity counts with the dashboards' own traffic. Skip api_request for admin
paths; keep login (admin sign-in from an IP is still valid audit).
This commit is contained in:
bot-backend 2026-07-13 23:49:13 +03:00
parent c904fbf94e
commit 5025732d12
2 changed files with 37 additions and 8 deletions

View file

@ -40,14 +40,19 @@ class RequestAuditMiddleware(BaseHTTPMiddleware):
ua = request.headers.get("user-agent")
# Общий behavior/activity-поток — каждый authenticated API-запрос.
schedule_event(
event_type="api_request",
username=username,
ip=ip,
user_agent=ua,
path=path,
method=request.method,
)
# /api/v1/admin/* исключаем: это ops-действия (просмотр самих
# дашбордов аудита/аналитики), а не поведение пилота — иначе
# запросы дашборда зашумляют top_paths и счётчики активности.
# login ниже логируем всегда (вход админа с IP — валидный аудит).
if not path.startswith("/api/v1/admin/"):
schedule_event(
event_type="api_request",
username=username,
ip=ip,
user_agent=ua,
path=path,
method=request.method,
)
# Дедуплицированный login/IP-audit сигнал — максимум раз в день
# на (юзер, IP, устройство).

View file

@ -114,3 +114,27 @@ def test_audit_failure_does_not_break_response(client: TestClient) -> None:
assert resp.status_code == 200
assert resp.json() == {"ok": True}
def test_admin_path_excluded_from_api_request_but_login_kept() -> None:
"""/api/v1/admin/* — ops-действия (просмотр дашбордов аудита/аналитики), не
поведение пилота: api_request НЕ пишем (иначе дашборд зашумляет активность),
а login (вход админа с IP) остаётся валидным аудитом."""
app = FastAPI()
app.add_middleware(RequestAuditMiddleware)
@app.get("/api/v1/admin/analytics")
def analytics() -> dict[str, bool]:
return {"ok": True}
with (
patch("app.core.request_audit.schedule_event") as mock_schedule,
patch("app.core.request_audit.should_log_login", return_value=True),
):
resp = TestClient(app).get(
"/api/v1/admin/analytics", headers={"X-Authenticated-User": "admin"}
)
assert resp.status_code == 200
event_types = [c.kwargs["event_type"] for c in mock_schedule.call_args_list]
assert event_types == ["login"]