Skip to content

[CI] (6fb03e7) tanstack-start/tanstack-start-saas#1490

Closed
wizard-ci-bot[bot] wants to merge 1 commit into
mainfrom
wizard-ci-6fb03e7-tanstack-start-tanstack-start-saas
Closed

[CI] (6fb03e7) tanstack-start/tanstack-start-saas#1490
wizard-ci-bot[bot] wants to merge 1 commit into
mainfrom
wizard-ci-6fb03e7-tanstack-start-tanstack-start-saas

Conversation

@wizard-ci-bot
Copy link
Copy Markdown

@wizard-ci-bot wizard-ci-bot Bot commented May 13, 2026

Automated wizard CI run

Source: scheduled
Trigger ID: 6fb03e7
App: tanstack-start/tanstack-start-saas
App directory: apps/tanstack-start/tanstack-start-saas
Workbench branch: wizard-ci-6fb03e7-tanstack-start-tanstack-start-saas
Wizard branch: main
Context Mill branch: main
PostHog (MCP) branch: master
Timestamp: 2026-05-13T17:51:13.104Z
Duration: 345.3s

@wizard-ci-bot
Copy link
Copy Markdown
Author

wizard-ci-bot Bot commented May 13, 2026


PR Evaluation Report

Summary

This PR integrates PostHog into a TanStack Start SaaS invoicing app (CloudFlow). It adds client-side tracking via PostHogProvider in the root layout, server-side event capture via posthog-node singleton, a Vite dev-server reverse proxy, and custom event captures for invoice creation and payment flows on both client and server.

Files changed Lines added Lines removed
9 +153 -4

Confidence score: 5/5 🧙

  • Fabricated distinctId on server-side captures: Server routes use distinctId: \invoice-`` which is an invoice ID, not a user identifier. This creates orphaned person profiles in PostHog and fragments analytics data. Should use a real user ID or the distinct ID from the client session header. [CRITICAL]
  • No identify() call anywhere: There is no posthog.identify() in the app despite this being a full-stack app. The docs explicitly state "Identifying users is required." Without it, all events remain anonymous and cannot be associated with known users. [CRITICAL]
  • No posthog.shutdown() on server: The server-side API routes capture events but never call await posthog.shutdown(). Per the TanStack Start docs, this is required to flush queued events before the response completes. Events may be silently lost. [MEDIUM]

File changes

Filename Score Description
package.json 5/5 Adds @posthog/react, posthog-js, and posthog-node dependencies
src/routes/__root.tsx 4/5 Wraps app with PostHogProvider; defaults date is 2025-05-24 instead of recommended 2026-01-30
src/utils/posthog-server.ts 4/5 Server-side singleton using posthog-node with correct flush config
vite.config.ts 4/5 Reverse proxy for /ingest, /ingest/static, /ingest/array — dev-server only
src/routes/posts.index.tsx 4/5 Client-side invoice_created capture in form submit handler with error tracking
src/routes/posts..tsx 4/5 Client-side invoice_paid capture in click handler with error tracking
src/routes/api/invoices.ts 2/5 Server capture uses fabricated distinctId, no shutdown
src/routes/api/invoices..pay.ts 2/5 Server capture uses fabricated distinctId, no shutdown
posthog-setup-report.md 3/5 Wizard report documenting changes and next steps

App sanity check ⚠️

Criteria Result Description
App builds and runs Yes All syntax is valid, dependencies added correctly
Preserves existing env vars & configs Yes Only adds PostHog-related config; existing code intact
No syntax or type errors Yes All files are syntactically valid TypeScript/TSX
Correct imports/exports Yes @posthog/react, posthog-js, posthog-node all imported correctly
Minimal, focused changes Yes All changes relate to PostHog integration
Pre-existing issues None Base app appears functional

