Skip to content

Commit 1e57831

Browse files
feat(inbox): surface health check issues as inbox signals
Adds the `health_checks` / `health_issue` signal source to the Inbox so instrumentation issues PostHog's health checks detect (missing events, reverse-proxy gaps, outdated SDKs, ingestion warnings, broken warehouse models) reach the Self-driving inbox. Mirrors PostHog/posthog#61955. Not gated behind a feature flag — per-team enablement is handled by `SignalSourceConfig` on the Cloud backend. - Add `health_checks` to the `SourceProduct` union, `SignalSourceConfig` (`source_product` + `health_issue` `source_type`), and the `SignalSourceConnected` analytics event. - Wire it through the source toggle surface: `signalSourceService`, `useSignalSourceToggles`, and a "Health checks" toggle card under "PostHog data" in `SignalSourceToggles`. - Map the source to the Heartbeat icon in `SOURCE_PRODUCT_META`, `INBOX_SOURCE_OPTIONS`, the responder roster, and the desktop/mobile signal cards (matching the `IconHeartPlus` health icon used in the posthog repo). - Cover the new source in `signalSourceService.test.ts`. Generated-By: PostHog Code Task-Id: 2b579b6c-3075-475e-8a1f-021df07cb260
1 parent df1c8cb commit 1e57831

15 files changed

Lines changed: 84 additions & 5 deletions

File tree

apps/mobile/src/features/inbox/components/FilterSheet.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ const SOURCE_PRODUCT_OPTIONS: { value: SourceProduct; label: string }[] = [
7777
{ value: "zendesk", label: "Zendesk" },
7878
{ value: "conversations", label: "Conversations" },
7979
{ value: "signals_scout", label: "Scout" },
80+
{ value: "health_checks", label: "Health checks" },
8081
];
8182

