From 26f8bcf86da24698a0a40f2ac066641c3c396202 Mon Sep 17 00:00:00 2001 From: Lars Date: Thu, 19 Mar 2026 12:40:25 +0100 Subject: [PATCH] docs: add Feature-Registry Pattern architecture for v9c Replaced hardcoded tier limits with flexible Feature-Registry Pattern: - features table: All limitable features (weight, AI, photos, export, etc.) - tier_limits: Tier x Feature matrix (admin-configurable) - user_feature_restrictions: Individual user overrides - user_feature_usage: Usage tracking with configurable reset periods Key capabilities: - Add new limitable features without schema changes - Admin UI for matrix-based limit configuration - User-level overrides for specific restrictions - Access hierarchy: User restriction > Tier limit > Feature default Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 217 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 182 insertions(+), 35 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index c95eaee..db7f837 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -151,18 +151,70 @@ Beispiele: - gift_coupons_per_month: 3 ``` -#### **tiers** - Tier-Konfiguration (Admin-editierbar) +#### **tiers** - Tier-Konfiguration (vereinfacht) ```sql -id, slug, name, description, sort_order -max_weight_entries, max_ai_calls_month, max_photos (NULL = unbegrenzt) -allow_export, allow_activity_import, allow_nutrition_import -allow_fitness_connectors, allow_gift_coupons +id, slug, name, description, sort_order, active Initial Tiers: -- free: 30 Einträge, 0 KI, 5 Fotos, kein Export/Import -- basic: unbegrenzt, 10 KI/Monat, 50 Fotos, Export/Import -- premium: unbegrenzt, unbegrenzt KI, unbegrenzt Fotos, alle Features -- selfhosted: unbegrenzt alles (für Lars) +- free, basic, premium, selfhosted + +Limits sind jetzt in tier_limits Tabelle (siehe unten)! +``` + +#### **features** - Feature-Registry (alle limitierbaren Features) +```sql +id, slug, name, category, description, unit +default_limit (NULL = unbegrenzt) +reset_period ('monthly' | 'daily' | 'never') +visible_in_admin, sort_order, active + +Initial Features: +- weight_entries: Gewichtseinträge, default: 30, never +- circumference_entries: Umfangsmessungen, default: 30, never +- caliper_entries: Caliper-Messungen, default: 30, never +- nutrition_entries: Ernährungseinträge, default: 30, never +- activity_entries: Aktivitäten, default: 30, never +- photos: Progress-Fotos, default: 5, never +- ai_calls: KI-Analysen, default: 0, monthly +- ai_pipeline: KI-Pipeline, default: 0, monthly +- csv_import: CSV-Importe, default: 0, monthly +- data_export: Daten-Exporte, default: 0, monthly +- fitness_connectors: Fitness-Connectoren, default: 0, never + +Neue Features einfach per INSERT hinzufügen - kein Schema-Change! +``` + +#### **tier_limits** - Limits pro Tier + Feature +```sql +id, tier_slug, feature_slug, limit_value, enabled + +Beispiel Free Tier: +- ('free', 'weight_entries', 30, true) +- ('free', 'ai_calls', 0, false) -- KI deaktiviert +- ('free', 'data_export', 0, false) + +Beispiel Premium: +- ('premium', 'weight_entries', NULL, true) -- unbegrenzt +- ('premium', 'ai_calls', NULL, true) -- unbegrenzt + +Admin kann in UI Matrix bearbeiten: Tier x Feature +``` + +#### **user_feature_restrictions** - Individuelle User-Limits +```sql +id, profile_id, feature_slug, limit_value, enabled +reason, set_by (admin_id) + +Überschreibt Tier-Limits für spezifische User. +Admin kann jeden User individuell einschränken oder erweitern. +``` + +#### **user_feature_usage** - Nutzungs-Tracking +```sql +id, profile_id, feature_slug, period_start, usage_count, last_used + +Für Features mit reset_period (z.B. ai_calls monthly). +Wird automatisch zurückgesetzt am Monatsanfang. ``` #### **coupons** - Coupon-Verwaltung @@ -214,15 +266,6 @@ total_weight_entries, total_ai_analyses, total_exports bonus_points (später), gift_coupons_available (später) ``` -#### **user_restrictions** - Individuelle Einschränkungen -```sql -profile_id, max_ai_calls_month, max_weight_entries, max_photos -block_export, block_ai, block_import -reason, set_by (admin_id) - -Überschreibt Tier-Limits für spezifische User -``` - #### **profiles** - Erweiterte Spalten ```sql tier, tier_locked (Admin kann Tier festnageln) @@ -238,18 +281,38 @@ stripe_customer_id (vorbereitet für v9d) #### Neue Router (v9c): ``` routers/tiers.py - Tier-Verwaltung (List, Edit, Create) +routers/features.py - Feature-Registry (List, Add, Edit, Delete) ⭐ NEU +routers/tier_limits.py - Tier-Limits-Matrix (Admin bearbeitet Tier x Feature) ⭐ NEU routers/coupons.py - Coupon-System (Redeem, Admin CRUD) routers/access_grants.py - Zugriffs-Verwaltung (Current, Grant, Revoke) -routers/user_admin.py - Erweiterte User-Verwaltung (Activity, Stats, Restrictions) +routers/user_admin.py - Erweiterte User-Verwaltung (Activity, Stats, Feature-Restrictions) routers/settings.py - App-Einstellungen (Admin) routers/registration.py - Registrierung + E-Mail-Verifizierung ``` #### Neue Middleware: ```python -require_tier(min_tier) - Feature-Gate basierend auf Tier -check_feature_limit(feature, action) - Limit-Prüfung (z.B. max_weight_entries) -log_activity(type, details) - Activity-Logging +check_feature_access(profile_id, feature_slug, action='use') + """ + Zentrale Feature-Access-Prüfung. + Hierarchie: + 1. User-Restriction (höchste Priorität) + 2. Tier-Limit + 3. Feature-Default + + Returns: {'allowed': bool, 'limit': int, 'used': int, 'remaining': int, 'reason': str} + """ + +increment_feature_usage(profile_id, feature_slug) + """ + Inkrementiert Nutzungszähler. + Berücksichtigt reset_period (monthly, daily, never). + """ + +log_activity(profile_id, activity_type, details=None) + """ + Loggt User-Aktivitäten in user_activity_log. + """ ``` #### Hintergrund-Tasks (Cron): @@ -302,22 +365,27 @@ def create_weight_entry(): #### Neue Seiten: ``` -RegisterPage.jsx - Registrierung (Name, E-Mail, Passwort) -VerifyEmailPage.jsx - E-Mail-Verifizierung (Token aus URL) -RedeemCouponPage.jsx - Coupon-Eingabe (oder Modal) -AdminCouponsPage.jsx - Coupon-Verwaltung (Admin) -AdminTiersPage.jsx - Tier-Konfiguration (Admin) -AdminSettingsPage.jsx - App-Einstellungen (Admin) +RegisterPage.jsx - Registrierung (Name, E-Mail, Passwort) +VerifyEmailPage.jsx - E-Mail-Verifizierung (Token aus URL) +RedeemCouponPage.jsx - Coupon-Eingabe (oder Modal) +AdminCouponsPage.jsx - Coupon-Verwaltung (Admin) +AdminTiersPage.jsx - Tier-Verwaltung (CRUD) (Admin) +AdminFeaturesPage.jsx - Feature-Registry (List, Add, Edit) ⭐ NEU +AdminTierLimitsPage.jsx - Tier x Feature Matrix (bearbeiten) ⭐ NEU +AdminUserRestrictionsPage.jsx - User-spezifische Limits (bearbeiten) ⭐ NEU +AdminSettingsPage.jsx - App-Einstellungen (Admin) ``` #### Neue Komponenten: ```jsx - // Tier-Anzeige mit Icon -... // Feature nur für Basic+ zeigen - // "Trial endet in 5 Tagen" Banner - // Coupon-Eingabefeld - // User-Activity-Log - // Login-Streak Anzeige (später) + // Tier-Anzeige mit Icon +... // Feature-basierte Sichtbarkeit ⭐ GEÄNDERT + // "Trial endet in 5 Tagen" Banner + // Coupon-Eingabefeld + // User-Activity-Log + // "5/10 verwendet" Anzeige ⭐ NEU + // Matrix-Editor ⭐ NEU + // Login-Streak (später) ``` #### Erweiterte Admin-Seiten: @@ -326,8 +394,87 @@ AdminUsersPage.jsx erweitert um: - Activity-Log Button → zeigt user_activity_log - Stats Button → zeigt user_stats - Access-Grants Button → zeigt aktive/abgelaufene Zugriffe -- Restrictions Button → individuelle Limits setzen +- Feature-Restrictions Button → individuelle Feature-Limits setzen ⭐ GEÄNDERT - Grant Access Button → manuell Tier-Zugriff gewähren +- Usage-Overview → zeigt user_feature_usage für alle Features ⭐ NEU +``` + +#### Admin-Interface-Details: + +**AdminFeaturesPage.jsx** - Feature-Registry verwalten +```jsx +// Alle Features auflisten + neue hinzufügen + + {features.map(f => ( + + {f.name} + {f.category} + {f.unit} + {f.reset_period} + {f.default_limit ?? '∞'} + + + + + + ))} + + +``` + +**AdminTierLimitsPage.jsx** - Matrix-Editor +```jsx +// Matrix-View: Tiers (Spalten) x Features (Zeilen) + + + + Feature + Free + Basic + Premium + Selfhosted + + + + + Gewichtseinträge + + + + + + + KI-Analysen/Monat + 0 + + ∞ + ∞ + + + +``` + +**AdminUserRestrictionsPage.jsx** - Individuelle User-Limits +```jsx + + + + + {features.map(f => ( + + {f.name} + {getTierLimit(user.tier, f.slug)} + {getUsage(user.id, f.slug)} + + + + + + ))} + ``` ---