jogosultsági szintek RBAC beállítva tesztelve
This commit is contained in:
254
.roo/history.md
254
.roo/history.md
@@ -238,3 +238,257 @@ Implementálni az Option C (Hybrid) architektúrát: `quick_add_provider()` most
|
||||
- 6/7 rendelkezik ServiceProfile kapcsolattal (MOL-nak 0 profilja volt)
|
||||
- 1 AssetCost linkelve (Aszalós Motorszervíz)
|
||||
- Safe list garázsok (13) érintetlenek a `fleet.organizations` táblában
|
||||
|
||||
## 2026-06-25 - P0 DATABASE PURGE & E2E VERIFICATION
|
||||
|
||||
### 🎯 Cél
|
||||
Teljes adatbázis tisztítás: fake organization-ök eltávolítása a `fleet.organizations` táblából, az összes hivatkozó FK rekord előzetes felszabadításával. E2E verifikáció: quick_add_provider flow tesztelése.
|
||||
|
||||
### 🔧 Eredmények
|
||||
|
||||
**deep_purge_fake_orgs.py** — Sikeres purge:
|
||||
- **Step A (Financial Relink):** 6 ServiceProfile organization_id → NULL (már volt sp_id), 1 residual vendor_org cleaned
|
||||
- **Step B (Garbage Destroyed):** 12 org_subscriptions, 26 asset_assignments, 24+19 vehicle.assets org refs NULLed, 5 asset_costs reassigned to org_id=15, 15 branches, 9 org_members
|
||||
- **Step C (Final Purge):** 18 fake organizations DELETED (IDs: 1,26,27,32,33,34,37,38,44,46,51,57,58,62,63,2406,4859,7676)
|
||||
- **Verification:** ✅ PASS — No fake organizations remain
|
||||
|
||||
**test_quick_add_flow.py** — E2E teszt:
|
||||
- Assert 1 ✅: ServiceProvider 'OMV Teszt Kút' létezik `marketplace.service_providers`-ben
|
||||
- Assert 2 ✅: Nincs Organization `fleet.organizations`-ben
|
||||
- Assert 3 ✅: AssetCost helyesen linkelve (service_provider_id=8, vendor_organization_id=NULL)
|
||||
- **Eredmény: 3/3 PASS**
|
||||
|
||||
### 📁 Létrehozott fájlok
|
||||
- `backend/scripts/deep_purge_fake_orgs.py` — Deep purge & relink script
|
||||
- `backend/scripts/test_quick_add_flow.py` — E2E verification script
|
||||
|
||||
## 2026-06-25 - P0 UI POLISH: Garages CRM & Display Name Normalization
|
||||
|
||||
### 🎯 Cél
|
||||
Private garázsok display_name normalizálása és a Garages CRM admin UI frissítése a clean display name-ek megjelenítésére.
|
||||
|
||||
### 🔧 Módosított fájlok
|
||||
- `backend/scripts/safe_rename_garages.py` — LÉTREHOZVA: Safe rename script (17 private garage updated)
|
||||
- `frontend_admin/pages/garages/index.vue` — MÓDOSÍTVA: display_name prioritás a cégnév oszlopban + "Részletek" gomb
|
||||
- `frontend_admin/i18n/locales/hu.json` — MÓDOSÍTVA: "details" i18n kulcs hozzáadva
|
||||
- `frontend_admin/i18n/locales/en.json` — MÓDOSÍTVA: "details" i18n kulcs hozzáadva
|
||||
|
||||
### ✅ Eredmények
|
||||
1. **Safe Rename Script:** 17 private garage `name` és `display_name` mezője frissítve. `name` tartalmazza az ID-t az egyediségért (`#{user_id}`), `display_name` tiszta, emberi olvasásra szánt formátumban (`{last_name} {first_name} - Privát Garázs`).
|
||||
2. **Frontend UI:** A "Cégnév" oszlop most `display_name`-t használ elsődlegesen, `name`-et csak fallback-ként. Új "Részletek" gomb hozzáadva az akciókhoz.
|
||||
3. **Corporate orgs érintetlenek:** Csak `individual` típusú szervezetek lettek módosítva.
|
||||
|
||||
---
|
||||
|
||||
## 2026-06-25 - P0 UI MICRO-FIX: Page Title & Expiration Date Logic
|
||||
|
||||
### 🎯 Cél
|
||||
Két UX hiba javítása az admin felületen: (1) böngésző fül címének beállítása, (2) lejárati dátum megjelenítése "Határozatlan" szöveggel NULL esetén.
|
||||
|
||||
### 🔧 Módosított fájlok
|
||||
- [`frontend_admin/app.vue`](frontend_admin/app.vue) — `useHead` hozzáadva `titleTemplate`-mel: "Service Finder Admin" alapértelmezett, oldalnév esetén "Oldalnév | Service Finder Admin" formátum.
|
||||
- [`frontend_admin/pages/garages/index.vue`](frontend_admin/pages/garages/index.vue:183) — Lejárati dátum cella: NULL esetén a "—" helyett `$t('garages.indefinite')` i18n kulcs jelenik meg.
|
||||
- [`frontend_admin/i18n/locales/hu.json`](frontend_admin/i18n/locales/hu.json:141) — `garages.indefinite`: "Határozatlan" kulcs hozzáadva.
|
||||
- [`frontend_admin/i18n/locales/en.json`](frontend_admin/i18n/locales/en.json:141) — `garages.indefinite`: "Indefinite" kulcs hozzáadva.
|
||||
|
||||
### ✅ Verifikáció
|
||||
- Nuxt build sikeres (`sf_admin_frontend` konténerben).
|
||||
- Böngésző fül: alapértelmezetten "Service Finder Admin", oldalnézetben "Page Name | Service Finder Admin".
|
||||
- Garázs tábla: subscription_expires_at = NULL esetén "Határozatlan" (HU) / "Indefinite" (EN) szöveg jelenik meg.
|
||||
|
||||
## 2026-06-25 - Garage Details (General Tab) - P0 Implementation
|
||||
|
||||
### 🎯 Cél
|
||||
Garázs részletes adatlap implementálása General Tab-bal: backend API végpont + frontend oldal + i18n fordítások.
|
||||
|
||||
### 🔧 Backend API
|
||||
- [`backend/app/api/v1/endpoints/admin_organizations.py`](backend/app/api/v1/endpoints/admin_organizations.py:301) — `GET /{org_id}/details` végpont:
|
||||
- Pydantic modellek: `ContactPersonInfo`, `SubscriptionSummary`, `GarageDetailsResponse`
|
||||
- Lekérdezi: Organization (selectinload subscription_tier), OrganizationSubscription (active, limit 1, selectinload tier), ContactPerson (is_primary == True, selectinload person), member_count via func.count
|
||||
- Fallback: ha nincs OrganizationSubscription, az org.subscription_tier adatait használja
|
||||
|
||||
### 🖼️ Frontend Oldal
|
||||
- [`frontend_admin/pages/garages/[id]/index.vue`](frontend_admin/pages/garages/[id]/index.vue) — Teljes Nuxt 3 oldal:
|
||||
- **Header:** Vissza gomb, Avatar (kezdőbetűk), Garázs név + státusz badge
|
||||
- **Tab navigáció:** Általános, Dolgozók, Flotta, Analitika (a 3 utolsó "Coming soon")
|
||||
- **General Tab (3 Info Card):**
|
||||
1. **Cég adatok:** cégnév, megjelenítési név, szervezet típusa, adószám, cégjegyzékszám, létrehozva, cím
|
||||
2. **Előfizetés státusza:** csomag, szint, lejárat (Határozatlan ha null), járműkorlát, járművek száma
|
||||
3. **Elérhetőség:** kapcsolattartó neve, szerepkör, osztály, telefonszám
|
||||
- Helper függvények: `garageDisplayName()`, `getInitials()`, `getInitialsColor()`, `statusBadgeClass()`, `statusDotClass()`, `statusLabel()`, `tierBadgeClass()`, `orgTypeLabel()`, `formatDate()`, `formattedAddress` computed
|
||||
|
||||
### 🌐 i18n Fordítások
|
||||
- [`frontend_admin/i18n/locales/hu.json`](frontend_admin/i18n/locales/hu.json:142) — `garages.details` objektum 20+ kulccsal
|
||||
- [`frontend_admin/i18n/locales/en.json`](frontend_admin/i18n/locales/en.json:142) — Angol megfelelők
|
||||
- [`frontend_admin/i18n/locales/hu.json`](frontend_admin/i18n/locales/hu.json:140) — `garages.view_details` kulcs (a régi `details` string átnevezve)
|
||||
|
||||
### 🔗 Navigáció
|
||||
- [`frontend_admin/pages/garages/index.vue`](frontend_admin/pages/garages/index.vue:570) — `openDetails()`: "Coming soon" helyett `navigateTo()` a részletes oldalra
|
||||
|
||||
### ✅ Verifikáció
|
||||
- Backend API `GET /api/v1/admin/organizations/51/details` → HTTP 200, teljes válasz (org adatok + subscription + member_count)
|
||||
- `sf_api` konténer újraindítva a kód élesítéséhez
|
||||
- `sf_admin_frontend` volume mount miatt automatikusan érzékeli a változásokat
|
||||
|
||||
## 2026-06-25 - P0 RECOVERY: Surgical Vehicle Relinking Verification
|
||||
|
||||
### 🎯 Cél
|
||||
Adatbázis restore után ellenőrizni, hogy a `vehicle.assets` táblában lévő járművek `current_organization_id` mezője nem NULL (nem árva rekordok). Ha szükséges, relinkelni a járműveket a `fleet.organization_members` tábla user-to-organization kapcsolatai alapján.
|
||||
|
||||
### 🔧 Diagnosztikai Eredmények
|
||||
|
||||
**1. DIAGNOSE — Orphaned Vehicles Query:**
|
||||
- SQL: `SELECT COUNT(*) FROM vehicle.assets WHERE current_organization_id IS NULL AND status NOT IN ('deleted', 'archived') AND owner_person_id IS NOT NULL`
|
||||
- **Eredmény: 0 orphaned vehicle** — mind a 42 jármű rendelkezik érvényes `current_organization_id` értékkel
|
||||
|
||||
**2. Teljes adatbázis konzisztencia ellenőrzés:**
|
||||
- Összes jármű: **42 db**
|
||||
- `current_organization_id IS NULL`: **0 db**
|
||||
- `current_organization_id` + `owner_person_id` együtt NULL: **0 db** (csak archived rekordoknál, ahol nincs owner)
|
||||
- Minden `current_organization_id` hivatkozás érvényes `fleet.organizations` rekordra mutat
|
||||
|
||||
**3. Járművek eloszlása szervezetenként:**
|
||||
| Org ID | Szervezet Neve | Járművek |
|
||||
|--------|----------------|----------|
|
||||
| 1 | Profibot Tester - Privát Garázs (#28) | 18 (10 active + 8 draft) |
|
||||
| 21 | Admin Super - Privát Garázs (#29) | 6 active |
|
||||
| 43 | Accipe Tímea - Privát Garázs (#79) | 2 (1 active + 1 draft) |
|
||||
| 44 | Profibot Kft. | 4 archived |
|
||||
| 45 | Gyöngyössy Zsolt - Privát Garázs (#86) | 1 active |
|
||||
| 46 | Gyöngyössy Krisztina - Privát Garázs (#100) | 1 active |
|
||||
| 48 | User Test - Privát Garázs (#104) | 2 active |
|
||||
| 49 | Test Final - Privát Garázs (#105) | 1 active |
|
||||
| 50 | Profibot Tester - Privát Garázs (#106) | 1 active |
|
||||
| 66 | Admin Super - Privát Garázs (#1) | 1 active |
|
||||
| 67 | User Admin - Privát Garázs (#2) | 3 archived |
|
||||
|
||||
**4. Organization Members verifikáció:**
|
||||
- Minden olyan org, amelyhez aktív jármű tartozik, rendelkezik OWNER vagy ADMIN taggal a `fleet.organization_members` táblában
|
||||
- A user-to-person kapcsolatok (`identity.users.person_id`) konzisztensek az org tagságokkal
|
||||
|
||||
### ✅ Végkövetkeztetés
|
||||
- **Recovery script nem szükséges** — az adatbázis restore után a `current_organization_id` kapcsolatok sértetlenek maradtak
|
||||
- **0 jármű maradt árva** — minden aktív jármű egy valid organizationhöz van linkelve
|
||||
- **Adatbázis konzisztencia:** ✅ PASS — nincs szükség beavatkozásra
|
||||
|
||||
## 2026-06-25 - P0 Phase 1: DB-Driven RBAC Foundation (Backend Schema & Seed)
|
||||
|
||||
### 🎯 Cél
|
||||
RBAC Phase 1 (Foundation) implementálása: DB-driven role/permission rendszer kiépítése a `system` sémában, a hardcoded `SYSTEM_CAPABILITIES_MATRIX` és `UserRole` enum leváltásának első lépése.
|
||||
|
||||
### 🔧 Létrehozott fájlok
|
||||
- `backend/app/models/system/rbac.py` - 3 új SQLAlchemy modell: SystemRole, SystemPermission, SystemRolePermission
|
||||
- `backend/app/scripts/seed_rbac.py` - Seed script: 6 role, 28 permission, 168 role-permission mapping, 33 user migráció
|
||||
|
||||
### 🔧 Módosított fájlok
|
||||
- `backend/app/models/system/__init__.py` - RBAC modellek exportja
|
||||
- `backend/app/models/__init__.py` - RBAC modellek globális exportja
|
||||
- `backend/app/models/identity/identity.py` - `role_id` FK + `system_role` relationship hozzáadva a User modellhez
|
||||
|
||||
### ✅ Eredmények
|
||||
- **Sync Engine:** 4 fix (3 új tábla + 1 új oszlop) ✅
|
||||
- **Seed:** 6 role, 28 permission, 168 role-permission mapping, 33 user migrálva ✅
|
||||
- **Adatbázis séma:** system.roles, system.permissions, system.role_permissions létrehozva
|
||||
- **User modell:** role_id (FK→system.roles.id, nullable=True, ondelete=SET NULL) hozzáadva
|
||||
|
||||
## 2026-06-25 - RBAC Phase 2: DB-Driven Permission Check (Backend Service Layer)
|
||||
|
||||
### 🎯 Cél
|
||||
Implementálni a DB-driven RBAC permission check-et: `RBACService.get_role_permissions()` metódus, `RequirePermission(permission_code)` dependency factory, és egy verifikációs végpont.
|
||||
|
||||
### 🔧 Módosított fájlok
|
||||
- `backend/app/services/rbac_service.py` - `get_role_permissions()` metódus hozzáadva (lekérdezi a `system.role_permissions` + `system.permissions` táblákból a granted permission code-okat role_id alapján); `invalidate_role_cache()` placeholder hozzáadva
|
||||
- `backend/app/api/deps.py` - `RequirePermission(permission_code: str)` dependency factory hozzáadva (SUPERADMIN bypass rank=100, DB lekérdezés, 403 ha hiányzik a permission)
|
||||
- `backend/app/api/v1/endpoints/admin_permissions.py` - `GET /admin/rbac-test` verifikációs végpont hozzáadva `RequirePermission("fleet:view")` védelemmel; dead code cleanup
|
||||
|
||||
### ✅ Eredmények
|
||||
- **Import check:** ✅ Minden modul importálható hiba nélkül
|
||||
- **Sync Engine:** ✅ 1265 OK, 0 Fixed - rendszer tökéletes szinkronban
|
||||
- **HTTP teszt:** ✅ `GET /api/v1/admin/rbac-test` → 200 OK, permission check passed (user_id=2, role=ADMIN, role_id=2, permission=fleet:view)
|
||||
- **Adatbázis:** 28 permission, 168 role-permission mapping (6 role × 28 permission) létezik és konzisztens
|
||||
|
||||
## 2026-06-25 - RBAC Phase 5: Backend Cleanup (Zombie Code Removal)
|
||||
|
||||
### 🎯 Cél
|
||||
Az RBAC Phase 1-3 legacy kód teljes eltávolítása, miután az új DB-driven RBAC rendszer élesben fut a frontenden.
|
||||
|
||||
### 🔧 Végrehajtott módosítások
|
||||
|
||||
1. **`backend/app/api/deps.py`** - Törölve: `get_current_admin()`, `RequireRole()`, `RequireSystemCapability()` függvények és az import `SYSTEM_CAPABILITIES_MATRIX, role_has_capability` a capabilities modulból. (~114 sor)
|
||||
|
||||
2. **`backend/app/core/capabilities.py`** - Törölve: `SYSTEM_CAPABILITIES_MATRIX` dictionary (196 sor), `get_capabilities_for_role()`, `role_has_capability()` helper függvények. Megtartva: `Capability` osztály (string konstansok). (~220 sor)
|
||||
|
||||
3. **`backend/app/services/rbac_service.py`** - Törölve: `ADMIN_SCOPE_ACTIONS`, `MODERATOR_SCOPE_ACTIONS`, `SALES_REP_SCOPE_ACTIONS`, `SERVICE_MGR_SCOPE_ACTIONS` hardcoded set-ek, `ROLE_ACTIONS` mapping, és az import `SYSTEM_CAPABILITIES_MATRIX, role_has_capability`. A `check_admin_access()` metódus továbbra is működik, de a `get_permitted_actions()` már csak SUPERADMIN-ra ad vissza action-öket. (~47 sor)
|
||||
|
||||
4. **Import javítások:** `organizations.py` (RequireSystemCapability import eltávolítva), `users.py` (get_capabilities_for_role import és hívás eltávolítva), `admin_permissions.py` (scope action set importok eltávolítva). (~9 sor)
|
||||
|
||||
### ✅ Eredmények
|
||||
- **Import check:** ✅ Minden modul importálható hiba nélkül (`deps.py`, `capabilities.py`, `rbac_service.py`)
|
||||
- **Sync Engine:** ✅ 1265 OK, 0 Fixed - rendszer tökéletes szinkronban
|
||||
- **Zombie code removed:** ~390 sor legacy kód eltávolítva a projektből
|
||||
- **Dead-code verification:** 0 maradék import a törölt függvényekre
|
||||
|
||||
## 2026-06-25 - RBAC Phase 4: Dynamic Permission Matrix UI & API
|
||||
|
||||
### 🎯 Cél
|
||||
Dinamikus permission management UI építése a DB-driven RBAC rendszerhez. Backend API végpontok (GET/PUT) a SystemRole és SystemPermission entitásokhoz, frontend permission mátrix UI toggle kapcsolókkal, SUPERADMIN védelemmel.
|
||||
|
||||
### 🔧 Módosított fájlok
|
||||
- `backend/app/api/v1/endpoints/admin_permissions.py` — 3 új végpont: GET /admin/permissions/roles, GET /admin/permissions, PUT /admin/permissions/roles/{role_id}/permissions
|
||||
- `frontend_admin/pages/permissions/index.vue` — Teljes átírás: statikus tömbök eltávolítva, dinamikus API-alapú permission mátrix UI
|
||||
- `frontend_admin/i18n/locales/en.json` — Elavult statikus permission kulcsok eltávolítva
|
||||
- `frontend_admin/i18n/locales/hu.json` — Elavult statikus permission kulcsok eltávolítva
|
||||
|
||||
### ✅ Eredmények
|
||||
- **API smoke test:** ✅ Minden végpont működik (GET roles, GET permissions, PUT permissions, SUPERADMIN 403 protection)
|
||||
- **Sync Engine:** ✅ 1265 OK, 0 Fixed - rendszer tökéletes szinkronban
|
||||
- **Permissions hozzáadva:** `permissions:view` (id=29), `permissions:edit` (id=30) — SUPERADMIN és ADMIN szerepkörökhöz rendelve
|
||||
- **SUPERADMIN védelem:** rank>=100, is_system=True szerepkörök módosítása 403-mal tiltva
|
||||
|
||||
## 2026-06-25 — RBAC Permission Audit (Gitea #298)
|
||||
**Auditor:** Rendszer-Architect
|
||||
**Scope:** Adatbázis ↔ Backend Service ↔ API ↔ Frontend Admin UI szinkron vizsgálata
|
||||
|
||||
### Vizsgált fájlok:
|
||||
- `backend/app/services/rbac_service.py` — Dual RBAC rendszer feltárva (Scope-based AdminAction vs DB-driven SystemPermission)
|
||||
- `backend/app/models/system/rbac.py` — SystemRole, SystemPermission, SystemRolePermission modellek validálva
|
||||
- `backend/app/api/v1/endpoints/admin_permissions.py` — Matrix endpoint hibás (Scope-based), roles/permissions endpointok helyesek (DB-driven)
|
||||
- `backend/app/api/v1/endpoints/users.py` — `system_capabilities` mindig üres, legacy mátrix eltávolítva, DB lekérdezés nem implementálva
|
||||
- `backend/app/api/deps.py` — `RequirePermission()` helyesen működik DB-driven rendszerrel
|
||||
- `backend/app/core/capabilities.py` — Deprecated Capability class, eltérő formátum
|
||||
- `frontend_admin/pages/permissions/index.vue` — Valós API hívások, NINCS mock adat
|
||||
- `frontend_admin/stores/auth.ts` — UserProfile interface helyes
|
||||
- `frontend_admin/middleware/auth.ts` — Role-alapú auth check OK
|
||||
|
||||
### Feltárt hibák:
|
||||
1. 🔴 KRITIKUS: Dual RBAC rendszer — `get_permitted_actions()` csak SUPERADMIN-nak ad vissza adatot
|
||||
2. 🔴 KRITIKUS: `system_capabilities`/`org_capabilities` mindig üres a `/auth/me` response-ban
|
||||
3. 🟡 KÖZEPES: Deprecated Capability class eltérő formátumú konstansokkal
|
||||
|
||||
### Pozitívum:
|
||||
- Frontend admin UI-ban NINCS mock adat — minden végpont valós API-t hív
|
||||
- Adatbázis séma helyes: 6 role, 30 permission, teljes role-permission mapping
|
||||
- `RequirePermission()` függőség jól működik
|
||||
- Permission mátrix UI (2D táblázat) megfelelően épül fel
|
||||
|
||||
## 2026-06-25 - P0 Phase 6: DB-Driven RBAC & Phantom Permission Fix
|
||||
|
||||
### 🎯 Cél
|
||||
8 darab "szellem" (orphaned) permission kód beillesztése a `system.permissions` táblába, az RBAC service refaktorálása az `AdminAction` enum eltávolításával, és a `_build_user_response` függvény átalakítása, hogy a `system_capabilities` mezőt DB-driven lekérdezésből töltse.
|
||||
|
||||
### 🔧 Módosított fájlok
|
||||
- `backend/scripts/fix_phantom_permissions.py` (ÚJ) - 8 hiányzó permission beszúrása + role mapping
|
||||
- `backend/app/services/rbac_service.py` - `AdminAction` enum eltávolítva, `get_permitted_actions` async + DB-driven
|
||||
- `backend/app/api/v1/endpoints/admin_permissions.py` - `AdminAction` import eltávolítva, DB-driven action validáció
|
||||
- `backend/app/api/v1/endpoints/users.py` - `_build_user_response` async-re váltva, DB-driven permission lookup
|
||||
- `backend/app/api/v1/endpoints/auth.py` - `_build_user_response` hívás `await`-el + `db` paraméter átadva
|
||||
- `backend/app/core/capabilities.py` - `Capability` osztály eltávolítva (deprecated)
|
||||
- `backend/app/api/v1/endpoints/organizations.py` - `Capability` import eltávolítva
|
||||
|
||||
### ✅ Eredmények
|
||||
- 8 új permission beszúrva (id: 31-38): `dual-control:request/approve/view`, `services:manage`, `subscription:manage`, `user:manage`, `moderation:manage`, `gamification:manage`
|
||||
- 16 role-permission mapping létrehozva (8 permission × 2 role: SUPERADMIN + ADMIN)
|
||||
- `get_permitted_actions` most már minden role-ra DB-driven lekérdezést használ
|
||||
- `_build_user_response` async függvény, ami `rbac_service.get_role_permissions(db, role_id)`-t hív
|
||||
- `/auth/me` és `/users/me` endpoint-ok 38 db system_capabilities-t adnak vissza (mind True)
|
||||
- `Capability` osztály eltávolítva a kódbázisból
|
||||
|
||||
Reference in New Issue
Block a user