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

@@ -0,0 +1,225 @@
# P0 Critical: DB Schema & Ownership Model Audit Report
**Dátum:** 2026-06-18
**Auditor:** Architect Mode
**Cél:** A 404 "Asset not found" hiba kivizsgálása event creation során — a Privát Garázsok (Private Garages) kezelésének DB vs API mismatch-e.
---
## 1. 🔍 SÉMA AUDIT (Tulajdonosi Modell Vizsgálata)
### 1.1 `vehicle.assets` tábla — Tulajdonosi Oszlopok
| Oszlop | Típus | Leírás |
|--------|-------|--------|
| `current_organization_id` | `integer NULL` | Melyik Org-ban van jelenleg a jármű |
| `owner_person_id` | `bigint NULL` | **Személy tulajdonos** (Person ID-re mutat, NEM User ID-ra!) |
| `owner_org_id` | `integer NULL` | **Szervezeti tulajdonos** (Organization ID) |
| `operator_person_id` | `bigint NULL` | **Üzemeltető személy** (Person ID) |
| `operator_org_id` | `integer NULL` | **Üzemeltető szervezet** (Organization ID) |
| `branch_id` | `uuid NULL` | Fizikai garázs (Branch) ahol áll |
| `status` | `varchar NOT NULL` | 'active', 'archived', stb. |
| `data_status` | `varchar NULL` | 'draft', 'active', 'enriched' |
**Következtetés:** Nincs direkt `owner_id` vagy `user_id` oszlop. A tulajdonjogot a `owner_person_id` (Person) és `owner_org_id` (Organization) kettőse modellezi. Ez a **Dual Entity** (Person vs User) modell része.
### 1.2 `fleet.organizations` tábla — Garázs Attribútumok
| Oszlop | Típus | Leírás |
|--------|-------|--------|
| `id` | `integer PK` | Szervezet azonosító |
| `owner_id` | `integer NULL` | Ki a tulajdonos (User ID) |
| `org_type` | `orgtype ENUM` | `'individual'`, `'fleet_owner'`, `'business'`, `'service_provider'` |
| `status` | `varchar` | `'active'`, `'pending_verification'` |
| `is_verified` | `boolean DEFAULT false` | KYC státusz |
| `name` | `varchar` | A garázs neve |
| `full_name` | `varchar` | Teljes cégnév |
**⚠️ KRITIKUS:** NINCS `is_personal`, `is_default` vagy `is_primary` flag az `organizations` táblában. A "Privát Garázs" fogalma **nem létezik külön mezőként** — csak az `org_type = 'individual'` jelzi.
### 1.3 `fleet.organization_members` tábla
| Oszlop | Típus |
|--------|-------|
| `organization_id` | `integer NOT NULL` |
| `user_id` | `integer NULL` |
| `person_id` | `bigint NULL` |
| `role` | `member_role ENUM` (OWNER, ADMIN, MEMBER, stb.) |
| `is_verified` | `boolean` |
| `status` | `varchar` ('active', 'pending_verification') |
### 1.4 `fleet.asset_assignments` tábla
| Oszlop | Típus |
|--------|-------|
| `id` | `uuid PK` |
| `asset_id` | `uuid NOT NULL` |
| `organization_id` | `integer NOT NULL` |
| `status` | `varchar NOT NULL` |
---
## 2. 👤 ADATBÁZIS AUDIT — User 28 és Asset rekord vizsgálata
### 2.1 User ID: 28
| Mező | Érték |
|------|-------|
| `id` | **28** |
| `email` | `tester_pro@profibot.hu` |
| `role` | `admin` |
| `person_id` | **29** ⚠️ (ez a Person ID!) |
| `subscription_plan` | `PREMIUM` |
| `is_active` | `true` |
| `is_deleted` | **`true`** 🛑 (SOFT-DELETED!) |
| `deleted_at` | **2026-06-14** (4 nappal ezelőtt) |
| `scope_level` | `organization` |
| `scope_id` | `null` |
### 2.2 Asset ID: `deb42aea-1f48-4a70-85b5-ba451d005577`
| Mező | Érték |
|------|-------|
| `id` | `deb42aea-...` |
| `license_plate` | `QWE123` |
| `current_organization_id` | **44** (Profibot Kft.) |
| `owner_person_id` | **29** ⚠️ (ez a Person ID, ami User 28-hoz tartozik!) |
| `owner_org_id` | **44** (Profibot Kft.) |
| `operator_person_id` | `null` |
| `operator_org_id` | `null` |
| `status` | `active` |
| `data_status` | `draft` |
| `branch_id` | `3bc1bff7-...` |
| `vehicle_class` | `motorcycle` |
| `brand` | `APRILIA` |
| `model` | `af1` |
### 2.3 Asset Assignment
| Mező | Érték |
|------|-------|
| `asset_id` | `deb42aea-...` |
| `organization_id` | **44** |
| `status` | `active` |
### 2.4 Organization ID: 44 (Profibot Kft.)
| Mező | Érték |
|------|-------|
| `id` | 44 |
| `name` | Profibot Kft. |
| `org_type` | `business` |
| **`owner_id`** | **86** ❗ (NEM User 28, hanem User 86 a tulajdonos!) |
| `legal_owner_id` | 93 (Person ID) |
| `status` | `pending_verification` |
### 2.5 User 28 Organization Tagsulatai
- **Org 1 (Test Company):** User 28 a `owner_id` (saját cége, `fleet_owner`)
- **Org 63 (Aszalós Motorszervíz):** Tag (`ADMIN`, `pending_verification`, `service_provider`)
- **Org 44 (Profibot Kft.):** **NEM tag, NEM tulajdonos**
### 2.6 Person ID 29 (User 28 Person rekordja)
User 28 `person_id` = 29. Az asset `owner_person_id` = 29. **Ez a helyes kapcsolat a User és az Asset között.**
---
## 3. 📋 REGISZTRÁCIÓS LOGIKA ELEMZÉSE
### 3.1 `register_lite()` (1. fázis)
Forrás: [`backend/app/services/auth_service.py:63`](backend/app/services/auth_service.py:63)
- Létrehoz egy `Person` rekordot
- Létrehoz egy `User` rekordot (a Person-hoz kapcsolva `person_id` segítségével)
- `scope_level = "individual"` (alapértelmezett)
- `is_active = False` (email verification szükséges)
- **NEM hoz létre Organization-t ebben a fázisban**
### 3.2 `complete_kyc()` (2. fázis — "KYC complete")
Forrás: [`backend/app/services/auth_service.py:178`](backend/app/services/auth_service.py:178)
- **AUTOMATIKUSAN létrehoz egy Organization rekordot** (`OrgType.individual`)
- Org naming template: `"{last_name} Flotta"` (pl. "Tester Flotta")
- Org name: `"{last_name} Garázsa"`
- Beállítja a `User.scope_id` = `new_org.id` (az új Organization ID-jára)
- Létrehoz egy `Branch` (fiók/garázs) rekordot "Home Base" néven
- Létrehoz egy `OrganizationMember` rekordot OWNER role-lal
- Létrehoz egy `Wallet` rekordot
- Aktiválja a usert (`is_active = True`)
**Összefoglalva:** Igen, a rendszer létrehoz egy automatikus "Privát Garázst" (Organization) a KYC fázisban. Ennek típusa `individual`. Nincs külön `is_personal` flag, csak az `org_type = 'individual'` jelzi.
---
## 4. 🐛 A 404 HIBA GYÖKERÉNEK AZONOSÍTÁSA
### 4.1 Elsődleges Bug: Person ID vs User ID összehasonlítás
A [`backend/app/api/v1/endpoints/assets.py:744`](backend/app/api/v1/endpoints/assets.py:744) sorban a `_check_asset_access()` függvény:
```python
Asset.owner_person_id == current_user.id, # ❌ BUG!
```
**Hiba:** Az asset `owner_person_id` mezőjét (`29`) a `current_user.id` (`28`) értékkel hasonlítja össze.
**Helyes:** `Asset.owner_person_id == current_user.person_id` (29 == 29 ✓)
Az asset-ben `owner_person_id = 29`, és a User 28-hoz tartozó `person_id = 29`. Ez egy valid tulajdonosi kapcsolat, de a kód rossz mezőt használ az összehasonlításra.
### 4.2 Ugyanez a bug TÖBB HELYEN is előfordul
| Sor | Hely | Hibás Kód | Javítás |
|-----|------|-----------|---------|
| [`assets.py:316`](backend/app/api/v1/endpoints/assets.py:316) | `get_asset()` | `Asset.owner_person_id == current_user.id` | `current_user.person_id` |
| [`assets.py:468`](backend/app/api/v1/endpoints/assets.py:468) | `update_vehicle()` | `Asset.owner_person_id == current_user.person_id` | ✅ **HELYES** |
| [`assets.py:548`](backend/app/api/v1/endpoints/assets.py:548) | `maintenance` GET | `Asset.owner_person_id == current_user.id` | `current_user.person_id` |
| [`assets.py:605`](backend/app/api/v1/endpoints/assets.py:605) | `maintenance` POST | `Asset.owner_person_id == current_user.id` | `current_user.person_id` |
| [`assets.py:744`](backend/app/api/v1/endpoints/assets.py:744) | `_check_asset_access()` | `Asset.owner_person_id == current_user.id` | `current_user.person_id` |
**FONTOS:** A 468. sor már helyes! Ott `current_user.person_id` van. Ez arra utal, hogy a többi helyen figyelmetlenségből maradt `current_user.id`.
### 4.3 Másodlagos Probléma: User 28 Soft-Deleted
User 28 (`tester_pro@profibot.hu`) **soft-deletelve** lett 2026-06-14-én (`deleted_at` mező kitöltve, `is_deleted = true`).
A [`backend/app/services/auth_service.py:313`](backend/app/services/auth_service.py:313) sorban:
```python
User.is_deleted == False
```
Ez azt jelenti, hogy User 28 **nem tud bejelentkezni** (az `authenticate()` függvény kiszűri a törölt usereket).
### 4.4 Harmadlagos Probléma: User 28 nincs az Org 44-ben
Az asset (`deb42aea`) `owner_org_id = 44` (Profibot Kft.), de User 28:
- Nem tagja az Org 44-nek
- Nem tulajdonosa az Org 44-nek (azt User 86 birtokolja)
- Csak az Org 1 (Test Company) tulajdonosa
Tehát még ha a Person ID bug javításra is kerül, a szervezeti ellenőrzés (`Asset.owner_org_id.in_(user_org_ids)`) akkor sem találna match-et, mert User 28 nincs az Org 44 tagjai között. **De ez nem is szükséges**, mert a személyes tulajdonjog (`owner_person_id = 29``User 28 person_id = 29`) önállóan is hozzáférést biztosít.
---
## 5. 📊 ÖSSZEFOGLALÓ JELENTÉS
### Prioritási Sorrend
| # | Probléma | Hatás | Javítás Jellege |
|---|----------|-------|-----------------|
| **P0** | `User 28 soft-deleted` (`deleted_at: 2026-06-14`) | A user nem tud bejelentkezni, minden API hívás sikertelen | **Fiók visszaállítása** (restore OTP) vagy új regisztráció |
| **P0** | `owner_person_id == current_user.id` bug (4 helyen) | Még élő user esetén is 404-et kapna event létrehozáskor | `current_user.id``current_user.person_id` kijavítása |
| **P1** | Asset `data_status = 'draft'` — lehet, hogy még nincs teljesen aktiválva | Bizonyos műveletek korlátozva lehetnek | Admin felületen aktiválás vagy API javítás |
| **P2** | Nincs `is_personal` / `is_default` flag az organizations táblában | A "Privát Garázs" detektálása csak `org_type = 'individual'` alapján lehetséges | Opcionális séma kiegészítés |
### Ajánlott Következő Lépések
1. **User 28 restore** — Mivel a soft-delete 4 napja történt (30 napos ablakon belül), a `/restore/verify` végponton keresztül visszaállítható
2. **Comparison bug javítása** — Mind a 4 helyen (`assets.py:316, 548, 605, 744`) `current_user.id``current_user.person_id`
3. **Ellenőrzés** — Jelenleg `update_vehicle()` (468. sor) már helyes `current_user.person_id`-t használ; a többi endpoint inkonzisztens
**Megjegyzés:** A regisztrációs logika automatikusan létrehoz egy `individual` típusú Organization-t a KYC fázisban ("Privát Garázs"), ami a `scope_id`-n keresztül kapcsolódik a userhez. Ez a modell konzisztens, a hiba kizárólag a **comparison logic-ben** van.