Issues

  • No posthog.shutdown() on server routes: Server-side captures in api/invoices.ts and api/invoices..pay.ts never call await posthog.shutdown(). With flushAt: 1 this may still work in many cases since the singleton persists, but events could be lost on cold starts or process termination. The TanStack Start docs explicitly recommend calling shutdown. [MEDIUM]

Other completed criteria

  • All changes are PostHog-related with no unrelated edits
  • Package.json correctly updated with all three PostHog packages
  • Environment variables documented in .env file and wizard report
  • Build configuration (vite.config.ts) is valid

PostHog implementation ⚠️

Criteria Result Description
PostHog SDKs installed Yes posthog-js@^1.373.4, @posthog/react@^1.9.0, posthog-node@^5.34.1 added
PostHog client initialized Yes PostHogProvider in __root.tsx with apiKey from env var; server singleton in posthog-server.ts
capture() Yes invoice_created and invoice_paid on both client and server
identify() No No posthog.identify() call anywhere in the app. No posthog.reset() on logout either
Error tracking Yes capture_exceptions: true in config + manual posthog.captureException() in catch blocks
Reverse proxy Yes Vite dev proxy routes /ingest/* to PostHog with correct /ingest/static and /ingest/array routing to us-assets.i.posthog.com

Issues

  • No user identification: There is no posthog.identify() call anywhere in the codebase. The docs state this is required to link events to known users. All client and server events will remain anonymous, making it impossible to build user-level funnels or retention analysis. [CRITICAL]
  • Fabricated distinctId on server: Server-side captures use distinctId: \invoice-`— an invoice identifier, not a user identifier. This creates phantom person profiles in PostHog (one per invoice) and fragments data. Should use a real user ID from authentication context, or at minimum theX-PostHog-Distinct-Id` header from the client. [CRITICAL]
  • Reverse proxy is dev-only: The Vite server.proxy configuration only applies during vite dev. In production, api_host: '/ingest' will fail since no production proxy (e.g., Nitro middleware or hosting provider rewrite) is configured. [MEDIUM]

Other completed criteria

  • API key loaded from VITE_PUBLIC_POSTHOG_PROJECT_TOKEN environment variable
  • Host correctly configured via reverse proxy pointing to us.i.posthog.com and us-assets.i.posthog.com
  • Server-side PostHog client uses correct singleton pattern with flushAt: 1 and flushInterval: 0
  • capture_exceptions: true enables automatic exception capture

PostHog insights and events ⚠️

Filename PostHog events Description
src/routes/posts.index.tsx invoice_created, captureException Captures invoice creation on form submit with title, amount, due_date properties; exceptions on failure
src/routes/posts..tsx invoice_paid, captureException Captures invoice payment on button click with invoice_id, title, amount; exceptions on failure
src/routes/api/invoices.ts invoice_created Server-side duplicate of creation event with additional source and session_id properties
src/routes/api/invoices..pay.ts invoice_paid Server-side duplicate of payment event with session_id correlation

Issues

  • Fabricated distinctId undermines event quality: Server events with distinctId: \invoice-`` cannot be correlated to real users, making server-side events analytically useless for person-level analysis. The events themselves are well-structured but orphaned from user profiles. [CRITICAL]
  • Duplicate client+server events: Both invoice_created and invoice_paid are captured on client AND server. Without proper distinct_id alignment, these will appear as events from different "users" and cannot be deduplicated. With proper user IDs this would be fine for data validation, but as-is it doubles noise. [MEDIUM]

Other completed criteria

  • Events represent real user actions (creating invoices, paying invoices)
  • Events enable product insights (invoice_created → invoice_paid funnel)
  • Events include relevant properties (amounts, titles, IDs, source)
  • No PII in event properties
  • Event names are descriptive and use consistent snake_case naming

Reviewed by wizard workbench PR evaluator

@wizard-ci-bot wizard-ci-bot Bot added the CI/CD label May 13, 2026
@wizard-ci-bot wizard-ci-bot Bot closed this May 13, 2026
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