🔥 chore(picture): remove PostHog analytics for GDPR compliance

- Remove posthog-js dependency from picture web app
- Delete PostHog integration module and setup documentation
- Remove PostHog initialization from root layout
- Clean up environment variables from .env.example
- Update logger comments to remove Sentry references
- Update PROJECT_OVERVIEW.md to reflect Umami as analytics tool
This commit is contained in:
Till-JS 2026-01-28 12:24:22 +01:00
parent 13754f2d55
commit cb130191ab
10 changed files with 2176 additions and 1778 deletions

View file

@ -1,7 +1,7 @@
/** /**
* Centralized logging utility * Centralized logging utility
* - Development: Logs to console * - Development: Logs to console
* - Production: Can be integrated with Sentry, LogRocket, etc. * - Production: Logs to console (can be extended for custom error tracking)
*/ */
const isDevelopment = __DEV__; const isDevelopment = __DEV__;
@ -38,7 +38,7 @@ export const logger = {
*/ */
error: (...args: any[]) => { error: (...args: any[]) => {
console.error('[ERROR]', ...args); console.error('[ERROR]', ...args);
// TODO: Send to error tracking service (Sentry, etc.) // In production: can be extended for custom error tracking
}, },
/** /**

View file

@ -11,7 +11,3 @@ PUBLIC_APPLE_CLIENT_ID=
# Umami Analytics # Umami Analytics
PUBLIC_UMAMI_URL=https://your-umami-instance.com PUBLIC_UMAMI_URL=https://your-umami-instance.com
PUBLIC_UMAMI_WEBSITE_ID=your-website-id PUBLIC_UMAMI_WEBSITE_ID=your-website-id
# PostHog Analytics
PUBLIC_POSTHOG_KEY=phc_your_posthog_project_api_key
PUBLIC_POSTHOG_HOST=https://us.i.posthog.com

View file

@ -33,7 +33,6 @@
"@picture/design-tokens": "workspace:*", "@picture/design-tokens": "workspace:*",
"@picture/shared": "workspace:*", "@picture/shared": "workspace:*",
"konva": "^10.0.2", "konva": "^10.0.2",
"posthog-js": "^1.273.1",
"svelte-i18n": "^4.0.1" "svelte-i18n": "^4.0.1"
}, },
"devDependencies": { "devDependencies": {

View file

@ -1,85 +0,0 @@
import posthog from 'posthog-js';
import { browser } from '$app/environment';
import { env } from '$env/dynamic/public';
export function initPostHog() {
const posthogKey = env.PUBLIC_POSTHOG_KEY;
const posthogHost = env.PUBLIC_POSTHOG_HOST;
if (browser && posthogKey && posthogHost) {
posthog.init(posthogKey, {
api_host: posthogHost,
person_profiles: 'identified_only', // Only track identified users
capture_pageview: true, // Automatically capture pageviews
capture_pageleave: true, // Track when users leave pages
// Privacy-friendly settings
opt_out_capturing_by_default: false,
persistence: 'localStorage',
autocapture: false, // Disable automatic event capture for better control
// Session recording (optional - can be disabled)
disable_session_recording: true, // Set to false if you want session recordings
// Performance
loaded: (posthog) => {
if (import.meta.env.DEV) {
console.log('PostHog loaded');
}
},
});
}
}
// Helper functions for common tracking events
export const analytics = {
// Track page view (usually automatic, but available for manual tracking)
pageView: (url?: string) => {
if (browser) {
posthog.capture('$pageview', { url: url || window.location.href });
}
},
// Identify a user
identify: (userId: string, properties?: Record<string, any>) => {
if (browser) {
posthog.identify(userId, properties);
}
},
// Track custom events
track: (eventName: string, properties?: Record<string, any>) => {
if (browser) {
posthog.capture(eventName, properties);
}
},
// Reset user identity (e.g., on logout)
reset: () => {
if (browser) {
posthog.reset();
}
},
// Set user properties
setUserProperties: (properties: Record<string, any>) => {
if (browser) {
posthog.setPersonProperties(properties);
}
},
// Feature flags
isFeatureEnabled: (featureKey: string): boolean => {
if (browser) {
return posthog.isFeatureEnabled(featureKey) ?? false;
}
return false;
},
// Get feature flag value
getFeatureFlag: (featureKey: string): string | boolean | undefined => {
if (browser) {
return posthog.getFeatureFlag(featureKey);
}
return undefined;
},
};
export default posthog;

View file

@ -4,7 +4,6 @@
import { authStore } from '$lib/stores/auth.svelte'; import { authStore } from '$lib/stores/auth.svelte';
import Toast from '$lib/components/ui/Toast.svelte'; import Toast from '$lib/components/ui/Toast.svelte';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { initPostHog, analytics } from '$lib/analytics/posthog';
// Import and initialize theme // Import and initialize theme
import { theme } from '$lib/stores/theme'; import { theme } from '$lib/stores/theme';
@ -18,18 +17,8 @@
// Initialize theme (applies CSS variables and loads from localStorage) // Initialize theme (applies CSS variables and loads from localStorage)
const cleanupTheme = theme.initialize(); const cleanupTheme = theme.initialize();
// Initialize PostHog
initPostHog();
// Initialize auth with Mana Core // Initialize auth with Mana Core
authStore.initialize().then(() => { authStore.initialize();
// Identify user in PostHog if logged in
if (authStore.user) {
analytics.identify(authStore.user.id, {
email: authStore.user.email,
});
}
});
return () => { return () => {
cleanupTheme(); cleanupTheme();

View file

@ -1,503 +0,0 @@
# PostHog Analytics Setup
This document describes how to set up PostHog Analytics for the Picture web application.
## Overview
PostHog is a powerful product analytics platform that provides:
- 📊 **Product Analytics**: Track user behavior and product usage
- 🎯 **Feature Flags**: Roll out features gradually and A/B test
- 📹 **Session Recordings**: Watch how users interact with your app
- 🔥 **Heatmaps**: Visualize where users click and scroll
- 👥 **User Profiles**: Understand individual user journeys
## Architecture
### Web App (SvelteKit)
- **Location**: `apps/web/src/lib/analytics/posthog.ts`
- **Framework**: SvelteKit
- **SDK**: posthog-js
- **Integration**: Initialized in root layout with automatic user identification
## Configuration
PostHog is configured using environment variables:
```bash
PUBLIC_POSTHOG_KEY=phc_your_posthog_project_api_key
PUBLIC_POSTHOG_HOST=https://us.i.posthog.com # or https://eu.i.posthog.com for EU
```
### Environment Variables
Create or update `apps/web/.env`:
```bash
PUBLIC_POSTHOG_KEY=phc_xxxxxxxxxxxxxxxxx
PUBLIC_POSTHOG_HOST=https://us.i.posthog.com
```
> **Note**: The `PUBLIC_` prefix is required in SvelteKit to expose variables to the client.
## Features
### 🔐 Privacy-First Configuration
- ✅ **Identified Users Only**: `person_profiles: 'identified_only'` - only tracks logged-in users
- ✅ **localStorage Persistence**: Uses localStorage instead of cookies
- ✅ **No Autocapture**: Manual event tracking for better control
- ✅ **Session Recording Disabled**: Can be enabled if needed
### 🚀 Automatic Features
- ✅ **Pageview Tracking**: Automatically tracks page navigation
- ✅ **Page Leave Tracking**: Tracks when users leave pages
- ✅ **User Identification**: Automatically identifies users on login/logout
- ✅ **User Properties**: Tracks email and account creation date
### 📊 Current Implementation
#### User Identification
Users are automatically identified on login with:
- User ID (from Supabase)
- Email address
- Account creation timestamp
```typescript
// Automatically done on login
analytics.identify(user.id, {
email: user.email,
created_at: user.created_at
});
```
#### Session Management
- **Login**: User is identified in PostHog
- **Logout**: PostHog session is reset
- **Auth State Changes**: PostHog identity is updated automatically
## Setup Steps
### 1. Create PostHog Account
You have two options:
#### Option A: PostHog Cloud (Recommended)
1. Sign up at [posthog.com](https://posthog.com)
2. Create a new project
3. Select your region (US or EU)
4. Copy your Project API Key (starts with `phc_`)
#### Option B: Self-Hosted PostHog
1. Follow the [PostHog deployment guide](https://posthog.com/docs/self-host)
2. Deploy to your preferred platform
3. Create a project
4. Note your instance URL and API key
### 2. Configure Environment Variables
#### Development
1. Copy `.env.example` to `.env` in `apps/web`:
```bash
cd apps/web
cp .env.example .env
```
2. Add your PostHog credentials:
```bash
PUBLIC_POSTHOG_KEY=phc_your_actual_api_key
PUBLIC_POSTHOG_HOST=https://us.i.posthog.com # or eu.i.posthog.com
```
#### Production
Add environment variables to your deployment platform:
**Vercel:**
```bash
vercel env add PUBLIC_POSTHOG_KEY
vercel env add PUBLIC_POSTHOG_HOST
```
**Netlify:**
- Go to Site settings → Environment variables
- Add `PUBLIC_POSTHOG_KEY` and `PUBLIC_POSTHOG_HOST`
**Other platforms:**
- Follow your platform's documentation for environment variables
- Ensure variables are prefixed with `PUBLIC_`
### 3. Verify Integration
1. Start the development server:
```bash
cd apps/web
pnpm dev
```
2. Open browser DevTools → Console
3. Look for "PostHog loaded" message (in dev mode)
4. Navigate between pages
5. Log in with a test account
6. Check PostHog dashboard for events
## Usage
### Tracking Custom Events
The analytics helper provides easy-to-use methods:
```typescript
import { analytics } from '$lib/analytics/posthog';
// Track a custom event
analytics.track('button_clicked', {
button_name: 'sign_up',
page: '/pricing'
});
// Track image generation
analytics.track('image_generated', {
model: 'flux-dev',
prompt_length: 150,
aspect_ratio: '16:9'
});
// Track feature usage
analytics.track('feature_used', {
feature: 'batch_generation',
count: 5
});
```
### User Properties
Set additional user properties:
```typescript
import { analytics } from '$lib/analytics/posthog';
analytics.setUserProperties({
plan: 'pro',
images_generated: 42,
favorite_model: 'flux-dev'
});
```
### Feature Flags
Use feature flags for gradual rollouts and A/B testing:
```typescript
import { analytics } from '$lib/analytics/posthog';
// Check if a feature is enabled
const showNewUI = analytics.isFeatureEnabled('new_ui_redesign');
// Get feature flag value (for multivariate flags)
const buttonColor = analytics.getFeatureFlag('button_color_test');
```
### Page View Tracking
Page views are tracked automatically. For manual tracking:
```typescript
import { analytics } from '$lib/analytics/posthog';
// Track a specific page view
analytics.pageView('/custom-page');
```
## Example Use Cases
### Track Image Generation
```typescript
// In your image generation component
import { analytics } from '$lib/analytics/posthog';
async function generateImage(prompt: string, settings: Settings) {
// Track the generation attempt
analytics.track('image_generation_started', {
model: settings.model,
prompt_length: prompt.length,
aspect_ratio: settings.aspectRatio,
num_images: settings.numImages
});
try {
const result = await generateImageAPI(prompt, settings);
// Track success
analytics.track('image_generation_completed', {
model: settings.model,
generation_time_ms: result.duration
});
return result;
} catch (error) {
// Track errors
analytics.track('image_generation_failed', {
model: settings.model,
error: error.message
});
throw error;
}
}
```
### Track User Engagement
```typescript
// Track when users interact with images
analytics.track('image_liked', {
image_id: image.id,
model: image.model
});
analytics.track('image_shared', {
image_id: image.id,
platform: 'twitter'
});
analytics.track('image_downloaded', {
image_id: image.id,
format: 'png'
});
```
### Track Feature Discovery
```typescript
// Track when users discover features
analytics.track('feature_discovered', {
feature: 'batch_generation',
source: 'tooltip'
});
analytics.track('tutorial_completed', {
tutorial: 'first_generation'
});
```
## PostHog Dashboard
### Key Metrics to Track
1. **User Engagement**
- Daily/Weekly/Monthly Active Users
- Session duration
- Pages per session
2. **Feature Usage**
- Image generation count
- Most used models
- Popular aspect ratios
- Batch generation usage
3. **User Journey**
- Signup → First generation time
- Feature adoption rate
- Retention cohorts
4. **Errors & Issues**
- Generation failures
- Error rates by model
- API timeout frequency
### Creating Insights
1. **Funnel Analysis**
```
Sign Up → First Generation → Image Download → Share
```
2. **Retention**
```
Track users who return after first generation
```
3. **Trends**
```
Image generations over time
Model popularity trends
```
## Feature Flags Setup
### Create a Feature Flag
1. Go to PostHog → Feature Flags
2. Click "New feature flag"
3. Set flag key (e.g., `new_ui_redesign`)
4. Configure rollout percentage
5. Save and deploy
### Use in Code
```svelte
<script lang="ts">
import { analytics } from '$lib/analytics/posthog';
import { onMount } from 'svelte';
let showNewUI = false;
onMount(() => {
showNewUI = analytics.isFeatureEnabled('new_ui_redesign');
});
</script>
{#if showNewUI}
<NewUIComponent />
{:else}
<OldUIComponent />
{/if}
```
## Session Recordings (Optional)
Session recordings are **disabled by default** for privacy. To enable:
1. Update `apps/web/src/lib/analytics/posthog.ts`:
```typescript
disable_session_recording: false, // Enable recordings
```
2. Configure in PostHog dashboard:
- Set recording sample rate
- Configure privacy settings
- Set up retention period
3. Add privacy notice to your app
## Privacy & Compliance
### GDPR Compliance
- ✅ Only tracks identified (logged-in) users
- ✅ Users can opt-out via PostHog settings
- ✅ Data retention policies can be configured
- ✅ Personal data can be deleted on request
### User Opt-Out
To allow users to opt-out:
```typescript
import posthog from '$lib/analytics/posthog';
// Opt user out
posthog.opt_out_capturing();
// Opt user back in
posthog.opt_in_capturing();
```
### Data Deletion
To delete user data (on account deletion):
```typescript
import { analytics } from '$lib/analytics/posthog';
// Reset all user data
analytics.reset();
```
## Troubleshooting
### PostHog Not Loading
- ✅ Verify `PUBLIC_POSTHOG_KEY` is set correctly
- ✅ Check `PUBLIC_POSTHOG_HOST` matches your region
- ✅ Ensure environment variables have `PUBLIC_` prefix
- ✅ Restart dev server after adding env vars
### No Events in Dashboard
- ✅ Verify API key matches PostHog project
- ✅ Check browser console for errors
- ✅ Ensure user is logged in (only tracks identified users)
- ✅ Check ad blocker isn't blocking requests
### Feature Flags Not Working
- ✅ Wait a few minutes after creating flag
- ✅ Verify flag key matches code
- ✅ Check user is identified
- ✅ Ensure flag is enabled in PostHog
### Development vs Production
- **Development**: All events are tracked, console logging enabled
- **Production**: Production mode, no console logs
- **Testing**: Use a separate PostHog project for testing
## Advanced Configuration
### Custom Initialization
To customize PostHog initialization, edit `apps/web/src/lib/analytics/posthog.ts`:
```typescript
posthog.init(PUBLIC_POSTHOG_KEY, {
api_host: PUBLIC_POSTHOG_HOST,
// Capture settings
capture_pageview: true,
capture_pageleave: true,
// Session settings
session_recording: {
recordCrossOriginIframes: false,
maskAllInputs: true,
maskTextSelector: '.sensitive'
},
// Privacy settings
respect_dnt: true,
opt_out_capturing_by_default: false,
// Performance
persistence: 'localStorage',
autocapture: false,
// Advanced features
enable_recording_console_log: true,
disable_compression: false
});
```
### Proxy Setup (Avoid Ad Blockers)
For production, proxy PostHog through your domain:
1. Set up a reverse proxy (e.g., Cloudflare Worker)
2. Update `PUBLIC_POSTHOG_HOST` to your proxy URL
3. Configure CORS headers
Example Cloudflare Worker:
```javascript
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
const url = new URL(request.url)
url.hostname = 'us.i.posthog.com'
return fetch(url, {
method: request.method,
headers: request.headers,
body: request.body
})
}
```
## Resources
- [PostHog Documentation](https://posthog.com/docs)
- [PostHog JavaScript SDK](https://posthog.com/docs/libraries/js)
- [Feature Flags Guide](https://posthog.com/docs/feature-flags)
- [Session Recordings](https://posthog.com/docs/session-replay)
- [Privacy Controls](https://posthog.com/docs/privacy)
## Support
For issues specific to:
- **PostHog Platform**: [PostHog Support](https://posthog.com/support)
- **Integration Code**: Create an issue in this repository
- **Privacy/Compliance**: Consult with your legal team

View file

@ -774,7 +774,7 @@ services:
- synapse_data:/data - synapse_data:/data
ports: ports:
- "8008:8008" - "8008:8008"
- "9000:9000" - "9002:9002" # Metrics (9000 used by MinIO)
healthcheck: healthcheck:
test: ["CMD", "curl", "-fSs", "http://localhost:8008/health"] test: ["CMD", "curl", "-fSs", "http://localhost:8008/health"]
interval: 30s interval: 30s

View file

@ -159,7 +159,7 @@ app_service_config_files: []
report_stats: false report_stats: false
enable_metrics: true enable_metrics: true
metrics_port: 9000 metrics_port: 9002
# ============================================ # ============================================
# Caching # Caching

View file

@ -226,7 +226,7 @@ Memoro transformiert Audio-Aufnahmen in strukturierte, durchsuchbare Inhalte mit
| Audio | expo-audio, Azure Speech Services | | Audio | expo-audio, Azure Speech Services |
| State | Zustand | | State | Zustand |
| Payments | RevenueCat | | Payments | RevenueCat |
| Analytics | PostHog, Sentry | | Analytics | Umami (self-hosted) |
| i18n | react-i18next (32 Sprachen) | | i18n | react-i18next (32 Sprachen) |
#### Projektstruktur #### Projektstruktur

3338
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff