Skip to content

[CI] (cef44b4) react-native/react-native-saas#1403

Closed
wizard-ci-bot[bot] wants to merge 1 commit intomainfrom
wizard-ci-cef44b4-react-native-react-native-saas
Closed

[CI] (cef44b4) react-native/react-native-saas#1403
wizard-ci-bot[bot] wants to merge 1 commit intomainfrom
wizard-ci-cef44b4-react-native-react-native-saas

Conversation

@wizard-ci-bot
Copy link
Copy Markdown

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

Automated wizard CI run

Source: context-mill-pr
Trigger ID: cef44b4
App: react-native/react-native-saas
App directory: apps/react-native/react-native-saas
Workbench branch: wizard-ci-cef44b4-react-native-react-native-saas
Wizard branch: main
Context Mill branch: basic-skills-v2
PostHog (MCP) branch: master
Timestamp: 2026-05-01T21:07:18.228Z
Duration: 331.3s

@wizard-ci-bot
Copy link
Copy Markdown
Author

wizard-ci-bot Bot commented May 1, 2026


PR Evaluation Report

Summary

This PR integrates PostHog analytics into a React Native SaaS app using the posthog-react-native SDK. It adds initialization via react-native-config, wraps routes with PostHogProvider, implements screen tracking, user identification on sign-in, posthog.reset() on sign-out, 12 custom events across 4 Redux saga files, and error tracking via captureException().

Files changed Lines added Lines removed
9 +134 -9

Confidence score: 4/5 👍

  • Email used as distinct_id: posthog.identify(email, ...) uses raw email as the distinct ID, which is discouraged — use a stable user ID from the backend (e.g., database user ID) instead. [CRITICAL]
  • **misused in `identify()`**: `posthog.identify(email, { email, : { initial_login_method: 'demo' } })` passes inside the second argument (userPropertiesToSet), which maps to . This creates a literal person property named instead of using set-once semantics. The correct approach is posthog.identify(id, { email }, { initial_login_method: 'demo' }) using the third parameter. [CRITICAL]
  • PII (email) in event properties: invite_email: email is sent in member_invited and member_invite_failed capture calls. Emails are PII and should be set via person properties, not event properties. [MEDIUM]
  • No .env.example: Environment variables POSTHOG_PROJECT_TOKEN and POSTHOG_HOST are not documented in a .env.example or README. [MEDIUM]
  • No re-identify on app resume: The init() saga restores the session token from AsyncStorage but never calls posthog.identify() for returning users, so events captured before the next sign-in will be anonymous. [MEDIUM]

File changes

Filename Score Description
src/config/posthog.js 4/5 New file: initializes PostHog with env vars, lifecycle tracking, debug mode
src/routes.js 4/5 Wraps app in PostHogProvider, adds manual screen tracking via onStateChange
src/store/modules/auth/sagas.js 2/5 Adds identify (with email as distinct_id + broken ), capture, reset, captureException
src/store/modules/members/sagas.js 3/5 Adds member invite/update events with PII in properties
src/store/modules/projects/sagas.js 4/5 Adds project creation events with appropriate properties
src/store/modules/teams/sagas.js 4/5 Adds team creation/switch events with appropriate properties
package.json 4/5 Adds posthog-react-native and peer dependencies
.gitignore 5/5 Adds .env to gitignore
posthog-setup-report.md 3/5 Setup report — not a code concern

App sanity check ⚠️

Criteria Result Description
App builds and runs Yes No syntax errors; dependencies are valid React Native packages
Preserves existing env vars & configs Yes No existing configs modified destructively
No syntax or type errors Yes All JS syntax is valid
Correct imports/exports Yes posthog-react-native exports PostHog default and PostHogProvider named export correctly
Minimal, focused changes Yes All changes are PostHog-related; extra packages are peer deps of posthog-react-native
Pre-existing issues None

Issues

  • No .env.example file: The required env vars (POSTHOG_PROJECT_TOKEN, POSTHOG_HOST) are not documented anywhere discoverable. A .env.example should be added. [MEDIUM]

Other completed criteria

  • Build configuration is valid — package.json additions are well-formed
  • Existing app code and navigation structure preserved
  • .env correctly added to .gitignore

PostHog implementation ⚠️

Criteria Result Description
PostHog SDKs installed Yes posthog-react-native@^4.44.0 added to package.json with peer deps
PostHog client initialized Yes new PostHog(apiKey, { host, ... }) with env vars in src/config/posthog.js, PostHogProvider wraps routes
capture() Yes 12 meaningful events across auth, teams, projects, members sagas
identify() No Uses raw email as distinct_id; `` misplaced in second arg instead of third arg
Error tracking Yes posthog.captureException(err, { level }) on all failure paths
Reverse proxy N/A Mobile app — reverse proxy is not applicable

Issues

  • Email as distinct_id: posthog.identify(email, ...) uses the user's email address as the distinct ID. This is fragile (email changes break identity) and leaks PII into the distinct_id field. Use a stable backend user ID instead. [CRITICAL]
  • **API misuse**: The code passes `{ email, : { initial_login_method: 'demo' } }` as the second argument to `identify()`. In the React Native SDK, the second parameter is properties and the third is . This creates a literal person property. Correct usage: posthog.identify(userId, { email }, { initial_login_method: 'demo' }). [CRITICAL]
  • No re-identify on app load: When the app restores a token from AsyncStorage in init(), it doesn't call posthog.identify(), so returning users are treated as anonymous until they explicitly sign in again. [MEDIUM]

Other completed criteria

  • API key loaded from environment variable via react-native-config
  • API host correctly configured from env var (defaults to https://us.i.posthog.com)
  • posthog.reset() called on sign out
  • Screen tracking implemented via NavigationContainer.onStateChange
  • PostHogProvider wraps navigation tree with touch autocapture enabled
  • PostHog disabled gracefully when API key is missing

PostHog insights and events ⚠️

Filename PostHog events Description
auth/sagas.js sign_in, sign_in_failed, sign_out, captureException Auth flow tracking with method property; error tracking on failure
projects/sagas.js project_created, project_create_failed, captureException Project creation with title and project_id properties
teams/sagas.js team_created, team_create_failed, team_switched, captureException Team lifecycle events with team name/id
members/sagas.js member_invited, member_invite_failed, member_role_updated, member_role_update_failed, captureException Member management events
routes.js screen (via posthog.screen()) Automatic screen tracking on navigation state change

Issues

  • PII in event properties: invite_email: email in member_invited and member_invite_failed events sends email addresses as event properties. Email is PII and should only be stored as person properties (via identify() or setPersonProperties()), not in capture() calls. [MEDIUM]

Other completed criteria

  • Events represent real user actions (sign in, create project, invite member, switch team)
  • Events enable product insights — funnels (sign_in → project_created → member_invited), trends, retention
  • Most events include relevant enrichment properties (method, team_name, team_id, project_id, role_count)
  • 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