620 lines
36 KiB
Markdown
620 lines
36 KiB
Markdown
# 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
|
|
- **`OrganizationUpdate`**: [`backend/app/schemas/organization.py`](backend/app/schemas/organization.py:40) - Új séma `visual_settings: Optional[dict]`, `display_name`, `default_currency`, `language` mezőkkel
|
|
- **`OrganizationResponse`**: [`backend/app/schemas/organization.py`](backend/app/schemas/organization.py:49) - Új DTO séma `visual_settings: Optional[dict]` mezővel, `from_attributes=True` konfigurációval
|
|
|
|
#### 2. API Végpont
|
|
- **`PATCH /organizations/{org_id}/visual-settings`**: [`backend/app/api/v1/endpoints/organizations.py`](backend/app/api/v1/endpoints/organizations.py:207) - Ú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
|
|
- **`GET /organizations/my`**: [`backend/app/api/v1/endpoints/organizations.py`](backend/app/api/v1/endpoints/organizations.py:203) - `visual_settings` mező hozzáadva a response-hoz
|
|
- **`PATCH /users/me/preferences`**: [`backend/app/api/v1/endpoints/users.py`](backend/app/api/v1/endpoints/users.py:333) - Már támogatja a `visual_settings`-et a generikus `exclude_unset=True` logikával
|
|
|
|
#### 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
|
|
- **User modell**: [`backend/app/models/identity/identity.py`](backend/app/models/identity/identity.py:157) - `visual_settings` JSONB oszlop hozzáadva a `ui_mode` után, `server_default` JSONB default értékkel (`{"theme": "default", "primary_color": null, "wall_logo_url": null}`)
|
|
- **Organization modell**: [`backend/app/models/marketplace/organization.py`](backend/app/models/marketplace/organization.py:109) - `visual_settings` JSONB oszlop hozzáadva az `external_integration_config` után, azonos default értékkel
|
|
|
|
#### 2. Pydantic Sémák
|
|
- **UserResponse**: [`backend/app/schemas/user.py`](backend/app/schemas/user.py:62) - `visual_settings: Optional[dict]` mező hozzáadva default értékkel
|
|
- **UserUpdate**: [`backend/app/schemas/user.py`](backend/app/schemas/user.py:107) - `visual_settings: Optional[dict]` mező hozzáadva
|
|
|
|
#### 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
|
|
|
|
|
|
## 2026-06-04 (B) - Magic Link Implementáció (Auto-Login Email Verification)
|
|
|
|
### 🎯 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`](backend/app/api/v1/endpoints/auth.py:93)
|
|
- 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()`](backend/app/services/auth_service.py:316) 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**:
|
|
```python
|
|
# 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": ..., ...}
|
|
```
|
|
|
|
#### 2. Frontend Magic Link Handler
|
|
**Fájl**: [`frontend/src/router/index.js`](frontend/src/router/index.js:1)
|
|
- Ú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`](backend/test_auth_e2e.py:1)
|
|
- 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`](backend/app/api/v1/endpoints/kyc.py:1)
|
|
- Ú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`](backend/app/models/identity/identity.py:271)
|
|
- `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`](backend/app/models/identity/identity.py:302)
|
|
- Ú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
|
|
|
|
---
|
|
|
|
## 2026-06-05 - Fix KYC Data Binding & Magic Link Device Registration
|
|
|
|
### 🎯 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`](frontend/src/views/ProfileView.vue:1)
|
|
- 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
|
|
|
|
#### 2. Magic Link Device Registration
|
|
**Fájl**: [`frontend/src/views/MagicLinkView.vue`](frontend/src/views/MagicLinkView.vue:1)
|
|
- 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`](backend/app/api/v1/endpoints/users.py:223)
|
|
- 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`](backend/app/api/v1/endpoints/geo.py:1)
|
|
- Ú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
|
|
- [`frontend/src/views/CompleteKycView.vue`](frontend/src/views/CompleteKycView.vue:1) - zippopotam.us → internal API
|
|
- [`frontend/src/views/ProfileView.vue`](frontend/src/views/ProfileView.vue:1) - Debounced zip lookup watcher
|
|
|
|
### 🧪 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`](backend/app/api/v1/endpoints/users.py:238)
|
|
- 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`](backend/app/services/geo_service.py:46) - 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`](backend/app/schemas/user.py:87) - 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**:
|
|
- [`backend/app/services/geo_service.py`](backend/app/services/geo_service.py:136) - `{door}. ajtó` → `{door}. a.`
|
|
|
|
**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`](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
|
|
- **Modell**: [`backend/app/models/marketplace/organization.py`](backend/app/models/marketplace/organization.py:89) - `reg_number: Mapped[Optional[str]]` már eleve nullable volt
|
|
- **Schema**: [`backend/app/schemas/organization.py`](backend/app/schemas/organization.py:17) - `reg_number: Optional[str] = None` már eleve opcionális volt
|
|
- **Adatbázis**: A `sync_engine` audit szerint a séma tökéletesen szinkronban van (1017/1017 elem OK)
|
|
|
|
#### 2. Duplikáció szűrése a NAV lekérdezés előtt
|
|
- **Végpont**: [`backend/app/api/v1/endpoints/organizations.py`](backend/app/api/v1/endpoints/organizations.py:124) - `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`](backend/app/services/nav_service.py:105) - `_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`](frontend/src/views/ProfileView.vue:14)
|
|
- 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`](frontend/src/components/DashboardHeader.vue:157)
|
|
- 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`](frontend/src/components/DashboardHeader.vue:394)
|
|
- `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`](frontend/src/stores/auth.ts:524)
|
|
- `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)
|
|
- Backend: [`identity.py`](backend/app/models/identity/identity.py:122), [`organization.py`](backend/app/models/marketplace/organization.py:35), [`translation.py`](backend/app/models/system/translation.py:8)
|
|
- Frontend Store: [`auth.ts`](frontend/src/stores/auth.ts:54), [`appModeStore.ts`](frontend/src/stores/appModeStore.ts:6)
|
|
- Frontend Layout: [`ConsumerLayout.vue`](frontend/src/layouts/ConsumerLayout.vue:1), [`CorporateLayout.vue`](frontend/src/layouts/CorporateLayout.vue:1), [`AdminLayout.vue`](frontend/src/layouts/AdminLayout.vue:1)
|
|
- Frontend Router: [`index.ts`](frontend/src/router/index.ts:1)
|
|
- Frontend i18n: [`hu.ts`](frontend/src/i18n/hu.ts:1), [`en.ts`](frontend/src/i18n/en.ts:1), [`translationService.ts`](frontend/src/services/translationService.ts:5)
|
|
- Frontend Komponens: [`DashboardHeader.vue`](frontend/src/components/DashboardHeader.vue:1), [`DashboardView.vue`](frontend/src/views/DashboardView.vue:1), [`CompanyGarageView.vue`](frontend/src/views/organization/CompanyGarageView.vue:1)
|
|
- Frontend Config: [`tailwind.config.js`](frontend/tailwind.config.js:1), [`main.css`](frontend/src/assets/main.css:1), [`main.ts`](frontend/src/main.ts:30)
|
|
- Frontend Types: [`organization.ts`](frontend/src/types/organization.ts:5)
|
|
|
|
#### 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ó
|
|
- Teljes elemzés: [`docs/frontend_architecture_2_0_feasibility_analysis.md`](docs/frontend_architecture_2_0_feasibility_analysis.md)
|
|
|
|
## 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`](backend/app/services/auth_service.py:253)
|
|
- **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**:
|
|
- **Fájl**: [`backend/app/api/v1/endpoints/documents.py`](backend/app/api/v1/endpoints/documents.py:63)
|
|
- **Hiba**: `"Dokumentum sikeresen archiválva a széfben."`
|
|
- **Javítás**: `"Dokumentum sikeresen archiválva a garázsban."`
|
|
|
|
**Ellenőrzött frontend fájlok (nem volt szükség módosításra)**:
|
|
- [`frontend/src/i18n/hu.ts`](frontend/src/i18n/hu.ts:38) - Már "garázs"-t használ (`personalGarage`, `privateGarage`, `companyGarageLabel`, `personalGarageLabel`)
|
|
- [`frontend/src/i18n/en.ts`](frontend/src/i18n/en.ts:41) - Már "garage"-t használ helyesen
|
|
- [`frontend/src/layouts/PrivateLayout.vue`](frontend/src/layouts/PrivateLayout.vue:42) - i18n kulcsokat használ, nincs hardkódolt "széf"
|
|
- [`frontend/src/layouts/OrganizationLayout.vue`](frontend/src/layouts/OrganizationLayout.vue:10) - Már "garázsa" szerepel a template-ben
|
|
|
|
#### 2. Regisztrációs Csendes Hiba Javítása
|
|
|
|
**Gyökér Ok**:
|
|
- **Fájl**: [`backend/app/services/geo_service.py`](backend/app/services/geo_service.py:50)
|
|
- 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: str` → `street_name: Optional[str] = None`
|
|
- `street_type: str` → `street_type: Optional[str] = None`
|
|
- `house_number: str` → `house_number: Optional[str] = None`
|
|
|
|
**Ellenőrzött fájlok (nem volt szükség módosításra)**:
|
|
- [`backend/app/schemas/auth.py`](backend/app/schemas/auth.py:28) - `UserKYCComplete` séma helyesen `Optional[str] = None`-t használ
|
|
- [`frontend/src/views/CompleteKycView.vue`](frontend/src/views/CompleteKycView.vue:411) - A `handleSubmit()` helyesen szűri az üres stringeket
|
|
|
|
### ✅ 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`](backend/app/schemas/asset.py:107)
|
|
- `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`](backend/app/models/vehicle/asset.py:157)
|
|
- `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`](backend/app/api/v1/endpoints/assets.py:49)
|
|
- 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`](backend/app/services/asset_service.py:148)
|
|
- `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`](frontend/src/stores/vehicle.ts:46)
|
|
- `is_primary: boolean` mező hozzáadva a `Vehicle` interfészhez
|
|
|
|
**6. Frontend - DashboardView:** [`frontend/src/views/DashboardView.vue`](frontend/src/views/DashboardView.vue:349)
|
|
- `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`](frontend/src/components/dashboard/PrivateVehicleManager.vue:129)
|
|
- 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_primary` → `individual_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.id` → `current_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 ✅ |