Skip to content

[CI] (bd496c4) next-js/15-pages-router-saas#120

Closed
wizard-ci-bot[bot] wants to merge 1 commit intomainfrom
wizard-ci-bd496c4-next-js-15-pages-router-saas
Closed

[CI] (bd496c4) next-js/15-pages-router-saas#120
wizard-ci-bot[bot] wants to merge 1 commit intomainfrom
wizard-ci-bd496c4-next-js-15-pages-router-saas

Conversation

@wizard-ci-bot
Copy link

@wizard-ci-bot wizard-ci-bot bot commented Jan 14, 2026

Automated wizard CI run

Trigger ID: bd496c4
App: next-js/15-pages-router-saas
App directory: apps/next-js/15-pages-router-saas
Workbench branch: wizard-ci-bd496c4-next-js-15-pages-router-saas
Wizard branch: main
Examples branch: rearchitect-generator
PostHog (MCP) branch: master
Timestamp: 2026-01-14T16:19:54.533Z
Duration: 453.4s

@wizard-ci-bot
Copy link
Author

wizard-ci-bot bot commented Jan 14, 2026

No TypeScript errors. Now I have all the information needed for the PR evaluation. Let me compile the review.


PR Evaluation Report

Summary

This PR integrates PostHog analytics into a Next.js 15 Pages Router SaaS application. It adds client-side initialization via instrumentation-client.ts, server-side tracking in API routes using posthog-node, a reverse proxy configuration to bypass adblockers, and comprehensive event tracking for authentication, Stripe payments, and team management flows.

Files changed Lines added Lines removed
19 +743 -7

Confidence score: 4/5 👍

  • PII in event properties: Email addresses are being captured in multiple events (user_signed_in, user_signed_up, account_updated, team_member_invited). While email may be acceptable for some use cases, this should be reviewed for GDPR/privacy compliance. [MEDIUM]
  • Server-side PostHog client not awaited: posthog.capture() and posthog.captureException() are fire-and-forget without awaiting flush. In serverless environments, events may be lost if the function terminates before flush completes. Consider using await posthog.flush() in critical paths. [MEDIUM]
  • Duplicate user identification: Users are identified on both client-side (login.tsx) and server-side (API routes) using different identifiers (email vs user.id). This could create separate PostHog users. The client should use the numeric user ID for consistency. [MEDIUM]

File changes

Filename Score Description
instrumentation-client.ts 4/5 New file for client-side PostHog init using Next.js 15.3+ pattern. Uses reverse proxy correctly. defaults: '2025-05-24' parameter is unusual - should verify this is valid.
lib/posthog-server.ts 4/5 Singleton pattern for server-side client. flushAt: 1 and flushInterval: 0 ensure immediate sends but may impact performance under load.
next.config.ts 5/5 Correct reverse proxy configuration for PostHog with skipTrailingSlashRedirect. Uses US cluster endpoints.
package.json 5/5 Adds posthog-js and posthog-node dependencies correctly.
components/header.tsx 4/5 Captures user_signed_out event and calls posthog.reset() before API call - correct order.
components/login.tsx 3/5 Identifies user by email string instead of user ID, inconsistent with server-side identification. Error capture added correctly.
pages/api/auth/sign-in.ts 4/5 Captures sign-in event with user ID, identifies user. Good properties captured.
pages/api/auth/sign-up.ts 4/5 Captures sign-up with has_invitation property - good for funnel analysis.
pages/api/auth/sign-out.ts 4/5 Gets user before clearing session for proper tracking. Good defensive coding.
pages/api/account/update.ts 4/5 Updates PostHog person properties on account update - good practice.
pages/api/stripe/checkout.ts 4/5 Captures checkout_completed with rich Stripe metadata.
pages/api/stripe/create-checkout.ts 4/5 Captures checkout_started - good for conversion funnel.
pages/api/stripe/customer-portal.ts 4/5 Captures portal access with plan context.
pages/api/stripe/webhook.ts 4/5 Webhook events captured. Falls back to customer ID if userId not in metadata.
pages/api/team/invite.ts 3/5 Captures invited email in properties - potential PII concern.
pages/api/team/remove-member.ts 4/5 Captures member removal with proper context.
pages/pricing.tsx 4/5 pricing_page_viewed event in useEffect. Dependency array includes products correctly.
pnpm-lock.yaml 5/5 Lock file updated with new dependencies.
posthog-setup-report.md 4/5 Good documentation of implemented events. Includes placeholder API key in example.

