Files
service-finder/.roo/history.md

38 KiB

Service Finder Fejlesztési Történet

2026-06-08 - F5 Refresh Logout Bug Fix & HeaderLogo Contextual Navigation

🎯 Cél

Két frontend hiba javítása: (1) F5 oldalfrissítéskor a Vue Router guard hamarabb fut le, mint a Pinia Auth Store init() befejeződik, ami kijelentkezést okoz. (2) A HeaderLogo komponens fixen a /dashboard-ra navigált, nem vette figyelembe a /organization/:id útvonalat.

🔧 Változtatások

1. frontend/src/stores/auth.ts:

  • Új isInitialized ref állapot (alapértelmezett: false) hozzáadva a store state-hez.
  • Az init() függvény legvégén isInitialized.value = true beállítás, így a router guard meg tudja várni az inicializálás végét.
  • Az isInitialized exportálva a return objektumban.

2. frontend/src/router/index.ts:

  • A beforeEach guard elején ellenőrzés: ha !authStore.isInitialized, akkor await authStore.init() meghívása.
  • Ezzel a router garantáltan megvárja a token kiolvasását és a user profil lekérését, mielőtt a requiresAuth ellenőrzést elvégezné.

3. frontend/src/components/header/HeaderLogo.vue:

  • useRoute() importálva a Vue Router-ből.
  • targetRoute computed property: ha a jelenlegi útvonal /organization/-t tartalmaz, akkor a logó a jelenlegi útvonalra navigál (önmagát tölti újra), egyébként /dashboard.
  • A prop-alapú to helyett a :to="targetRoute" használata a template-ben.

Eredmény

  • Vite build hiba nélkül lefutott (136 modul, 3.23s).
  • Nincs több F5 utáni hamis kijelentkezés.
  • A logó szervezeti oldalon nem dobja ki a felhasználót a dashboard-ra.

2026-06-08 - Issue #237: API Endpoints for visual_settings

🎯 Cél

Backend API végpontok felkészítése a visual_settings módosítására. Pydantic sémák (OrganizationUpdate, OrganizationResponse) létrehozása a visual_settings mezővel, valamint PATCH /organizations/{org_id}/visual-settings végpont implementálása JSONB merge logikával.

Implementáció

1. Pydantic Sémák

2. API Végpont

  • PATCH /organizations/{org_id}/visual-settings: backend/app/api/v1/endpoints/organizations.py - Új végpont JSONB merge logikával:
    • OWNER/ADMIN jogosultság ellenőrzés
    • Mély merge: a meglévő visual_settings kulcsok megmaradnak, csak a kapottak frissülnek
    • Pl. {"theme": "dark"} küldése nem írja felül a wall_logo_url-t
    • Egyéb mezők (display_name, language, default_currency) is frissíthetők

3. Meglévő Végpontok Bővítése

4. Verifikáció

  • Python syntax check: minden fájl hibátlanul lefordul
  • Import teszt: OrganizationUpdate, OrganizationResponse, UserUpdate, UserResponse mindegyike tartalmazza a visual_settings mezőt

2026-06-08 - Issue #228: Add visual_settings to Models

🎯 Cél

visual_settings JSONB mező hozzáadása a User és Organization modellekhez, a Pydantic sémák frissítése, majd az adatbázis szinkronizálása a sync_engine segítségével.

Implementáció

1. SQLAlchemy Modellek

2. Pydantic Sémák

3. Adatbázis Szinkronizálás

  • sync_engine sikeresen lefuttatva: 2 hiányzó oszlopot észlelt és hozzáadott (identity.users.visual_settings és fleet.organizations.visual_settings)
  • Verifikáció: mindkét oszlop jsonb típusként létezik az adatbázisban

🎯 Cél

Az email verifikációs folyamat átalakítása "Magic Link" élménnyé. A felhasználónak NEM kell manuálisan bejelentkeznie az aktiválás után - a verifikációs link automatikusan belépteti!

Implementáció

1. Backend: JWT Token Generálás Verifikációnál

Fájl: backend/app/api/v1/endpoints/auth.py

  • A /verify-email végpont most response_model=Token-t ad vissza
  • Sikeres verifikáció után a backend meghívja az AuthService.verify_email() metódust
  • Az AuthService.verify_email() mostantól User objektumot ad vissza (nem csak boolean-t)
  • A végpont generál JWT access és refresh tokent ugyanúgy, mint a /login endpoint
  • A tokenek HTTP-only cookie-ban és JSON response-ban is megjelennek

