Files
service-finder/docs/subscription_limit_bug_root_cause_analysis.md

5.7 KiB
Raw Blame History

🔍 Subscription Limit Data Binding Bug — Root Cause Analysis

Dátum: 2026-07-28 Issue: #431 (Gitea) Súlyosság: P1 — A felhasználó rossz limiteket lát a frontenden


1. A Felhasználó Által Jelentett Hiba

A frontend "Előfizetés Információ" modális ablakon (SubscriptionStatusWidget) és a FinanceMainView Card 2-n a következő látszik:

  • Jármű Limit: 1/1
  • Garázs Limit: 2/1

Egy Pro/VIP csomag esetén a valós limit max_vehicles=3 (Pro) vagy max_vehicles=10 (VIP) lenne.


2. Adatbázis Réteg — Valós Állapot

Tábla Rekord Kulcs mező Érték
identity.users id=2 (admin@profibot.hu) subscription_plan private_vip_v1
identity.users id=2 scope_id 67
identity.users id=2 scope_level system
identity.users id=2 ui_mode personal
finance.user_subscriptions id=34 tier_id 15 (VIP) AKTÍV
finance.user_subscriptions id=33 tier_id 14 (Pro) inaktív
finance.org_subscriptions org_id=67 NINCS REKORD
system.subscription_tiers id=14 (private_pro_v1) allowances.max_vehicles 3
system.subscription_tiers id=14 allowances.max_garages 1
system.subscription_tiers id=14 display_name NULL
system.subscription_tiers id=15 (private_vip_v1) allowances.max_vehicles 10
system.subscription_tiers id=15 allowances.max_garages 2
system.subscription_tiers id=15 display_name "Privát VIP"

3. ROOT CAUSE #1 (Elsődleges) — Hibás Vezérlési Logika

Fájl: backend/app/api/v1/endpoints/users.py, read_users_me() függvény, sorok 212254.

A problémás kódszakasz (pszeudokód):

if active_org_id is not None:        # ← scope_id=67 → active_org_id=67 → IGAZ
    # 1. Org subscription keresés
    tier = org_sub_query(scalar_one_or_none)
    if tier and tier.rules:           # ← NINCS org subscription (üres finance.org_subscriptions org_id=67-re)
        allowances = tier.rules.get("allowances", {})
        max_vehicles = int(allowances.get("max_vehicles", 1))
        max_garages = int(allowances.get("max_garages", 1))
    else:
        # 2. Fallback: Organization.base_asset_limit
        org = select(Organization).where(id == active_org_id)
        max_vehicles = org.base_asset_limit or 1   # ← 1-et ad!
        max_garages = 1                            # ← 1-et ad!
        # ❌ HIBA: Soha nem nézi meg a user_subscriptions táblát!
else:
    # 3. Personal mode: user subscription keresés
    # ← SOHA NEM FUT LE, mert active_org_id != None
    tier = user_sub_query(scalar_one_or_none)
    if tier and tier.rules:
        allowances = tier.rules.get("allowances", {})
        max_vehicles = int(allowances.get("max_vehicles", 1))   # ← 10 lenne!
        max_garages = int(allowances.get("max_garages", 1))     # ← 2 lenne!

Miért hibás?

A user-nek van scope_id=67-e (egy szervezet ID), de az adott szervezethez nincs org subscription rekord. A felhasználónak viszont van aktív user subscription-e a VIP tier-re (tier_id=15, max_vehicles=10, max_garages=2).

A kód hibásan feltételezi, hogy ha van active_org_id, akkor:

  1. vagy van org subscription (→ abból olvassa a limiteket),
  2. vagy nincs (→ Organization.base_asset_limit fallback, ami 1).

Soha nem esik át a user subscription ágra, mert active_org_id is not None.

Hatás

A GET /auth/me válaszban:

{
  "max_vehicles": 1,   // ← 10 helyett
  "max_garages": 1,    // ← 2 helyett
  "subscription_display_name": null  // ← mert a tier változó None
}

4. ROOT CAUSE #2 (Másodlagos) — private_pro_v1 display_name NULL

Tábla: system.subscription_tiers id=14 Mező: rules->>'display_name' = NULL

A seederben (seed_packages.py:131) a display_name "Privát Pro"-ként van definiálva, de az éles adatbázisban NULL. Valószínűleg egy korábbi migráció vagy kézi módosítás írta felül.

Ez jelenleg nem okoz közvetlen hibát a felhasználónál (mert ő VIP-n van), de a Pro csomagra váltó felhasználóknál a display_name üres lenne.


5. Javítási Terv

5.1 Backend Fix (users.py)

A read_users_me() függvényben a fallback láncot ki kell egészíteni:

if active_org_id is not None:
    1. Org subscription keresés (MEGLÉVŐ)
    2. Ha nincs → User subscription keresés (ÚJ!)
    3. Ha user subscription sincs → Organization.base_asset_limit (MEGLÉVŐ fallback)
else:
    4. User subscription keresés (MEGLÉVŐ)

Ugyanez a logika kell a subscription_valid_until / subscription_tier_id feloldására is (sorok 267308), valamint a subscription_display_name feloldására (sor 311312).

5.2 DB Fix

UPDATE system.subscription_tiers
SET rules = jsonb_set(rules, '{display_name}', '"Privát Pro"')
WHERE id = 14 AND rules->>'display_name' IS NULL;

5.3 Frontend

A frontend komponensek (FinanceMainView.vue, SubscriptionStatusWidget.vue) már helyesen olvassák az authStore.user?.max_vehicles és authStore.user?.max_garages értékeket. A backend fix után automatikusan a helyes értékek jelennek meg.


6. Érintett Fájlok

Fájl Változtatás
backend/app/api/v1/endpoints/users.py read_users_me(): fallback lánc javítása
Adatbázis (SQL) private_pro_v1 display_name beállítása
frontend_app/src/views/FinanceMainView.vue Nincs változtatás szükséges (már a helyes mezőket olvassa)
frontend_app/src/components/dashboard/SubscriptionStatusWidget.vue Nincs változtatás szükséges