View File

@@ -0,0 +1,161 @@
# P0 Reconnaissance Report — Subscription Tiers & Organization State
**Dátum:** 2026-06-18
**Szerző:** Fast Coder (Core Developer)
**Cél:** A meglévő előfizetési csomagok (subscription_tiers) és a hozzájuk tartozó JSON rules struktúrák teljes körű felmérése, valamint a fleet.organizations tábla aktuális hozzárendeléseinek auditálása.
---
## 1. AUDIT: Subscription Tiers (`system.subscription_tiers`)
A tábla jelenleg **10 aktív csomagot** tartalmaz. Az alábbi táblázat összefoglalja az összes csomagot:
| ID | Név (name) | Típus (rules->>type) | Display Name | Árazás |
|----|-----------|---------------------|-------------|--------|
| 13 | `private_free_v1` | `private` | Privát Ingyenes | 0 EUR |
| 14 | `private_pro_v1` | `private` | Privát Pro | 4.99 EUR/hó |
| 15 | `private_vip_v1` | `private` | Privát VIP | 9.99 EUR/hó |
| 16 | `corp_premium_v1` | `corporate` | Céges Prémium | 29.99 EUR/hó |
| 17 | `corp_premium_plus_v1` | `corporate` | Céges Prémium Plus | 59.99 EUR/hó |
| 18 | `corp_vip_v1` | `corporate` | Céges VIP | 149.99 EUR/hó |
| 19 | `private_test_v01` | `private` | Privát teszt | 0 HUF |
| 20 | `org_test_v01` | `corporate` | Céges teszt | 0 EUR |
| 21 | `corp_ree` | `corporate` | Corp Free | 0 EUR |
| 22 | `corp_free_v1` | `corporate` | Céges Ingyenes | 0 EUR |
### 1.1 Teljes JSON rules — "Free" csomag (ID 13: `private_free_v1`)
```json
{
"type": "private",
"pricing": {
"currency": "EUR",
"credit_price": 0,
"yearly_price": 0,
"monthly_price": 0
},
"affiliate": {
"referral_bonus_credits": 0,
"commission_rate_percent": 0
},
"lifecycle": {
"is_public": true
},
"allowances": {
"max_garages": 1,
"max_vehicles": 1,
"monthly_free_credits": 0
},
"display_name": "Privát Ingyenes",
"entitlements": []
}
```
### 1.2 Teljes JSON rules — "Legnagyobb céges" csomag (ID 18: `corp_vip_v1`)
```json
{
"type": "corporate",
"pricing": {
"currency": "EUR",
"credit_price": 15000,
"yearly_price": 1499.99,
"monthly_price": 149.99
},
"affiliate": {
"referral_bonus_credits": 500,
"commission_rate_percent": 25
},
"lifecycle": {
"is_public": true
},
"allowances": {
"max_garages": 50,
"max_vehicles": 200,
"monthly_free_credits": 2500
},
"display_name": "Céges VIP",
"entitlements": [
"SRV_DATA_EXPORT",
"SRV_AI_UPLOAD",
"SRV_ACCOUNTING_SYNC",
"SRV_API_ACCESS"
]
}
```
### 1.3 A JSON rules struktúra elemzése
A `rules` JSONB mező egységes szerkezetet követ minden csomagnál:
| Kulcs | Típus | Leírás |
|-------|-------|--------|
| `type` | `string` | `"private"` vagy `"corporate"` — a csomag típusa |
| `pricing` | `object` | Árazási adatok: `currency`, `credit_price`, `yearly_price`, `monthly_price` |
| `affiliate` | `object` | MLM/affiliate beállítások: `referral_bonus_credits`, `commission_rate_percent` |
| `lifecycle` | `object` | Életciklus: `is_public` (bool), opcionálisan `available_until` (date/null) |
| `allowances` | `object` | Korlátok: `max_garages`, `max_vehicles`, `monthly_free_credits` |
| `display_name` | `string` | Felhasználói felületen megjelenő név |
| `entitlements` | `string[]` | Jogosultságok listája (pl. `SRV_DATA_EXPORT`, `SRV_AI_UPLOAD`) |
**Felfedezett entitlement kódok:**
- `SRV_DATA_EXPORT` — Adatexport szolgáltatás
- `SRV_AI_UPLOAD` — AI feltöltés
- `SRV_ACCOUNTING_SYNC` — Számviteli szinkron
- `SRV_API_ACCESS` — API hozzáférés
---
## 2. AUDIT: Current Assignments (`fleet.organizations`)
A `fleet.organizations` táblában jelenleg **2 garázs** rendelkezik nem-NULL `subscription_tier_id` értékkel:
| Org ID | Név | Csomag ID | Csomag Neve | Display Name |
|--------|-----|-----------|-------------|-------------|
| 45 | Gyöngyössy garázs | 17 | `corp_premium_plus_v1` | Céges Prémium Plus |
| 49 | Test Garázsa | 16 | `corp_premium_v1` | Céges Prémium |
**Megjegyzés:** A többi garázs (beleértve az admin garázsait is) `subscription_tier_id = NULL` értékkel rendelkezik, azaz jelenleg nincs hozzájuk rendelve előfizetési csomag.
---
## 3. IDENTIFY: Admin Garages (User ID 2 — admin@profibot.hu)
### 3.1 Tulajdonolt garázsok (owner_id = 2)
| Org ID | Név | Típus (org_type) | Státusz | subscription_tier_id |
|--------|-----|------------------|---------|---------------------|
| 67 | Admin Garázsa | `individual` | active | **NULL** |
### 3.2 Tagsági viszonyok (organization_members)
A 2-es user (admin@profibot.hu) az alábbi szervezetekben tag:
| Org ID | Szervezet Neve | Szerepkör | Státusz |
|--------|---------------|-----------|---------|
| 1 | **Test Company** | `ADMIN` | active |
| 57 | Teszt Autószerviz Kft. | `OWNER` | active |
| 58 | Autónyíri Kft. | `OWNER` | active |
| 62 | Bokebo Kft. | `OWNER` | active |
| 67 | **Admin Garázsa** | `OWNER` | active |
### 3.3 Kiemelt garázsok azonosítói
A Tervező által kért két kiemelt garázs:
| Megnevezés | Organization ID | Jelenlegi Csomag |
|------------|---------------|-----------------|
| **Test Company** (Céges) | **1** | **NINCS** (NULL) |
| **Admin Garázsa** (Privát) | **67** | **NINCS** (NULL) |
---
## 4. Összefoglaló és Következtetések
1. **A subscription_tiers rendszer teljes és jól strukturált.** 10 csomag áll rendelkezésre, 4 privát és 6 céges kategóriában. A JSON rules séma egységes, jól bővíthető.
2. **Csak 2 garázs kapott eddig csomagot** (Gyöngyössy garázs → corp_premium_plus_v1, Test Garázsa → corp_premium_v1). A többi garázs, köztük az admin garázsai is, csomag nélküli állapotban vannak.
3. **Az admin két kiemelt garázsa**`Test Company` (org_id=1) és `Admin Garázsa` (org_id=67) — jelenleg nem rendelkezik előfizetési csomaggal. Ezeket a későbbiekben fel kell címkézni a megfelelő tier-rel.
4. **A JSON rules struktúra lehetővé teszi** a korlátok (max_vehicles, max_garages), árazás, affiliate jutalékok és entitlement-ök (feature flagek) finomhangolását csomagonként.

View File

@@ -0,0 +1,189 @@
# P0 PRE-FLIGHT CHECK: Unified Workspace Impact Analysis
**Dátum:** 2026-06-18
**Auditor:** Architect Mode
**Cél:** A 28-as User (tester_pro@profibot.hu) privát járműveinek organization_id auditja, mielőtt bevezetjük az új "Unified Workspace" szabályt (ahol a hozzáférés szigorúan organization_id + OrganizationMember alapú).
---
## 1. 🔍 SZERVEZETI STRUKTÚRA (Organization Audit)
### 1.1 User 28 → Person 29
| Mező | Érték |
|------|-------|
| User ID | **28** |
| Email | tester_pro@profibot.hu |
| Person ID | **29** |
| Név | Tester Profibot |
### 1.2 Privát Garázs (individual type)
A 28-as User saját "Privát Garázsa":
| Mező | Érték |
|------|-------|
| **Organization ID** | **21** |
| Név | Private_28 |
| Típus | `individual` |
| Tulajdonos (owner_id) | 29 (Person) |
| folder_slug | priv_28 |
### 1.3 A Person 29 által birtokolt összes szervezet
| Org ID | Név | Típus | Van tagja? |
|--------|-----|-------|-----------|
| 15 | Profibot Test Fleet | `fleet_owner` | ❌ NINCS |
| **21** | **Private_28** | **`individual`** | **❌ NINCS** |
| 26 | Test Kft. Alpha | `fleet_owner` | ❌ NINCS |
| 27 | Test Kft. Beta | `fleet_owner` | ❌ NINCS |
| 38 | Admin Széfe | `individual` | ❌ NINCS |
### 1.4 Ahol Person 29 TAG (OrganizationMember)
| Org ID | Név | Típus | Szerep |
|--------|-----|-------|--------|
| 63 | Aszalós Motorszervíz | `service_provider` | ADMIN |
**⚠️ KRITIKUS:** Person 29 NEM tagja a saját privát garázsának (org 21)! A `fleet.organization_members` táblában egyetlen rekord sincs a `Private_28`-hoz.
---
## 2. 🚗 JÁRMŰVEK ÁLLAPOTA (Assets Audit)
### 2.1 Person 29 tulajdonában lévő összes jármű
| # | ID (UUID) | Rendszám | Márka | Modell | current_org_id | owner_org_id | Státusz |
|---|-----------|----------|-------|--------|---------------|-------------|---------|
| 1 | deb42aea... | QWE123 | APRILIA | af1 | **44** | 44 | active/draft |
| 2 | da49269e... | TTRFGHZT | BAYLINER | 1750 CAPRY BOWRIDER | **44** | 44 | active/draft |
| 3 | 72b0a0cf... | UOK795 | Honda | CB1000R | **NULL** ⚠️ | 34 | active/verified |
| 4 | 0b97a975... | PKT215 | Mazda | 2 | **NULL** ⚠️ | 34 | active/draft |
| 5 | 09700990... | AIML519 | Skoda | Citigo e | **NULL** ⚠️ | 34 | active/enriched |
| 6 | 104d6753... | ABC-123 | Toyota | Corolla | **34** | 34 | active/verified |
### 2.2 Érintett szervezetek részletei
| Org ID | Név | Típus | Tulajdonos |
|--------|-----|-------|-----------|
| 21 | Private_28 | `individual` | Person 29 ✅ |
| 34 | Swagger-Test Kft. | `business` | Nincs tulajdonos (owner_id = NULL) |
| 44 | Profibot Kft. | `business` | User 86 |
---
## 3. 📊 HATÁSELEMZÉS (Impact Analysis)
### 3.1 Unified Workspace forgatókönyv
Ha bevezetjük a szabályt: **"Egy User csak olyan járművet érhet el, ahol a `current_organization_id` egyezik egy olyan Organization-nel, aminek a User tagja (OrganizationMember)"**:
#### 3.1.1 NULL current_organization_id-val rendelkező járművek
**3 jármű** (Honda CB1000R, Mazda 2, Skoda Citigo e) **jelenleg NULL** `current_organization_id`-val rendelkezik. Ezek:
- Nincsenek egyetlen szervezethez sem rendelve jelenleg
- Csak a `owner_person_id = 29` alapján lennének elérhetők
- **Az új szabály szerint KI lennének ZÁRVA** (orphaned), mert nincs organization contextusuk
#### 3.1.2 Más szervezethez rendelt járművek
**3 jármű** (Toyota Corolla → org 34, Aprilia + Bayliner → org 44) olyan szervezetekhez van rendelve, amelyeknek Person 29 NEM tagja:
- **Toyota Corolla** (`current_org = 34` = Swagger-Test Kft.) → **KI VAN ZÁRVA** (Person 29 nem tag)
- **APRILIA** (`current_org = 44` = Profibot Kft.) → **KI VAN ZÁRVA** (Person 29 nem tag)
- **BAYLINER** (`current_org = 44` = Profibot Kft.) → **KI VAN ZÁRVA** (Person 29 nem tag)
### 3.2 Összegzés
| Kategória | Darab | Járművek | Sorsa új szabály alatt |
|-----------|-------|----------|----------------------|
| NULL current_org_id | **3** | Honda, Mazda, Skoda | ❌ ORPHANED |
| Idegen org (nincs tagság) | **3** | Toyota (org 34), Aprilia+Bayliner (org 44) | ❌ ORPHANED |
| Saját privát garázsban (org 21) | **0** | — | ✅ OK |
| **ÖSSZESEN** | **6/6** | **MIND** | **❌ 100%-OS ORPHANED** |
---
## 4. 💾 ELŐKÉSZÍTETT SQL JAVÍTÁS (NE FUTTASD KI - CSAK TERVEZÉS)
### 4.1 Első lépés: Person 29 felvétele a Private_28 (org 21) tagjai közé
```sql
INSERT INTO fleet.organization_members (organization_id, user_id, person_id, role, is_permanent, is_verified, status)
VALUES (21, 28, 29, 'OWNER', true, true, 'active');
```
**VAGY ha a user_id nem elvárás (person_id alapú):**
```sql
INSERT INTO fleet.organization_members (organization_id, person_id, role, is_permanent, is_verified, status)
VALUES (21, 29, 'OWNER', true, true, 'active');
```
### 4.2 Második lépés: NULL current_organization_id javítása
```sql
UPDATE vehicle.assets
SET current_organization_id = 21
WHERE owner_person_id = 29 AND current_organization_id IS NULL;
```
Ez a **Honda CB1000R** (UOK795), **Mazda 2** (PKT215) és **Skoda Citigo e** (AIML519) járműveket beköti a Privát Garázsba.
### 4.3 Harmadik lépés: Üzleti döntés szükséges
A következő járművekhez **üzleti döntés** kell:
1. **Toyota Corolla** (ABC-123) - `current_org = 34, owner_org = 34`
- **Opció A:** Áttenni a Private_28-ba (org 21)
- **Opció B:** Felvenni Person 29-et a Swagger-Test Kft. (org 34) tagjai közé
- **Opció C:** Megtartani a jelenlegi állapotot és kivételt képezni az új szabály alól
2. **APRILIA af1** (QWE123) + **BAYLINER** (TTRFGHZT) - `current_org = 44, owner_org = 44`
- **Opció A:** Áttenni a Private_28-ba (org 21)
- **Opció B:** Felvenni Person 29-et a Profibot Kft. (org 44) tagjai közé (de User 86 a tulajdonos!)
- **Opció C:** Megtartani a jelenlegi állapotot
### 4.4 Teljes körű SQL javítás (ha az összes járművet a privát garázsba tennénk)
```sql
-- 1. Person 29 taggá tétele a Private_28-ban
INSERT INTO fleet.organization_members (organization_id, user_id, person_id, role, is_permanent, is_verified, status)
VALUES (21, 28, 29, 'OWNER', true, true, 'active');
-- 2. Összes jármű áthelyezése a Private_28-ba
UPDATE vehicle.assets
SET current_organization_id = 21
WHERE owner_person_id = 29;
```
---
## 5. ⚠️ KIEGÉSZÍTŐ MEGJEGYZÉSEK
### 5.1 User 28 soft-deleted állapota
A korábbi audit ([`docs/db_schema_ownership_audit_2026-06-18.md`](docs/db_schema_ownership_audit_2026-06-18.md)) feltárta, hogy User 28 **soft-deletelve** van (`is_deleted = true`, `deleted_at = 2026-06-14`). Ez azt jelenti:
- Jelenleg NEM tud bejelentkezni
- Még az adatjavítás után sem fér hozzá a járművekhez, amíg a fiókja nincs visszaállítva
### 5.2 Tervezési ajánlás
Az új "Unified Workspace" szabály bevezetése ELŐTT kötelező:
1. **Adatjavítás:** A NULL `current_organization_id`-val rendelkező járművek bekötése
2. **Tagság rögzítése:** Minden `individual` típusú org tulajdonosának automatikus OWNER taggá tétele
3. **Üzleti járművek felülvizsgálata:** Döntés a org 34-be és 44-be sorolt járművekről
4. **User 28 restore:** A soft-delete feloldása a KYC/restore folyamaton keresztül
5. **Átmeneti időszak:** Az `owner_person_id` alapú hozzáférés megtartása fallback-ként, amíg a fenti pontok nem teljesülnek
---
## 6. 🔮 ARCHITECT AJÁNLÁS
**Javaslat:** NE vezessük be a "pure Unified Workspace"-t (kizárólag org + membership alapú hozzáférés), amíg:
1. Az összes `individual` org-nak nincs automatikusan létrehozott OWNER OrganizationMember rekordja
2. Az összes meglévő jármű `current_organization_id` mezője ki van töltve
3. A soft-deletelt userek vissza vannak állítva vagy tisztázva van a státuszuk
**Ajánlott átmeneti megoldás:** Tartsd meg az `owner_person_id == user.person_id` ellenőrzést fallback-ként az org-based check mellett, amíg a fenti adatjavítások meg nem történnek.