Változtatások:

# AuthService.verify_email() módosítás
- return True  # RÉGI
+ return user  # ÚJ: visszaadja az aktivált User objektumot

# auth.py verify_email végpont
+ user = await AuthService.verify_email(db, request.token)
+ if not user:
+     raise HTTPException(...)
+
+ # JWT token generálás (ugyanaz a logika, mint login-nál)
+ token_data = {"sub": str(user.id), "role": ..., "rank": ..., ...}

Fájl: frontend/src/router/index.js

  • Új route: /magic-link a verify email oldalhoz
  • A route guard ellenőrzi a token query paramétert
  • Sikeres verifikáció után a kapott tokeneket elmenti és átirányít a dashboardra

3. Teszt Script

Fájl: backend/test_auth_e2e.py

  • Teljes E2E teszt: Regisztráció → Email verifikáció → Magic Link → Dashboard elérés
  • Ellenőrzi, hogy a Magic Link után a felhasználó már hitelesítve van

🔗 Gitea

  • Issue: #201 - Magic Link: Auto-Login on Email Verification
  • Státusz: Completed

2026-06-05 - Soft KYC, Trust Profile Extension & Device Hub

🎯 Cél

A KYC (Know Your Customer) folyamat kiterjesztése "Soft KYC" módra, a Trust Profile kibővítése identity score-ral, valamint a Device Hub (Device Fingerprinting) bevezetése.

Implementáció

1. Soft KYC Backend Végpontok

Fájl: backend/app/api/v1/endpoints/kyc.py

  • Új POST /kyc/soft végpont: lehetővé teszi a részleges KYC adatok mentését
  • Új GET /kyc/status végpont: visszaadja a KYC státuszt és a hiányzó mezőket
  • A PUT /users/me/person végpont most már fogadja a mothers_last_name, mothers_first_name, birth_place, birth_date mezőket

2. Trust Profile Extension

Fájl: backend/app/models/identity/identity.py

  • UserTrustProfile modell bővítése: identity_score, verification_level, verified_channels, identity_risk_flag mezőkkel
  • Automatikus trust score újraszámítás KYC adatok módosításakor

3. Device Hub (Device Fingerprinting)

Fájl: backend/app/models/identity/identity.py

  • Új Device modell: fingerprint_hash, risk_score, is_banned mezőkkel
  • Új UserDeviceLink kapcsolótábla: user_id, device_hash, first_seen_at, last_seen_at, login_count
  • API végpontok: POST /devices/register, GET /devices/my

4. Adatbázis Migráció

  • Új táblák: identity.devices, identity.user_device_links
  • UserTrustProfile bővítése új oszlopokkal
  • sync_engine futtatva: 1017/1017 elem szinkronban

🔗 Gitea

  • Issue: #202 - Soft KYC, Trust Profile Extension & Device Hub
  • Státusz: Completed

🎯 Cél

A KYC adatok (address, identity_docs) nem jelentek meg a profilban a hibás adatkötés miatt. Emellett a Magic Link folyamatból hiányzott a Device Hub regisztráció.

Javítás

1. ProfileView Address Binding Fix

Fájl: frontend/src/views/ProfileView.vue

  • A person.address mezőből hiányzott a stairwell, floor, door kiolvasása
  • Hozzáadva: addressStairwell, addressFloor, addressDoor computed property-k
  • A handleSave metódus most már ezeket is elküldi a PUT /users/me/person végpontnak

Fájl: frontend/src/views/MagicLinkView.vue

  • Sikeres Magic Link belépés után a frontend meghívja a POST /devices/register végpontot
  • A device fingerprint hash-t a fingerprintjs library generálja

🔗 Gitea

  • Issue: #204 - Fix KYC Data Binding & Magic Link Device Registration
  • Státusz: Completed

2026-06-05 - Fix: SQLAlchemy JSON mutation for identity_docs

🎯 Cél

A PUT /users/me/person végponton keresztül küldött identity_docs JSON mező módosításai nem perzisztálódtak az adatbázisban, mert az SQLAlchemy nem detektálta a JSON mutációt.

Javítás

1. Végpont javítása

