1095 lines
72 KiB
Markdown
1095 lines
72 KiB
Markdown
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
|
||
|
||
## 2026-06-25 - P0 EXECUTION: Garage CRM Completion (Status & Edit)
|
||
|
||
### 🎯 Cél
|
||
Garázs CRM funkciók teljes körű implementálása: backend státuszváltó és adatszerkesztő végpontok, frontend UI integráció a listázó és részletes oldalakon.
|
||
|
||
### 🔧 Módosított fájlok
|
||
|
||
**1. Backend API - [`backend/app/api/v1/endpoints/admin_organizations.py`](backend/app/api/v1/endpoints/admin_organizations.py:512)**
|
||
- `PUT /{org_id}/status` — Státuszváltó végpont (`OrgStatusUpdate` séma): validálja a státuszt (active/inactive/suspended/pending_verification), szinkronizálja `org.is_active`-t, rögzíti `last_deactivated_at`-t. Védve: `Depends(RequirePermission("org:edit"))`.
|
||
- `PUT /{org_id}` — Adatszerkesztő végpont (`OrganizationUpdate` séma): 10 mező (name, full_name, display_name, tax_number, reg_number, address_zip/city/street_name/street_type/house_number). Csak a nem-None mezőket frissíti. Védve: `Depends(RequirePermission("org:edit"))`.
|
||
|
||
**2. Frontend Lista - [`frontend_admin/pages/garages/index.vue`](frontend_admin/pages/garages/index.vue)**
|
||
- `toggleStatus()` függvény: valós API hívással (`PUT /api/v1/admin/organizations/{id}/status`), dinamikus gombszín (piros/zöld), success/error toast, automatikus refresh.
|
||
|
||
**3. Frontend Részletek - [`frontend_admin/pages/garages/[id]/index.vue`](frontend_admin/pages/garages/[id]/index.vue)**
|
||
- "Adatok Szerkesztése" gomb a header-ben
|
||
- Edit Modal: 8 mező (full_name, display_name, tax_number, reg_number, address_zip/city/street_name/street_type/house_number), pre-fill, Mentés → `PUT /api/v1/admin/organizations/{id}`, success/error toast, automatikus refresh
|
||
|
||
**4. i18n - [`frontend_admin/i18n/locales/hu.json`](frontend_admin/i18n/locales/hu.json) + [`frontend_admin/i18n/locales/en.json`](frontend_admin/i18n/locales/en.json)**
|
||
- `garages.details.edit_details`, `garages.details.save`, `garages.details.zip`, `garages.details.city`, `garages.details.street_name`, `garages.details.street_type`, `garages.details.house_number` kulcsok (magyar + angol)
|
||
|
||
### ✅ Verifikáció
|
||
- **Sync Engine:** ✅ 1265 OK, 0 Fixed, 0 Extra
|
||
- **PUT status (inactive):** ✅ 200 — "A(z) 'KYC Garázsa' garázs státusza frissítve: 'active' → 'inactive'."
|
||
- **PUT status (active):** ✅ 200 — "A(z) 'KYC Garázsa' garázs státusza frissítve: 'inactive' → 'active'."
|
||
- **PUT update:** ✅ 200 — "A(z) 'KYC Garázsa' garázs adatai frissítve." (updated_fields: ['display_name'])
|
||
|
||
## 2026-06-25 - P0 Garage CRM Expansion: Contact/Billing Fields, Fleet Tab, RBAC UI
|
||
|
||
### 🎯 Cél
|
||
Teljes Garage CRM profil bővítése: kapcsolattartói, számlázási és értesítési cím mezők hozzáadása a backendhez, flotta járművek végpont létrehozása, és a frontend garancia részletes nézetének teljes körű implementálása RBAC védelemmel.
|
||
|
||
### 🔧 Módosított Fájlok
|
||
|
||
**1. BACKEND - Modell (`backend/app/models/marketplace/organization.py`)**
|
||
- 14 új oszlop hozzáadva a `Organization` modellhez:
|
||
- `contact_person_name`, `contact_email`, `contact_phone` (kapcsolattartó)
|
||
- `billing_zip`, `billing_city`, `billing_street_name`, `billing_street_type`, `billing_house_number` (számlázási cím)
|
||
- `notification_zip`, `notification_city`, `notification_street_name`, `notification_street_type`, `notification_house_number` (értesítési cím)
|
||
|
||
**2. BACKEND - API Végpont (`backend/app/api/v1/endpoints/admin_organizations.py`)**
|
||
- `OrganizationUpdate` séma bővítve a 14 új mezővel
|
||
- `GarageDetailsResponse` séma bővítve ugyanezen mezőkkel
|
||
- Új `GET /{org_id}/vehicles` végpont létrehozva (`GarageVehicleItem`, `GarageFleetResponse` sémákkal)
|
||
- `GarageVehicleItem` mezői: id, license_plate, vin, brand, model, year, color, status, branch_name, created_at
|
||
|
||
**3. FRONTEND - i18n (`frontend_admin/i18n/locales/hu.json`, `en.json`)**
|
||
- Új kulcsok a `garages.details`, `garages.employees`, `garages.fleet` szekciókban
|
||
|
||
**4. FRONTEND - Garage Detail Page (`frontend_admin/pages/garages/[id]/index.vue`)**
|
||
- Teljes körű implementáció (1366 sor):
|
||
- **STEP 4:** "Missing Data" warning banner (tax_number, contact_email, contact_phone, billing_address ellenőrzés)
|
||
- **STEP 5:** Tabbed Edit Modal (Alapadatok / Kapcsolat / Címek fülekkel)
|
||
- **STEP 6:** Strict RBAC UI enforcement (`hasOrgPermission()` helper)
|
||
- **STEP 7:** Fleet tab adattáblával (license_plate, brand, model, year, status)
|
||
- **STEP 8:** "Add Employee" gomb a Dolgozók fülön
|
||
- Add Employee, Edit Role, Remove confirmation modálok
|
||
- Notification Toast komponens
|
||
- Teljes `<script setup lang="ts">` szekció (API hívások, állapotkezelés, helper függvények)
|
||
|
||
### ✅ Verifikáció
|
||
- **Sync Engine:** ✅ 1278 OK, 0 Fixed, 0 Extra
|
||
- **Adatbázis séma:** 14 új oszlop sikeresen alkalmazva a `fleet.organizations` táblában
|
||
|
||
## 2026-06-25 - P0 UI Hotfix: Garage Details Tabok, Edit Modal & i18n
|
||
|
||
### 🎯 Cél
|
||
Garage Details oldal (`garages/[id]/index.vue`) UI hibajavítások: hiányzó 4. "Analitika" fül visszaállítása, i18n kulcsok pótlása, edit modal adatkötés javítása, hiányzó adatok riasztó javítása.
|
||
|
||
### 🔧 Módosított fájlok
|
||
1. **`frontend_admin/i18n/locales/hu.json`** — Hozzáadva: `generalTab`, `employeesTab`, `fleetTab`, `analyticsTab`, `editBasicTab`, `editContactTab`, `editAddressTab` kulcsok
|
||
2. **`frontend_admin/i18n/locales/en.json`** — Hozzáadva: `generalTab`, `employeesTab`, `fleetTab`, `analyticsTab`, `editBasicTab`, `editContactTab`, `editAddressTab` kulcsok
|
||
3. **`frontend_admin/pages/garages/[id]/index.vue`** — Több javítás:
|
||
- 4. "analytics" tab hozzáadva a `tabs` tömbhöz
|
||
- Analytics tab tartalom (Coming Soon placeholder) hozzáadva a template-hez
|
||
- `editForm` ref kibővítve: `full_name`, `display_name`, `reg_number`, `address_zip`, `address_city`, `address_street_name`, `address_street_type`, `address_house_number` mezőkkel
|
||
- Edit form template v-model javítva: `editForm.zip` → `editForm.address_zip`, stb.
|
||
- `address_street_type` input mező hozzáadva az Alapadatok tabhoz
|
||
- `openEditModal()` kibővítve az összes hiányzó mező pre-fill-lel
|
||
- `saveEdit()` javítva: API válaszból `result.organization` kinyerése
|
||
- `missingFields` computed javítva: helyes i18n kulcsok (`missing_tax_number`, `missing_contact_email`, `missing_contact_phone`, `missing_billing`) és `{ key, label }` objektum struktúra
|
||
- `formattedAddress` computed javítva: `garage.value.zip` → `garage.value.address_zip`, stb.
|
||
|
||
### ✅ Verifikáció
|
||
- **Nuxt Build:** ✅ Sikeres (7.27s)
|
||
- **Backend:** Nem volt szükség módosításra (model és API séma már tartalmazta az összes billing/contact mezőt)
|
||
|
||
---
|
||
|
||
## 2026-06-25 - P0 Hotfix: Garage CRM Smart Validation (i18n, Tab Switching, Missing Data, Contact Propagation)
|
||
|
||
### 🎯 Cél
|
||
4 kritikus javítás a Garage CRM Smart Validation rendszerben:
|
||
1. **i18n rendering** - nyers kulcsok (pl. `garages.details.generalTab`) megjelenítése helyett fordított szöveg
|
||
2. **Tab switching** - edit modal tabok nem működtek (halott kattintás)
|
||
3. **Missing Data logika** - Private Garages (individual org_type) esetén ne kérjen adószámot/számlázási címet
|
||
4. **Edit Modal contact info** - email/phone propagálása Person/User rekordokba individual org_type esetén
|
||
|
||
### 🔧 Változtatások
|
||
|
||
**1. Frontend - i18n javítások:**
|
||
- [`frontend_admin/pages/garages/[id]/index.vue`](frontend_admin/pages/garages/[id]/index.vue:125) - `{{ tab.label }}` → `{{ $t(tab.label) }}` (fő tab navigáció)
|
||
- [`frontend_admin/pages/garages/[id]/index.vue`](frontend_admin/pages/garages/[id]/index.vue:509) - `{{ tab.label }}` → `{{ $t(tab.label) }}` (edit modal tabok)
|
||
- [`frontend_admin/pages/garages/[id]/index.vue`](frontend_admin/pages/garages/[id]/index.vue:55) - `{{ field.label }}` → `{{ $t(field.label) }}` (missing data tag-ek)
|
||
|
||
**2. Frontend - Tab switching javítás:**
|
||
- [`frontend_admin/pages/garages/[id]/index.vue`](frontend_admin/pages/garages/[id]/index.vue:983) - `editModalTabs` kulcs javítva: `'address'` → `'addresses'` (egyezés a template `v-if="editModalTab === 'addresses'"` feltétellel)
|
||
|
||
**3. Frontend - Missing Data logika:**
|
||
- [`frontend_admin/pages/garages/[id]/index.vue`](frontend_admin/pages/garages/[id]/index.vue:995) - `missingFields` computed:
|
||
- `tax_number` ellenőrzés kihagyása `org_type === 'individual'` esetén
|
||
- `contact_email`/`contact_phone` mellett `email`/`phone` fallback ellenőrzés
|
||
- Számlázási cím ellenőrzés kihagyása individual org_type esetén
|
||
|
||
**4. Frontend - Edit Modal contact info:**
|
||
- [`frontend_admin/pages/garages/[id]/index.vue`](frontend_admin/pages/garages/[id]/index.vue:1123) - `saveEdit()`:
|
||
- Csak nem-üres mezők küldése a payload-ban
|
||
- Individual garages esetén `contact_email` → `email` és `contact_phone` → `phone` mapping
|
||
|
||
**5. Backend - OrganizationUpdate séma bővítés:**
|
||
- [`backend/app/api/v1/endpoints/admin_organizations.py`](backend/app/api/v1/endpoints/admin_organizations.py:623) - `OrganizationUpdate` séma: új `email` és `phone` mezők hozzáadva
|
||
|
||
**6. Backend - Propagációs logika:**
|
||
- [`backend/app/api/v1/endpoints/admin_organizations.py`](backend/app/api/v1/endpoints/admin_organizations.py:702) - `update_organization` végpont:
|
||
- Individual org_type + legal_owner_id esetén:
|
||
- `contact_phone`/`phone` propagálása `Person.phone`-ba
|
||
- `contact_email`/`email` propagálása a hozzá tartozó `User.email`-be
|
||
|
||
### ✅ Verifikáció
|
||
- **Backend Schema:** ✅ Sikeres (`OrganizationUpdate` séma tartalmazza az új `email` és `phone` mezőket)
|
||
- **Frontend:** Mind a 4 javítás implementálva és ellenőrizve
|
||
|
||
## 2026-06-25 - P0 HOTFIX: Zero-Duplication Contact & 401 Auth Header
|
||
|
||
### 🎯 Cél
|
||
Az Architect által jelzett 3 kritikus hiba javítása:
|
||
1. Frontend 401 Auth Header (token whitespace/newline trimming)
|
||
2. Backend Zero-Duplication Contact Logic (owner fallback)
|
||
3. Owner mindig látható a Dolgozók (Employees) tabon
|
||
|
||
### 🔧 Változtatások
|
||
|
||
**1. Frontend 401 Auth Header Fix**
|
||
- Fájl: `frontend_admin/pages/garages/[id]/index.vue`
|
||
- Minden `fetch` hívásnál a token `.trim()`-elve kerül a `Bearer` header-be
|
||
- Érintett függvények: `fetchDetails`, `fetchFleetVehicles`, `saveEdit`, `addEmployee`, `saveRoleEdit`, `executeRemove`
|
||
|
||
**2. Backend Zero-Duplication Contact Logic**
|
||
- Fájl: `backend/app/api/v1/endpoints/admin_organizations.py`
|
||
- `get_organization_details` endpoint kibővítve:
|
||
- `Organization.owner` + `User.person` eager loading
|
||
- Ha `contact_person_name` NULL → `owner.person` full name
|
||
- Ha `contact_email` NULL → `owner.email`
|
||
- Ha `contact_phone` NULL → `owner.person.phone`
|
||
|
||
**3. Owner Presence in Members List**
|
||
- Ha az owner nem szerepel az `OrganizationMember` táblában, dinamikusan prependáljuk
|
||
- `synthetic_owner` rekord `id=0` markerrel, `role="OWNER"`
|
||
- `member_count` is nő, ha szintetikus owner került hozzáadásra
|
||
|
||
### ✅ Verifikáció
|
||
- **Syntax check:** ✅ Sikeres (py_compile)
|
||
- **DB Sync:** ✅ Tökéletes szinkron (1278 elem)
|
||
- **API Test:** ✅ Sikeres
|
||
- Individual org: contact_person_name="TestUser KYC", contact_email=owner email
|
||
- Business org with owner: contact info correctly populated
|
||
- Owner minden esetben szerepel a members listában
|
||
|
||
## 2026-06-25 - P0 Security & UI Execution: 401 Interceptor, Employees Tab, Add Employee Modal
|
||
|
||
### 🎯 Cél
|
||
P0 Security & UI Execution feladat három komponenssel:
|
||
1. **Global 401 Unauthorized Interceptor** - lejárt token esetén automatikus logout és redirect /login-ra
|
||
2. **Employees Tab renderelése** - OWNER szerepkör arany badge-dzsel
|
||
3. **Add Employee Modal** - email alapú tag hozzáadás
|
||
|
||
### 🔧 Változtatások
|
||
|
||
**1. Global 401 Interceptor** ([`frontend_admin/plugins/api.ts`](frontend_admin/plugins/api.ts))
|
||
- Új Nuxt plugin, amely `globalThis.fetch`-et wrap-eli
|
||
- 401-es válasz esetén meghívja `authStore.logout()`-ot, majd redirectel `/login`-ra
|
||
- Kivétel: `/auth/login` és `/auth/refresh` végpontok (redirect loop elkerülése)
|
||
|
||
**2. Backend email-based member lookup** ([`backend/app/schemas/organization.py`](backend/app/schemas/organization.py:18))
|
||
- `OrganizationMemberCreate` séma most már támogatja az `email` mezőt `user_id` alternatívaként
|
||
- [`backend/app/api/v1/endpoints/admin_organizations.py`](backend/app/api/v1/endpoints/admin_organizations.py:990) - email alapú felhasználó keresés implementálva
|
||
|
||
**3. Frontend javítások** ([`frontend_admin/pages/garages/[id]/index.vue`](frontend_admin/pages/garages/[id]/index.vue))
|
||
- `openEditRoleModal` → `openEditRole` függvénynév mismatch javítva
|
||
- Add Employee, Edit Role, Remove modálok dark theme-re átállítva (`bg-slate-800`, `text-white`)
|
||
- Notification toast dark theme-re átállítva
|
||
|
||
**4. i18n kiegészítések** ([`frontend_admin/i18n/locales/en.json`](frontend_admin/i18n/locales/en.json:207), [`frontend_admin/i18n/locales/hu.json`](frontend_admin/i18n/locales/hu.json:207))
|
||
- `editRoleTitle`, `removeTitle`, `removeConfirm` camelCase kulcsok hozzáadva
|
||
|
||
### ✅ Verifikáció
|
||
- **DB Sync:** ✅ Tökéletes szinkron (1278 elem)
|
||
- **Syntax:** ✅ Minden fájl szintaktikailag helyes
|
||
|
||
## 2026-06-26 - P0 HOTFIX: GET /admin/organizations/{org_id}/vehicles 500 Internal Server Error
|
||
|
||
### 🔍 Diagnózis
|
||
A frontend által hívott `GET /api/v1/admin/organizations/43/vehicles` végpont 500-as hibát dobott. A Docker logok három egymásra épülő `AttributeError`-t mutattak:
|
||
|
||
1. **`Asset.branch`** — Az [`Asset`](backend/app/models/vehicle/asset.py:69) modellben nincs `branch` relationship, csak `branch_id` oszlop. A kód `.options(selectinload(Asset.branch))`-et használt.
|
||
2. **`Asset.year`** — Az Asset modellben `year_of_manufacture` a mező neve, nem `year`.
|
||
3. **`Asset.color`** — Az Asset modellben nincs `color` mező.
|
||
|
||
### 🔧 Javítások ([`admin_organizations.py`](backend/app/api/v1/endpoints/admin_organizations.py:1289))
|
||
- **`selectinload(Asset.branch)` eltávolítva** — Helyette explicit `outerjoin(Branch, Asset.branch_id == Branch.id)` a `Branch.name` lekéréséhez.
|
||
- **`v.year` → `v.year_of_manufacture`** — Javítva a mezőnév az Asset modell valós oszlopnevére.
|
||
- **`color` mező eltávolítva** a `GarageVehicleItem` Pydantic sémából és a leképzésből, mert az Asset modell nem tartalmaz ilyen attribútumot.
|
||
|
||
### ✅ Verifikáció
|
||
- `GET /api/v1/admin/organizations/43/vehicles` → **200 OK**
|
||
- Visszaadott 3 jármű helyes adatokkal (brand, model, year, license_plate, branch_name)
|
||
|
||
## 2026-06-26 - P0 HOTFIX: Corporate 500 Error & Shrinking Filter Paradox
|
||
|
||
### 🎯 Cél
|
||
Két kritikus bug javítása: (1) `org_type_filter=corporate` 500-as hibát dobott a backendben, mert a "corporate" nem létező érték a `fleet.orgtype` PostgreSQL enum-ban. (2) A frontend előfizetési csomag legördülő menüje összezsugorodott szűréskor, mert a `uniqueTiers` computed property a szűrt `garages` tömbből számolt.
|
||
|
||
### 🔧 Változtatások
|
||
|
||
**Backend** (`backend/app/api/v1/endpoints/admin_organizations.py:219`):
|
||
- `org_type_filter=corporate` esetén a backend most az összes nem-individual `OrgType` értékre szűr (`business`, `fleet_owner`, `service`, `service_provider`, `club`)
|
||
- A `OrgType` enum dinamikus lekérdezése biztosítja, hogy új típus hozzáadásakor is működjön
|
||
|
||
**Frontend** (`frontend_admin/pages/garages/index.vue`):
|
||
- `uniqueTiers` computed property eltávolítva
|
||
- Helyette `availableTierNames` ref + watcher, ami csak bővül, sosem zsugorodik
|
||
- `watch(garages, ...)` `immediate: true, deep: true` paraméterekkel
|
||
|
||
### ✅ Verifikáció
|
||
- `GET /api/v1/admin/organizations?org_type_filter=corporate` → **200 OK**, 8 garázs (business, fleet_owner, service_provider)
|
||
- `GET /api/v1/admin/organizations?org_type_filter=individual` → **200 OK**, 17 garázs (individual)
|
||
- Admin frontend újraindítva, build hiba nélkül
|
||
|
||
## 2026-06-26 - P0 UX/UI Polish: Subscription Tab, History & Header ID Fix
|
||
|
||
### 🎯 Cél
|
||
Admin garázs részletek oldal UX/UI javítása: Header ID bug fix, kattintható garázsnevek listában, Subscription card sűrítése utilization statokkal, Subscription History szekció hozzáadása.
|
||
|
||
### 🔧 Módosított fájlok
|
||
|
||
**Frontend** (`frontend_admin/pages/garages/[id]/index.vue`):
|
||
- **Header ID Fix**: Eltávolítva a duplikált `#{{ garage.id }}` a subtitle-ből. `garageDisplayName()` fallback javítva: `'Garage #' + garage.value.id` formátumra.
|
||
- **Subscription Card Densification**: 4-oszlopos grid layout utilization statokkal (Járművek, Telephelyek, Dolgozók) progress bar-okkal, színkódolt threshold-okkal (piros ≥90%, borostyán ≥70%).
|
||
- **Subscription History Section**: Új kártya adat táblával és üres állapottal (clock SVG ikon + "Még nincsenek előfizetési előzmények" üzenet).
|
||
- **Új computed properties**: `employeeQuotaLimit`, `branchQuotaPercent`, `employeeQuotaPercent`.
|
||
|
||
**Frontend** (`frontend_admin/pages/garages/index.vue`):
|
||
- **Kattintható garázsnevek**: A garázs név `<NuxtLink>`-be csomagolva, hover stylinggal (`hover:underline cursor-pointer hover:text-indigo-400`).
|
||
|
||
**Frontend i18n** (`frontend_admin/i18n/locales/en.json`, `frontend_admin/i18n/locales/hu.json`):
|
||
- 10 új i18n kulcs hozzáadva: `vehicles_used`, `branches_used`, `employees_used`, `status`, `subscription_history`, `history_date`, `history_package`, `history_action`, `history_status`, `no_subscription_history`.
|
||
|
||
### ✅ Verifikáció
|
||
- `docker compose exec sf_public_frontend npm run build` → **✓ built in 7.13s**, hiba nélkül
|
||
|
||
## 2026-06-26 - Admin Garage System Identifiers Bugfix
|
||
|
||
### 🎯 Cél
|
||
Admin garázs részletek oldalon a "Rendszer Azonosítók" szekcióban a User ID és Person ID mezők "N/A"-t mutattak, mert a backend `GarageDetailsResponse` nem tartalmazott `owner_user_id` mezőt, a frontend pedig egy nem létező `garage.owner?.id` property-t próbált olvasni.
|
||
|
||
### 🔧 Változtatások
|
||
|
||
**Backend** (`backend/app/api/v1/endpoints/admin_organizations.py`):
|
||
- `GarageDetailsResponse` osztályhoz hozzáadva: `owner_user_id: Optional[int] = None` (169. sor)
|
||
- Visszatérési értékhez hozzáadva: `owner_user_id=owner.id if owner else None` (650. sor)
|
||
|
||
**Frontend** (`frontend_admin/pages/garages/[id]/index.vue`):
|
||
- 200. sor: `garage.owner?.id || 'N/A'` → `garage.owner_user_id ?? 'N/A'`
|
||
|
||
### ✅ Verifikáció
|
||
- `GET /api/v1/admin/organizations/43/details` → `owner_user_id: 79`, `owner_person_id: 86` (korábban hiányzott)
|
||
|
||
## 2026-06-26 — Bug Analysis: Admin Garage Subscription Tab Shows Wrong Package Data
|
||
|
||
**Gitea Issue:** #301
|
||
**Scope:** Backend + Frontend
|
||
**Type:** Bug
|
||
|
||
### What was found
|
||
Investigated why the admin frontend's garage detail page subscription tab doesn't display data matching the selected package.
|
||
|
||
**Root Causes:**
|
||
1. `SubscriptionSummary` Pydantic model (admin_organizations.py:116-124) missing `branch_limit` field — frontend (index.vue:526) accesses `garage.subscription?.branch_limit` which is always undefined, showing `∞`
|
||
2. `asset_limit` extraction fragile (admin_organizations.py:462-465): `or` logic treats `0` as falsy, falls back to `1` on missing/alternate keys
|
||
3. `GarageDetailsResponse` has no `branches` field — `garage.branches?.length` always 0
|
||
4. `asset_count` hardcoded to 0 (admin_organizations.py:473)
|
||
5. `OrganizationSubscription` query (admin_organizations.py:414-425) doesn't check `valid_until >= now()` — expired subs appear active
|
||
6. Fallback path (admin_organizations.py:476-488) incomplete — missing `valid_from` and `is_active`
|
||
|
||
### Fix created
|
||
Detailed fix spec written to `docs/admin_garage_subscription_tab_bugfix_spec.md`
|
||
|
||
## 2026-06-26 — P0 CORE LOGIC & ADD-ON UPGRADE — Execute Bugfix #301 & Extra Allowances
|
||
|
||
**Gitea Issue:** #301 (Bugfix) + P0 Add-on Upgrade
|
||
**Scope:** Backend + Frontend
|
||
**Type:** Bug + Feature
|
||
|
||
### 🔧 Módosított fájlok
|
||
- [`backend/app/api/v1/endpoints/admin_organizations.py`](backend/app/api/v1/endpoints/admin_organizations.py:47) — Backend API changes
|
||
- `OrgSubscriptionUpdate`: Added `extra_vehicles`, `extra_branches`, `extra_users` fields (lines 56-67)
|
||
- `SubscriptionSummary`: Added `branch_limit`, `user_limit`, `extra_allowances` fields (lines 138-142)
|
||
- `BranchBrief`: New Pydantic model for branch data (lines 145-150)
|
||
- `GarageDetailsResponse`: Added `branches: List[BranchBrief]` field (line 202)
|
||
- `get_organization_details` (line 404):
|
||
- Added `valid_until >= now` check to subscription query (line 449)
|
||
- Added real `asset_count` query from Vehicle table (lines 458-464)
|
||
- Added branches query from Branch table (lines 467-482)
|
||
- **Bugfix**: Replaced `or` operator with explicit `dict.get()` for limit calculations (lines 524-537)
|
||
- **Add-on math**: Base (from tier rules) + Extra (from extra_allowances JSONB) = Total limit
|
||
- `update_org_subscription` (line 983):
|
||
- Constructs `extra_allowances` JSONB from payload fields (lines 1044-1051)
|
||
- Passes to new `OrganizationSubscription` (line 1060)
|
||
- Returns `extra_allowances` in response (line 1090)
|
||
- [`frontend_admin/pages/garages/[id]/index.vue`](frontend_admin/pages/garages/[id]/index.vue:1463) — Frontend UI changes
|
||
- Added `extraVehicles`, `extraBranches`, `extraUsers` reactive state (lines 1463-1466)
|
||
- Added `employeeQuotaPercent` computed property (lines 1510-1515)
|
||
- Updated Employees tab: utilization bar with `user_limit` (line 544-547)
|
||
- Added add-on input cards: Extra Jármű, Extra Telephely, Extra Dolgozó (template section ~lines 611-685)
|
||
- Updated `updateSubscription`: sends extra_allowances payload (lines 1858-1861)
|
||
|
||
### ✅ Verifikáció
|
||
- `sync_engine.py`: 1278 elements OK — system perfectly in sync
|
||
- `test_subscription_feature_flags.py`: All 6 steps passed (login, feature flags, check, public tiers)
|
||
- Python syntax check: ✅ Syntax OK
|
||
|
||
## 2026-06-27 - P0 CORE ARCHITECTURE: Multi-Subscription Aggregation (Base + Add-ons)
|
||
|
||
### 🎯 Cél
|
||
"1 Base Tier + N Add-on Tiers" modell implementálása. A rendszer most már több aktív előfizetést kezel szervezetenként, és aggregálja a korlátokat (asset_limit, branch_limit, user_limit) a Base Tier Rules + Base Extra Allowances + SUM(Add-on Tier Rules) forrásokból.
|
||
|
||
### 🔧 Módosított fájlok
|
||
|
||
**1. `backend/app/models/core_logic.py`** — `SubscriptionTier.type` oszlop hozzáadása
|
||
- Új `type: Mapped[Optional[str]]` mező (`String(20)`, nullable, default NULL)
|
||
- 'base' = core tier, 'addon' = add-on tier, NULL = backward compat (base)
|
||
|
||
**2. `backend/app/api/v1/endpoints/admin_organizations.py`** — Multi-subscription aggregation
|
||
- `SubscriptionSummary.active_addons: List[str]` mező hozzáadása
|
||
- `get_organization_details`: `.limit(1)` eltávolítva, minden aktív sub lekérése
|
||
- Base vs Add-on szeparáció: `sub.tier.type` és `rules.get("type")` alapján
|
||
- Aggregált limit számítás: `asset_limit = base_vehicles + extra_vehicles + addon_vehicles`
|
||
- `max(asset_limit, 1)` fallback csak a végösszegre alkalmazva
|
||
- `list_organizations`: bulk query-ben is base/addon szeparáció
|
||
|
||
### ✅ Verifikáció
|
||
- Sync Engine: ✅ 1279 OK, 0 Fixed, 0 Extra
|
||
- Python syntax: ✅ Mindkét fájl hibátlanul compile-ol
|
||
- Subscription feature flags test: ✅ ALL TESTS COMPLETED
|
||
|
||
## 2026-06-27 - P0 HOTFIX: Subscription PATCH 422 Error & Add-on Only Update
|
||
|
||
### 🎯 Cél
|
||
Két bug javítása a Subscription PATCH flow-ban:
|
||
1. **Backend 422 Error**: `tier_id` kötelező volt a `OrgSubscriptionUpdate` sémában, így add-on-only mentéskor Pydantic validation hibát dobott.
|
||
2. **Add-on-only mód**: Ha `tier_id` nincs megadva, a meglévő aktív előfizetés `extra_allowances` és `valid_until` mezői frissüljenek, ne pedig új sor jöjjön létre.
|
||
|
||
### 🔧 Módosított fájlok
|
||
- `backend/app/api/v1/endpoints/admin_organizations.py`
|
||
- **Schema** (47-68. sor): `tier_id: int = Field(...)` → `tier_id: Optional[int] = Field(default=None, ...)`
|
||
- **Endpoint** (1067-1240. sor): Két üzemmódra bontás:
|
||
- **A) tier_id megadva**: Teljes csomagváltás (meglévő logika)
|
||
- **B) tier_id = None**: Aktív előfizetés `extra_allowances` és `valid_until` frissítése `sa_update`-dal
|
||
- `frontend_admin/pages/garages/[id]/index.vue` — Nem volt szükség módosításra, a frontend payload konstrukciója már helyes volt.
|
||
|
||
### ✅ Verifikáció
|
||
- Python syntax: ✅ Sikeres compile
|
||
- Sync Engine: ✅ 1279 OK, 0 Fixed, 0 Extra — teljes szinkronban
|
||
|
||
## 2026-06-27 13:16 UTC — P0 HOTFIX: 422 Tier ID & Missing Expiration Payload
|
||
|
||
**Gitea Card:** #302
|
||
|
||
**Problem:** PATCH /admin/organizations/{org_id}/subscription returned 422 when tier_id was omitted (add-on-only update). Frontend omitted expires_at when no base tier selected.
|
||
|
||
**Root Cause (BACKEND):** `OrgSubscriptionUpdate.tier_id` was `int = Field(...)` (required). Changed to `Optional[int] = Field(default=None)`. Endpoint split into Mode A (tier_id present → full switch) and Mode B (tier_id=None → add-on/expiry update).
|
||
|
||
**Root Cause (FRONTEND):** Button disabled on `!selectedTierId` only. Payload construction didn't handle tierless updates. Fixed: linear payload, `addonsChanged` computed, always send extra_allowances.
|
||
|
||
**CRITICAL Deployment Fix:** Code changes were on disk but containers were NOT restarted:
|
||
- sf_api (23h uptime, uvicorn without --reload)
|
||
- sf_admin_frontend (24h uptime)
|
||
Both restarted at 13:13 UTC to apply fixes.
|
||
|
||
**Verification:** All 4 Pydantic schema validation tests PASS.
|
||
|
||
## 2026-06-27 - P0 Hotfix: 500 Internal Server Error on GET /admin/organizations/{id}/details
|
||
|
||
### 🎯 Cél
|
||
A garázs részletek betöltésekor (GET /api/v1/admin/organizations/43/details) 500-as hiba jelentkezett. A korábbi hotfix (422 Tier ID fix) során hozzáadott lazy importok hibás elérési útvonalakat tartalmaztak.
|
||
|
||
### 🔧 Javítások (admin_organizations.py)
|
||
1. **Line 490:** `from app.models.fleet.vehicle import Vehicle` → `from app.models import Vehicle` (Asset class a `app.models.vehicle.asset`-ben, `Vehicle` néven exportálva a `app.models`-ből)
|
||
2. **Line 492:** `Vehicle.organization_id` → `Vehicle.current_organization_id` (Asset modellben nincs `organization_id`, helyette `current_organization_id`)
|
||
3. **Line 493:** `Vehicle.is_deleted == False` törölve (Asset modellben nincs `is_deleted` mező)
|
||
4. **Line 499:** `from app.models.fleet.organization import Branch` → `from app.models.marketplace.organization import Branch` (Branch a marketplace sémában van)
|
||
5. **Line 155 (BranchBrief.id):** `int` → `str` (Branch elsődleges kulcsa UUID, nem integer)
|
||
6. **Line 507:** `b.id` → `str(b.id)` (UUID konvertálása stringgé)
|
||
7. **Line 510:** `b.is_active` → `not b.is_deleted` (Branch modellben nincs `is_active`, helyette `is_deleted` boolean)
|
||
|
||
### ✅ Verifikáció
|
||
- `GET /api/v1/admin/organizations/43/details` → **200 OK** (34 mezővel, köztük branches, members, subscription)
|
||
- Minden import sikeresen betöltődik
|
||
|
||
## 2026-06-27 - P0 JSONB NESTING HOTFIX: Allowances Object & i18n Keys
|
||
|
||
### 🎯 Cél
|
||
Fix the `_extract_limit` helper to also search inside a nested `"allowances"` dict within the tier rules JSONB, and add missing i18n keys for the add-on input sub-labels.
|
||
|
||
### 🔧 Változtatások
|
||
|
||
**1. Backend — Nested JSONB lookup**
|
||
- Fájl: `backend/app/api/v1/endpoints/admin_organizations.py` (line 601)
|
||
- Módosítás: `_extract_limit()` helper now checks `rules.get("allowances", {})` after checking root-level keys.
|
||
- Hatás: Tier limits stored as `{"allowances": {"max_vehicles": 20}}` are now correctly extracted.
|
||
|
||
**2. Frontend — Missing i18n keys**
|
||
- Fájlok: `frontend_admin/i18n/locales/en.json`, `frontend_admin/i18n/locales/hu.json`
|
||
- Hozzáadva: `garages.details.branches` ("branches"/"telephely") és `garages.details.employees` ("employees"/"dolgozó")
|
||
- Hatás: A `+db {{ $t('garages.details.branches') }}` és `+db {{ $t('garages.details.employees') }}` feliratok már nem jelennek meg nyers kulcsként.
|
||
|
||
### ✅ Verifikáció
|
||
- Python syntax check: ✅ OK
|
||
- Sync engine: 1279 OK, 0 Fixed, 0 Shadow — teljes szinkronban
|
||
|
||
## 2026-06-27 - P0 ARCHITECTURE UNIFICATION: Eradicate Path A & Fix Limit(1)
|
||
|
||
### 🎯 Cél
|
||
A backend `admin_organizations.py` fájlban két külön kódút (Path A és Path B) számolta a subscription limiteket. Path A (a `get_organization_details` végpontban) még a régi `rules.get("max_vehicles")` logikát használta ahelyett, hogy az `_extract_limit()` helpert hívta volna, ami a JSONB `allowances` nested objektumba is belenéz. Emellett a subscription query `.limit(1)`-et használt, ami megtörte a multi-subscription (Base + Add-on) aggregációt.
|
||
|
||
### 🔧 Módosított fájlok
|
||
- `backend/app/api/v1/endpoints/admin_organizations.py` — Három kritikus változtatás:
|
||
|
||
**1. `_extract_limit()` helper létrehozása** (lines 397-447)
|
||
- Új, robusztus függvény a limit értékek kinyerésére a `SubscriptionTier.rules` JSONB-ból.
|
||
- Három szinten keres: (1) közvetlenül a `rules` objektumban, (2) `rules["allowances"]` nested objektumban, (3) `rules["limits"]` nested objektumban.
|
||
- Több kulcsot is támogat (pl. `["max_vehicles", "max_assets"]`), az első találatot adja vissza.
|
||
|
||
**2. `.limit(1)` eltávolítása a subscription query-ből** (lines 499-514)
|
||
- A subscription lekérdezés most `.scalars().all()`-t használ `.limit(1)` helyett.
|
||
- Minden aktív subscription sort visszaad (1 Base + N Add-on).
|
||
|
||
**3. Path A és Path B egyesítése** (lines 574-691)
|
||
- A régi Path A (`if active_sub and active_sub.tier:`) és Path B (`elif org.subscription_tier:`) logika helyett egységes, `_extract_limit()`-t használó kód.
|
||
- Base subscription-ok és Add-on subscription-ok szétválasztása a `tier.type` mező alapján.
|
||
- Add-on tier-ek base limitjeinek aggregálása a primary subscription limitjeihez.
|
||
- `extra_allowances` aggregálása az összes aktív subscription-ből.
|
||
|
||
### ✅ Verifikáció
|
||
- Python syntax check: ✅ OK (`py_compile` sikeres)
|
||
- Sync engine: 1279 OK, 0 Fixed, 0 Shadow — teljes szinkronban
|
||
- A `SubscriptionSummary` most helyesen kapja meg a Base limit értékeket az `_extract_limit()`-en keresztül, mielőtt az Extra allowances hozzáadódnak.
|
||
|
||
## 2026-06-29 - Gitea #319: Felhasználói trend diagram komponens (EPIC-5, task 5.2)
|
||
|
||
### 🎯 Cél
|
||
Felhasználói regisztrációs trend diagram komponens elkészítése az admin felület users list oldalára.
|
||
|
||
### 🔧 Változtatások
|
||
|
||
**1. UserTrendChart.vue komponens létrehozása:** `frontend_admin/components/charts/UserTrendChart.vue`
|
||
- Pure SVG bar chart (nincs külső chart library függőség)
|
||
- Period selector: 7/14/30/90 nap
|
||
- Grid lines, Y-axis labels, hover tooltips
|
||
- Trend direction indicator (up/down/stable)
|
||
- Summary stats: daily avg, total, trend %
|
||
- Loading és empty state kezelés
|
||
|
||
**2. i18n kulcsok hozzáadása:** `frontend_admin/locales/hu.json`, `frontend_admin/locales/en.json`
|
||
- trend_title, trend_subtitle, trend_7d/14d/30d/90d
|
||
- trend_no_data, trend_daily, trend_avg, trend_total, trend_vs_prev
|
||
|
||
**3. Integrálás a users oldalba:** `frontend_admin/pages/users/index.vue`
|
||
- Import: `import UserTrendChart from '~/components/charts/UserTrendChart.vue'`
|
||
- Template: `<UserTrendChart :data="stats.registration_trend" :loading="loading" />`
|
||
- A stats kártyák és a filter bar közé helyezve
|
||
|
||
### ✅ Eredmény
|
||
- A backend `GET /admin/users/stats` endpoint már létezik és visszaadja a `registration_trend` adatokat
|
||
- A frontend build hibátlanul lefutott a `sf_admin_frontend` konténerben
|
||
- A komponens automatikusan használja a meglévő `stats.registration_trend` adatokat
|
||
|
||
## 2026-06-29 - EPIC-6 Task 6.1: i18n Fordítások Felvétele (hu/en) - User & Person Oldalak
|
||
|
||
### 🎯 Cél
|
||
i18n fordítások (hu/en) hozzáadása a frontend_admin user és person kezelő oldalakhoz a [`plans/logic_spec_admin_user_person_management.md`](plans/logic_spec_admin_user_person_management.md) specifikáció alapján (EPIC-6, task 6.1).
|
||
|
||
### 🔧 Módosított fájlok
|
||
- [`frontend_admin/locales/en.json`](frontend_admin/locales/en.json) - Teljes `users` szekció hozzáadva (users.* és users.details.* kulcsok); JSON szintaxis hiba javítva (hiányzó vessző a persons.details után)
|
||
- [`frontend_admin/locales/hu.json`](frontend_admin/locales/hu.json) - Teljes `users` szekció hozzáadva magyar fordításokkal; JSON szintaxis hiba javítva
|
||
|
||
### ✅ Eredmények
|
||
- **JSON validáció:** ✅ Sikeres (python3 json.load)
|
||
- **Nuxt build:** ✅ Sikeres (6.78s, AdminUsersView chunk: 19.93 kB)
|
||
- **Hiányzó kulcsok pótolva:** `users.title`, `users.subtitle`, `users.search_placeholder`, `users.*` (status, role, plan filterek), `users.details.*` (profil, subscription, személyes adatok, tagságok)
|
||
- **JSON hiba javítva:** Hiányzó vessző a `persons.details` objektum záró kapcsos zárójele után (224. sor) mindkét locale fájlban
|
||
|
||
## 2026-06-29 — RBAC Permission Check Implementation (Gitea #321)
|
||
|
||
### 🎯 Cél
|
||
Card #321: "6.2: RBAC permission check implementáció" — Minden admin user/person oldalnak ellenőriznie kell a DB-driven RBAC permissionöket a spec szerint.
|
||
|
||
### 🔧 Módosított fájlok
|
||
- [`frontend_admin/pages/users/index.vue`](frontend_admin/pages/users/index.vue) — `useAuthStore`/`useRouter` importok, `canViewUsers`/`canEditUsers`/`canBanUsers`/`canDeleteUsers` computed property-k, redirect guard `users:view` hiányában, `v-if="canEditUsers"` a bulk actions bar-on és toggle gombokon
|
||
- [`frontend_admin/pages/users/[id]/index.vue`](frontend_admin/pages/users/%5Bid%5D/index.vue) — `hasEditPermission` átírva legacy `'user:edit'`-ről (singular) `'users:edit'`-re (plural, spec szerint)
|
||
- [`frontend_admin/pages/persons/index.vue`](frontend_admin/pages/persons/index.vue) — `useAuthStore`/`useRouter` importok, `canViewPersons`/`canEditPersons`/`canMergePersons` computed property-k, redirect guard `persons:view` hiányában
|
||
- [`frontend_admin/pages/persons/[id]/index.vue`](frontend_admin/pages/persons/%5Bid%5D/index.vue) — `hasEditPermission` egyszerűsítve `!!` koercícióra
|
||
|
||
### ✅ Verifikáció
|
||
- **Nuxt build:** ✅ Sikeres (`docker compose exec sf_admin_frontend npm run build`)
|
||
- **Permission kódok:** `users:view`, `users:edit`, `users:ban`, `users:delete`, `persons:view`, `persons:edit`, `persons:merge` — mind implementálva a spec (5.8) szerint
|
||
- **Fallback:** Minden computed property `auth.isAdmin`-re esik vissza, ha nincs `system_capabilities`
|
||
|
||
## 2026-06-29 - Admin Users Filter Buttons Fix (#323)
|
||
|
||
### 🎯 Cél
|
||
Az admin felületen a felhasználók listájában nem működő szűrő gombok (státusz, szerepkör, csomag) javítása.
|
||
|
||
### 🔧 Módosított fájlok
|
||
- **`backend/app/api/v1/endpoints/admin.py`**:
|
||
- `plan_filter` query paraméter hozzáadása a `list_users()` végponthoz
|
||
- `plan_filter` szűrési logika: `User.subscription_plan == plan_filter.upper()`
|
||
- `person_name` mező hozzáadása a válaszhoz (last_name + first_name összefűzés)
|
||
- Case-insensitive role matching: `role.upper()` a `UserRole` enumhoz
|
||
|
||
- **`frontend_admin/pages/users/index.vue`**:
|
||
- `status_filter` → `is_active`/`is_deleted` boolean mapping (switch/case)
|
||
- `role_filter` → `role` paraméter átnevezés
|
||
- `plan_filter` paraméter megtartva (backend most már támogatja)
|
||
|
||
### ✅ Eredmények
|
||
- API szintaxis ellenőrzés: ✅ PASS
|
||
- API végpont tesztek (7 teszt): ✅ ALL PASS
|
||
- Basic list: 34 user, person_name megjelenik
|
||
- role=admin (lowercase): 2 admin (case-insensitive)
|
||
- role=user (lowercase): 30 user
|
||
- is_active=true: 16 aktív
|
||
- plan_filter=FREE: 28 FREE csomagos
|
||
- Combined (role=user, is_active=true, plan_filter=PREMIUM): 2 találat
|
||
- is_deleted=true: 1 törölt
|
||
|
||
## 2026-06-29 - Architect: Gamification Admin Integration Audit & Gitea Kártyák
|
||
|
||
### 🎯 Cél
|
||
A meglévő Gamification rendszer (backend modellek, service-ek, API végpontok) teljes körű auditálása, komplex specifikáció készítése az admin felületre történő bekötéshez, és 15 Gitea implementációs kártya létrehozása.
|
||
|
||
### 🔧 Elvégzett Munka
|
||
|
||
**1. GAMIFICATION RENDSZER AUDIT:** ✅
|
||
- Feltárt 10+ adatbázis tábla a `gamification` sémában (point_rules, level_configs, points_ledger, user_stats, badges, user_badges, user_contributions, seasons, seasonal_competitions, competitions, user_competition_scores)
|
||
- Azonosított hiányzó mezők: UserStats (services_submitted, total_points), PointsLedger (xp, source_type, source_id)
|
||
- Feltárt 14+ meglévő API végpont a `/gamification/*` útvonalon
|
||
- Feltárt hibás végpont: `PATCH /admin/users/{id}/penalty` direkt `level` módosítás a GamificationService helyett
|
||
- Feltárt 3 business logic probléma (szolgáltatáskikerülés, GamificationService bypass)
|
||
|
||
**2. KOMPLEX SPECIFIKÁCIÓ:** ✅
|
||
- Létrehozva: [`plans/logic_spec_gamification_admin_integration.md`](plans/logic_spec_gamification_admin_integration.md)
|
||
- 30+ új admin API endpoint terv az `admin_gamification.py` routerben
|
||
- 12 új frontend oldal terv a `frontend_admin/pages/gamification/` mappában
|
||
- Új Gamification menücsoport terv 6 menüponttal
|
||
- Adatbázis séma javítások (UserStats, PointsLedger)
|
||
- Business logic javítások (penalty endpoint, GamificationService bypass)
|
||
- RBAC: `gamification:manage` permission
|
||
- Adatfolyam diagram (Mermaid)
|
||
- 15 implementációs kártya prioritási sorrenddel és függőségekkel
|
||
|
||
**3. GITEA KÁRTYÁK LÉTREHOZÁSA:** ✅
|
||
15 kártya a `Epic 8 Gamification 2.0, Verseny és Önvéde` mérföldkő alatt:
|
||
|
||
| # | ID | Kártya Név | Scope |
|
||
|---|----|-----------|-------|
|
||
| 1 | #324 | Adatbázis: Gamification modell javítások (UserStats, PointsLedger) | Database |
|
||
| 2 | #325 | Backend: Új admin_gamification.py router (30+ admin végpont) | Backend |
|
||
| 3 | #326 | Backend: GamificationService refaktor (point_rules integráció) | Backend |
|
||
| 4 | #327 | Backend: Meglévő PATCH /admin/users/{id}/penalty endpoint javítása | Backend |
|
||
| 5 | #328 | Backend: gamification.py endpointok GamificationService-re átállítása | Backend |
|
||
| 6 | #329 | Frontend: Gamification menüpont + routing az admin Nuxt felületben | Frontend |
|
||
| 7 | #330 | Frontend: Gamification Dashboard oldal (/gamification/index.vue) | Frontend |
|
||
| 8 | #331 | Frontend: Pontszabályok + Szintek CRUD oldalak | Frontend |
|
||
| 9 | #332 | Frontend: Kitüntetések (Badge) kezelő oldal | Frontend |
|
||
| 10 | #333 | Frontend: Szezonok + Versenyek kezelő oldalak | Frontend |
|
||
| 11 | #334 | Frontend: Felhasználói statisztikák + büntetés/jutalom oldalak | Frontend |
|
||
| 12 | #335 | Frontend: Ranglista admin nézet (leaderboard.vue) | Frontend |
|
||
| 13 | #336 | Frontend: Master Config szerkesztő és Rendszerparaméterek oldalak | Frontend |
|
||
| 14 | #337 | Frontend: Pontnapló böngésző oldal (ledger.vue) | Frontend |
|
||
| 15 | #338 | Tesztelés: Gamification admin E2E tesztek | Backend+Frontend |
|
||
|
||
### 📂 Létrehozott fájlok
|
||
- [`plans/logic_spec_gamification_admin_integration.md`](plans/logic_spec_gamification_admin_integration.md) (373 sor)
|
||
|
||
### ⚠️ Feltárt kockázatok
|
||
1. UserStats modellből hiányzó mezők runtime hibát okozhatnak a meglévő gamification.py endpointokban
|
||
2. A PATCH /admin/users/{id}/penalty végpont a `gamification.level` nem létező mezőt módosítja
|
||
3. Több gamification.py végpont direktül módosít UserStats mezőket a GamificationService megkerülésével
|