App sanity check: 4/5 ✅

Criteria Result Description
App builds and runs Yes TypeScript compiles successfully. Build fails only due to missing POSTGRES_URL (pre-existing app requirement).
Preserves existing env vars & configs Yes Existing app code preserved. New PostHog env vars added correctly.
No syntax or type errors Yes tsc --noEmit passes with no errors.
Correct imports/exports Yes All PostHog imports are correct (posthog-js for client, posthog-node for server).
Minimal, focused changes Yes Changes are strictly PostHog-related. Original business logic preserved.

Issues

  • POSTGRES_URL required for full build: App requires database env var which is not PostHog-related but prevents full production build verification. [LOW]

Other completed criteria

  • Uses correct reactStrictMode: true setting
  • Error handling preserved in all modified files
  • Validation logic unchanged in API routes
  • Database operations unaffected

PostHog implementation: 4/5 ✅

Criteria Result Description
PostHog SDKs installed Yes posthog-js@^1.321.1 and posthog-node@^5.21.0 added to package.json
PostHog client initialized Yes Client-side via instrumentation-client.ts, server-side via singleton in lib/posthog-server.ts
capture() Yes 12 distinct events captured across auth, Stripe, and team management flows
identify() Yes Users identified on sign-in, sign-up, and account update. Issue: client uses email, server uses user ID
Error tracking Yes captureException called in all catch blocks. capture_exceptions: true enabled in client config
Reverse proxy Yes Configured via Next.js rewrites to /ingestus.i.posthog.com with trailing slash support

Issues

  • Inconsistent user identification: Client-side posthog.identify() uses email as distinctId while server-side uses numeric user ID. This may create duplicate user profiles in PostHog. Should use consistent identifier (recommend user ID). [MEDIUM]
  • Server events may not flush: In serverless environments, posthog.capture() without await posthog.flush() may lose events if the function terminates early. [MEDIUM]
  • Unusual defaults parameter: defaults: '2025-05-24' in client config is non-standard. Verify this is a valid PostHog option. [LOW]

Other completed criteria

  • posthog.reset() called on sign-out (client-side)
  • Debug mode enabled in development only
  • API host configured for reverse proxy (/ingest)
  • UI host configured correctly for US region

PostHog insights and events: 4/5 ✅

Filename PostHog events Description
login.tsx user_signed_in, user_signed_up, captureException Client-side auth events with email, allows tracking login/signup funnel
header.tsx user_signed_out Logout tracking before session reset
pricing.tsx pricing_page_viewed Top-of-funnel event with available plans array
sign-in.ts user_signed_in Server-side with user_id, team_id, email - full attribution
sign-up.ts user_signed_up Includes has_invitation for viral coefficient analysis
sign-out.ts user_signed_out Server-side logout with user context
account/update.ts account_updated Tracks profile updates, updates person properties
stripe/checkout.ts checkout_completed Revenue event with plan_name, subscription_id, status
stripe/create-checkout.ts checkout_started Checkout funnel entry with price_id
stripe/customer-portal.ts customer_portal_opened Tracks billing management intent
stripe/webhook.ts subscription_updated, subscription_cancelled Server-side subscription lifecycle events
team/invite.ts team_member_invited Tracks team growth with role context
team/remove-member.ts team_member_removed Tracks team churn

Issues

  • Missing pageview tracking: No explicit `` capture. Relies on default autocapture which may not work reliably with SPA navigation in Pages Router. Consider adding router-based pageview tracking. [MEDIUM]
  • No group analytics: Team/organization grouping not implemented. Would improve B2B analytics for team-based metrics. [LOW]

Other completed criteria

  • Events cover complete user lifecycle (signup → checkout → subscription management → churn)
  • Stripe events include financial context (plan_name, subscription_status)
  • Source property (api vs client) allows distinguishing event origins
  • Team management events enable viral/growth analysis
  • Error tracking in all API routes for debugging

Reviewed by wizard workbench PR evaluator

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