Skip to content

[CI] (3393d57) next-js/15-app-router-todo#884

Closed
wizard-ci-bot[bot] wants to merge 1 commit intomainfrom
wizard-ci-3393d57-next-js-15-app-router-todo
Closed

[CI] (3393d57) next-js/15-app-router-todo#884
wizard-ci-bot[bot] wants to merge 1 commit intomainfrom
wizard-ci-3393d57-next-js-15-app-router-todo

Conversation

@wizard-ci-bot
Copy link

@wizard-ci-bot wizard-ci-bot bot commented Mar 17, 2026

Automated wizard CI run

Source: wizard-pr
Trigger ID: 3393d57
App: next-js/15-app-router-todo
App directory: apps/next-js/15-app-router-todo
Workbench branch: wizard-ci-3393d57-next-js-15-app-router-todo
Wizard branch: release-please--branches--main--components--wizard
Context Mill branch: main
PostHog (MCP) branch: master
Timestamp: 2026-03-17T00:18:10.379Z
Duration: 285.6s

@wizard-ci-bot
Copy link
Author

wizard-ci-bot bot commented Mar 17, 2026

Now I have all the information I need to produce the evaluation report.


PR Evaluation Report

Summary

This PR integrates PostHog into a Next.js 15 App Router todo application. It adds both client-side (posthog-js) and server-side (posthog-node) SDKs, initializes the client via instrumentation-client.ts, sets up a reverse proxy via Next.js rewrites, and adds event capture for all CRUD operations on todos. It also includes exception tracking on the client side.

Files changed Lines added Lines removed
9 +135 -0

Confidence score: 4/5 👍

  • Hardcoded distinctId: 'anonymous' in server-side captures: All server-side posthog.capture() calls use a hardcoded string 'anonymous' as the distinctId, making it impossible to attribute server-side events to actual users. This creates a single merged "user" for all server activity. [CRITICAL]
  • No identify() call anywhere in the codebase: There is no posthog.identify() call to link anonymous users to authenticated users, and no posthog.reset() on logout. The docs explicitly state identifying users is required. [CRITICAL]
  • No .env.example file committed: The .env.local is gitignored (correctly), but there is no .env.example or equivalent committed file documenting the required NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN and NEXT_PUBLIC_POSTHOG_HOST environment variables. The setup report mentions .env.local was updated but it's not in the committed files. [MEDIUM]
  • Missing await posthog.shutdown() in API routes: Server-side captures in API routes never call await posthog.shutdown(), which means events may not be flushed before the response is sent, even though flushAt: 1 and flushInterval: 0 are set. Per the Next.js docs, shutdown() should be called after sending events in short-lived server functions. [MEDIUM]

File changes

Filename Score Description
instrumentation-client.ts 5/5 New file correctly initializing PostHog client-side using the Next.js 15.3+ instrumentation-client.ts pattern with env vars, reverse proxy, exception capture, and defaults
lib/posthog-server.ts 3/5 Singleton server-side PostHog client. Uses correct flushAt/flushInterval settings but the env var name (NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN) differs from the conventional NEXT_PUBLIC_POSTHOG_TOKEN
next.config.ts 5/5 Proper reverse proxy rewrites for PostHog with skipTrailingSlashRedirect
components/todos/todo-list.tsx 4/5 Good client-side event capture in event handlers with captureException in catch blocks
app/api/todos/route.ts 2/5 Server-side capture with hardcoded distinctId: 'anonymous'; no shutdown call
app/api/todos/[id]/route.ts 2/5 Server-side captures with hardcoded distinctId: 'anonymous'; no shutdown call
package.json 5/5 Both posthog-js and posthog-node correctly added
.gitignore 5/5 .env.local correctly added to gitignore
posthog-setup-report.md 3/5 Helpful documentation but no .env.example committed

App sanity check ⚠️

Criteria Result Description
App builds and runs Yes No syntax errors; valid TypeScript; dependencies correctly added
Preserves existing env vars & configs Yes Existing code and configs preserved; PostHog additions are additive
No syntax or type errors Yes All files have valid syntax and types
Correct imports/exports Yes posthog-js used client-side, posthog-node server-side; correct import paths
Minimal, focused changes Yes All changes relate to PostHog integration
Pre-existing issues None No pre-existing issues observed