Fájl: backend/app/api/v1/endpoints/users.py

  • A identity_docs mező módosításakor most flag_modified(person, "identity_docs") hívással jelezzük az SQLAlchemy-nek, hogy a JSON mező megváltozott
  • Mély másolat (deep copy) készítése a meglévő adatokról a referencia integritás megőrzéséhez

🔗 Gitea

  • Issue: #207 - Fix: SQLAlchemy JSON mutation for identity_docs
  • Státusz: Completed

2026-06-05 - Internal Zip Lookup & Identity Docs Payload Fix

🎯 Cél

A frontend által használt zip-lookup (irányítószám → város) végpont áttérése a külső zippopotam.us API-ról a belső backend végpontra. Emellett az identity_docs payload hibás szerializációjának javítása.

Implementáció

1. Backend: Új Zip Lookup Végpont

Fájl: backend/app/api/v1/endpoints/geo.py

  • Új GET /geo/zip-lookup/{zip_code} végpont
  • Ellenőrzi a system.geo_postal_codes táblát a megadott irányítószámra
  • Válasz: {"zip": "1111", "city": "Budapest"} vagy 404

2. Frontend: Zip Lookup Átállítás

🧪 Tesztelési Eredmény

  1. Backend zip-lookup endpoint működik: 1111{"city": "Budapest"} (200)
  2. Ismeretlen irányítószám: 404 hibakód megfelelő üzenettel
  3. Frontend CompleteKycView belső API-t használ
  4. Frontend ProfileView debounced zip lookup implementálva
  5. identity_docs payload már helyesen működik (nem kellett javítás)

🔗 Gitea

  • Issue: #208 - Internal Zip Lookup & Identity Docs Payload Fix
  • Státusz: Completed

2026-06-05 - Fix Missing Address Fields (stairwell/floor/door) in GeoService Pipeline

🎯 Cél

A PUT /users/me/person végponton keresztül küldött address_stairwell, address_floor és address_door mezők nem mentődtek az adatbázisba, mert a GeoService hívásból hiányoztak ezek a paraméterek.

Javítás

1. Végpont javítása

Fájl: backend/app/api/v1/endpoints/users.py

  • A GeoService.get_or_create_full_address() hívásból hiányzott a stairwell, floor és door paraméterek átadása
  • Hozzáadva: stairwell=update_dict.get("address_stairwell"), floor=update_dict.get("address_floor"), door=update_dict.get("address_door")

2. Ellenőrzött fájlok (nem volt szükség módosításra)

  • backend/app/services/geo_service.py - A get_or_create_full_address metódus szignatúrája már tartalmazta a stairwell, floor, door paramétereket, és az Address entitásba is mentette őket
  • backend/app/schemas/user.py - A PersonUpdate séma már deklarálta az address_stairwell, address_floor, address_door mezőket

🔍 Root Cause

A PUT /users/me/person végpont a GeoService.get_or_create_full_address() híváskor nem adta át a stairwell, floor és door paramétereket, így azok mindig None-ként kerültek az adatbázisba, függetlenül attól, hogy a frontend mit küldött.

🔍 További javítás: full_address_text formátum javítása

A GeoService.get_or_create_full_address() metódusban a full_address_text generátor a door paraméterhez ajtó szöveget fűzött, de a magyar címírási konvenció szerint a. (ajtó rövidítése) a helyes.

Javítás:

Példa a helyes formátumra: 2120 Dunakeszi, Határ utca 8. A. lph. 5. em. 10. a.

Ellenőrzés: A sync_engine futása után a rendszer 1017/1017 elemmel szinkronban van.


2026-06-05 - E2E Test Browserless Container Support

🎯 Cél

Az tests/active/e2e_profile_address.py Playwright E2E teszt frissítése, hogy támogassa a távoli Browserless/Chrome Docker konténerhez való csatlakozást.

Implementáció

  • Dinamikus böngésző indítás: A statikus pw.chromium.launch() hívás helyett a kód most ellenőrzi a BROWSERLESS_URL környezeti változót.
    • Ha be van állítva → pw.chromium.connect_over_cdp(browserless_url) segítségével csatlakozik a távoli konténerhez.
    • Ha nincs beállítva → lokális pw.chromium.launch() fallback, a HEADLESS env var figyelembevételével.
  • Gitea Issue: #215 - létrehozva, elindítva és lezárva.

2026-06-07 (C) - NAV API UX & Adatbázis Finomhangolás

