Skip to content

[CI] (6fb03e7) nuxt/movies-nuxt-3-6#1477

Closed
wizard-ci-bot[bot] wants to merge 1 commit into
mainfrom
wizard-ci-6fb03e7-nuxt-movies-nuxt-3-6
Closed

[CI] (6fb03e7) nuxt/movies-nuxt-3-6#1477
wizard-ci-bot[bot] wants to merge 1 commit into
mainfrom
wizard-ci-6fb03e7-nuxt-movies-nuxt-3-6

Conversation

@wizard-ci-bot
Copy link
Copy Markdown

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

Automated wizard CI run

Source: scheduled
Trigger ID: 6fb03e7
App: nuxt/movies-nuxt-3-6
App directory: apps/nuxt/movies-nuxt-3-6
Workbench branch: wizard-ci-6fb03e7-nuxt-movies-nuxt-3-6
Wizard branch: main
Context Mill branch: main
PostHog (MCP) branch: master
Timestamp: 2026-05-13T17:32:16.332Z
Duration: 422.7s

@wizard-ci-bot
Copy link
Copy Markdown
Author

wizard-ci-bot Bot commented May 13, 2026

Now I have all the context needed to evaluate this PR.


PR Evaluation Report

Summary

This PR integrates PostHog into a Nuxt 3 movies app, adding a client-side plugin (posthog.client.ts) that initializes posthog-js, captures events across multiple pages/components (login, logout, search, media view, video play), implements user identification on login, error tracking via vue:error hook, and adds a server-side posthog-node event on the login API route. Both posthog-js and posthog-node are added as dependencies.

Files changed Lines added Lines removed
11 +169 -13

Confidence score: 4/5 👍

  • Username used as distinct_id in identify(): posthog.identify(username.value) uses the raw username string as the distinct ID. In a demo app that "accepts any username and password," this is fragile — usernames are not guaranteed unique IDs and could cause identity merging issues. A real user ID from a database would be preferred. [MEDIUM]
  • Server-side login headers never sent: The server handler reads x-posthog-session-id and x-posthog-distinct-id headers, but the useAuth composable's `` call to /api/auth/login never sends these headers. The server-side `server_login` event will have `undefined` session/distinct IDs and fall back to the sanitized username. This is dead code that doesn't achieve the stated session correlation. [CRITICAL]
  • No reverse proxy configured: The client-side posthog-js SDK points directly to https://us.i.posthog.com with no reverse proxy, leaving analytics vulnerable to ad blockers. [MEDIUM]
  • PostHog client instantiated per request on server: new PostHog() + shutdown() is called on every login request in login.post.ts, which is inefficient. Should be a singleton or at least reused. [MEDIUM]

File changes

Filename Score Description
plugins/posthog.client.ts 4/5 New plugin initializing posthog-js client, providing `` to the app, with vue:error hook for exception tracking. Well-structured.
nuxt.config.ts 4/5 Added runtimeConfig.public.posthog block reading env vars. Clean.
package.json 4/5 Added posthog-js and posthog-node as dependencies.
pages/login.vue 3/5 Adds identify and capture on login, but uses raw username as distinct_id. Some gratuitous reformatting (self-closing tags, whitespace).
components/NavBar.vue 5/5 Clean logout handler with capture + reset.
pages/search.vue 4/5 Captures search_performed with query property.
pages/[type]/[id].vue 5/5 Captures media_viewed on mount with rich properties.
components/video/Card.vue 5/5 Captures video_played with video metadata.
server/api/auth/login.post.ts 2/5 Server-side PostHog tracking with header correlation that never receives the expected headers. Creates a new client per request.
types/nuxt-app.d.ts 5/5 Proper TypeScript declaration for .
posthog-setup-report.md N/A Setup report / documentation.

App sanity check ⚠️

