""" User Restrictions Management Endpoints for Mitai Jinkendo Admin-only user-specific feature overrides. """ from fastapi import APIRouter, HTTPException, Depends from db import get_db, get_cursor, r2d from auth import require_admin router = APIRouter(prefix="/api/user-restrictions", tags=["user-restrictions"]) @router.get("") def list_user_restrictions(profile_id: str = None, session: dict = Depends(require_admin)): """ Admin: List user restrictions. Optional query param: ?profile_id=... (filter by user) """ with get_db() as conn: cur = get_cursor(conn) if profile_id: cur.execute(""" SELECT ur.*, f.name as feature_name, f.category as feature_category, p.name as profile_name FROM user_feature_restrictions ur JOIN features f ON f.id = ur.feature_id JOIN profiles p ON p.id = ur.profile_id WHERE ur.profile_id = %s ORDER BY f.category, f.name """, (profile_id,)) else: cur.execute(""" SELECT ur.*, f.name as feature_name, f.category as feature_category, p.name as profile_name, p.email as profile_email FROM user_feature_restrictions ur JOIN features f ON f.id = ur.feature_id JOIN profiles p ON p.id = ur.profile_id ORDER BY p.name, f.category, f.name """) return [r2d(r) for r in cur.fetchall()] @router.post("") def create_user_restriction(data: dict, session: dict = Depends(require_admin)): """ Admin: Create user-specific feature restriction. Body: { "profile_id": "uuid", "feature_id": "weight_entries", "limit_value": 10, // NULL = unlimited, 0 = disabled "reason": "Spam prevention" } """ profile_id = data.get('profile_id') feature_id = data.get('feature_id') limit_value = data.get('limit_value') reason = data.get('reason', '') if not profile_id or not feature_id: raise HTTPException(400, "profile_id und feature_id fehlen") with get_db() as conn: cur = get_cursor(conn) # Check if restriction already exists cur.execute(""" SELECT id FROM user_feature_restrictions WHERE profile_id = %s AND feature_id = %s """, (profile_id, feature_id)) if cur.fetchone(): raise HTTPException(400, "Einschränkung existiert bereits (nutze PUT zum Aktualisieren)") # Create restriction cur.execute(""" INSERT INTO user_feature_restrictions ( profile_id, feature_id, limit_value, reason, created_by ) VALUES (%s, %s, %s, %s, %s) RETURNING id """, (profile_id, feature_id, limit_value, reason, session['profile_id'])) restriction_id = cur.fetchone()['id'] conn.commit() return {"ok": True, "id": restriction_id} @router.put("/{restriction_id}") def update_user_restriction(restriction_id: str, data: dict, session: dict = Depends(require_admin)): """Admin: Update user restriction.""" with get_db() as conn: cur = get_cursor(conn) updates = [] values = [] if 'limit_value' in data: updates.append('limit_value = %s') values.append(data['limit_value']) if 'reason' in data: updates.append('reason = %s') values.append(data['reason']) if not updates: return {"ok": True} updates.append('updated = CURRENT_TIMESTAMP') values.append(restriction_id) cur.execute( f"UPDATE user_feature_restrictions SET {', '.join(updates)} WHERE id = %s", values ) conn.commit() return {"ok": True} @router.delete("/{restriction_id}") def delete_user_restriction(restriction_id: str, session: dict = Depends(require_admin)): """Admin: Delete user restriction (reverts to tier limit).""" with get_db() as conn: cur = get_cursor(conn) cur.execute("DELETE FROM user_feature_restrictions WHERE id = %s", (restriction_id,)) conn.commit() return {"ok": True}