8283
function SectionHeader({ title }: { title: string }) {

apps/mobile/src/features/inbox/components/SignalCard.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
Code,
1010
Compass,
1111
GithubLogo,
12+
Heartbeat,
1213
LinkSimple,
1314
Question,
1415
Robot,
@@ -53,6 +54,8 @@ function sourceLine(signal: Signal): string {
5354
)
5455
return "Scout · Cross-source issue";
5556
if (source_product === "signals_scout") return "Scout";
57+
if (source_product === "health_checks" && source_type === "health_issue")
58+
return "Health checks · Issue";
5659
const product = source_product.replace(/_/g, " ");
5760
const type = source_type.replace(/_/g, " ");
5861
return `${product} · ${type}`;
@@ -82,6 +85,8 @@ function SourceIcon({
8285
return <LinkSimple size={size} color={color} />;
8386
case "signals_scout":
8487
return <Compass size={size} color={color} />;
88+
case "health_checks":
89+
return <Heartbeat size={size} color={color} />;
8590
default:
8691
return <WarningCircle size={size} color={color} />;
8792
}

apps/mobile/src/features/inbox/stores/inboxFilterStore.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ export type SourceProduct =
2222
| "linear"
2323
| "zendesk"
2424
| "conversations"
25-
| "signals_scout";
25+
| "signals_scout"
26+
| "health_checks";
2627

2728
export const DEFAULT_STATUS_FILTER: SignalReportStatus[] = [
2829
"ready",

packages/api-client/src/posthog-client.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,8 @@ export interface SignalSourceConfig {
236236
| "conversations"
237237
| "error_tracking"
238238
| "pganalyze"
239-
| "signals_scout";
239+
| "signals_scout"
240+
| "health_checks";
240241
source_type:
241242
| "session_analysis_cluster"
242243
| "evaluation"
@@ -245,7 +246,8 @@ export interface SignalSourceConfig {
245246
| "issue_created"
246247
| "issue_reopened"
247248
| "issue_spiking"
248-
| "cross_source_issue";
249+
| "cross_source_issue"
250+
| "health_issue";
249251
enabled: boolean;
250252
config: Record<string, unknown>;
251253
created_at: string;

packages/core/src/inbox/signalSourceService.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ describe("computeSourceValues", () => {
6060
const values = computeSourceValues([config("github", "issue", true)]);
6161
expect(values.github).toBe(true);
6262
});
63+
64+
it("enables health_checks when its config is enabled", () => {
65+
const values = computeSourceValues([
66+
config("health_checks", "health_issue", true),
67+
]);
68+
expect(values.health_checks).toBe(true);
69+
});
6370
});
6471

6572
describe("deriveSourceStates", () => {
@@ -106,6 +113,17 @@ describe("SignalSourceService.toggleSource", () => {
106113
expect(client.createSignalSourceConfig).toHaveBeenCalledTimes(1);
107114
});
108115

116+
it("creates a health_checks config with the health_issue source type", async () => {
117+
const client = fakeClient();
118+
const service = new SignalSourceService();
119+
await service.toggleSource(client, 1, "health_checks", true, [], []);
120+
expect(client.createSignalSourceConfig).toHaveBeenCalledWith(1, {
121+
source_product: "health_checks",
122+
source_type: "health_issue",
123+
enabled: true,
124+
});
125+
});
126+
109127
it("ensures the issues table syncs with full_refresh for github before enabling", async () => {
110128
const client = fakeClient();
111129
const service = new SignalSourceService();

packages/core/src/inbox/signalSourceService.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export interface SignalSourceValues {
1515
zendesk: boolean;
1616
conversations: boolean;
1717
pganalyze: boolean;
18+
health_checks: boolean;
1819
}
1920

2021
export type SignalSourceProduct = keyof SignalSourceValues;
@@ -48,6 +49,7 @@ const SOURCE_TYPE_MAP: Record<
4849
zendesk: "ticket",
4950
conversations: "ticket",
5051
pganalyze: "issue",
52+
health_checks: "health_issue",
5153
};
5254

5355
const ERROR_TRACKING_SOURCE_TYPES: SourceType[] = [
@@ -74,6 +76,7 @@ const ALL_SOURCE_PRODUCTS: SignalSourceProduct[] = [
7476
"zendesk",
7577
"conversations",
7678
"pganalyze",
79+
"health_checks",
7780
];
7881

7982
function isWarehouseSource(
@@ -109,6 +112,7 @@ export function computeSourceValues(
109112
zendesk: false,
110113
conversations: false,
111114
pganalyze: false,
115+
health_checks: false,
112116
};
113117
if (!configs?.length) {
114118
return result;

packages/shared/src/analytics-events.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,8 @@ export interface SignalSourceConnectedProperties {
732732
| "zendesk"
733733
| "conversations"
734734
| "pganalyze"
735-
| "llm_analytics";
735+
| "llm_analytics"
736+
| "health_checks";
736737
/** True when this is a brand-new createSignalSourceConfig, false for re-enable of an existing config. */
737738
is_first_connection: boolean;
738739
/** True when the connection went through the DataSourceSetup wizard (warehouse OAuth path). */

packages/shared/src/inbox-types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ export type SourceProduct =
1414
| "zendesk"
1515
| "conversations"
1616
| "pganalyze"
17-
| "signals_scout";
17+
| "signals_scout"
18+
| "health_checks";

packages/ui/src/features/inbox/CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ When adding or changing UI, reuse those primitives first. Avoid encoding one-off
136136
- Do not put page-level Inbox title or navigation into the global app header; `InboxView` owns the Inbox page chrome.
137137
- Do not add a configure shortcut back into the Inbox header; Responders configuration is a sidebar destination.
138138
- Scout (`signals_scout`) is a real Cloud source product. Keep it covered wherever source products surface: `INBOX_SOURCE_OPTIONS`, `SOURCE_PRODUCT_META`, and the scout-name display in `SignalCard`.
139+
- Health checks (`health_checks` / `health_issue`) is a real Cloud source product — instrumentation issues (missing events, proxy gaps, outdated SDKs) surfaced from PostHog's health checks. Keep it covered wherever source products surface: the `SourceProduct` union, `SignalSourceConfig`, the source toggle (`SignalSourceToggles`, `useSignalSourceToggles`, `signalSourceService`), `SOURCE_PRODUCT_META`, `INBOX_SOURCE_OPTIONS`, and the source line in `SignalCard`.
139140
- Scout management UI (fleet configuration, run history) lives in `features/scouts/` and is backed by the PostHog Cloud scout endpoints (`/api/projects/{teamId}/signals/scout/`). Do not add scout controls that have no backing endpoint there.
140141
- Do not put preview shims or mock report data in `apps/code/index.html`; the app shell should stay minimal.
141142
- Do not call `electronTRPC` directly from Inbox code. Use the existing API client, React Query hooks, or tRPC client wrappers.

packages/ui/src/features/inbox/components/SignalSourceToggles.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
ChatsIcon,
66
CircleNotchIcon,
77
GithubLogoIcon,
8+
HeartbeatIcon,
89
KanbanIcon,
910
TicketIcon,
1011
VideoIcon,
@@ -24,6 +25,7 @@ export interface SignalSourceValues {
2425
zendesk: boolean;
2526
conversations: boolean;
2627
pganalyze: boolean;
28+
health_checks: boolean;
2729
}
2830

2931
interface SignalSourceToggleCardProps {
@@ -298,6 +300,10 @@ export function SignalSourceToggles({
298300
(checked: boolean) => onToggle("conversations", checked),
299301
[onToggle],
300302
);
303+
const toggleHealthChecks = useCallback(
304+
(checked: boolean) => onToggle("health_checks", checked),
305+
[onToggle],
306+
);
301307
const togglePgAnalyze = useCallback(
302308
(checked: boolean) => onToggle("pganalyze", checked),
303309
[onToggle],
@@ -326,6 +332,17 @@ export function SignalSourceToggles({
326332
docsUrl="https://posthog.com/docs/error-tracking"
327333
docsLabel="Error Tracking"
328334
/>
335+
<SignalSourceToggleCard
336+
icon={<HeartbeatIcon size={20} />}
337+
label="Health checks"
338+
description="Instrumentation issues — missing events, proxy gaps, outdated SDKs"
339+
checked={value.health_checks}
340+
onCheckedChange={toggleHealthChecks}
341+
disabled={disabled}
342+
syncStatus={sourceStates?.health_checks?.syncStatus}
343+
docsUrl="https://posthog.com/docs/product-analytics/troubleshooting"
344+
docsLabel="Health checks"
345+
/>
329346
<SignalSourceToggleCard
330347
icon={<ChatsIcon size={20} />}
331348
label="Support"

0 commit comments

Comments
 (0)