Skip to Content
Living documentation — last reviewed 2026-05-28
FeaturesInsightsInsights — QA Plan

Insights — QA Plan

This is a scenario plan, not an execution record. Runtime verification is recorded separately; no production, responsive-coverage, or latency claim is implied.

Auth and roles

Use GET /organizations/:orgId/insights.

ScenarioExpected
Owner/admin with active org membership200; all 20 rules are eligible, empty rules omitted.
Coach with active org membership200; only the seven operations/engagement rules; finance, members, and leads rules are not evaluated.
Ordinary member or caller without active org membershipForbidden.
Foreign/nonexistent orgMembership authorization prevents treating it as an empty public feed.
Owner/admin analytics.org_insightsRead-only tool returns the same service projection.
Coach using SpotterDo not expect the HTTP feed’s role scope to apply to analytics.org_insights: its current tool registration is owner/admin-only. The coach’s dashboard HTTP feed remains allowed.

Organization isolation

ScenarioExpected
Different organizationsNo cross-org population, sample, or route-data leakage.

Full 20-rule matrix

Use the exact destinations for every row. Seed isolated populations so an empty-rule expectation is not obscured by another legitimate rule.

RulePopulation / boundary scenarioExpected
finance.outstanding_debtPositive debt on live, non-payment-cancelled and otherwise-cancelled rows; a former member who owes; a guardian_only seatLive and non-payment-cancelled rows count (former member included), otherwise-cancelled and guardian_only do not; total equals revenue summary and payments dashboard outstanding (analytics-vocabulary.int.spec.ts); tab=debt.
finance.failed_chargesFailed charge/recurring rows inside/outside rolling seven-day cutoff and other transaction types/statusesCount only eligible rows; warning below five, urgent at five; Transactions href.
finance.refunds_pendingOpen/closed/deleted manual-refund tasksOnly nondeleted open tasks; warning; not_completed&type=manual_refund.
finance.join_checkout_failedMore than 20 tasks, duplicate tasks for one person, foreign/inactive/deleted/staff membershipsUncapped distinct active member count, same-org linked-user match, task IDs ≤20, unique sample ≤3; urgent; not_completed&type=payment_follow_up.
members.at_risk_billingPast-due, debt-status and positive-balance members; a cancelled membership, a coach and a guardian_only seat with past-due rowsDistinct-member scope; cancelled/staff/guardian_only excluded; count equals ?paymentStatus=at_risk list size (analytics-vocabulary.int.spec.ts); sample ≤3; info/3 warning/10 urgent.
members.expiring_membershipsMultiple qualifying subscriptions per person, inactive member, cancelling/deleted/expired/outside-window subscriptionActive-member dedup, earliest eligible expiry sample; now through now+7d inclusive; warning at five; member sample action, root null.
members.low_creditsMultiple eligible balances, untracked credits, expired period, null period end, inactive memberActive-member dedup, lowest eligible balance sample; tracked balance ≤2 with time remaining/no end; info; root null.
members.notices_openRequest + notice for same person, resolved case, deleted subscription, SLA and effective-date boundariesCount cases, not unique members; deleted subscriptions excluded; unique sample ≤3. Severity info → warning past acknowledgement SLA → urgent when any qualifying uncontacted effective date ≤now+7d.
members.join_never_paidJoin-link membership younger/older than 24h, live subscription, activation, presale withdrawal, settled/refunded moneyGrace/history exclusions; warning/10 urgent; paymentStatus=not_paying.
members.presale_withdrawnCancelled presale withdrawal, re-buy/live replacement, deleted subscriptionActive-member win-back population; warning/5 urgent; paymentStatus=withdrawn.
members.recent_churnActivated cancellation inside/outside rolling 30 days and live replacementRecent-churn scope; info/3 warning/10 urgent; paymentStatus=churned.
members.invitations_lapsedInvited member whose every invitation expired/was revoked, one with a live invitation, a signed-up member, a cancelled membershipOnly non-cancelled lapsed members; info/10 warning; accountStatus=lapsed, and the roster filter lists the same people.
operations.tasks_overdueDue yesterday/today in org timezone; completed/cancelled/deleted tasksStrictly before org-local today only; warning/10 urgent; not_completed sorted by due date; oldest three samples informational.
operations.sessions_missing_workoutPublished upcoming session today with/without workout, already started, next-local-day, deletedOnly eligible sessions from now to next org midnight; warning; valid program/date/session sample actions, no generic root queue.
operations.waitlisted_bookingsSame member across sessions, duplicate booking rows, foreign/deleted membership, foreign/deleted/unpublished/past sessionDistinct members with matching ownership/deletion; no role/status restriction; distinct-session meta and sample ≤3 share eligibility; root null.
engagement.checkin_missedMultiple unanswered occurrences per person; archived occurrence; inactive/deleted/foreign roster; boundary in DST timezoneDistinct active roster people; strict < cutoff; cutoff org-local midnight fourteen dates earlier; info/5 warning/10 urgent; membership sample actions.
engagement.checkins_to_reviewAnswered, reviewed, archived check-in occurrencesOnly answered/unarchived occurrences; info; existing inline review queue; root null.
engagement.forms_missingSeveral pending forms per person; archived/answered forms; inactive/deleted/foreign rosterDistinct active roster people; warning at five; earliest pending form per person before sample cap; inline queue.
engagement.birthdaysActive member with no subscription, staff birthday, inactive/deleted member, today/+6/+7 dates, Dec→JanMembership-only scope; today through +6 inclusive; membership dedup and sample actions; info; no subscription requirement.
leads.attention_neededUnanswered inbound, overdue, due today, new unanswered, stale/waiting/archived/foreign leadShared lead attention states and clock; urgent for inbound/overdue, otherwise warning; sample ≤3; ranked lead-list href unchanged.