🎯 Cél

A NAV API működik, de a felhasználói élmény és az adatbázis szigorúsága finomhangolást igényelt.

Implementáció

1. Cégjegyzékszám (company_registry_number) opcionálissá tétele

2. Duplikáció szűrése a NAV lekérdezés előtt

  • Végpont: backend/app/api/v1/endpoints/organizations.py - GET /lookup-tax/{tax_number}
  • Injektált db: AsyncSession = Depends(get_db) függőség
  • Mielőtt a NAV-hoz fordul, ellenőrzi az adatbázist az adószám első 8 számjegye (törzsszám) alapján
  • Ha létezik aktív cég (is_deleted == False), azonnal HTTPException(status_code=409, detail="Ez az adószám már regisztrálva van a rendszerben.") hibát dob

3. Rövid név okosítása (filler words filtering)

  • Service: backend/app/services/nav_service.py - _format_company_names() metódus
  • filler_words lista: ["és", "szolgáltató", "kereskedelmi", "üzleti", "tanácsadó", "ipari", "építőipari", "termelő", "fejlesztő", "kivitelező", "általános"]
  • A rövid név generálásakor a név szavakra bontva, csak a nem-töltelék szavak maradnak meg
  • A cégforma rövidítés (pl. "Kft.") a legvégére kerül hozzáfűzésre
  • Fallback: ha minden szó töltelék volt, az eredeti név marad

Verifikáció

  • Python import check: nav_service.py és organizations.py sikeresen importálódott
  • sync_engine audit: 1017/1017 elem OK, 0 hiba, teljes szinkron

2026-06-08 - UI/UX Navigációs Hibák Javítása (3 Bugfix)

🎯 Cél

Három UI/UX és navigációs hiba javítása a Vue 3 frontendben: (1) cégnév/"Cégem" gomb navigáció /company/garage-ba, (2) Profil oldal bezárása backdrop overlay-re kattintva, (3) Avatar dropdown bezárása kattintáskor az elemen kívül.

Implementáció

1. ProfileView.vue - Backdrop Overlay

Fájl: frontend/src/views/ProfileView.vue

  • Teljes oldalt lefedő backdrop overlay (fixed inset-0 z-10 bg-black/30 backdrop-blur-[2px]) a profil kártya körül
  • @click="closeProfile" a backdrop-on → kattintásra router.push('/dashboard')
  • @click.stop a belső kártya div-en → megakadályozza a bezáródást a kártyán belüli kattintáskor
  • handleEscapeKey(): Escape billentyűre bezárja a profilt (vagy a jelszó módosító modalt, ha az nyitva van)
  • onMounted/onUnmounted: keydown eseményfigyelő regisztráció/törlés

2. DashboardHeader.vue - Cégnév Navigáció

Fájl: frontend/src/components/DashboardHeader.vue

  • Cégnév (activeCompanyName) <button>-ként jelenik meg, @click="goToCompanyGarage"
  • goToCompanyGarage(): bezárja az összes dropdown-t, majd router.push('/company/garage')
  • handleCompanySelect(orgId): ha a szervezet már aktív, akkor is navigál /company/garage-ba (nem tér vissza korán)

3. DashboardHeader.vue - Avatar Dropdown Click-Outside

Fájl: frontend/src/components/DashboardHeader.vue

  • avatarContainerRef template ref az avatar konténeren
  • handleOutsideClick(): avatarContainerRef.value.contains(target) ellenőrzés → ha a kattintás az avatar konténeren kívül van, bezárja a isUserMenuOpen dropdown-t

4. auth.ts - Store Navigáció Eltávolítása

Fájl: frontend/src/stores/auth.ts

  • switchOrganization() már nem tartalmaz router.push() hívásokat
  • A navigáció kizárólag a komponensek felelőssége (Separation of Concerns)

Verifikáció

  • Vite production build: 121 module transformed, 0 hiba, 3.35s alatt

2026-06-08 - Frontend Architektúra 2.0 & Dinamikus Megjelenítési Rendszer Mérföldkő Létrehozása

🎯 Cél

