Skip to content

[CI] (7c90ff9) next-js/15-pages-router-saas#154

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

[CI] (7c90ff9) next-js/15-pages-router-saas#154
wizard-ci-bot[bot] wants to merge 1 commit intomainfrom
wizard-ci-7c90ff9-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: 7c90ff9
App: next-js/15-pages-router-saas
App directory: apps/next-js/15-pages-router-saas
Workbench branch: wizard-ci-7c90ff9-next-js-15-pages-router-saas
Wizard branch: feat-skill-based-integration
Examples branch: rearchitect-generator
PostHog (MCP) branch: feat-mcp-skill-deployment
Timestamp: 2026-01-14T21:15:53.628Z
Duration: 365.6s

@wizard-ci-bot
Copy link
Author

wizard-ci-bot bot commented Jan 14, 2026

Now I have read all the changed files. Let me compile the PR evaluation report.


PR Evaluation Report

Summary

This PR integrates PostHog analytics into a Next.js 15 Pages Router SaaS application. The integration includes client-side initialization via instrumentation-client.ts, server-side tracking via a Node SDK wrapper, a reverse proxy configuration for ad-blocker circumvention, and event tracking across authentication, subscription, and team management flows.

Files changed Lines added Lines removed
15 +627 -6

Confidence score: 3/5 🤔

  • Webhook handler breaks original subscription handling: The customer.subscription.created case does not call handleSubscriptionChange(), which may break subscription provisioning logic. [CRITICAL]
  • Distinct ID inconsistency: Server-side webhook events use Stripe customer ID as distinctId, but client-side events use email. This will create fragmented user profiles in PostHog. [CRITICAL]
  • Missing posthog.shutdown() calls: Server-side PostHog events in API routes are not flushed/awaited, risking event loss in serverless environments. [MEDIUM]
  • PII exposure: Email addresses are included in event properties on multiple client-side capture calls, violating PostHog best practices. [MEDIUM]

File changes

Filename Score Description
.env.example 5/5 Correctly documents NEXT_PUBLIC_POSTHOG_KEY and NEXT_PUBLIC_POSTHOG_HOST environment variables
components/header.tsx 4/5 Adds user_signed_out event capture and posthog.reset() call for identity cleanup
components/login.tsx 3/5 Adds posthog.identify() and sign-in/sign-up events, but includes email in event properties (PII concern)
instrumentation-client.ts 4/5 Client-side PostHog init with proxy, exception capture, and debug mode. Uses defaults: '2025-05-24' config
lib/posthog-server.ts 4/5 Singleton PostHog Node client with flushAt: 1 for immediate sends. Includes shutdown helper.
next.config.ts 5/5 Proper reverse proxy configuration for /ingest routes to PostHog with skipTrailingSlashRedirect
package.json 5/5 Adds posthog-js and posthog-node dependencies correctly
pages/api/stripe/customer-portal.ts 4/5 Captures customer_portal_opened event server-side with user context
pages/api/stripe/webhook.ts 2/5 Adds subscription events but breaks original handler by not calling handleSubscriptionChange for created event and uses inconsistent distinctId
pages/api/team/invite.ts 4/5 Captures team_member_invited with relevant properties. Does not await/flush PostHog.
pages/api/team/remove-member.ts 4/5 Captures team_member_removed with relevant properties. Does not await/flush PostHog.
pages/dashboard/general.tsx 3/5 Captures account_updated but includes updated email in properties (PII)
pages/pricing.tsx 5/5 Captures checkout_started with plan details and pricing metadata
pnpm-lock.yaml 5/5 Lock file correctly updated with PostHog dependencies
posthog-setup-report.md 4/5 Good documentation of implemented events and next steps

App sanity check: 3/5 ⚠️

Criteria Result Description
App builds and runs Likely Yes No syntax errors detected; standard Next.js patterns followed
Preserves existing env vars & configs Yes Only additive changes to .env.example and next.config.ts
No syntax or type errors Yes TypeScript types appear correct; imports are valid
Correct imports/exports Yes All PostHog imports from correct packages
Minimal, focused changes No Webhook handler has unnecessary restructuring that broke original logic

Issues

  • Webhook handler logic regression: The original webhook.ts handled both customer.subscription.updated and customer.subscription.deleted with the same handleSubscriptionChange(subscription) call. The new code correctly handles updated and deleted, but customer.subscription.created does NOT call handleSubscriptionChange(). This may break subscription provisioning for new subscriptions. [CRITICAL]
  • No flush/await for server-side events: In serverless/edge environments, PostHog events may be lost because posthog.capture() is fire-and-forget. Should await posthog.flush() or use the shutdown helper. [MEDIUM]

Other completed criteria

  • Environment variables properly documented with comments
  • PostHog SDK versions are current
  • No hardcoded API keys
  • Reverse proxy configuration is correct

PostHog implementation: 3/5 ⚠️

Criteria Result Description
PostHog SDKs installed Yes posthog-js@^1.321.2 and posthog-node@^5.21.0 in dependencies
PostHog client initialized Yes Client-side via instrumentation-client.ts with proxy config; server-side via singleton in lib/posthog-server.ts
capture() Yes 11 events captured across auth, billing, and team flows
identify() Yes User identified on sign-in/sign-up using email as distinct ID
Error tracking Yes capture_exceptions: true enabled in client init
Reverse proxy Yes /ingest rewrites to us.i.posthog.com and us-assets.i.posthog.com configured

Issues

  • Distinct ID fragmentation: Client-side events use email as distinct ID, but webhook events use Stripe customer ID. This creates separate users in PostHog that cannot be merged without manual aliasing. The webhook should either use email (if available via customer lookup) or the integration should use a consistent user ID. [CRITICAL]
  • PII in event properties: Email addresses are captured in event properties for user_signed_up, user_signed_in, team_member_invited, and account_updated. PostHog recommends avoiding PII in properties. [MEDIUM]
  • No pageview tracking: Auto-pageview capture is not explicitly configured. While posthog-js may auto-capture pageviews by default, this should be verified or explicitly set. [LOW]

Other completed criteria

  • Proper posthog.reset() on sign-out
  • ui_host configured for PostHog Cloud UI
  • Debug mode enabled in development
  • Server-side client has flushAt: 1 for immediate event sending

PostHog insights and events: 4/5 ✅

Filename PostHog events Description
components/login.tsx user_signed_up, user_signed_in Tracks user acquisition funnel entry points with invite context
components/header.tsx user_signed_out Tracks session end for engagement analysis
pages/pricing.tsx checkout_started Captures plan selection with price, interval, and trial info for conversion analysis
pages/api/stripe/webhook.ts subscription_created, subscription_updated, subscription_canceled Tracks complete subscription lifecycle for MRR and churn analysis
pages/api/stripe/customer-portal.ts customer_portal_opened Tracks billing self-service usage
pages/api/team/invite.ts team_member_invited Tracks team expansion with role context
pages/api/team/remove-member.ts team_member_removed Tracks team contraction
pages/dashboard/general.tsx account_updated Tracks profile engagement

Issues

  • Limited event enrichment on webhooks: Subscription events only capture subscription_id, status, and customer_id. Missing valuable properties like plan name, price amount, billing interval, and MRR impact. [MEDIUM]
  • No failure events: Authentication failures, checkout failures, and team operation failures are not tracked. These friction points are valuable for product analysis. [LOW]

Other completed criteria

  • Events map to clear user actions and product flows
  • Can build acquisition funnel: user_signed_upcheckout_startedsubscription_created
  • Can build churn analysis from subscription_canceled
  • Team growth trackable via invite/remove events
  • Event naming follows noun_verb convention consistently

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