# Service Finder Fejlesztési Történet ## 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.