Issues

  • No .env.example committed: The .env.local file exists locally but is gitignored. No .env.example or README update documents the required environment variables (NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN, NEXT_PUBLIC_POSTHOG_HOST). New developers cloning the repo won't know what env vars are needed. [MEDIUM]

Other completed criteria

  • App builds without errors — valid TypeScript, correct dependency versions
  • No existing functionality broken — all additions are additive
  • Build configuration is valid — package.json scripts unchanged, dependencies parseable

PostHog implementation ⚠️

Criteria Result Description
PostHog SDKs installed Yes posthog-js@^1.360.2 and posthog-node@^5.28.2 added to package.json
PostHog client initialized Yes Client initialized in instrumentation-client.ts with env var token, reverse proxy host, capture_exceptions: true, and defaults. Server singleton in lib/posthog-server.ts with flushAt: 1 and flushInterval: 0
capture() Yes Client-side: todo_created, todo_completed, todo_reopened, todo_deleted. Server-side: todo_created_api, todo_updated_api, todo_deleted_api
identify() No No posthog.identify() call anywhere. No posthog.reset() on logout. This is a full-stack Next.js app that would benefit from user identification
Error tracking Yes capture_exceptions: true in init config for automatic exception capture; posthog.captureException(error) in client-side catch blocks
Reverse proxy Yes Next.js rewrites configured in next.config.ts proxying /ingest/* to us.i.posthog.com and /ingest/static/* to us-assets.i.posthog.com; api_host: "/ingest" in client init

Issues

  • No identify() implementation: No posthog.identify() call exists anywhere in the codebase. The PostHog docs state "Identifying users is required." Without identification, all client-side events are anonymous and cannot be linked to specific users across sessions or devices. [CRITICAL]
  • Hardcoded distinctId: 'anonymous' on server: All three server-side posthog.capture() calls use distinctId: 'anonymous', which means all server events collapse into a single "anonymous" person in PostHog. Events should use a real user identifier or at minimum forward the PostHog distinct ID from client cookies. [CRITICAL]
  • Missing await posthog.shutdown(): Server-side API route handlers do not call await posthog.shutdown() after capturing events. While flushAt: 1 should cause immediate flushing, the PostHog Next.js docs explicitly recommend calling shutdown() in short-lived server functions. Events could be lost if the runtime terminates before the flush completes. [MEDIUM]
  • Non-standard env var name: The env var NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN differs from the conventional NEXT_PUBLIC_POSTHOG_TOKEN used in PostHog documentation. While functional, this creates confusion for developers comparing against docs. [LOW]

Other completed criteria

  • API key loaded from environment variable (NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN) — not hardcoded
  • API host correctly configured — reverse proxy /ingest on client, NEXT_PUBLIC_POSTHOG_HOST on server
  • Reverse proxy correctly set up with Next.js rewrites including static assets path and skipTrailingSlashRedirect

PostHog insights and events ⚠️

Filename PostHog events Description
components/todos/todo-list.tsx todo_created, todo_completed, todo_reopened, todo_deleted, captureException Client-side event capture for all CRUD operations in event handlers; exception capture in catch blocks
app/api/todos/route.ts todo_created_api Server-side capture when a todo is successfully created via POST
app/api/todos/[id]/route.ts todo_updated_api, todo_deleted_api Server-side capture when a todo is updated or deleted via PATCH/DELETE
instrumentation-client.ts capture_exceptions (automatic) Automatic exception capture enabled in PostHog init config

Issues

  • Hardcoded distinctId: 'anonymous' fragments server data: Server-side events all use the same distinctId, making them useless for per-user analysis. A todo completion funnel mixing client and server events would not work because client events use PostHog's auto-generated anonymous ID while server events all map to a single "anonymous" string. [CRITICAL]

Other completed criteria

  • Events represent real user actions — create, complete, reopen, delete map to actual product flows
  • Events enable product insights — can build creation trend, completion funnel, deletion rate
  • Events include relevant properties — todo_id, has_description, completed status
  • No PII in event properties — only todo IDs and boolean flags
  • Event names are descriptive and consistent — snake_case convention, meaningful names

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