Criteria Result Description
App builds and runs Yes No syntax errors; dependencies added correctly; plugin follows Nuxt conventions
Preserves existing env vars & configs Yes Existing runtimeConfig and modules untouched; only additions made
No syntax or type errors Yes Valid Vue SFC and TypeScript throughout
Correct imports/exports Yes posthog-js imported client-side, posthog-node imported server-side; #imports used correctly
Minimal, focused changes No Some gratuitous reformatting in login.vue (self-closing tags, whitespace changes, brace style)
Pre-existing issues None Base app appears clean

Issues

  • Gratuitous reformatting in login.vue: Several whitespace and self-closing tag changes (/>>, brace placement) unrelated to PostHog. These are cosmetic and don't break anything but add noise. [LOW]

Other completed criteria

  • Environment variables documented in .env file with NUXT_PUBLIC_POSTHOG_PROJECT_TOKEN and NUXT_PUBLIC_POSTHOG_HOST
  • Build configuration valid — package.json is well-formed with correct dependency entries

PostHog implementation ⚠️

Criteria Result Description
PostHog SDKs installed Yes posthog-js@^1.373.4 and posthog-node@^5.34.1 added to dependencies
PostHog client initialized Yes posthog.init() called in plugins/posthog.client.ts with api_host and defaults from runtimeConfig
capture() Yes 5 meaningful capture calls across client pages/components plus 1 server-side
identify() Yes posthog.identify(username.value) called on login, posthog.reset() on logout. However, uses raw username as distinct_id which is fragile.
Error tracking Yes vue:error hook calls captureException(error) in the plugin
Reverse proxy No No reverse proxy configured — api_host points directly to https://us.i.posthog.com

Issues

  • Server-side header correlation is broken: The server handler in login.post.ts reads x-posthog-session-id and x-posthog-distinct-id from request headers, but the useAuth composable's ('/api/auth/login', ...) call never sends these headers. The withContext({ sessionId, distinctId }) call will always receive undefined values. This means the server-side server_login event is never correlated to the client session as intended. [CRITICAL]
  • Username as distinct_id: posthog.identify(username.value) uses the raw username string. This demo app accepts any username/password, so there's no guarantee of uniqueness. A database user ID would be more appropriate. For a demo app this is acceptable but not best practice. [MEDIUM]
  • No reverse proxy: Client-side posthog-js sends data directly to us.i.posthog.com, making it susceptible to ad blockers. A Nuxt server route or nitro proxy could handle this. [MEDIUM]
  • PostHog client instantiated per request: new PostHog() and shutdown() on every login request is wasteful. Should use a singleton pattern. [MEDIUM]

Other completed criteria

  • API key loaded from environment variable via runtimeConfig.public.posthog.publicKey
  • API host correctly configured via environment variable (https://us.i.posthog.com)
  • defaults: '2026-01-30' correctly set following current SDK patterns
  • posthog.reset() correctly called on logout in NavBar.vue

PostHog insights and events ⚠️

Filename PostHog events Description
pages/login.vue user_logged_in, identify() Captures login event and identifies user by username
components/NavBar.vue user_logged_out, reset() Captures logout and resets PostHog session
pages/search.vue search_performed Captures search with query property
pages/[type]/[id].vue media_viewed Captures media detail page view with media_id, media_type, media_title
components/video/Card.vue video_played Captures video play with video_key, video_name, video_type
server/api/auth/login.post.ts server_login Server-side login event (but session correlation is broken)
plugins/posthog.client.ts captureException Vue error boundary captures exceptions

Issues

  • No PII concerns but search query is captured: search_performed includes { query: currentSearch.value } which contains user-typed search text. This is acceptable as search queries are generally not PII, but worth noting. [LOW]

Other completed criteria

  • Events represent real user actions (login, logout, search, view media, play video)
  • Events enable product insights — can build login→media_viewed→video_played funnel
  • Events include relevant enriched properties (media_id, media_type, media_title, video_key, query, etc.)
  • Event names are descriptive and follow consistent snake_case naming convention

Reviewed by wizard workbench PR evaluator

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