Skip to content

[CI] (cef44b4) django/django3-saas#1383

Closed
wizard-ci-bot[bot] wants to merge 1 commit into
mainfrom
wizard-ci-cef44b4-django-django3-saas
Closed

[CI] (cef44b4) django/django3-saas#1383
wizard-ci-bot[bot] wants to merge 1 commit into
mainfrom
wizard-ci-cef44b4-django-django3-saas

Conversation

@wizard-ci-bot
Copy link
Copy Markdown

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

Automated wizard CI run

Source: context-mill-pr
Trigger ID: cef44b4
App: django/django3-saas
App directory: apps/django/django3-saas
Workbench branch: wizard-ci-cef44b4-django-django3-saas
Wizard branch: main
Context Mill branch: basic-skills-v2
PostHog (MCP) branch: master
Timestamp: 2026-05-01T20:41:22.976Z
Duration: 337.5s

@wizard-ci-bot
Copy link
Copy Markdown
Author

wizard-ci-bot Bot commented May 1, 2026


PR Evaluation Report

Summary

This PR integrates PostHog analytics into a Django 3 SaaS application. It initializes PostHog in AppConfig.ready(), adds the Django context middleware, and instruments 12 events across accounts, billing, and dashboard views covering authentication, subscription lifecycle, and project management flows.

Files changed Lines added Lines removed
7 +172 -1

Confidence score: 4/5 👍

  • .env.example not updated: PostHog env vars (POSTHOG_PROJECT_TOKEN, POSTHOG_HOST) are not added to .env.example, only to the uncommitted .env file. New developers cloning the repo won't know these variables are needed. [MEDIUM]
  • Module-level initialization instead of Posthog() constructor: The code uses posthog.api_key = ... module-level configuration instead of the recommended Posthog() class constructor with enable_exception_autocapture=True. While the Django docs do show this pattern, the SDK rules recommend the instance-based API for better control and exception autocapture. The middleware partially compensates for missing enable_exception_autocapture. [MEDIUM]
  • Username leaked into event properties via tag(): posthog.tag('username', user.username) puts the username on every event captured in that context. Usernames should be set as person properties (via `` in a capture call), not as event-level tags. [MEDIUM]

File changes

Filename Score Description
accounts/apps.py 4/5 New AppConfig initializing PostHog with env vars and atexit shutdown — uses module-level pattern instead of constructor
accounts/views.py 4/5 Login, logout, registration, and settings events with context API — leaks username as event property via tag()
billing/views.py 5/5 Comprehensive billing lifecycle events (checkout, subscription, plan change, cancel, payment failed) with good properties
config/settings.py 5/5 Correctly wires AppConfig, adds PosthogContextMiddleware, adds env-based PostHog settings
dashboard/views.py 4/5 Project CRUD events with context API — project_deleted has no properties
requirements.txt 5/5 posthog added as dependency
posthog-setup-report.md 5/5 Wizard-generated report documenting all changes and suggested insights

App sanity check ⚠️

Criteria Result Description
App builds and runs Yes All syntax is valid, imports resolve, no missing dependencies
Preserves existing env vars & configs Yes Existing settings, env vars, and app configs are preserved; only PostHog additions made
No syntax or type errors Yes All Python code is syntactically correct
Correct imports/exports Yes import posthog is correct for module-level API; middleware import path is valid
Minimal, focused changes Yes All changes directly relate to PostHog integration
Pre-existing issues None No pre-existing issues observed

Issues

  • .env.example not updated with PostHog variables: POSTHOG_PROJECT_TOKEN and POSTHOG_HOST are referenced in settings.py but not documented in .env.example. Add them so new developers know to configure these values. [MEDIUM]

Other completed criteria

  • Build configuration is valid — requirements.txt properly includes posthog
  • accounts entry in INSTALLED_APPS correctly updated to accounts.apps.AccountsConfig
  • PosthogContextMiddleware properly positioned in middleware stack

PostHog implementation ⚠️

Criteria Result Description
PostHog SDKs installed Yes posthog added to requirements.txt
PostHog client initialized Yes Initialized in AccountsConfig.ready() with api_key and host from Django settings; atexit.register(posthog.shutdown) ensures flush on exit
capture() Yes 12 meaningful capture calls across accounts, billing, and dashboard views
identify() N/A Server-only app
Error tracking Yes PosthogContextMiddleware captures exceptions by default (Django-recommended approach)
Reverse proxy N/A Server-only app

Issues

  • Module-level init instead of Posthog() constructor: The code uses posthog.api_key = settings.POSTHOG_PROJECT_TOKEN instead of the recommended posthog = Posthog(api_key, host=host, enable_exception_autocapture=True) instance-based pattern. This means enable_exception_autocapture=True cannot be set, relying solely on the middleware for exception capture. The middleware handles request-scoped exceptions, but exceptions outside request contexts won't be auto-captured. [MEDIUM]

Other completed criteria

  • API key loaded from environment variable via os.environ.get('POSTHOG_PROJECT_TOKEN', '')
  • Host correctly configured with default https://us.i.posthog.com
  • atexit.register(posthog.shutdown) ensures events are flushed on exit
  • Context API (new_context(), identify_context(), capture()) used correctly throughout
  • identify_context(str(user.id)) uses real user IDs from Django auth — correct distinct_id pattern

PostHog insights and events ⚠️

Filename PostHog events Description
accounts/views.py user_logged_in, user_logged_out, user_registered, profile_updated Auth lifecycle events; login includes login_method, registration includes has_company
billing/views.py checkout_initiated, subscription_started, plan_changed, subscription_canceled, payment_failed Full subscription lifecycle with plan_slug/interval properties; plan_changed tracks old→new plan
dashboard/views.py project_created, project_updated, project_deleted Project CRUD events with is_active property on create/update

Issues

  • Username set as event property via tag(): In accounts/views.py, posthog.tag('username', user.username) adds the username to all events captured in that context. Usernames are user-identifying information and should be set as person properties using `` within a capture call, not as event-level tags. Replace with posthog.capture('user_logged_in', properties={'login_method': 'email', '': {'username': user.username}}). [MEDIUM]

Other completed criteria

  • All events represent real user actions mapped to actual product flows
  • Events enable product insights: signup→project funnel, subscription conversion trends, churn monitoring
  • Events include relevant contextual properties (plan_slug, plan_interval, has_company, is_active, old/new plan)
  • Event names are descriptive, consistent snake_case convention
  • No emails, phone numbers, or other explicit PII in event properties (only username concern noted above)

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