Skip to main content

The AI Executive view

/executive is a cross-survey, AI-powered leadership summary. It is deterministic-first: every number, anomaly, forecast and risk is computed from the existing reporting aggregates, and an AI narrative is layered on top — so the page never fails when the model is down.

Where it lives

  • Serviceapi/src/domains/insights.tsExecutiveInsightsService(db, ai).
  • Routesapi/src/routes/executive.ts: GET /v1/executive/insights (the payload) and POST /v1/executive/ask (natural-language Q&A grounded in the same snapshot). Gated on the executive.view permission and the executive feature flag.
  • Pagefrontend/src/pages/ExecutivePage.tsx.

How a report is built

  1. Gather one deterministic snapshot in a single tenant transaction, reusing existing reporting methods (npsSummaryAll, metricAll, volumeByDayAll, channelBreakdown, surveyPortfolio, leaderboard, alertStatusCounts/alertTotalsByRule, verbatim.sentimentBreakdown, keyDrivers) over a current + prior window (the ReportFilter has no prior-period field — two windows are computed). No new SQL was added.
  2. Compute deterministic insights: KPI deltas, an NPS forecast (least-squares projection), anomalies, a risk radar and an alerts digest.
  3. Enrich with one constrained-JSON Gemini call (ai.completeJson) → headline, summary, emerging themes, recommended actions, agent coaching, driver storyline, forecast framing. On failure the deterministic payload is returned with ai.available = false.

Caching

The full payload is cached server-side for 12 hours per (client_account, period/scope) in system.executive_insight_cache (owner connection, account-keyed; Database.get/setExecInsightCache). Repeat views and multiple viewers reuse it instead of re-running ~25 aggregates + the Gemini call. The Refresh button forces a recompute (?refresh=1); an AI-down result is not cached (so the next view retries). cachedAt drives the "Updated …" indicator.

Filtering

The Executive filter bar shows only the time period, defaulting to the last 30 days; the report uses that window. Survey/channel scope still applies for a scoped member (it's part of the cache key).