"""Хук before_send для GlitchTip/Sentry SDK (tradein-local, #396). Redact-ит consumer-PII (client_name / client_phone / client_email и пр.) из error events до отправки в GlitchTip — estimator/trade-in flow таскает эти поля, а send_default_pii=False их не покрывает (это user-data в request.data / extra / contexts, не PII-заголовки). """ from __future__ import annotations from typing import Any from sentry_sdk.types import Event _REDACTED = "[REDACTED]" # Ключи consumer-PII (нижний регистр; сверка case-insensitive). _PII_KEYS = frozenset( {"client_name", "client_phone", "client_email", "phone", "email", "name"} ) def _scrub(obj: Any) -> None: """Рекурсивно заменить значения PII-ключей в dict на [REDACTED] (in-place).""" if isinstance(obj, dict): for key, value in obj.items(): if isinstance(key, str) and key.lower() in _PII_KEYS: obj[key] = _REDACTED else: _scrub(value) elif isinstance(obj, list): for item in obj: _scrub(item) def scrub_pii_event(event: Event, _hint: dict[str, Any]) -> Event | None: """Redact consumer-PII из error event перед отправкой. Возвращает event (не None).""" if not isinstance(event, dict): return event request = event.get("request") if isinstance(request, dict): _scrub(request.get("data")) _scrub(event.get("extra")) _scrub(event.get("contexts")) return event