#1082 — Include healthy in lifecycle_status_counts so frontend doesn’t infer from merchant_status_counts

Repo: Twill-AI/facade State: open | Status: open Assignee: sparsh-twillpayments

Created: 2026-03-02 · Updated: 2026-03-02

Description

Summary

Today the API returns:

  • merchant_status_counts: counts by funnel status (e.g. approved, active, in_review, …).
  • lifecycle_status_counts: only activation_overdue, dormant, and churned.

“Healthy” merchants are those with processing status = null (see app/api/merchants_kpis.py: the status calc uses ELSE 'null' for healthy). The frontend currently has to infer the healthy count by combining these two sources (e.g. post-approval statuses minus the three lifecycle buckets), which is fragile and duplicates lifecycle logic on the client.

Goal: Add a healthy key inside lifecycle_status_counts (e.g. { activation_overdue: 2, dormant: 11, churned: 0, healthy: 31 }) so that:

  • Lifecycle logic stays server-side.
  • The API is self-consistent: every lifecycle status, including healthy, comes from the same source of truth.
  • The frontend no longer needs to infer healthy from two separate fields.

Current behaviour

  • Lifecycle status is computed in calculate_processing_status_for_all_merchants() in app/api/merchants_kpis.py and stored in merchant_kpi with metric_label = PROCESSING_STATUS and categorical_value in activation_overdue | dormant | churned | null (null = healthy).
  • In app/api/master_partners_router.py, fetch_partners_stats():
    • Builds lifecycle_status_counts from a query that excludes categorical_value = 'null' (see lifecycle_status_query filters around lines 205–207).
    • Ini

Notes

Add implementation notes, blockers, and context here

Add wikilinks to related people, meetings, or other tickets