Spaces:
Running
Running
| """PostHog product analytics — privacy-safe by construction. | |
| Only event *metadata* is ever sent (file type, char count, effect size, p-value, | |
| winner). Raw resume text never leaves the process. If ``POSTHOG_KEY`` is unset the | |
| functions are silent no-ops, so the app runs fully without analytics. | |
| """ | |
| from __future__ import annotations | |
| import os | |
| from functools import lru_cache | |
| # Canonical event names (see docs/business + PostHog plan). | |
| EVENTS = { | |
| "app_loaded": "app_loaded", | |
| "resume_a_uploaded": "resume_a_uploaded", | |
| "resume_b_uploaded": "resume_b_uploaded", | |
| "comparison_run": "comparison_run", | |
| "verdict_revealed": "verdict_revealed", | |
| "methodology_toggled": "methodology_toggled", | |
| "per_cluster_sorted": "per_cluster_table_sorted", | |
| "pdf_downloaded": "pdf_report_downloaded", | |
| } | |
| def _client(): | |
| key = os.getenv("POSTHOG_KEY", "").strip() | |
| if not key: | |
| return None | |
| try: | |
| from posthog import Posthog | |
| return Posthog( | |
| project_api_key=key, | |
| host=os.getenv("POSTHOG_HOST", "https://us.i.posthog.com"), | |
| ) | |
| except Exception: # noqa: BLE001 - analytics must never break the app | |
| return None | |
| def capture(distinct_id: str, event: str, properties: dict | None = None) -> None: | |
| """Best-effort event capture. Never raises; never sends resume content.""" | |
| client = _client() | |
| if client is None: | |
| return | |
| try: | |
| client.capture(distinct_id=distinct_id, event=event, properties=properties or {}) | |
| except Exception: # noqa: BLE001 | |
| pass | |