Skip to content

feat(product-events): identify Maple's own events per org and user, and cover in-product actions - #2473

Merged
JeremyFunk merged 1 commit into
mainfrom
feat/product-events-identity
Nov 11, 2026
Merged

JeremyFunk merged 1 commit into
mainfrom
feat/product-events-identity

feat(product-events): identify Maple's own events per org and user, a…

ca6620f
Select commit
Loading
Failed to load commit list.
Maple Review Bot / Maple / review succeeded Nov 11, 2026 in 5m 30s

Confidence 10/10 · No issues found

🟢 Confidence 10/10 · safe to merge. Every source hunk is read and the identity, webhook and span-attribute paths are test-pinned; only new test-file diffs went unread.
no findings · tests covered · risk medium · 3/3 new units observable

Identifies Maple's own product events with Clerk user and org, stops server events being projected twice as trace rows, and adds in-product events across web, webhook and MCP. Identity, dedupe and success-guard paths check out; safe to merge, but the Clerk webhook must be registered to deliver anything.

  • ProductEvents.track renames its span attributes to maple.product_events.*, ending duplicate trace-sourced rows
  • identify() carries role and plan traits and re-runs when the customer read settles
  • Webhook and existing spans identify member_joined/member_removed, mcp_tool_called, investigation_started
  • Ten new web events cover invites, disconnects, acknowledgements and created objects

Before merge

  • Manual · Register POST /webhooks/clerk in the Clerk dashboard for user.created and organizationMembership.*; until then signup_completed, member_joined and member_removed stay empty

Production impact

Telemetry this change adds and removes (5)
  • ➖ attribute maple.product_event.name (~5/day today) · packages/backend/src/services/product-events/ProductEventsService.ts:166
  • ➖ attribute maple.product_event.enabled (~5/day today) · packages/backend/src/services/product-events/ProductEventsService.ts:166
  • ➕ attribute maple.product_events.event · packages/backend/src/services/product-events/ProductEventsService.ts:166
  • ➕ attribute maple.product_events.enabled · packages/backend/src/services/product-events/ProductEventsService.ts:167
  • ➕ attribute maple.product_events.dropped · packages/backend/src/services/product-events/ProductEventsService.ts:192
What was checked
  • Empty include projects zero span attributes: present-and-empty keeps no key in mapFilter (product-event-attributes.ts:106)
  • member_removed is tracked only on a 200, and revoke answers 500 only when the sweep fails (clerk.http.ts:59)
  • chain accumulates every step's commands, so the added TrackDisconnected steps are not dropped (update-status.ts:42)
Observability coverage: 3 of 3 changes observable
Change Kind Observable Evidence
mcp_tool_called on the public MCP surface span-derived product event yes Annotates the existing McpToolExecutor.execute span (apps/ai/src/mcp/dispatcher.ts:235), pinned by dispatcher.test.ts:318
investigation_started when a run is claimed span-derived product event yes packages/backend/src/services/errors/InvestigationService.ts:604 annotates the claim's span with user, org and subject_type
member_joined / member_removed from the Clerk webhook server product event yes Tracked inside the ClerkWebhook.membership span (clerk.http.ts:111, :122); ProductEvents.track annotates and logs a drop

ca6620f · Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.