🌐 US-Proxy
class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
Skip to content

feat: wire up Template Builder session telemetry endpoint - #27124

Merged
jeremyruppel merged 11 commits into
mainfrom
jeremy/devex-599-wire-up-template-builder-session-telemetry-pipeline
Jul 27, 2026
Merged

feat: wire up Template Builder session telemetry endpoint#27124
jeremyruppel merged 11 commits into
mainfrom
jeremy/devex-599-wire-up-template-builder-session-telemetry-pipeline

Conversation

@jeremyruppel

@jeremyruppel jeremyruppel commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

TemplateBuilderSession telemetry types and telemetry-server ingestion were added in earlier PRs (#25082, coder/coder-telemetry-server#41), but no code ever produced session events. This adds the missing producer.

Backend: POST /api/v2/templatebuilder/sessions reports wizard entry and compose completion events directly via api.Telemetry.Report(), using the same inline pattern as NetworkEvents and UserTailnetConnections. No database migration or createSnapshot() changes needed. RBAC requires policy.ActionCreate on ResourceTemplate.AnyOrganization(), matching the compose endpoint.

Frontend: The template builder wizard fires wizard_entry on page mount and compose_completion on create success or failure. A client-generated session ID (UUID) correlates the two events for the same wizard visit, enabling precise funnel analysis and abandonment detection in BigQuery. Duration is tracked via Date.now() in the wizard state.

Closes https://linear.app/codercom/issue/DEVEX-599

Implementation plan

Root Cause Analysis

The DEVEX-599 ticket diagnosis suggested missing DB tables, queries, and eg.Go blocks. That diagnosis assumes the DB-backed periodic snapshot path is required. It is not. Investigation shows two telemetry reporting patterns in the codebase:

  1. DB-backed periodic snapshots (createSnapshot() with eg.Go blocks): Used for durable entities like workspaces, templates, users.
  2. Direct inline reporting (api.Telemetry.Report(&telemetry.Snapshot{...})): Used for ephemeral events like NetworkEvents, UserTailnetConnections, CLIInvocations.

Template builder sessions are ephemeral events, so the direct inline reporting pattern is the correct fit.

Backend Changes

  • codersdk/templatebuilder.go: TemplateBuilderSessionRequest type with SessionID, EventType enum, TemplateBuilderSession() client method
  • coderd/coderd.go: Route registration in /templatebuilder group
  • coderd/templatebuilder_handler.go: Handler with RBAC check, request validation, session ID fallback, and inline telemetry report
  • coderd/templatebuilder_handler_test.go: Tests for wizard entry, compose completion, invalid event type, disabled feature, and member RBAC rejection

Frontend Changes

  • site/src/api/api.ts: recordTemplateBuilderSession API method
  • site/src/api/queries/templateBuilder.ts: React Query mutation
  • site/src/pages/TemplateBuilder/wizardState.ts: sessionId and enteredAt fields, createWizardState() factory for per-mount initialization
  • site/src/pages/TemplateBuilder/TemplateBuilderPageView.tsx: sessionId prop, useReducer initializer form
  • site/src/pages/TemplateBuilder/TemplateBuilderPage.tsx: Telemetry calls for wizard entry (on mount) and compose completion (on create success/failure)

🤖 Generated by Coder Agents

@linear-code

linear-code Bot commented Jul 9, 2026

Copy link
Copy Markdown

DEVEX-599

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

Docs preview

Check off each page once it's been reviewed. If a page changes in a later push, its checkbox clears automatically so it gets a fresh look. Pages not yet wired into the docs navigation aren't listed here.

@jeremyruppel jeremyruppel changed the title feat(coderd/templatebuilder): wire up session telemetry endpoint feat: wire up Template Builder session telemetry endpoint Jul 9, 2026
@jeremyruppel
jeremyruppel marked this pull request as ready for review July 9, 2026 14:59
jeremyruppel and others added 7 commits July 27, 2026 13:49
Add POST /api/v2/templatebuilder/sessions to report template builder
session events (wizard_entry, compose_completion) for telemetry. Uses
direct inline reporting via api.Telemetry.Report() matching the pattern
used by NetworkEvents and UserTailnetConnections.

RBAC: requires policy.ActionCreate on ResourceTemplate (same as compose).

No database table or migration needed; events are reported as partial
telemetry snapshots.
Wire up the frontend to call POST /api/v2/templatebuilder/sessions:

- wizard_entry: fired once when the builder page becomes ready
- compose_completion: fired on create success or failure, includes
  base_template_id, module_ids, duration_seconds, and success flag

Duration is tracked via Date.now() stored in the wizard state at
initialization, then computed as elapsed seconds on create submission.
Add a client-supplied session_id (UUID) that correlates wizard_entry
and compose_completion events for the same wizard visit. This enables
precise funnel analysis and abandonment detection in BigQuery without
relying on timestamp proximity heuristics.

The session ID is generated once per page mount via crypto.randomUUID()
and threaded through the wizard state. The backend falls back to
uuid.New() if the client omits it.
…requests

Reject requests with a missing session_id as 400 Bad Request via the
validate:"required" struct tag instead of silently fabricating a UUID
server-side. A missing session ID is a client bug.
Regenerate docs/reference/api/templatebuilder.md so the code sample fence
matches generator output (sh, not shell), fixing the gen and offlinedocs
unstaged-changes checks. Drop the unused export on WizardInit to satisfy
the frontend knip lint check.

Co-authored-by: Coder Agent <agent@coder.com>
@jeremyruppel
jeremyruppel force-pushed the jeremy/devex-599-wire-up-template-builder-session-telemetry-pipeline branch from ea6edd3 to 1b06396 Compare July 27, 2026 13:54
@jeremyruppel
jeremyruppel requested a review from a team as a code owner July 27, 2026 13:54
Drop the reportSession alias in favor of calling sessionMutation.mutate
directly, and extract the duplicated compose_completion payload into a
reportCompletion helper.
…elpers

Extract reportEntry and reportCompletion helpers to dedupe the session
telemetry payloads, replacing the reportSession alias and the repeated
compose_completion mutate calls.
…lpers together

Move reportEntry and reportCompletion to component scope as useCallback
hooks so both telemetry payloads are defined side by side.
reportCompletion takes state and duration as parameters since state is
only available inside handleCreate.
BaseTemplateID string `json:"base_template_id,omitempty"`
ModuleIDs []string `json:"module_ids,omitempty"`
DurationSeconds float64 `json:"duration_seconds,omitempty"`
Success bool `json:"success,omitempty"`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thinking out loud here - these events events are aggregated outside of the Coder deployement - I think you mentioned BigQuery, right? So if these fields are missing, would BigQuery be able to do searches for ... WHERE success = false ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep it's bigquery on the other side, and the struct we use in the telemetry server has Success bool, so if Success is omitted from this payload, it'll default to false before hitting bigquery.

this is a little confusing in the case of event_type = "wizard_entry" because it's meaningless there, but we can always AND event_type = "compose_completion"

@fioan89 fioan89 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jeremyruppel
jeremyruppel merged commit 51ac968 into main Jul 27, 2026
52 of 54 checks passed
@jeremyruppel
jeremyruppel deleted the jeremy/devex-599-wire-up-template-builder-session-telemetry-pipeline branch July 27, 2026 20:10
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 27, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants