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.