Skip to content

[CI] (3393d57) tanstack-router/tanstack-router-code-based-saas#899

Closed
wizard-ci-bot[bot] wants to merge 1 commit intomainfrom
wizard-ci-3393d57-tanstack-router-tanstack-router-code-based-saas
Closed

[CI] (3393d57) tanstack-router/tanstack-router-code-based-saas#899
wizard-ci-bot[bot] wants to merge 1 commit intomainfrom
wizard-ci-3393d57-tanstack-router-tanstack-router-code-based-saas

Conversation

@wizard-ci-bot
Copy link

@wizard-ci-bot wizard-ci-bot bot commented Mar 17, 2026

Automated wizard CI run

Source: wizard-pr
Trigger ID: 3393d57
App: tanstack-router/tanstack-router-code-based-saas
App directory: apps/tanstack-router/tanstack-router-code-based-saas
Workbench branch: wizard-ci-3393d57-tanstack-router-tanstack-router-code-based-saas
Wizard branch: release-please--branches--main--components--wizard
Context Mill branch: main
PostHog (MCP) branch: master
Timestamp: 2026-03-17T00:40:06.266Z
Duration: 456.2s

@wizard-ci-bot
Copy link
Author

wizard-ci-bot bot commented Mar 17, 2026

Now I have all the information I need to produce the evaluation.


PR Evaluation Report

Summary

This PR integrates PostHog analytics into a TanStack Router-based SaaS demo app (CloudFlow). It installs posthog-js and @posthog/react, wraps the root component in PostHogProvider, adds a Vite dev-server reverse proxy for /ingest, captures six business events, identifies users on login, resets on logout, and enables error tracking via capture_exceptions.

Files changed Lines added Lines removed
6 +101 -8

Confidence score: 4/5 👍

  • PII in capture event properties: user_signed_in includes username in event properties, and team_member_viewed includes user_name. These should be person properties via identify() or ``, not event properties. [MEDIUM]
  • Username as distinct_id: posthog.identify(username) uses a user-typed username as the distinct ID. This is fragile — usernames can be case-inconsistent, changeable, or non-unique in some systems. A stable internal user ID would be preferred, though this demo app only has usernames as identifiers. [LOW]
  • No .env.example file: While .env is gitignored and the env vars are documented in the setup report, there is no .env.example committed to help new developers set up. [MEDIUM]
  • Reverse proxy is dev-only: The Vite proxy only works in development (server.proxy). In production builds there is no reverse proxy configured — requests would go to /ingest and fail. [MEDIUM]

File changes

Filename Score Description
src/main.tsx 4/5 Core integration: PostHogProvider wrapping root, identify on login, reset on logout, 6 capture events with properties
vite.config.js 3/5 Adds dev-server reverse proxy for /ingest — only works in dev mode, not production
package.json 5/5 Adds posthog-js and @posthog/react dependencies correctly
.gitignore 5/5 Adds .env to gitignore
src/vite-env.d.ts 5/5 Adds Vite client types reference for import.meta.env
posthog-setup-report.md 4/5 Clear documentation of changes and next steps

App sanity check ⚠️

Criteria Result Description
App builds and runs Yes Valid syntax, dependencies installed, Vite config valid
Preserves existing env vars & configs Yes Only additive changes to existing files
No syntax or type errors Yes TypeScript/JSX is well-formed, vite-env.d.ts added for import.meta.env
Correct imports/exports Yes @posthog/react package exists and exports PostHogProvider and usePostHog
Minimal, focused changes Yes All changes relate to PostHog integration
Pre-existing issues None Base app is functional

Issues

  • No .env.example committed: The .env file is gitignored but no .env.example or equivalent is committed to guide new developers on required environment variables. The setup report documents them but is not a standard convention. [MEDIUM]

Other completed criteria

  • All changes are relevant to PostHog integration
  • Code follows existing codebase patterns (hooks, event handlers, component structure)
  • Build configuration remains valid with additive Vite proxy config

PostHog implementation ⚠️

Criteria Result Description
PostHog SDKs installed Yes posthog-js ^1.360.2 and @posthog/react ^1.8.2 added to package.json
PostHog client initialized Yes PostHogProvider wraps root with apiKey from env, correct options including defaults, api_host, ui_host
capture() Yes 6 meaningful capture calls: user_signed_in, user_signed_out, invoice_created, invoice_updated, upgrade_clicked, team_member_viewed
identify() Yes Called on login with username; posthog.reset() called on both logout paths
Error tracking Yes capture_exceptions: true enabled in PostHogProvider options
Reverse proxy No Vite server.proxy only applies in dev mode; production builds have no proxy, so /ingest requests will 404

Issues

  • Reverse proxy is dev-only: The Vite server.proxy configuration only works during development. In production, requests to /ingest will not be proxied and will fail. A production-ready solution (e.g., Vercel rewrites, nginx config, or Cloudflare proxy) is needed, or the api_host should fall back to the direct PostHog host in production. [MEDIUM]
  • Username as distinct_id: posthog.identify(username, { username }) uses a free-form text input as the distinct ID. In this demo app there's no better identifier available, but in a real app this would cause fragmentation if usernames change or are case-sensitive. [LOW]

Other completed criteria

  • API key loaded from VITE_PUBLIC_POSTHOG_PROJECT_TOKEN environment variable (not hardcoded)
  • Host configured via environment variable VITE_PUBLIC_POSTHOG_HOST
  • posthog.reset() correctly called on both logout code paths
  • defaults: '2026-01-30' included in initialization options
  • debug: import.meta.env.DEV only enables debug mode in development

PostHog insights and events ⚠️

Filename PostHog events Description
src/main.tsx user_signed_in Captured on login with { username } — enables sign-in tracking
src/main.tsx user_signed_out Captured on both logout paths (profile page and login page)
src/main.tsx invoice_created Captured on mutation success with { invoice_id, invoice_title } — core business action
src/main.tsx invoice_updated Captured on mutation success with { invoice_id, invoice_title } — tracks edits
src/main.tsx upgrade_clicked Captured on upgrade button click with { current_plan: 'free' } — monetization signal
src/main.tsx team_member_viewed Captured on team member link click with { user_id, user_name, role } — engagement tracking
src/main.tsx capturedException Automatic via capture_exceptions: true — error tracking

Issues

  • PII in event properties: user_signed_in captures { username } as an event property, and team_member_viewed captures { user_name } (the viewed user's full name). Usernames/names are PII and should be set as person properties via identify() or ``, not included in capture() event properties. The `username` in `user_signed_in` is redundant since `identify()` is called on the same line. The `user_name` in `team_member_viewed` is the name of another user being viewed — this is PII about a third party in event properties. [MEDIUM]

Other completed criteria

  • Events represent real user actions mapped to actual product flows
  • Events enable product insights (sign-in → invoice funnel, upgrade intent, team engagement)
  • Events include relevant contextual properties (invoice IDs, plan info, user IDs)
  • Event names are descriptive and use consistent snake_case convention

Reviewed by wizard workbench PR evaluator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants