Files
service-finder/.roo/history.md

495 lines
34 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
1 | # Service Finder Fejlesztési Történet
2 |
3 | ## 2026-06-21 - P0 Deep Audit: Database Consistency & Zombie API Hunt
4 |
5 | ### 🎯 Cél
6 | Teljes körű adatbázis konzisztencia ellenőrzés és zombie API végpontok felderítése a `vehicle`, `finance`, `fleet_finance` sémákban, mielőtt a frontend fejlesztés elkezdődik.
7 |
8 | ### 🔧 Eredmények
9 |
10 | **1. ADATBÁZIS TISZTASÁG:** ✅ PASS
11 | - API modul import: ✅ Sikeres (2 route: GET, POST)
12 | - Sync Engine: ✅ 1210 OK, 0 Fixed, 0 Extra
13 | - E2E test: ⚠️ Pre-existing conftest hiba (verification token timeout - nem kapcsolódó)
14 |
15 | ## 2026-06-23 - Cost Entry Wizard (CostEntryWizard.vue) - 4-lépéses Számla Űrlap
16 |
17 | ### 🎯 Cél
18 | 4-lépéses stepper wizard építése részletes számla/invoice költségek rögzítésére a CostsActionsCard-ból indíthatóan.
19 |
20 | ### 🔧 Módosított fájlok
21 |
22 | ## 2026-06-24 - P0 Fix & Enhance: Permissions Page Data Flow, Editing & i18n
23 |
24 | ### 🎯 Cél
25 | Permissions oldal adatáramlás javítása, szerkesztés/mentés funkció bevezetése, és @nuxtjs/i18n telepítése/konfigurálása.
26 |
27 | ### 🔧 Módosított fájlok
28 | - `frontend_admin/pages/permissions/index.vue` - Teljes átírás: client-side data fetch onMounted-ben, szerkeszthető toggle-ok (modifiedPermissions Map), PATCH mentés, toast notification, $t() hívások
29 | - `frontend_admin/nuxt.config.ts` - @nuxtjs/i18n modul hozzáadása, locales konfiguráció (hu/en)
30 | - `frontend_admin/i18n/locales/hu.json` - Magyar fordítási fájl (permissions oldal összes szövege)
31 | - `frontend_admin/i18n/locales/en.json` - Angol fordítási fájl
32 |
33 | ### ✅ Eredmények
34 | - Build: ✅ Sikeres (hu-DbjfOUfH.mjs, en-DnJ23n0t.mjs locale chunk-ok)
35 | - i18n modul: @nuxtjs/i18n v10.4.0 telepítve, no_prefix stratégiával
36 | - Szerkesztés: modified/original Map-ek, handleToggle, savePermissions (PATCH /admin/permissions/override/{org_id})
37 | - Adatmentés: success/error toast notification auto-clear-el
38 |
39 | ## 2026-06-24 - P0 Execution: Wire Packages UI to Real Database
40 |
41 | ### 🎯 Cél
42 | A frontend_admin Packages oldal (packages/index.vue) mock adatok helyett valós API adatbázisból töltse a SubscriptionTier csomagokat. "Új Csomag Létrehozása" gomb és modal hozzáadása.
43 |
44 | ### 🔧 Módosított fájlok
45 | - `backend/app/schemas/subscription.py` - `tier_level` és `feature_capabilities` mezők hozzáadva a SubscriptionTierResponse, SubscriptionTierCreate, SubscriptionTierUpdate modellekhez
46 | - `backend/app/api/v1/endpoints/admin_packages.py` - create/update végpontok frissítve az új mezők kezelésére
47 | - `frontend_admin/pages/packages/index.vue` - Teljes átírás: mock adatok eltávolítva, fetchPackages() API hívás, create/edit/delete modal-ok, loading/error/empty állapotok, i18n támogatás
48 | - `frontend_admin/locales/hu.json` - packages i18n kulcsok (magyar)
49 | - `frontend_admin/locales/en.json` - packages i18n kulcsok (angol)
50 |
51 | ### ✅ Eredmények
52 | - Backend API: GET /api/v1/admin/packages → 200 OK, 10 tier (tier_level, feature_capabilities mezőkkel)
53 | - Frontend: mock adatok eltávolítva, valós API hívás onMounted-ben, loading/error/empty állapotok
54 | - CRUD: Létrehozás (POST), Szerkesztés (PATCH), Törlés (DELETE soft-delete) teljes körűen implementálva
55 | - i18n: Minden UI szöveg magyar és angol nyelven elérhető
56 |
57 | ## 2026-06-24 - P0 CRITICAL FIX: Deep Merge JSONB (Multi-zone Pricing Data Loss)
58 |
59 | ### 🎯 Cél
60 | Javítani a `PATCH /api/v1/admin/packages/{tier_id}` végpontot, hogy a `rules` JSONB oszlop frissítésekor a meglévő nested kulcsok (pl. `pricing_zones.HU`, `pricing_zones.US`, `lifecycle.available_until`) ne vesszenek el, ha a frontend csak egy részhalmazt küld (pl. csak `pricing_zones.DEFAULT`).
61 |
62 | ### 🔧 Módosított fájlok
63 | - `backend/app/api/v1/endpoints/admin_packages.py``deep_merge_dict()` függvény hozzáadva, `update_package` endpoint átírva deep merge szemantikára
64 | - `tests/active/test_deep_merge_fix.py` — Verifikációs teszt (unit + API PATCH)
65 |
66 | ### ✅ Eredmények
67 | - **Unit test:** ✅ PASS — `deep_merge_dict()` helyesen működik: nested dict-ek rekurzív merge, None értékek megőrzése, üres override megőrzése
68 | - **API test:** ✅ PASS — `private_pro_v1` (id=14) csomagon: HU, US, DEFAULT zónák mind megmaradtak a PATCH után, DEFAULT ára frissült, lifecycle.available_until megőrződött
69 | - **Sync Engine:** ✅ 1220 OK, 0 Fixed — adatbázis séma konzisztens
70 | - **Root cause:** A frontend `packages/index.vue` `rulesPayload` függvénye csak `pricing_zones.DEFAULT`-ot állítja elő, a backend pedig wholesale replace-t végzett → multi-zone adatvesztés
## 2026-06-24 - P0 System Architecture: Global Region Config & Smart Pricing
### 🎯 Cél
Globális régió konfigurációs rendszer (RegionConfig modell + API) megvalósítása, frontend region store és formatter composable létrehozása, Smart Pricing Calculator beépítése a package edit modalba, valamint nyelvi preferencia perzisztálása a layoutban.
### 🔧 Módosított fájlok
- `backend/app/models/core_logic.py``RegionConfig` osztály hozzáadva (`system.region_config` séma, mezők: country_code, name, currency, default_vat_rate, locale_code, timezone, is_active)
- `backend/app/models/__init__.py``RegionConfig` import hozzáadva
- `backend/app/api/v1/endpoints/regions.py`**LÉTREHOZVA**: `GET /system/regions` publikus végpont
- `backend/app/api/v1/api.py` — regions router regisztrálva `/system` prefix-szel
- `backend/scripts/seed_regions.py`**LÉTREHOZVA**: 3 régió seedelése (HU, GB, DEFAULT)
- `backend/app/api/v1/endpoints/auth.py``PATCH /auth/me/language` végpont hozzáadva nyelvi preferencia perzisztáláshoz
- `frontend_admin/stores/region.ts`**LÉTREHOZVA**: Pinia store régiók lekérésére, aktív régió getterekkel (currency, locale, VAT, timezone)
- `frontend_admin/composables/useFormatter.ts`**LÉTREHOZVA**: Lokalizált formatter (number, currency, date, datetime, percent, VAT számítás)
- `frontend_admin/pages/packages/index.vue` — Tabbed modal refaktor (Basic Info, Pricing, Features), per-régió árazási grid, Smart Pricing Calculator net/VAT/gross kijelzéssel
- `frontend_admin/layouts/default.vue` — Nyelvváltó perzisztálás PATCH hívással, region store inicializálás onMounted-ban
### ✅ Eredmények
- **Sync Engine:** ✅ 1220 OK, 1 Fixed, 0 Shadow — `system.region_config` tábla létrejött
- **GET /api/v1/system/regions:** ✅ 200 — 3 régió (DEFAULT/EUR/0%, GB/GBP/20%, HU/HUF/27%)
- **PATCH /auth/me/language:** ✅ 200 — `preferred_language` perzisztálódik és visszaolvasható
- **Frontend build (admin):** ✅ Sikeres — `region-*.mjs` chunk generálódott
- **Adatbázis:** `country_code` VARCHAR(5)→VARCHAR(10) manuális ALTER a seed előtt
## 2026-06-25 - P0 CRITICAL SECURITY & UI FIX - RBAC Middleware & Mock Data Removal
### 🎯 Cél
Szigorú frontend Route-Based Access Control (RBAC) bevezetése az admin middleware-ben, és a hardcoded mock email (`admin@servicefinder.hu`) eltávolítása a Topbar-ból.
### 🔧 Módosított fájlok
- `frontend_admin/middleware/auth.ts` — Teljes átírás: token cookie ellenőrzés után `authStore.fetchUser()` hívás, majd `authStore.user.role` ellenőrzés az allowed staff role-ok listája (`SUPERADMIN`, `ADMIN`, `MODERATOR`, `SALES_REP`, `SERVICE_MGR`) alapján. Ha a role nem staff szintű → `authStore.logout()` + `navigateTo('/login')`.
- `frontend_admin/layouts/default.vue``userEmail` computed fallback `'admin@servicefinder.hu'``'Ismeretlen Felhasználó'`, `userInitials` fallback `'AD'``'??'`, dropdown role label `'Administrator'` → dinamikus `authStore.userRole` alapú.
### ✅ Eredmények
- **RBAC Middleware:** ✅ Standard USER role esetén a middleware kilépteti a felhasználót és a `/login` oldalra irányítja
- **Mock adatok eltávolítva:** ✅ `admin@servicefinder.hu` sehol sem szerepel hardcoded értékként
- **Auth Store:** ✅ Tiszta, nincs benne mock/default user adat
- **Minden admin oldal** (`index.vue`, `garages/index.vue`, `packages/index.vue`, `permissions/index.vue`) használja a `definePageMeta({ middleware: 'auth' })` direktívát
## 2026-06-25 - P0 Data Architecture: Populate Full EU Region Registry
### 🎯 Cél
A `system.region_config` tábla feltöltése mind a 27 EU tagállammal, plusz UK, Svájc és DEFAULT/Eurozone fallback rekorddal. Korábban csak 3 dummy/seed régió (HU, GB, DEFAULT) volt az adatbázisban.
### 🔧 Módosított fájlok
- `backend/scripts/seed_regions.py` — Teljes átírás: 30 régiós adatbázis (27 EU + GB + CH + DEFAULT), UPSERT logika (meglévő rekordok frissítése, új rekordok beszúrása), pontos VAT kulcsok, devizanemek, locale kódok és időzónák minden országra.
### ✅ Eredmények
- **Seed futtatás:** ✅ 27 új régió létrehozva, 3 meglévő frissítve (HU, GB, DEFAULT)
- **API verifikáció:** ✅ `GET /api/v1/system/regions` → 30 régió visszaadva, minden adat helyes
- **UPSERT idempotencia:** ✅ A script többször is futtatható, frissíti a meglévő rekordokat ahelyett, hogy duplikációt okozna
## 2026-06-25 - Garages CRM Wiring & Custom B2B Deals UI
### 🎯 Cél
Garázsok (Organizations) CRM felületének teljes körű implementálása: backend API végpontok, frontend adattábla mock adatok nélkül, előfizetéskezelő modál egyedi lejárati dátumokkal (B2B deal-ekhez).
### 🔧 Módosított/Létrehozott fájlok
**1. `backend/app/api/v1/endpoints/admin_organizations.py`** (LÉTREHOZVA)
- `GET /admin/organizations` — Garázsok listázása előfizetési adatokkal, taglétszámmal, kereséssel, szűréssel, lapozással
- `PATCH /admin/organizations/{org_id}/subscription` — Előfizetés módosítása tier_id és opcionális expires_at megadásával
- Tömeges subscription és member_count lekérdezés (N+1 elkerülése)
**2. `backend/app/api/v1/api.py`** (MÓDOSÍTVA)
- `admin_organizations` router regisztrációja
**3. `frontend_admin/pages/garages/index.vue`** (ÁTÍRVA)
- Mock adatok eltávolítva, valós API hívások (`$fetch`)
- Statisztikai kártyák (összes, aktív, premium, enterprise)
- Keresés és szűrés (tier alapján)
- Adattábla: ID, cégnév, státusz, csomag, lejárat, műveletek
- Előfizetéskezelő modál: tier dropdown + egyéni datetime-local input
- Mentés utáni automatikus refresh
**4. `frontend_admin/i18n/locales/hu.json`** (MÓDOSÍTVA)
- Garázs CRM-hez kapcsolódó összes magyar fordítás hozzáadva
**5. `frontend_admin/i18n/locales/en.json`** (MÓDOSÍTVA)
- Garázs CRM-hez kapcsolódó összes angol fordítás hozzáadva
### ✅ Teszt Eredmények
- Sync Engine: ✅ 1230 OK, 0 Fixed, 0 Extra (tökéletes szinkron)
- `GET /admin/organizations?limit=5`: ✅ 200 — 31 garázs, 5 visszaadva
- `GET /admin/packages?limit=5`: ✅ 200 — 5 tier elérhető
- `PATCH /admin/organizations/2406/subscription`: ✅ 200 — Celebro Kft. → corp_premium_v1, lejárat: 2027-06-25
- Verifikáció: ✅ Tier és lejárati dátum helyesen perzisztálva
## 2026-06-25 - P0 FIX & ENHANCE: Auth Token Missing & Duplicate Package Button
### 🎯 Cél
1. Garázsok oldal "Not authenticated" hiba javítása — hiányzó Authorization header pótlása
2. "Másolás" (Duplicate) gomb implementálása a csomagok oldalon
### 🔧 Módosított fájlok
**1. `frontend_admin/pages/garages/index.vue`** (MÓDOSÍTVA)
- `getAuthHeaders()` helper hozzáadva — `access_token` cookie-ból olvassa a tokent
- `fetchGarages()` és `fetchTiers()` hívásokhoz `headers: getAuthHeaders()` hozzáadva
- `saveSubscription()` PATCH híváshoz `Authorization` header hozzáadva
**2. `frontend_admin/pages/packages/index.vue`** (MÓDOSÍTVA)
- "Másolás" (Duplicate) gomb hozzáadva a kártya akcióihoz (Szerkesztés mellett, zöld színnel)
- `duplicatePackage(pkg)` függvény implementálva:
- Megnyitja a Create Modalt a kiválasztott csomag adataival előtöltve
- `id` mező törölve (új rekordként mentődik)
- Névhez `_copy` utótag fűzve, display_name-hez ` (másolat)` fűzve
- `is_default_fallback` false-ra állítva (nem duplikálható a visszaesési státusz)
- Árazási zónák, allowance-ok, feature_capabilities teljes körű másolása
**3. `frontend_admin/i18n/locales/en.json`** (MÓDOSÍTVA)
- `packages.duplicate: "Duplicate"` kulcs hozzáadva
**4. `frontend_admin/i18n/locales/hu.json`** (MÓDOSÍTVA)
- `packages.duplicate: "Másolás"` kulcs hozzáadva
### ✅ Domain Audit
- `backend/app/api/v1/endpoints/admin_organizations.py` végpont kizárólag core táblákat érint:
- `Organization`, `OrganizationMember`, `OrganizationSubscription`, `SubscriptionTier`, `User`
- Nincs scraped provider tábla lekérdezés — domain határok helyesek
## 2026-06-25: P0 Audit - Domain Conflation in Expense/Cost Service Provider Flow
**Gitea Card:** #291
**Scope:** Backend
**Type:** Bug / Domain Conflation
### Findings
Identified **6 code locations** causing domain conflation when `quick_add_provider()` creates `Organization()` (→ `fleet.organizations`) instead of `ServiceProvider()` (→ `marketplace.service_providers`):
1. **PRIMARY (provider_service.py:507-550):** `quick_add_provider()` creates `Organization()` instead of `ServiceProvider()`
2. **SECONDARY (provider_service.py:561-570):** `ServiceProfile.organization_id` FK to incorrectly created fleet.organizations
3. **TERTIARY (provider_service.py:618-630):** Branch creation in fleet.branches for lightweight vendor
4. **QUATERNARY (provider_service.py:639-646):** OrganizationMember addition for creating user
5. **SYSTEMIC (fleet_finance/models.py:104-110):** `AssetCost.vendor_organization_id` FK references ONLY `fleet.organizations.id`
6. **STRUCTURAL (provider_service.py):** `search_providers()` UNION masks domain conflation
### Outcome
- Report: `/opt/docker/docs/p0_domain_conflation_cost_provider_audit.md` (in roo-helper container)
- **No code changes made.** Awaiting Architect decision on refactoring approach.
- Refactoring Options proposed: A (flag in fleet), B (split to marketplace), C (hybrid - recommended)
## 2026-06-25 - P0 Hybrid Vendor Refactor & Categorization (Option C)
### 🎯 Cél
Implementálni az Option C (Hybrid) architektúrát: `quick_add_provider()` mostantól `ServiceProvider`-t (`marketplace.service_providers`) hoz létre `Organization` helyett (`fleet.organizations`). A valódi garázsok (safe list: 13 ID) továbbra is Organization-ként maradnak.
### 🔧 Módosított fájlok
**PHASE 1 - Schema Updates:**
- `backend/app/models/fleet_finance/models.py``service_provider_id` hozzáadva `AssetCost`-hoz + FK javítás (relációk indentálása)
- `backend/app/models/marketplace/service.py``service_provider_id` hozzáadva `ServiceProfile`-hoz
- `backend/app/models/identity/social.py``ServiceProvider` kiterjesztve 10 új mezővel (cím, kontakt)
- `unified_db_sync.py` futtatva → 10 új oszlop létrehozva az adatbázisban
**PHASE 2 - Refactor quick_add_provider():**
- `backend/app/services/provider_service.py``quick_add_provider()` átírva: `ServiceProvider` + `ServiceProfile` létrehozása (NO Organization, NO Branch, NO OrganizationMember)
- `backend/app/schemas/asset_cost.py``service_provider_id` hozzáadva a Pydantic modellekhez
- `backend/app/schemas/provider.py``ProviderQuickAddIn` kiegészítve új mezőkkel
- `backend/app/api/v1/endpoints/expenses.py``service_provider_id` átadva `AssetCost` creation-nél
**PHASE 3 - Data Migration:**
- `backend/scripts/migrate_providers.py` — Létrehozva: 7 Organization → ServiceProvider migrálva
**PHASE 4 - Verification:**
- 7 ServiceProvider rekord létrejött (`marketplace.service_providers`)
- 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