Skip to content

[CI] (963eeb8) fastapi/fastapi3-ai-saas - #3805

Closed
wizard-ci-bot[bot] wants to merge 1 commit into
mainfrom
wizard-ci-963eeb8-fastapi-fastapi3-ai-saas
Closed

wizard-ci-bot[bot] wants to merge 1 commit into
mainfrom
wizard-ci-963eeb8-fastapi-fastapi3-ai-saas

Conversation

@wizard-ci-bot

@wizard-ci-bot wizard-ci-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown

Automated wizard CI run

Source: wizard-pr
Trigger ID: 963eeb8
App: fastapi/fastapi3-ai-saas
App directory: apps/fastapi/fastapi3-ai-saas
Workbench branch: wizard-ci-963eeb8-fastapi-fastapi3-ai-saas
Wizard branch: release-please--branches--main--components--wizard
Context Mill branch: main
PostHog (MCP) branch: master
Timestamp: 2026-09-03T18:13:20.211Z
Duration: 382.2s

YARA Scanner

✓ 159 tool calls scanned, 0 violations detected

No violations: ✓ 159 clean scans

@wizard-ci-bot

wizard-ci-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown
Author

PR Evaluation Report

Summary

This PR integrates PostHog into a FastAPI AI SaaS application using the Python SDK (instance-based API). It adds initialization in the lifespan handler, a custom ASGI middleware for request-scoped identity context, event captures across auth, API key, content generation, and settings routes, and error tracking via both autocapture and a manual 500 handler.

Files changed Lines added Lines removed
9 +164 -6

Confidence score: 5/5 🧙

  • No critical issues found; the integration follows documented patterns correctly
  • Minor: PostHog client accessed via getattr(request.app.state, ...) repeated across all routes instead of using FastAPI's Depends() injection — functional but verbose [LOW]
  • Minor: Middleware performs synchronous DB query (SessionLocal()) inside an async ASGI call path, which could block the event loop under load — not a PostHog issue but worth noting [LOW]

File changes

Filename Score Description
requirements.txt 5/5 Adds posthog>=7.45.3
.env.example 5/5 Documents POSTHOG_PROJECT_TOKEN and POSTHOG_HOST
app/config.py 5/5 Adds PostHog settings fields to Pydantic Settings model
app/main.py 4/5 Initializes PostHog client in lifespan with enable_exception_autocapture=True, registers atexit shutdown, adds 500 error handler with capture_exception
app/middleware.py 4/5 Custom ASGI middleware wraps requests in new_context(fresh=True) with user identity from session cookie
app/routers/auth.py 5/5 Captures user_logged_in, user_signed_up, user_logged_out; sets person properties via set()
app/routers/generate.py 5/5 Captures content_generated with rich properties
app/routers/api_keys.py 5/5 Captures api_key_created and api_key_revoked
app/routers/settings.py 5/5 Captures settings_updated and password_changed; updates person properties

App sanity check ✅

Criteria Result Description
App builds and runs Yes No syntax errors; imports resolve correctly
Preserves existing env vars & configs Yes Existing env vars and configs untouched; PostHog additions are additive
No syntax or type errors Yes All changed files have valid Python syntax
Correct imports/exports Yes from posthog import Posthog is correct for instance-based API
Minimal, focused changes Yes All changes are PostHog-related
Pre-existing issues None —

Issues

No issues found.

Other completed criteria

  • Environment variables documented in .env.example
  • Build configuration valid — posthog>=7.45.3 in requirements.txt
  • Pydantic Settings used for PostHog configuration with optional None defaults for graceful degradation

PostHog implementation ✅

Criteria Result Description
PostHog SDKs installed Yes posthog>=7.45.3 added to requirements.txt
PostHog client initialized Yes Posthog() constructor in lifespan with enable_exception_autocapture=True; atexit.register(posthog_client.shutdown) for cleanup
capture() Yes 8 meaningful capture calls across auth, generation, API keys, and settings routes
identify() N/A Server-only app
Error tracking Yes enable_exception_autocapture=True in constructor + manual capture_exception(exc) in 500 handler + context auto-capture in middleware
Reverse proxy N/A Server-only app

Issues

No issues found.

Other completed criteria

  • API key and host loaded from environment variables via Pydantic Settings
  • PostHog client stored on app.state and accessed safely with getattr(..., None) fallback
  • Middleware uses new_context(fresh=True) with identify_context() per the documented context API pattern
  • flush() called in lifespan shutdown; shutdown() registered with atexit
  • Auth routes correctly create nested fresh contexts for login/signup since the user isn't authenticated when the middleware runs
  • Person properties set via posthog_client.set() (correct — Python SDK has no identify() method)

PostHog insights and events ✅

Filename PostHog events Description
app/routers/auth.py user_logged_in, user_signed_up, user_logged_out Auth funnel tracking with login_method/signup_method properties; person properties (email, credits) set via set()
app/routers/generate.py content_generated Core product action with generation_type, credits_used, prompt_length, credits_remaining
app/routers/api_keys.py api_key_created, api_key_revoked API key lifecycle with active_api_key_count
app/routers/settings.py settings_updated, password_changed Account management actions; email person property updated via set()
app/main.py capturedException 500 error handler captures exceptions via capture_exception()

Issues

No issues found.

Other completed criteria

  • Events represent real user actions mapping to actual product flows (signup → login → generate content)
  • Events enable product insights: signup-to-generation funnel, credit usage trends, API key management retention
  • Events enriched with relevant properties (generation type, credits, prompt length, login method)
  • No PII in event properties — email only in set() person property calls
  • Consistent snake_case naming convention across all events

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