Skip to content

[CI] (c537a08) tanstack-start/tanstack-start-saas#1534

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

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

Conversation

@wizard-ci-bot
Copy link
Copy Markdown

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

Automated wizard CI run

Source: manual
Trigger ID: c537a08
App: tanstack-start/tanstack-start-saas
App directory: apps/tanstack-start/tanstack-start-saas
Workbench branch: wizard-ci-c537a08-tanstack-start-tanstack-start-saas
Wizard branch: main
Context Mill branch: main
PostHog (MCP) branch: master
Timestamp: 2026-05-21T00:33:50.104Z
Duration: 378.3s

@wizard-ci-bot
Copy link
Copy Markdown
Author

wizard-ci-bot Bot commented May 21, 2026

Now I have all the context I need. Let me produce the evaluation.


PR Evaluation Report

Summary

This PR integrates PostHog into a TanStack Start SaaS invoicing app, adding both client-side (posthog-js/@posthog/react) and server-side (posthog-node) analytics. It includes a reverse proxy via Vite dev server, client-side event captures for invoice actions, server-side event captures in API routes, and exception autocapture. However, it is missing user identification, has broken server-side session correlation, and leaks PII in event properties.

Files changed Lines added Lines removed
11 +186 -4

Confidence score: 4/5 👍

  • No identify() calls anywhere — users are never identified, so all events remain anonymous and cannot be associated with known users across sessions or devices. [CRITICAL]
  • Server-side session correlation is broken__add_tracing_headers is not configured in posthog.init(), so X-PostHog-Session-Id / X-PostHog-Distinct-Id headers are never sent by the client. All server-side captures fall back to distinctId: 'anonymous', merging every anonymous user into a single person profile. [CRITICAL]
  • PII (user_name) in event propertiesteam_member_viewed includes user_name directly in capture properties. Names should be set via person properties, not event properties. [MEDIUM]
  • No posthog.shutdown() in API routes — server-side events may be lost if the process ends before flushing, especially in serverless/short-lived environments. [MEDIUM]

File changes

Filename Score Description
package.json 5/5 Adds posthog-js, @posthog/react, posthog-node correctly
src/routes/__root.tsx 3/5 PostHogProvider setup is correct, but missing __add_tracing_headers for server correlation
vite.config.ts 4/5 Correct reverse proxy config for /ingest/static, /ingest/array, /ingest (dev-only)
src/utils/posthog-server.ts 4/5 Singleton pattern with flushAt/flushInterval correct per docs
src/routes/posts.index.tsx 4/5 Client-side invoice_created capture in event handler
src/routes/posts..tsx 4/5 Client-side invoice_paid capture in event handler
src/routes/posts_..deep.tsx 4/5 invoice_paid and invoice_pdf_download_clicked captures in handlers
src/routes/users..tsx 2/5 PII in event properties; useEffect for page view tracking is acceptable but has PII issue
src/routes/api/invoices.ts 2/5 Server capture with broken header correlation and no shutdown
src/routes/api/invoices..pay.ts 2/5 Server capture with broken header correlation and no shutdown
posthog-setup-report.md 3/5 Wizard report file, not production code

App sanity check ⚠️

Criteria Result Description
App builds and runs Yes All imports resolve, packages added, no syntax issues
Preserves existing env vars & configs Yes Existing code preserved; only PostHog additions made
No syntax or type errors Yes All changed files are syntactically valid
Correct imports/exports Yes @posthog/react, posthog-node, posthog-js imports are all correct
Minimal, focused changes Yes All changes relate to PostHog integration
Pre-existing issues None No pre-existing issues detected

Issues

  • Environment variables not documented: No .env.example file was created or updated. The .env file exists but is not committed (not in the diff). New users would not know VITE_PUBLIC_POSTHOG_PROJECT_TOKEN and VITE_PUBLIC_POSTHOG_HOST are required. [MEDIUM]

Other completed criteria

  • All changes are relevant to PostHog integration
  • Code follows existing codebase patterns (hooks in components, singleton for server)
  • Build configuration (package.json, vite.config.ts) is valid

PostHog implementation ⚠️

Criteria Result Description
PostHog SDKs installed Yes posthog-js@^1.374.3, @posthog/react@^1.9.0, posthog-node@^5.34.7 added to package.json
PostHog client initialized Yes PostHogProvider in __root.tsx with apiKey from env var, reverse proxy host, capture_exceptions, and debug mode
capture() Yes Multiple meaningful captures: invoice_created, invoice_paid, invoice_pdf_download_clicked, team_member_viewed, plus server-side events
identify() No No posthog.identify() calls anywhere in the codebase. No posthog.reset() on logout either
Error tracking Yes capture_exceptions: true in PostHogProvider options enables exception autocapture
Reverse proxy Yes Vite dev proxy correctly routes /ingest/static and /ingest/arrayus-assets.i.posthog.com, /ingestus.i.posthog.com

Issues

  • No user identification: No posthog.identify() is called anywhere — not on login, not on page load, nowhere. All client events remain anonymous. For a SaaS invoicing app with users, this is a critical gap that prevents associating events with known users. [CRITICAL]
  • Broken server-side session/user correlation: The __add_tracing_headers option is not passed to posthog.init(), so the client never sends X-POSTHOG-SESSION-ID or X-POSTHOG-DISTINCT-ID headers. The server API routes read these headers but will always get null, falling back to distinctId: 'anonymous'. This merges all server-side events into a single "anonymous" user, destroying data integrity. [CRITICAL]
  • No posthog.shutdown() in server API routes: The docs require await posthog.shutdown() after server-side captures to ensure events are flushed. While flushAt: 1 and flushInterval: 0 mitigate this, events could still be lost in short-lived serverless contexts. [MEDIUM]
  • Reverse proxy is dev-only: The Vite server.proxy config only applies during vite dev. Production deployments would need a separate proxy (e.g., Vercel rewrites, Nginx). Not blocking, but worth noting. [LOW]

Other completed criteria

  • API key loaded from VITE_PUBLIC_POSTHOG_PROJECT_TOKEN environment variable (not hardcoded)
  • Host correctly configured via reverse proxy /ingest path
  • Server-side PostHog client correctly uses singleton pattern with appropriate flushAt/flushInterval settings
  • ui_host correctly set for PostHog toolbar access

PostHog insights and events ⚠️

Filename PostHog events Description
src/routes/posts.index.tsx invoice_created Client-side: tracks when user submits the create invoice form, with title, amount, due_date
src/routes/posts..tsx invoice_paid Client-side: tracks when user marks invoice as paid from detail view
src/routes/posts_..deep.tsx invoice_paid, invoice_pdf_download_clicked Client-side: tracks mark-as-paid and PDF download from deep view
src/routes/users..tsx team_member_viewed Client-side: tracks page view of team member profile (contains PII)
src/routes/api/invoices.ts invoice_created Server-side: tracks invoice creation via API (broken correlation)
src/routes/api/invoices..pay.ts invoice_payment_processed Server-side: tracks payment processing via API (broken correlation)

Issues

  • PII in event properties: team_member_viewed captures user_name (a person's name) directly in event properties. Per PostHog best practices, names are PII and should be set via posthog.identify() or posthog.setPersonProperties(), not in capture() event properties. [MEDIUM]

Other completed criteria

  • Events represent real user actions (creating invoices, paying invoices, downloading PDFs, viewing profiles)
  • Events enable product insights — invoice_created → invoice_paid funnel is actionable
  • Events include relevant contextual properties (invoice_id, title, amount, status)
  • Event names are descriptive, consistent snake_case convention

Reviewed by wizard workbench PR evaluator

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