diff --git a/backend/routers/caliper.py b/backend/routers/caliper.py index 6b0e1c2..3c53e52 100644 --- a/backend/routers/caliper.py +++ b/backend/routers/caliper.py @@ -7,7 +7,7 @@ import uuid import logging from typing import Optional -from fastapi import APIRouter, Header, Depends +from fastapi import APIRouter, Header, Depends, HTTPException from db import get_db, get_cursor, r2d from auth import require_auth, check_feature_access, increment_feature_usage @@ -35,15 +35,20 @@ def upsert_caliper(e: CaliperEntry, x_profile_id: Optional[str]=Header(default=N """Create or update caliper entry (upsert by date).""" pid = get_pid(x_profile_id) - # Phase 2: Check feature access (non-blocking, log only) + # Phase 4: Check feature access and ENFORCE access = check_feature_access(pid, 'caliper_entries') log_feature_usage(pid, 'caliper_entries', access, 'create') if not access['allowed']: logger.warning( - f"[FEATURE-LIMIT] User {pid} would be blocked: " + f"[FEATURE-LIMIT] User {pid} blocked: " f"caliper_entries {access['reason']} (used: {access['used']}, limit: {access['limit']})" ) + raise HTTPException( + status_code=403, + detail=f"Limit erreicht: Du hast das Kontingent für Caliper-Einträge überschritten ({access['used']}/{access['limit']}). " + f"Bitte kontaktiere den Admin oder warte bis zum nächsten Reset." + ) with get_db() as conn: cur = get_cursor(conn) diff --git a/backend/routers/circumference.py b/backend/routers/circumference.py index bca2a14..41c06fa 100644 --- a/backend/routers/circumference.py +++ b/backend/routers/circumference.py @@ -7,7 +7,7 @@ import uuid import logging from typing import Optional -from fastapi import APIRouter, Header, Depends +from fastapi import APIRouter, Header, Depends, HTTPException from db import get_db, get_cursor, r2d from auth import require_auth, check_feature_access, increment_feature_usage @@ -35,15 +35,20 @@ def upsert_circ(e: CircumferenceEntry, x_profile_id: Optional[str]=Header(defaul """Create or update circumference entry (upsert by date).""" pid = get_pid(x_profile_id) - # Phase 2: Check feature access (non-blocking, log only) + # Phase 4: Check feature access and ENFORCE access = check_feature_access(pid, 'circumference_entries') log_feature_usage(pid, 'circumference_entries', access, 'create') if not access['allowed']: logger.warning( - f"[FEATURE-LIMIT] User {pid} would be blocked: " + f"[FEATURE-LIMIT] User {pid} blocked: " f"circumference_entries {access['reason']} (used: {access['used']}, limit: {access['limit']})" ) + raise HTTPException( + status_code=403, + detail=f"Limit erreicht: Du hast das Kontingent für Umfangs-Einträge überschritten ({access['used']}/{access['limit']}). " + f"Bitte kontaktiere den Admin oder warte bis zum nächsten Reset." + ) with get_db() as conn: cur = get_cursor(conn) diff --git a/backend/routers/weight.py b/backend/routers/weight.py index 414bd8b..2d49baa 100644 --- a/backend/routers/weight.py +++ b/backend/routers/weight.py @@ -7,7 +7,7 @@ import uuid import logging from typing import Optional -from fastapi import APIRouter, Header, Depends +from fastapi import APIRouter, Header, Depends, HTTPException from db import get_db, get_cursor, r2d from auth import require_auth, check_feature_access, increment_feature_usage @@ -35,19 +35,23 @@ def upsert_weight(e: WeightEntry, x_profile_id: Optional[str]=Header(default=Non """Create or update weight entry (upsert by date).""" pid = get_pid(x_profile_id) - # Phase 2: Check feature access (non-blocking, log only) + # Phase 4: Check feature access and ENFORCE access = check_feature_access(pid, 'weight_entries') # Structured logging (always) log_feature_usage(pid, 'weight_entries', access, 'create') - # Warning if limit exceeded (legacy) + # BLOCK if limit exceeded if not access['allowed']: logger.warning( - f"[FEATURE-LIMIT] User {pid} would be blocked: " + f"[FEATURE-LIMIT] User {pid} blocked: " f"weight_entries {access['reason']} (used: {access['used']}, limit: {access['limit']})" ) - # NOTE: Phase 2 does NOT block - just logs! + raise HTTPException( + status_code=403, + detail=f"Limit erreicht: Du hast das Kontingent für Gewichtseinträge überschritten ({access['used']}/{access['limit']}). " + f"Bitte kontaktiere den Admin oder warte bis zum nächsten Reset." + ) with get_db() as conn: cur = get_cursor(conn)