From 430541f49be621cabcb1c84e862db49b31b57eb9 Mon Sep 17 00:00:00 2001 From: Claude Code Date: Sat, 2 May 2026 22:51:27 +0000 Subject: [PATCH] STAGING_MODE Env-Flag: kein Hard-Stop, kein Org-Switcher in Staging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wenn STAGING_MODE=1 (oder true/yes) in der .env gesetzt ist: - check_license() liefert immer unlimited_budget=True -> kein Token-Budget-Hard-Stop, egal was in der DB steht. - /api/auth/me liefert is_global_admin=False -> Frontend ruft _initOrgSwitcher nicht auf, Org-Switcher-Section bleibt versteckt. Nur in ~/AegisSight-Monitor-staging/.env gesetzt; Live-.env hat das Flag nicht, daher dort unverändertes Produktiv-Verhalten. --- src/routers/auth.py | 13 ++++++++++++- src/services/license_service.py | 14 ++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/routers/auth.py b/src/routers/auth.py index 7f68cf8..629aaec 100644 --- a/src/routers/auth.py +++ b/src/routers/auth.py @@ -1,7 +1,13 @@ """Auth-Router: Magic-Link-Login und Nutzerverwaltung.""" import logging +import os from datetime import datetime, timedelta from fastapi import APIRouter, Depends, HTTPException, Request, status + + +def _staging_mode() -> bool: + """STAGING_MODE Env-Flag (vgl. services.license_service).""" + return os.environ.get("STAGING_MODE", "").lower() in ("1", "true", "yes") from models import ( MagicLinkRequest, MagicLinkResponse, @@ -203,6 +209,11 @@ async def get_me( credits_remaining = max(0, int(credits_total - credits_used)) credits_percent_used = round((credits_used / credits_total) * 100, 1) if credits_total > 0 else 0 + # STAGING_MODE: Org-Switcher im Frontend deaktivieren + is_global_admin_response = current_user.get("is_global_admin", False) + if _staging_mode(): + is_global_admin_response = False + return UserMeResponse( id=current_user["id"], username=current_user["username"], @@ -219,7 +230,7 @@ async def get_me( read_only=license_info.get("read_only", False), read_only_reason=license_info.get("read_only_reason"), unlimited_budget=unlimited_budget, - is_global_admin=current_user.get("is_global_admin", False), + is_global_admin=is_global_admin_response, ) diff --git a/src/services/license_service.py b/src/services/license_service.py index 52f2a75..5e85f76 100644 --- a/src/services/license_service.py +++ b/src/services/license_service.py @@ -1,5 +1,6 @@ """Lizenz-Verwaltung und -Pruefung.""" import logging +import os from datetime import datetime from config import TIMEZONE import aiosqlite @@ -7,6 +8,15 @@ import aiosqlite logger = logging.getLogger("osint.license") +def _staging_mode() -> bool: + """Staging-Mode aktiv? Wenn ja, gilt: immer unlimited Budget, kein Hard-Stop. + + Wird ueber ENV-Variable STAGING_MODE=1 (oder true) aktiviert. + Nur in Staging-.env gesetzt; Live-.env hat das Flag nicht. + """ + return os.environ.get("STAGING_MODE", "").lower() in ("1", "true", "yes") + + async def check_license(db: aiosqlite.Connection, organization_id: int) -> dict: """Prueft den Lizenzstatus einer Organisation. @@ -50,6 +60,10 @@ async def check_license(db: aiosqlite.Connection, organization_id: int) -> dict: credits_total = lic_dict.get("credits_total") credits_used = lic_dict.get("credits_used") or 0 + # STAGING_MODE: kein Token-Budget-Hard-Stop, immer unlimited + if _staging_mode(): + unlimited_budget = True + # Ablauf pruefen now = datetime.now(TIMEZONE) valid_until = license_row["valid_until"] -- 2.49.1