Case count versus membership context

  1. Seed two unresolved request/notice cases on one eligible person. Count and severity metadata include both cases; sample names that person once.
  2. Follow not_completed&type=cancellation_review; the Tasks tab and type are selected; it is not Members ending.
  3. Open Members paymentStatus=ending separately. Treat it as an ending-roster view, not a claim that its row count equals open requests/notices.

Real URL hydration and actions

  1. Direct-load, reload, and use back/forward for the three task links: tab=not_completed&type=manual_refund, payment_follow_up, and cancellation_review. Confirm matching tab/type and API fields.
  2. A malformed supported field must not discard other valid task fields. Date bounds are valid only for date_range; reversed/invalid dates are dropped. Filter changes reset pagination.
  3. tab=overdue is unsupported and falls back to Today. Do not fabricate an overdue-only open-task filter.
  4. /dashboard/payments?tab=debt selects Debt; supported tab navigation and history update state. Invalid tab falls back to Transactions. Failed charges link to Transactions without inventing a status/date filter.
  5. Follow a named missing-workout/waitlist sample with valid UUID program and session plus a real date. Confirm redirect to the correct program’s tab=schedule, selected week, and matching session detail.
  6. Missing/malformed program context falls back to Programs. Invalid optional date/session values are dropped individually; no global schedule queue is invented. Destination authorization still applies.
  7. Null-root rows have no root navigation. Named member/session sample links work where supplied; missing/unnamed samples do not create fake actions. Overdue-task samples remain informational.
  8. Check-in review expands inline; marking reviewed refreshes its queue/feed through the existing workflow. Missing forms expands the existing queue when actionable. Ask Spotter remains separate from row navigation.

Ordering, empty state, locale, and failures

  • Seed no qualifying population across all 20 rules: { data: [] } and explicit Action Center all-clear state.
  • Mixed severities sort urgent → warning → info; ties use descending count.
  • Check en/he/ru dictionary copy, count plurals, bounded sample names, language-prefixed destinations, and Hebrew logical-direction controls.
  • A rule error rejects the feed request; there is no per-rule isolation.
  • Record actual viewport and environment with any browser evidence; an 800×600 local smoke does not establish full responsive or production coverage.