feat(customer-analytics): add account health score prototype#11
Open
lordspline wants to merge 4 commits into
Open
feat(customer-analytics): add account health score prototype#11lordspline wants to merge 4 commits into
lordspline wants to merge 4 commits into
Conversation
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Customer analytics users need an actionable way to assess account health at a glance. Historically, they've asked to prioritize outreach based on engagement patterns—identifying which accounts are thriving, which are at risk, and which need intervention. A clear, transparent scoring mechanism helps users make data-driven decisions without relying on opaque "magic numbers" or LLM-generated summaries that may drift over time.
Changes
This PR introduces a query-time account health score for Customer analytics, computed on demand from existing activity metrics. The score (0–100) and its contributing factors appear in the accounts list and in a new Health tab on account detail rows.
Backend (
products/customer_analytics/backend/hogql_queries/):account_health_score.py(new): Core scoring contract and calculator. Determines 30-day activity metrics (current/previous windows, active users, active days, last activity), normalizes against team baselines (p90 activity count, p90 active users), and aggregates five weighted factors into a global score. Status mapping: healthy (≥75), neutral (≥40), at risk (<40), no_data (no activity or missing configuration). No LLMs, no persisted scores.accounts_query_runner.py: Addshealth_scoreas a default column, resolves it post-query, and batches baseline + metrics queries for efficiency. Filters out health-score ordering clauses at the query layer (fallback to default ordering) because scores are computed per-page-row.test/test_accounts_query_runner.py: Adds 12 new test methods covering normalization, no-data conditions, team isolation, unsupported activity sources, batched query execution, and ordering fallback.Frontend (
products/customer_analytics/frontend/components/Accounts/):AccountHealthScore.tsx(new): Types (AccountHealthScore,AccountHealthStatus,AccountHealthFactor), parser (parseAccountHealthScore), badge renderer (AccountHealthScoreBadgewith accessible label), and explanation view (AccountHealthScoreExplanation) showing score, status, lookback window, and grid of factor details (value, previous, weight, per-factor description).AccountHealthScore.test.tsx(new): Unit tests for parsing, badge rendering, and explanation display across all four status buckets.AccountsHogQLTable.tsx: Addshealth_scorecolumn template with badge renderer, pipes health-score cell toAccountNotebooksExpansionon row expand, and marks column as non-sortable.AccountNotebooksExpansion.tsx: Adds Health tab (new, becomes default) containingAccountHealthScoreExplanation. Receives health score as a prop and passes it to the health tab content.accountsExpansionLogic.ts: ExpandsAccountExpansionTabto include'health'and sets it as the new default tab.accountsLogic.ts: AddsNON_SORTABLE_COLUMNSset and helperisAccountsColumnSortable()to disable sort toggling onhealth_score.accountsColumnConfigLogic.ts: Adds'health_score'to default select, defines an'account_health'column group for the column picker, and exposesACCOUNTS_HEALTH_SCORE_COLUMNconstant.AccountsMaxTools.tsx: UpdatesOpenAccountTooldefault tab from'usage'to'health'.Stories/docs (
products/customer_analytics/frontend/components/Accounts/):AccountsTab.stories.tsx: AddsRowExpandedHealthScorestory and fixture helpers (healthScore()) demonstrating all four statuses with rich factor data. Updates mock responses to include health-score column.AGENTS.md: Documents expanded row structure (Health tab now first), column contract (synthetichealth_score), and addscustomer analytics account tab viewedevent tracking for'health'.Max tools (
products/customer_analytics/backend/max_tools/):open_account.py: Updates description and signature to default to'health'tab.test/test_open_account.py: Updates test assertion for new default tab.How did you test this code?
test_accounts_query_runner.py(64) andtest_open_account.py(4). Covered normalization, baseline/metrics batching, team isolation, no-data fallbacks, unsupported activity sources, and ordering safety.AccountHealthScore.test.tsxandaccountsLogic.test.ts. Tested parsing, badge rendering, factor explanation, non-sortable column behavior, and storybook interactions with MSW mocks./home/account-health-evidence/*.pngfor all states.As an agent, I did not perform manual exploratory testing. All verification came from automated tests and scripted browser evidence.
🤖 Agent context
Autonomy: Fully autonomous
Implemented vertical slice for account health scoring:
AccountsQueryRunner,system.accounts, hogQL-based metrics) andTeamCustomerAnalyticsConfigfor activity event/group source configuration.AccountsQueryResponse.resultsonly whenhealth_scorecolumn is selected.Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.