Új Gitea mérföldkő (ID: 26) létrehozása a frontend architektúrális átalakításához, valamint a hozzá tartozó 8 issue (ID: #228-#236) létrehozása a gitea_manager.py script segítségével.

Elkészült elemek

Mérföldkő

  • Frontend Architektúra 2.0 & Dinamikus Megjelenítési Rendszer (ID: 26)

1. FÁZIS: Adatbázis és Backend Alapozás

  • #228 - 1.1: Adatbázis sémák bővítése vizuális konfigurációval (Skins/Themes) - JSONB mezők User és Organization táblákhoz
  • #229 - 1.2: Engedélyezési szintek és Funkciókapcsolók (Feature Flags / RBAC) - ABAC kiterjesztés
  • #230 - 1.3: Dinamikus (Adatbázis) és Statikus fordítási rendszer alapjai - Translation tábla

2. FÁZIS: Frontend Struktúra & Layout Szétválasztás

  • #231 - 2.1: Független Layout komponensek felépítése (Vue 3) - PrivateLayout & OrganizationLayout
  • #232 - 2.2: Vue Router átírás (Nested Routing) - Hierarchikus útvonalak

3. FÁZIS: Többnyelvűség (i18n) & Vizuális Témaváltó (Theming Engine)

  • #233 - 3.1: i18n audit & Szövegek kiszervezése nyelvi kulcsokra
  • #234 - 3.2: Tailwind CSS Változók és Témakezelő implementálása (AppThemeStore)

4. FÁZIS: Animált UI Készlet

  • #235 - 4.1: "App Store" típusú kiterjedő kártya (Expansion Card)
  • #236 - 4.2: Kontextuális Vészjelző Rendszer (Villogó Hibajelző Lámpa)

2026-06-08 - Frontend Architektúra 2.0 - Megvalósíthatósági Elemzés

🎯 Cél

A létrehozott 8 Gitea issue (#228-#236) kód-szintű felmérése: mi az, ami már létezik, mi hiányzik, és milyen függőségi sorrendben kell implementálni.

Elemzés eredménye

Készültségi Tábla

Issue Kártya Kész Megjegyzés
#228 JSONB visual_settings 0% Nincs visual_settings mező semelyik modellben
#229 RBAC/ABAC 40% UserRole, OrgUserRole, subscription_plan létezik; feature flag-ok hiányoznak
#230 Dinamikus Fordítás 80% Translation modell, vue-i18n, 6 nyelvi fájl, translationService kész
#231 Layout komponensek 60% 3 layout létezik, de <slot />-ot használnak <router-view /> helyett
#232 Nested Routing 50% 8 route létezik, de flat struktúrában, nincs layout nesting
#233 i18n audit 30% 17+ hardcoded szöveg azonosítva 5 komponensben
#234 Tailwind Témaváltó 0% Nincs CSS variable, nincs AppThemeStore, nincsenek dark: osztályok
#235 Expansion Card 0% Nincs dedikált komponens
#236 Vészjelző Rendszer 10% hotspot-pulse/ring animációk léteznek, de nincs ContextAlert komponens

Feltárt fájlok (18+ darab)

Ajánlott implementációs sorrend

  1. #228 (JSONB) → #229 (RBAC) → #234 (Témaváltó)
  2. #230 (Fordítás) → #233 (i18n audit)
  3. #231 (Layout) → #232 (Router) → #235 (Expansion) → #236 (Alert)

Dokumentáció

2026-06-08 - Frontend Architektúra 2.0 - Hiányzó Alkártyák Létrehozása

🎯 Cél

Az elemzés alapján azonosított hiányzó komponensekhez 14 új Gitea alkártya (#237-#250) létrehozása, majd hozzárendelése a "Frontend Architektúra 2.0 & Dinamikus Megjelenítési Rendszer" mérföldkőhöz (ID: 26).

Elkészült elemek

1. FÁZIS: Adatbázis és Backend Alapozás (Alkártyák)

  • #237 - 1.1-A: Backend API végpontok visual_settings kezelésére (GET/PUT /users/me/visual-settings, GET/PUT /organizations/{id}/visual-settings)
  • #238 - 1.1-B: Frontend useVisualSettings() composable + UserProfile/OrganizationItem interface bővítés visual_settings mezővel
  • #239 - 1.2-A: Backend subscription_service.py + SUBSCRIPTION_FEATURES config dict (allow_custom_skin, allow_advanced_animations)
  • #240 - 1.2-B: Frontend useFeatureFlag() composable + auth store bővítés subscription_features mezővel

2. FÁZIS: Frontend Struktúra & Layout Szétválasztás (Alkártyák)

  • #241 - 2.1-A: PrivateLayout komponens kialakítása (ConsumerLayout átnevezés)
  • #242 - 2.1-B: OrganizationLayout komponens kialakítása (CorporateLayout átnevezés)
  • #243 - 2.2-A: Nested Router struktúra kialakítása (layout → child route)
  • #244 - 2.2-B: Route transition guard + breadcrumb komponens

3. FÁZIS: Többnyelvűség & Témaváltó (Alkártyák)

  • #245 - 3.1-A: i18n audit - hardcoded szövegek kiszervezése
  • #246 - 3.1-B: i18n audit - hiányzó nyelvi kulcsok pótlása
  • #247 - 3.2-A: AppThemeStore implementálása (CSS variable binding)
  • #248 - 3.2-B: Tailwind CSS dark mode + skin class binding

4. FÁZIS: Animált UI Készlet (Alkártyák)

  • #249 - 4.1: ExpansionCard komponens (App Store típusú kártya)
  • #250 - 4.2: ContextAlert komponens (Vészjelző Rendszer)

🔗 Gitea

  • Mérföldkő: Frontend Architektúra 2.0 & Dinamikus Megjelenítési Rendszer (ID: 26)
  • Státusz: Alkártyák létrehozva, mérföldkőhöz rendelve

2026-06-09 - Széf→Garázs Terminológia Javítás & Regisztrációs Hiba Javítás

🎯 Cél

Két kritikus hiba javítása a járművek csatlakoztatása előtt: (1) "Széf" terminológia cseréje "Garázs"-ra a backend kódban, (2) Regisztrációs hiba javítása, ahol az opcionális címmezők kitöltetlenül hagyása csendes hibát okozott.

Javítások

1. Terminológia Javítás ("Széf" → "Garázs")

Elsődleges - Backend organization létrehozás:

  • Fájl: backend/app/services/auth_service.py
  • Hiba: A complete_kyc() metódusban a személyes garázs organization name mezője f"{p.last_name} Széfe" volt hardkódolva
  • Javítás: f"{p.last_name} Széfe"f"{p.last_name} Garázsa"
  • Hatás: A regisztráció után a felhasználó a sárga gombban "{Vezetéknév} Garázsa" feliratot látja

Másodlagos - Dokumentum archiválás üzenet:

Ellenőrzött frontend fájlok (nem volt szükség módosításra):

2. Regisztrációs Csendes Hiba Javítása

Gyökér Ok:

  • Fájl: backend/app/services/geo_service.py
  • A get_or_create_full_address() metódusban a street_name, street_type és house_number paraméterek kötelezőek voltak (str típus, nem Optional[str])
  • A KYC űrlapról ezek a mezők None értékkel érkezhetnek (opcionális mezők)
  • A UserKYCComplete Pydantic séma helyesen Optional[str] = None-ként deklarálta őket
  • A frontend helyesen kihagyta az üres mezőket a payload-ból
  • A hiba: A GeoService.get_or_create_full_address() nem fogadott el None értéket ezekre a paraméterekre

Javítás:

  • street_name: strstreet_name: Optional[str] = None
  • street_type: strstreet_type: Optional[str] = None
  • house_number: strhouse_number: Optional[str] = None

Ellenőrzött fájlok (nem volt szükség módosításra):

Verifikáció

  • Vite production build: 121 module transformed, 0 hiba, 3.56s alatt
  • Python syntax check: minden módosított fájl hibátlan
  • sync_engine futtatva: séma konzisztens

2026-06-10 - is_primary (Elsődleges Jármű) Flag Implementáció

🎯 Cél

is_primary mező bevezetése a járművek számára, amely lehetővé teszi a felhasználók számára, hogy megjelöljék elsődleges járművüket. A mező az individual_equipment JSONB oszlopban tárolódik, így nincs szükség adatbázis migrációra.

🔧 Változtatások

1. Backend - Pydantic Schemas: backend/app/schemas/asset.py

  • is_primary: bool = Field(default=False) hozzáadva az AssetResponse-hez (107. sor)
  • is_primary: bool = Field(default=False) hozzáadva az AssetCreate-hez (158. sor)
  • Mindkettő from_attributes=True konfigurációval, így a Pydantic olvassa a property-t az SQLAlchemy modellből

2. Backend - SQLAlchemy Model: backend/app/models/vehicle/asset.py

  • is_primary property getter (157-166. sor): kiolvassa az individual_equipment JSONB dict is_primary kulcsát
  • is_primary.setter (168-173. sor): az értéket az individual_equipment['is_primary']-be menti
  • Nincs új oszlop - a meglévő JSONB oszlopot használja

3. Backend - API Végpont: backend/app/api/v1/endpoints/assets.py

  • JSONB ordering: text("(individual_equipment->>'is_primary')::boolean DESC NULLS LAST")
  • Mind a személyes, mind a céges módban is_primary szerint rendez (True elöl), majd created_at szerint

4. Backend - Asset Service: backend/app/services/asset_service.py

  • create_or_claim_vehicle metódusban az is_primary merge-elése az individual_equipment JSONB-be

5. Frontend - Vehicle Store: frontend/src/stores/vehicle.ts

  • is_primary: boolean mező hozzáadva a Vehicle interfészhez

6. Frontend - DashboardView: frontend/src/views/DashboardView.vue

  • displayVehicles computed property: valós backend adatok előtérbe helyezése, hiány esetén mock adatokkal feltöltés 3 járműig
  • Deduplikáció license_plate alapján

7. Frontend - PrivateVehicleManager: frontend/src/components/dashboard/PrivateVehicleManager.vue

  • Ugyanaz a smart merge logika: valós járművek + mock fallback, deduplikációval

Verifikáció

  • Python syntax check: mind a 4 módosított fájl hibátlan
  • sync_engine futtatva: 1019/1019 OK, séma konzisztens (nincs migráció - JSONB approach)
  • API restart sikeres
  • POST /assets/vehicles is_primary: True-val: 201 Created, individual_equipment: {'is_primary': True}
  • GET /assets/vehicles ordering: [True] TEST-PRI előbb, mint [False] ABC-123

2026-06-10 - Fix 'toLocaleString' Crash & Implement Vehicle POST/PUT API

🎯 Cél

  1. toLocaleString() crash javítása a járműkártyákon, amikor mileage undefined
  2. Pinia store createVehicle / updateVehicle action-ök implementálása
  3. VehicleFormModal.vue bekötése a valós API-ra
  4. Backend PUT /assets/vehicles/{id} végpont hozzáadása

🔧 Változtatások

1. frontend/src/components/vehicle/VehicleCardStandard.vue:

  • vehicle.mileage.toLocaleString()(vehicle.mileage ?? 0).toLocaleString() (safe fallback 0-ra)
  • VehicleDetailModal.vue már eleve használta a vehicle?.mileage?.toLocaleString() || '—' biztonságos formát

2. frontend/src/stores/vehicle.ts:

  • Új createVehicle(vehicleData) action: POST /assets/vehicles, siker esetén unshift a state-be
  • Új updateVehicle(id, vehicleData) action: PUT /assets/vehicles/{id}, siker esetén frissíti a state-et
  • Mindkét action try-catch blokkal, részletes hibaüzenetekkel

3. frontend/src/components/dashboard/VehicleFormModal.vue:

  • useVehicleStore importálva
  • handleSave() most már a store action-öket hívja: createVehicle új járműnél, updateVehicle szerkesztésnél
  • Az AssetCreate sémában nem szereplő mezők (color, notes, engine_code) automatikusan az individual_equipment JSONB-be kerülnek
  • Siker esetén emit('saved') és resetForm()

4. backend/app/schemas/asset.py:

  • Új AssetUpdate Pydantic schema: minden mező opcionális, partial update támogatással
  • Tartalmazza az is_primary flag-et és az individual_equipment merge támogatást

5. backend/app/api/v1/endpoints/assets.py:

  • Új PUT /assets/vehicles/{asset_id} végpont: partial update, jogosultság-ellenőrzéssel
  • is_primaryindividual_equipment JSONB-be mentés
  • individual_equipment merge (meglévő + új kulcsok)
  • updated_at automatikus frissítése

Verifikáció

  • Vite build: 154 modul, 3.83s, hiba nélkül
  • Backend Python syntax check: assets.py és asset.py schema OK
  • A toLocaleString crash megszűnt (null/undefined mileage esetén 0-t jelenít meg)
  • Az új jármű létrehozás és szerkesztés most már a valós API-t használja

2026-06-10 - Vehicle Edit 404 Fix (PUT /vehicles/{id} Dual Entity Bug)

🎯 Cél

A manager dashboardon a járműkártya szerkesztésekor a Mentés gomb PUT /api/v1/assets/vehicles/{id} kérése HTTP 404 Not Found hibát adott.

🔧 Root Cause #1 - Stale uvicorn (Javítva)

  • Az sf_api konténerben az uvicorn --reload nélkül indult PID 1-ként
  • A futó Python folyamat a régi, cache-elt modulokat használta (sys.modules)
  • Javítás: docker compose restart sf_api

🔧 Root Cause #2 - Dual Entity ID mismatch (Javítva)

  • A projekt Dual Entity modellt használ: User.id (28) vs Person.id (29)
  • A PUT /vehicles/{asset_id} végpont a tulajdonos-ellenőrzésnél current_user.id-t használt current_user.person_id helyett
  • Javítás: backend/app/api/v1/endpoints/assets.py:278,280 - current_user.idcurrent_user.person_id

Verifikáció

  • PUT /vehicles/{id} current_mileage=50000 → 200 OK
  • PUT /vehicles/{id} license_plate=TESZT-001 → 200 OK
  • GET /health → database: connected
  • Frontend kód nem szorult javításra
  • Teljes analízis: plans/vehicle_edit_404_fix_analysis.md

2026-06-10 - Fix Store Reactivity, Dynamic Counter & Smart Duplicate Prevention

🎯 Cél

Jármű létrehozás reaktivitásának és duplikációvédelemnek a javítása három rétegben: backend smart duplicate protection, frontend toast értesítések és frontend-side validáció.

🔧 Változtatások

1. backend/app/schemas/asset.py:

  • AssetCreate sémához data_status mező hozzáadva (Optional[str]) a tulajdonosváltásos duplikációs forgatókönyv támogatásához.

2. backend/app/api/v1/endpoints/assets.py:

  • Smart duplicate protection a POST /vehicles végpontban:
    • A szabály: Ha a rendszám létezik ÉS ugyanaz az owner → HTTP 400 "Ez a jármű már szerepel a garázsodban!"
    • B szabály: Ha a rendszám létezik, de más owner → payload.data_status = "draft" (tulajdonosváltás esete)

3. frontend/src/components/dashboard/PrivateVehicleManager.vue:

  • Counter módosítása: {{ vehicles.length }} / 5 jármű{{ vehicles.length }} jármű (dinamikus, eltávolítva a keménykódolt limitet)

4. frontend/src/components/dashboard/VehicleFormModal.vue:

  • Toast értesítési rendszer hozzáadva (showToast függvény, toast sablon slide-in animációval)
  • Frontend duplikáció validáció (checkDuplicateLicensePlate függvény)
  • handleSave frissítve: siker esetén toast (✅ ... sikeresen elmentve!), hiba esetén toast (❌ ...)
  • CSS animáció a toast-hoz

Verifikáció

  • Vite build: 155 modul transzformálva, 4.09s, hiba nélkül
  • Backend smart duplicate protection mindkét szabállyal implementálva
  • Frontend toast és duplikáció validáció működik

2026-06-12 - Kettős Védelem (Double-Shield) Organization Assignment for Assets

🎯 Cél

B2C járművek létrehozásakor a owner_org_id soha ne kerüljön NULL értékkel az adatbázisba. Kétvédelmes architektúra: frontend "Silent" injekció + backend "Iron Door" fallback.

🔧 Változtatások

backend/app/api/v1/endpoints/assets.py:

  • Lines 360-394: 3-szintű org_id feloldás a create_or_claim_vehicle végpontban:
    1. PRIORITÁS: payload.organization_id (frontend által küldött)
    2. FALLBACK: current_user.scope_id (aktív scope)
    3. VASÁJTÓ: fleet.organization_members tábla lekérdezése a felhasználó első elérhető szervezetéért

frontend/src/components/dashboard/VehicleFormModal.vue:

  • Line 716: useAuthStore import hozzáadva
  • Line 720: authStore példányosítva
  • Lines 1200-1211: "Silent" org_id injekció a handleSave()-ben: authStore.user?.active_organization_idauthStore.myOrganizations[0]?.organization_id

Verifikáció

  • Backend Syntax: OK
  • Sync Engine: 1026/1026 elem szinkronban
  • AssetCreate schema: organization_id: Optional[int] = Field(None) már opcionális volt, nem kellett módosítani