5.7 KiB
🔍 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 212–254.
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:
- vagy van org subscription (→ abból olvassa a limiteket),
- vagy nincs (→
Organization.base_asset_limitfallback, 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 267–308), valamint a subscription_display_name feloldására (sor 311–312).
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 |