View File

@@ -0,0 +1,275 @@
# 🔐 Jogosultságkezelés Audit Jelentés (2026-06-18)
## Teljes Rendszerkép a Jogosultsági Szintekről
---
## 1. Adatbázis Réteg (Database Schema)
### 1.1 `identity.users` - Felhasználói Jogosultságok
| Mező | Típus | Leírás |
|------|-------|--------|
| `role` | `identity.userrole` enum | Rendszerszintű szerepkör |
| `scope_level` | `VARCHAR(30)` | Hatókör szint (pl. "individual") |
| `scope_id` | `VARCHAR(50)` | Hatókör azonosító (pl. org ID vagy user ID) |
| `custom_permissions` | `JSON` | Egyedi jogosultságok (`{"capabilities": [...]}`) |
**`userrole` enum értékei** (Python `UserRole` osztály, `backend/app/models/identity/identity.py:24`):
```
superadmin, admin, region_admin, country_admin, moderator,
sales_agent, user, service_owner, fleet_manager, driver
```
> ⚠️ **Probléma**: Az adatbázis enum duplikált értékeket tartalmaz (pl. "admin" és "ADMIN" is létezik, "user" kétszer szerepel). Ez az enum korábbi migrációk során keletkezett.
### 1.2 `fleet.org_roles` - Szervezeti Szerepkör Definíciók
**🔴 KRITIKUS: A tábla ÜRES!**
A modell (`backend/app/models/marketplace/organization.py:34`) definiál egy dinamikus szerepkör rendszert (`OrgRole` modell), de **seed-elés nem történt meg**. A `OrgUserRole` enum (`backend/app/models/marketplace/organization.py:27`) az alábbi értékeket tartja számon:
```
OWNER, ADMIN, MANAGER, MEMBER, AGENT
```
### 1.3 `fleet.organization_members` - Tagságok és Jogosultságok
| Mező | Típus | Leírás |
|------|-------|--------|
| `role` | `VARCHAR(50)` | Szerepkör a szervezetben (OWNER/ADMIN/MANAGER/MEMBER/AGENT) |
| `permissions` | `JSON` | Egyedi JSON jogosultságok |
| `is_permanent` | `BOOLEAN` | Állandó tagság |
| `is_verified` | `BOOLEAN` | Megerősített tagság |
| `status` | `VARCHAR(20)` | Státusz (active/inactive) |
### 1.4 `system.system_parameters` - Hierarchikus Paraméterezés
| Mező | Típus | Leírás |
|------|-------|--------|
| `key` | `VARCHAR` | Paraméter kulcs |
| `value` | `JSONB` | Paraméter érték |
| `scope_level` | `parameter_scope` enum | Hatókör: GLOBAL, COUNTRY, REGION, USER, ORGANIZATION |
| `scope_id` | `VARCHAR` | Hatókör azonosító |
**`parameter_scope` enum értékei** (`backend/app/models/system/system.py:12`):
```
GLOBAL, COUNTRY, REGION, ORGANIZATION, USER
```
> ⚠️ **Probléma**: Minden meglévő paraméter `global` scope_level-lel rendelkezik. A hierarchikus scope (country, region, organization, user) **nincs használatban** gyakorlatban.
### 1.5 `system.pending_actions` - Dual Control (Négy Szem Elv)
| Mező | Típus | Leírás |
|------|-------|--------|
| `requester_id` | `INTEGER` | Kérelem indítója |
| `approver_id` | `INTEGER` | Jóváhagyó (nullable) |
| `status` | `action_status` enum | pending/approved/rejected |
| `action_type` | `VARCHAR` | CHANGE_ROLE, SET_VIP, WALLET_ADJUST, SOFT_DELETE_USER, ORGANIZATION_TRANSFER |
| `payload` | `JSONB` | Művelet adatok |
### 1.6 `system.subscription_tiers` - Előfizetési Csomagok
| Mező | Típus | Leírás |
|------|-------|--------|
| `name` | `VARCHAR` | Csomag neve (FREE, PREMIUM, VIP, stb.) |
| `rules` | `JSONB` | Szabályok (pl. `{"max_vehicles": 5}`) |
---
## 2. Backend Kód Réteg
### 2.1 Rang Rendszer - `DEFAULT_RANK_MAP`
Definiálva: `backend/app/core/security.py:56`
| Rang | Érték | Van UserRole enum-ban? |
|------|-------|----------------------|
| SUPERADMIN | 100 | ✅ Igen |
| ADMIN | 90 | ✅ Igen |
| REGION_ADMIN | 85 | ✅ Igen |
| COUNTRY_ADMIN | 80 | ✅ Igen |
| MODERATOR | 75 | ✅ Igen |
| AUDITOR | 70 | ❌ Nincs |
| ORGANIZATION_OWNER | 65 | ❌ Nincs |
| ORGANIZATION_MANAGER | 60 | ❌ Nincs |
| ORGANIZATION_MEMBER | 50 | ❌ Nincs |
| SERVICE_PROVIDER | 40 | ❌ Nincs |
| SALES_AGENT | 30 | ✅ Igen |
| FLEET_MANAGER | 25 | ✅ Igen |
| PREMIUM_USER | 20 | ❌ Nincs |
| USER | 10 | ✅ Igen |
| DRIVER | 5 | ✅ Igen |
| GUEST | 0 | ❌ Nincs |
> 🔴 **KRITIKUS**: 16 rang van definiálva, de a `UserRole` enum csak 10 értéket tartalmaz. A hiányzók (AUDITOR, ORGANIZATION_OWNER/MANAGER/MEMBER, SERVICE_PROVIDER, PREMIUM_USER, GUEST) sosem kerülnek kiosztásra!
### 2.2 RBAC Osztály - 3 Szintű Ellenőrzés
Forrás: `backend/app/core/rbac.py`
```
1. Superadmin check → mindent átenged
2. Rang ellenőrzés → DEFAULT_RANK_MAP alapján
3. Custom permissions → capabilities lista ellenőrzése
```
### 2.3 API Deps - `get_current_admin`
Forrás: `backend/app/api/deps.py:158`
Engedélyezett admin szerepkörök:
```python
allowed_roles = {superadmin, admin, region_admin, country_admin, moderator}
```
### 2.4 Scoped RBAC - `check_resource_access`
Forrás: `backend/app/api/deps.py:106`
```
- Superadmin → mindenhez hozzáfér
- Saját ID vagy scope_id egyezés → hozzáfér
- Egyéb → 403 Forbidden
```
### 2.5 Dual Control - `SecurityService`
Forrás: `backend/app/services/security_service.py`
| Típus | Leírás |
|-------|--------|
| `CHANGE_ROLE` | Szerepkör módosítás |
| `SET_VIP` | VIP státusz |
| `WALLET_ADJUST` | Pénztárca módosítás |
| `SOFT_DELETE_USER` | Felhasználó törlés |
| `ORGANIZATION_TRANSFER` | Szervezet átadás |
### 2.6 JWT Token Felépítése
Forrás: `backend/app/api/v1/endpoints/auth.py:108`
```json
{
"sub": "user_id",
"role": "superadmin",
"rank": 100,
"scope_level": "individual",
"scope_id": "user_id_vagy_org_id"
}
```
---
## 3. Frontend Réteg
### 3.1 Frontend Auth Store
Forrás: `frontend/src/stores/authStore.ts:4`
```typescript
export type UserRole = 'guest' | 'user' | 'manager' | 'admin' | 'superadmin'
```
> ⚠️ **Probléma**: A frontend `UserRole` típus **NEM egyezik** a backend `UserRole` enum-jával! Hiányzik: `region_admin`, `country_admin`, `moderator`, `sales_agent`, `service_owner`, `fleet_manager`, `driver`.
### 3.2 Router Admin Guard
Forrás: `frontend/src/router/index.ts:133`
```typescript
const adminRoles = ['superadmin', 'admin', 'region_admin', 'country_admin', 'moderator']
```
Ez a lista egyezik a backend `get_current_admin` függvényével.
---
## 4. Problémák és Hiányosságok
### 🔴 KRITIKUS Problémák
| # | Probléma | Hely | Hatás |
|---|----------|------|-------|
| P1 | `fleet.org_roles` tábla ÜRES | OrgRole modell | Dinamikus szerepkör rendszer nem működik |
| P2 | Rank map inkonzisztens a UserRole enum-mal | DEFAULT_RANK_MAP vs UserRole | 6 rang sosem kerül kiosztásra |
| P3 | Enum duplikáció (kis/nagybetű) | userrole és orgtype adatbázis enumok | Migrációs hiba, karbantartási nehézség |
| P4 | Frontend/backend UserRole eltérés | authStore.ts | Frontend hibás role-okat kezel |
| P5 | parameter_scope enum 3 sémában | public, system | Inkonzisztens definíciók |
### 🟡 FIGYELMEZTETÉS
| # | Probléma | Hely | Hatás |
|---|----------|------|-------|
| W1 | Csak `global` scope használatban | system_parameters | Hierarchikus paraméterezés nem kihasznált |
| W2 | Minden user `individual` scope_level | users tábla | Többszintű scope nincs implementálva |
| W3 | Nincs explicit "deny" mechanizmus | RBAC rendszer | Csak elégtelen rangot jelez, explicit tiltás nincs |
| W4 | custom_permissions nincs validálva | User modell | Bármilyen JSON elfogadott |
---
## 5. Összefüggés Diagram
```mermaid
graph TB
subgraph Frontend
FS[authStore.ts<br/>UserRole: guest/user/manager/admin/superadmin]
RG[Router Guard<br/>adminRoles: superadmin, admin,<br/>region_admin, country_admin, moderator]
end
subgraph API_Layer
JWT[JWT Token payload<br/>sub + role + rank + scope_level + scope_id]
DC[Dual Control SecurityService<br/>5 művelettípus]
end
subgraph Backend
UR[UserRole enum<br/>10 érték]
RM[DEFAULT_RANK_MAP<br/>16 rang - csak 10 használható]
RBAC[RBAC osztály<br/>3 szint: superadmin + rank + capabilities]
GR[get_current_admin<br/>5 engedélyezett szerepkör]
end
subgraph Database
U[identity.users<br/>role + scope_level + scope_id + custom_permissions]
OM[fleet.organization_members<br/>role + permissions JSON]
OR[fleet.org_roles<br/>🔴 ÜRES! Nincs seed data]
SP[system.system_parameters<br/>scope_level + scope_id - csak global használva]
PA[system.pending_actions<br/>Dual Control tároló]
end
FS -- eltérő role halmaz --> UR
JWT -- kiolvassa --> U
RBAC -- ellenőrzi --> RM
GR -- engedélyezi --> UR
DC -- naplóz --> PA
OR -- üres, nem használható --> OM
```
---
## 6. Azonosított Problémák Részletesen
### P1: `fleet.org_roles` tábla üres
- A dinamikus szerepkör rendszer teljesen kiépített (OrgRole modell, OrgUserRole enum)
- De a `fleet.org_roles` táblában egyetlen rekord sincs
- Következmény: a `organization_members.role` mező validálatlan string-ként működik
### P2: DEFAULT_RANK_MAP inkonzisztencia
- A `DEFAULT_RANK_MAP` tartalmaz olyan rangokat (AUDITOR, ORGANIZATION_OWNER, PREMIUM_USER, GUEST), amelyek nem szerepelnek a `UserRole` enum-ban
- Ezek a rangok soha nem kerülnek kiosztásra
- Megoldás: vagy bővíteni a `UserRole` enumot, vagy törölni a felesleges rangokat
### P3: Enum duplikáció
- A `userrole` enum minden értéke kétszer szerepel (kis és NAGY betűs változat)
- Az `orgtype` enum értékei szintén duplikáltak (business/BUSINESS, stb.)
- Ez a korábbi migrációk során keletkezett
### P4: Frontend-Backend eltérés
- A frontend auth store 5 role-t definiál: guest, user, manager, admin, superadmin
- A backend 10 role-t: superadmin, admin, region_admin, country_admin, moderator, sales_agent, user, service_owner, fleet_manager, driver
- A `manager` frontend role nem létezik a backendben, a `region_admin` és `country_admin` és `moderator` hiányzik a frontendből
### P5: Hierarchikus scope nem kihasznált
- A `ParameterScope` enum (GLOBAL, COUNTRY, REGION, ORGANIZATION, USER) teljesen kiépített
- De minden `system_parameter` `global` scope_level-lel rendelkezik
- A hierarchikus paraméterezés (ország → régió → szervezet → felhasználó) nincs implementálva