diff --git a/apps/mana/apps/web/src/hooks.server.ts b/apps/mana/apps/web/src/hooks.server.ts
index 54d37b067..319abe1a7 100644
--- a/apps/mana/apps/web/src/hooks.server.ts
+++ b/apps/mana/apps/web/src/hooks.server.ts
@@ -1,5 +1,4 @@
import type { Handle } from '@sveltejs/kit';
-import { injectUmamiAnalytics } from '@mana/shared-utils/analytics-server';
import { setSecurityHeaders } from '@mana/shared-utils/security-headers';
/**
@@ -226,7 +225,7 @@ window.__PUBLIC_MANA_ANALYTICS_URL__ = ${JSON.stringify(PUBLIC_MANA_ANALYTICS_UR
window.__PUBLIC_AI_MISSION_GRANTS__ = ${JSON.stringify(PUBLIC_AI_MISSION_GRANTS)};
window.__PUBLIC_GLITCHTIP_DSN__ = ${JSON.stringify(PUBLIC_GLITCHTIP_DSN)};
`;
- return injectUmamiAnalytics(html.replace('
', `${envScript}`));
+ return html.replace('', `${envScript}`);
},
});
diff --git a/apps/picture/apps/landing/.env.example b/apps/picture/apps/landing/.env.example
deleted file mode 100644
index 36877ecfb..000000000
--- a/apps/picture/apps/landing/.env.example
+++ /dev/null
@@ -1,3 +0,0 @@
-# Umami Analytics
-PUBLIC_UMAMI_URL=https://your-umami-instance.com
-PUBLIC_UMAMI_WEBSITE_ID=your-website-id
diff --git a/docker/init-db/01-create-databases.sql b/docker/init-db/01-create-databases.sql
index 54b5f854f..b92887326 100644
--- a/docker/init-db/01-create-databases.sql
+++ b/docker/init-db/01-create-databases.sql
@@ -6,10 +6,8 @@ CREATE DATABASE mana_sync;
-- Infrastructure databases (external tools)
CREATE DATABASE glitchtip;
-CREATE DATABASE umami;
-- Grant privileges
GRANT ALL PRIVILEGES ON DATABASE mana_platform TO mana;
GRANT ALL PRIVILEGES ON DATABASE mana_sync TO mana;
GRANT ALL PRIVILEGES ON DATABASE glitchtip TO mana;
-GRANT ALL PRIVILEGES ON DATABASE umami TO mana;
diff --git a/docs/ANALYTICS.md b/docs/ANALYTICS.md
deleted file mode 100644
index 74ba345bd..000000000
--- a/docs/ANALYTICS.md
+++ /dev/null
@@ -1,424 +0,0 @@
-# Analytics & Event Tracking
-
-Mana verwendet Umami für Web Analytics. Alle Events werden zu `stats.mana.how` gesendet.
-
-## Umami Dashboard
-
-- **URL**: https://stats.mana.how
-- **Public Stats**: Alle Websites haben Public Sharing aktiviert
-
-## Architektur
-
-Web-App Analytics werden über `hooks.server.ts` injiziert (nicht mehr hardcoded in `app.html`).
-
-```
-.env.development → UMAMI_WEBSITE_ID_CHAT=xxx
- ↓ (scripts/generate-env.mjs)
-apps/chat/apps/web/.env → PUBLIC_UMAMI_WEBSITE_ID=xxx
- ↓ (process.env in hooks.server.ts)
-injectUmamiAnalytics(html) →
-
-
-```
-
-### Astro Landing Pages
-
-```astro
----
-// Layout.astro - Script tag is already in
----
-
-
-```
-
-### Development Mode
-
-Im Development-Modus ist Umami normalerweise nicht geladen (kein Script-Tag), daher werden Events stillschweigend ignoriert (`isUmamiAvailable()` gibt `false` zurück). Fehler beim Tracking werden als `console.warn` ausgegeben.
-
----
-
-## Event Naming Conventions
-
-1. **snake_case** für Event-Namen: `task_created`, nicht `taskCreated`
-2. **Kurze, beschreibende Namen**: `signup_completed`, nicht `user_has_completed_signup_process`
-3. **Konsistente Suffixe**:
- - `_created`, `_updated`, `_deleted` für CRUD
- - `_started`, `_completed`, `_canceled` für Prozesse
- - `_clicked`, `_viewed` für UI-Interaktionen
-
-## Privacy
-
-- Keine persönlichen Daten in Events (keine E-Mails, Namen, etc.)
-- Suchanfragen: Nur Länge wird getracked, nicht der Inhalt
-- Error Messages: Auf 100 Zeichen gekürzt
-- GDPR-konform: Umami ist privacy-focused und setzt keine Cookies
-
-## Umami Server
-
-- **Host**: Mac Mini (mana-server)
-- **Container**: `mana-mon-umami`
-- **Image**: `ghcr.io/umami-software/umami:postgresql-latest`
-- **Datenbank**: PostgreSQL (`umami` DB, shared Postgres-Instanz)
-- **Port**: 3000 (intern) → 8010 (extern), via Cloudflare Tunnel erreichbar unter stats.mana.how
diff --git a/infrastructure/docker-compose.gpu-box.yml b/infrastructure/docker-compose.gpu-box.yml
index f1e016e73..9a5a3d1de 100644
--- a/infrastructure/docker-compose.gpu-box.yml
+++ b/infrastructure/docker-compose.gpu-box.yml
@@ -80,24 +80,6 @@ services:
retries: 3
start_period: 60s
- umami:
- image: ghcr.io/umami-software/umami:postgresql-v2.18.0
- container_name: mana-mon-umami
- restart: unless-stopped
- ports:
- - '8010:3000'
- environment:
- DATABASE_URL: postgresql://postgres:${POSTGRES_PASSWORD}@192.168.178.131:5432/umami
- DATABASE_TYPE: postgresql
- APP_SECRET: ${UMAMI_APP_SECRET}
- DISABLE_TELEMETRY: '1'
- healthcheck:
- test: ['CMD-SHELL', 'wget -q -O- http://127.0.0.1:3000/api/heartbeat || exit 1']
- interval: 30s
- timeout: 5s
- retries: 3
- start_period: 30s
-
# ============================================
# Photon Geocoder (pre-existing user container, adopted into compose
# 2026-05-07 to gain a healthcheck). Backs mana-geocoding's
diff --git a/packages/shared-auth/src/core/authService.ts b/packages/shared-auth/src/core/authService.ts
index 087afd241..05077a59e 100644
--- a/packages/shared-auth/src/core/authService.ts
+++ b/packages/shared-auth/src/core/authService.ts
@@ -23,20 +23,6 @@ import {
getAppSettings as getAppSettingsFromToken,
} from './jwtUtils';
-/**
- * Inline analytics helper - tracks auth events via Umami if available.
- * No-ops silently in environments without Umami (mobile, SSR, dev).
- */
-function trackAuth(event: string, data?: Record): void {
- if (typeof window !== 'undefined' && (window as any).umami?.track) {
- try {
- (window as any).umami.track(event, { ...data, module: 'auth' });
- } catch {
- // Silently ignore tracking errors
- }
- }
-}
-
/**
* Default storage keys
*/
@@ -135,11 +121,9 @@ export function createAuthService(config: AuthServiceConfig): AuthServiceInterfa
// SSO cookie is nice-to-have, don't fail login if this fails
}
- trackAuth('login', { method: 'email' });
return { success: true };
} catch (error) {
console.error('Error signing in:', error);
- trackAuth('login_failed', { method: 'email' });
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error during sign in',
@@ -175,11 +159,9 @@ export function createAuthService(config: AuthServiceConfig): AuthServiceInterfa
// If emailVerified is false, the user needs to verify their email before login
const needsVerification = data?.user?.emailVerified === false;
- trackAuth('signup', { method: 'email' });
return { success: true, needsVerification };
} catch (error) {
console.error('Error signing up:', error);
- trackAuth('signup_failed', { method: 'email' });
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error during sign up',
@@ -203,7 +185,6 @@ export function createAuthService(config: AuthServiceConfig): AuthServiceInterfa
}).catch((err) => console.error('Error logging out on server:', err));
}
- trackAuth('logout');
await service.clearAuthStorage();
} catch (error) {
console.error('Error signing out:', error);
@@ -228,7 +209,6 @@ export function createAuthService(config: AuthServiceConfig): AuthServiceInterfa
return service.handleAuthError(response.status, errorData);
}
- trackAuth('password_reset_requested');
return { success: true };
} catch (error) {
console.error('Error sending password reset email:', error);
@@ -484,7 +464,6 @@ export function createAuthService(config: AuthServiceConfig): AuthServiceInterfa
return { success: false, error: err.message || 'Passkey registration failed' };
}
- trackAuth('passkey_registered');
return { success: true };
} catch (error) {
// User cancelled or WebAuthn error
@@ -572,14 +551,12 @@ export function createAuthService(config: AuthServiceConfig): AuthServiceInterfa
storage.setItem(storageKeys.USER_EMAIL, data.user?.email || ''),
]);
- trackAuth('login', { method: 'passkey' });
return { success: true };
} catch (error) {
if (error instanceof Error && error.name === 'NotAllowedError') {
return { success: false, error: 'Passkey authentication was cancelled' };
}
console.error('Passkey authentication error:', error);
- trackAuth('login_failed', { method: 'passkey' });
return {
success: false,
error: error instanceof Error ? error.message : 'Passkey authentication failed',
@@ -758,7 +735,6 @@ export function createAuthService(config: AuthServiceConfig): AuthServiceInterfa
}
}
- trackAuth('login', { method: '2fa' });
return { success: true };
} catch (error) {
return {
@@ -805,7 +781,6 @@ export function createAuthService(config: AuthServiceConfig): AuthServiceInterfa
}
}
- trackAuth('login', { method: 'backup_code' });
return { success: true };
} catch (error) {
return {
@@ -892,7 +867,6 @@ export function createAuthService(config: AuthServiceConfig): AuthServiceInterfa
return { success: false, error: err.message || 'Failed to send magic link' };
}
- trackAuth('magic_link_sent');
return { success: true };
} catch (error) {
return {
@@ -1297,7 +1271,6 @@ export function createAuthService(config: AuthServiceConfig): AuthServiceInterfa
]);
console.log('SSO: Successfully authenticated via session cookie');
- trackAuth('login', { method: 'sso' });
return { success: true };
} catch (error) {
// SSO failed - this is expected if user hasn't logged in anywhere
diff --git a/packages/shared-utils/src/analytics-server.ts b/packages/shared-utils/src/analytics-server.ts
deleted file mode 100644
index 16a5927b0..000000000
--- a/packages/shared-utils/src/analytics-server.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * Server-side Umami Analytics Utilities
- *
- * Used in SvelteKit hooks.server.ts to inject the Umami analytics script.
- * Reads the website ID from the PUBLIC_UMAMI_WEBSITE_ID environment variable.
- *
- * @example
- * ```typescript
- * import { injectUmamiAnalytics } from '@mana/shared-utils/analytics-server';
- *
- * export const handle: Handle = async ({ event, resolve }) => {
- * return resolve(event, {
- * transformPageChunk: ({ html }) => injectUmamiAnalytics(html),
- * });
- * };
- * ```
- */
-
-const UMAMI_SCRIPT_URL = 'https://stats.mana.how/script.js';
-
-/**
- * Get the Umami analytics script tag.
- * Returns empty string if no website ID is configured.
- */
-export function getUmamiScriptTag(websiteId?: string): string {
- const id = websiteId || process.env.PUBLIC_UMAMI_WEBSITE_ID || '';
- if (!id) return '';
- return ``;
-}
-
-/**
- * Inject the Umami analytics script into HTML.
- * Designed to be used in SvelteKit's transformPageChunk.
- *
- * @param html - The HTML string to inject the script into
- * @param websiteId - Optional website ID override (defaults to PUBLIC_UMAMI_WEBSITE_ID env var)
- * @returns The HTML with the Umami script injected before
- */
-export function injectUmamiAnalytics(html: string, websiteId?: string): string {
- const scriptTag = getUmamiScriptTag(websiteId);
- if (!scriptTag) return html;
- return html.replace('', `${scriptTag}\n`);
-}
diff --git a/packages/shared-utils/src/analytics.ts b/packages/shared-utils/src/analytics.ts
index 0faaae4be..79d6c4374 100644
--- a/packages/shared-utils/src/analytics.ts
+++ b/packages/shared-utils/src/analytics.ts
@@ -1,37 +1,13 @@
/**
- * Umami Analytics Utility
+ * Event-API — Web-Analytics DEAKTIVIERT (2026-05-26).
*
- * Provides type-safe event tracking for all Mana apps.
- * Events are automatically sent to Umami at stats.mana.how
- *
- * @example
- * ```typescript
- * import { trackEvent, trackClick } from '@mana/shared-utils/analytics';
- *
- * // Track a custom event
- * trackEvent('signup_completed', { method: 'email' });
- *
- * // Track a button click
- * trackClick('cta_hero', 'Get Started');
- * ```
+ * Verein-weit kein Besucher-Tracking mehr (keine Tracking-Pixel, auch
+ * nicht „nur Analytics" — siehe mana/docs/MISSION.md). Die `*Events`-
+ * Objekte und `track*`-Funktionen bleiben als No-ops bestehen, damit die
+ * bestehenden Aufruf-Stellen quer durch die Module weiter kompilieren —
+ * sie senden nichts mehr.
*/
-// Umami types
-declare global {
- interface Window {
- umami?: {
- track: (eventName: string, eventData?: Record) => void;
- };
- }
-}
-
-/**
- * Check if Umami is available
- */
-export function isUmamiAvailable(): boolean {
- return typeof window !== 'undefined' && typeof window.umami?.track === 'function';
-}
-
/**
* Track a custom event
*
@@ -45,15 +21,9 @@ export function trackEvent(
eventName: string,
data?: Record
): void {
- if (!isUmamiAvailable()) {
- return;
- }
-
- try {
- window.umami!.track(eventName, data);
- } catch (error) {
- console.warn('[Analytics] Failed to track event:', eventName, error);
- }
+ // No-op: Web-Analytics entfernt (2026-05-26). Bewusst kein Tracking.
+ void eventName;
+ void data;
}
/**
diff --git a/scripts/mac-mini/setup-umami-db.sh b/scripts/mac-mini/setup-umami-db.sh
deleted file mode 100755
index 4e63a510d..000000000
--- a/scripts/mac-mini/setup-umami-db.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/bash
-# Setup Umami database on Mac Mini
-# Run this script after starting PostgreSQL container
-
-set -e
-
-echo "Creating Umami database..."
-
-# Check if running inside docker network or from host
-if docker ps | grep -q mana-postgres; then
- docker exec -i mana-postgres psql -U postgres <