RABC fejlesztése és beélesítése hibák kijavításával

This commit is contained in:
Roo
2026-06-18 18:09:51 +00:00
parent 611307a24b
commit fe3c32597d
57 changed files with 4689 additions and 655 deletions

View File

@@ -492,10 +492,12 @@ class AssetService:
async def get_user_vehicle_limit(db: AsyncSession, user_id: int, org_id: int) -> int:
"""
Get the vehicle limit for a user, checking:
1. Config-based limits (user role, subscription plan, org-specific)
2. Subscription tier JSONB rules['allowances']['max_vehicles']
1. Subscription tier JSONB rules['allowances']['max_vehicles'] (PRIMARY source of truth)
2. Organization-level base_asset_limit (fallback if no user subscription)
3. Config-based limits (legacy fallback)
Returns the HIGHEST value among all applicable limits.
P0: The subscription_tier JSONB rules are now the Single Source of Truth.
Legacy string-based subscription_plan lookups have been removed.
Args:
db: AsyncSession
@@ -503,10 +505,11 @@ class AssetService:
org_id: Organization ID
Returns:
Maximum allowed vehicles (highest of all applicable limits)
Maximum allowed vehicles
"""
from app.models.identity import User
from app.models.core_logic import UserSubscription, SubscriptionTier
from app.models.marketplace.organization import Organization
from app.services.config_service import config
try:
@@ -514,34 +517,11 @@ class AssetService:
user_stmt = select(User).where(User.id == user_id)
user = (await db.execute(user_stmt)).scalar_one()
# ── 1. CONFIG-BASED LIMIT ──
limits = await config.get_setting(db, "VEHICLE_LIMIT")
if limits is None:
logger.error(f"VEHICLE_LIMIT configuration not found in database for user {user_id}")
limits = {"admin": 9999, "superadmin": 9999, "user": 100, "free": 100, "premium": 100, "vip": 100, "service_pro": 100}
user_role = user.role.value if hasattr(user.role, 'value') else str(user.role)
subscription_plan = user.subscription_plan or "free"
config_limit = limits.get(user_role)
if config_limit is None:
config_limit = limits.get(subscription_plan.lower())
if config_limit is None:
config_limit = limits.get("free", 1)
# ── 2. ORGANIZATION-SPECIFIC LIMIT ──
org_limit = None
try:
org_limits = await config.get_setting(db, "VEHICLE_LIMIT", org_id=org_id)
if org_limits and isinstance(org_limits, dict):
org_limit = org_limits.get(user_role) or org_limits.get(subscription_plan.lower())
if org_limit is None and "default" in org_limits:
org_limit = org_limits["default"]
except Exception as e:
logger.debug(f"No organization-specific VEHICLE_LIMIT found for org {org_id}: {e}")
# ── 3. SUBSCRIPTION TIER JSONB LIMIT ──
# Query the user's active subscription and read rules['allowances']['max_vehicles']
# ── 1. SUBSCRIPTION TIER JSONB LIMIT (PRIMARY) ──
# P0: This is now the Single Source of Truth for vehicle limits.
# Reads rules['allowances']['max_vehicles'] from the user's active subscription tier.
subscription_limit = None
try:
sub_stmt = (
@@ -564,12 +544,53 @@ class AssetService:
if max_vehicles is not None and isinstance(max_vehicles, (int, float)):
subscription_limit = int(max_vehicles)
logger.info(
f"Subscription tier limit for user {user_id}: "
f"max_vehicles={subscription_limit} (from rules={tier_rules})"
f"[P0] Subscription tier limit for user {user_id}: "
f"max_vehicles={subscription_limit} (from JSONB rules)"
)
except Exception as e:
logger.debug(f"Could not read subscription tier limit for user {user_id}: {e}")
# ── 2. ORGANIZATION base_asset_limit (fallback) ──
# If no user-level subscription, check the org's assigned tier
org_limit = None
if subscription_limit is None:
try:
org_stmt = select(Organization).where(Organization.id == org_id)
org = (await db.execute(org_stmt)).scalar_one_or_none()
if org and org.subscription_tier_id:
# Read from the org's subscription tier
tier_stmt = select(SubscriptionTier).where(SubscriptionTier.id == org.subscription_tier_id)
tier = (await db.execute(tier_stmt)).scalar_one_or_none()
if tier and tier.rules:
allowances = tier.rules.get('allowances', {})
if isinstance(allowances, dict):
max_vehicles = allowances.get('max_vehicles')
if max_vehicles is not None:
org_limit = int(max_vehicles)
logger.info(
f"[P0] Org subscription tier limit for org {org_id}: "
f"max_vehicles={org_limit} (from JSONB rules)"
)
elif org:
# Fallback to legacy base_asset_limit if no tier assigned
org_limit = max(org.base_asset_limit or 1, 1)
except Exception as e:
logger.debug(f"Could not read org subscription tier limit for org {org_id}: {e}")
# ── 3. CONFIG-BASED LIMIT (legacy fallback, role-based only) ──
config_limit = None
try:
limits = await config.get_setting(db, "VEHICLE_LIMIT")
if limits and isinstance(limits, dict):
config_limit = limits.get(user_role)
if config_limit is None:
config_limit = limits.get("default")
except Exception as e:
logger.debug(f"Could not read VEHICLE_LIMIT config: {e}")
if config_limit is None:
config_limit = 1 # absolute fallback
# ── 4. FINAL: Take the HIGHEST of all applicable limits ──
final_limit = config_limit
if org_limit is not None:
@@ -578,8 +599,8 @@ class AssetService:
final_limit = max(final_limit, subscription_limit)
logger.info(
f"Vehicle limit for user {user_id} (role={user_role}, plan={subscription_plan}): "
f"config={config_limit}, org={org_limit}, subscription={subscription_limit}, "
f"[P0] Vehicle limit for user {user_id} (role={user_role}): "
f"subscription_tier={subscription_limit}, org={org_limit}, config={config_limit}, "
f"final={final_limit}"
)