Skip to content

[CI] (0ae2102) react-native/react-native-saas#1234

Closed
wizard-ci-bot[bot] wants to merge 1 commit into
mainfrom
wizard-ci-0ae2102-react-native-react-native-saas
Closed

[CI] (0ae2102) react-native/react-native-saas#1234
wizard-ci-bot[bot] wants to merge 1 commit into
mainfrom
wizard-ci-0ae2102-react-native-react-native-saas

Conversation

@wizard-ci-bot
Copy link
Copy Markdown

@wizard-ci-bot wizard-ci-bot Bot commented Apr 15, 2026

Automated wizard CI run

Source: wizard-pr
Trigger ID: 0ae2102
App: react-native/react-native-saas
App directory: apps/react-native/react-native-saas
Workbench branch: wizard-ci-0ae2102-react-native-react-native-saas
Wizard branch: release-please--branches--main--components--wizard
Context Mill branch: main
PostHog (MCP) branch: master
Timestamp: 2026-04-15T19:31:35.176Z
Duration: 406.4s

@wizard-ci-bot
Copy link
Copy Markdown
Author

wizard-ci-bot Bot commented Apr 15, 2026

Now I have all the information I need. Let me note the key findings:

  1. .env file exists but was NOT committed in this PR (it's not in the changed files list). The .gitignore was updated to add .env. However, there's no .env.example file either.

  2. identify() is called with email as distinct_id — this is a PII concern. The identify call uses email as the distinct ID: posthog.identify(email, { : { email } ... }). Using raw email as distinct_id is flagged in the rubric.

  3. Error tracking uses manual posthog.capture('', ...) instead of posthog.captureException(error) which is the proper SDK method available.

  4. PII in capture eventsemail is passed as an event property in posthog.capture('user_signed_in', { email, demo_mode: true }).

  5. No .env.example — Environment variables are only documented in the setup report markdown, not in a .env.example file.

  6. Reverse proxy — N/A for React Native (mobile app, not browser).

  7. The sign_in_failed event uses and properties in a regular capture, not captureException().

Now let me compile the full evaluation report.


PR Evaluation Report

Summary

This PR integrates PostHog analytics into a React Native SaaS application using the posthog-react-native SDK. It adds a PostHog singleton client, wraps the app in PostHogProvider, implements screen tracking via React Navigation, user identification on sign-in, reset on sign-out, and 10 custom event captures across authentication, team, project, and member flows, plus manual exception tracking in saga catch blocks.

Files changed Lines added Lines removed
11 +160 -14

Confidence score: 4/5 👍

  • PII in capture event properties: email is passed directly as a property in posthog.capture('user_signed_in', { email, ... }) — emails should only be in person properties (via identify), not in event properties. [CRITICAL]
  • Email used as distinct_id: posthog.identify(email, ...) uses the user's raw email address as the distinct ID. This is a recognized anti-pattern — a database user ID should be used instead. [MEDIUM]
  • Error tracking uses manual `` capture instead of captureException(): The SDK provides `posthog.captureException(error)` which correctly normalizes error data, but all catch blocks use `posthog.capture('', { , })` instead. [MEDIUM]
  • No .env.example file committed: The .env file is gitignored, and no .env.example or equivalent template is committed, so new developers won't know which environment variables are required. [MEDIUM]

File changes

Filename Score Description
src/config/posthog.js 4/5 New file: PostHog singleton instance with react-native-config env vars, lifecycle tracking, and dev debug mode
src/routes.js 5/5 Adds PostHogProvider with client prop and manual screen tracking via onReady/onStateChange
src/store/modules/auth/sagas.js 3/5 Adds identify, capture, reset — but uses email as distinct_id and includes email in event properties
src/store/modules/members/sagas.js 3/5 Adds member_invited and member_role_updated events; uses manual capture instead of captureException()
src/store/modules/projects/sagas.js 3/5 Adds project_created event; uses manual capture instead of captureException()
src/store/modules/teams/sagas.js 3/5 Adds team_created and team_selected events; uses manual capture instead of captureException()
src/pages/SignIn/index.js 4/5 Adds sign_in_viewed event on mount via useEffect
src/components/TeamSwitcher/index.js 5/5 Adds new_team_modal_opened event on button press
package.json 5/5 Adds posthog-react-native and peer dependencies
.gitignore 5/5 Adds .env to gitignore
posthog-setup-report.md 4/5 Comprehensive setup report documenting all changes

App sanity check ⚠️

Criteria Result Description
App builds and runs Yes All imports resolve to valid packages, syntax is correct, no type errors
Preserves existing env vars & configs Yes Existing code and configs are preserved; PostHog additions are additive
No syntax or type errors Yes All JavaScript syntax is valid; API usage matches SDK signatures
Correct imports/exports Yes PostHog, PostHogProvider, usePostHog correctly imported from posthog-react-native; Config from react-native-config
Minimal, focused changes Yes All changes relate to PostHog integration
Pre-existing issues None No pre-existing issues found

Issues

  • No .env.example file: While the .gitignore correctly excludes .env, there is no committed .env.example or equivalent template to document required variables (POSTHOG_PROJECT_TOKEN, POSTHOG_HOST). The setup report describes them, but a .env.example is the standard approach. [MEDIUM]

Other completed criteria

  • Build configuration is valid — posthog-react-native and peer dependencies (react-native-device-info, react-native-localize, react-native-svg) correctly added to package.json
  • Existing navigation structure, Redux sagas, and component structure preserved
  • Code follows existing codebase patterns (saga imports, dispatch patterns, component hooks)

PostHog implementation ⚠️

Criteria Result Description
PostHog SDKs installed Yes posthog-react-native@^4.41.2 added to package.json along with required peer dependencies
PostHog client initialized Yes Singleton PostHog instance created in src/config/posthog.js with host, lifecycle events, debug mode; wrapped in PostHogProvider in routes
capture() Yes 10 meaningful capture calls across auth, team, project, and member flows
identify() Yes (with issues) posthog.identify() called on sign-in, posthog.reset() on sign-out — but uses email as distinct_id instead of a database user ID
Error tracking No Uses manual posthog.capture('', {...}) instead of the SDK's posthog.captureException(error) method, which properly normalizes error data
Reverse proxy N/A React Native mobile app — reverse proxy is not applicable

Issues

  • Email used as distinct_id: posthog.identify(email, ...) uses the raw email address as the distinct ID. Per PostHog best practices, a stable database user ID should be used as distinct_id, with email set only as a person property. Using email leads to fragmented data if the user changes their email. [MEDIUM]
  • Manual `` capture instead of captureException(): All saga catch blocks use `posthog.capture('', { : err.name, : err.message })` rather than `posthog.captureException(err)`. The SDK method properly handles stack traces, error normalization, and metadata extraction. Additionally, the `sign_in_failed` event also embeds exception properties in a custom event name. [MEDIUM]
  • API key loaded from env: API key is correctly loaded from Config.POSTHOG_PROJECT_TOKEN via react-native-config, not hardcoded. The disabled flag gracefully handles missing config. [OK]

Other completed criteria

  • PostHog host correctly configured to Config.POSTHOG_HOST
  • PostHogProvider correctly wraps the navigator with client prop
  • Manual screen tracking correctly implemented via onReady/onStateChange on NavigationContainer
  • captureScreens: false on provider avoids duplicate screen events since manual tracking is used
  • posthog.reset() correctly called on sign-out
  • Lifecycle events enabled via captureAppLifecycleEvents: true

PostHog insights and events ⚠️

Filename PostHog events Description
src/pages/SignIn/index.js sign_in_viewed Top-of-funnel event fired when sign-in screen is displayed
src/store/modules/auth/sagas.js user_signed_in, sign_in_failed, user_signed_out Auth lifecycle events with identify/reset; sign_in_failed includes error info
src/components/TeamSwitcher/index.js new_team_modal_opened UI interaction event when user taps "+" to create a team
src/store/modules/teams/sagas.js team_created, team_selected, `` Team CRUD events with team name/id properties; exception on error
src/store/modules/projects/sagas.js project_created, `` Project creation with title/id properties; exception on error
src/store/modules/members/sagas.js member_invited, member_role_updated, `` Member management events; exception on error
src/routes.js `` (via posthog.screen()) Automatic screen view tracking on navigation state changes

Issues

  • PII in event properties: posthog.capture('user_signed_in', { email, demo_mode: true }) includes the user's email directly in event properties. Per PostHog guidelines, PII (emails, names) should only be set via person properties (e.g., identify() or ``), not in capture() event properties. [CRITICAL]
  • **sign_in_failed mixes custom event with properties**: The `sign_in_failed` capture uses and as properties on a custom event name, which is non-standard. These prefixed properties are reserved for the event type. Use posthog.captureException(err) for error tracking and a separate sign_in_failed event for the business metric. [MEDIUM]

Other completed criteria

  • Events represent real user actions aligned with actual product flows (sign-in, team management, project creation, member management)
  • Events enable useful product insights — sign-in funnel, team/project creation trends, collaboration metrics
  • Events include relevant contextual properties (team_id, project_title, role_count, demo_mode)
  • Event names are descriptive and follow 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