# Service Finder Fejlesztési Történet ## 2026-06-14 - Admin Search Bugs Fix & Sticky UX ### 🎯 Cél Backend SQL hibák javítása a GET /admin/users végponton (Address outerjoin, phone search), valamint frontend UX fejlesztések (sticky bulk action bar, clear/X gomb, üres állapot üzenet, HeaderProfile az AdminLayout-ban). ### 🔧 Változtatások **1. BACKEND - [`admin.py`](backend/app/api/v1/endpoints/admin.py:502):** - `GET /admin/users` SQL javítás: `Address` outerjoin-ra változtatva (`isouter=True`), hogy a cím nélküli userek is visszajöjjenek - Telefonszám keresés: `phone` mező hozzáadva a `or_()` feltételhez **2. FRONTEND - [`AdminLayout.vue`](frontend/src/layouts/AdminLayout.vue:1):** - `HeaderProfile` komponens beillesztve a jobb felső sarokba (belépett user avatar + név) - A `SidebarToggle` gomb fixálva a sidebar szélén **3. FRONTEND - [`AdminUsersView.vue`](frontend/src/views/AdminUsersView.vue:1):** - **Sticky Bulk Action Bar:** A tömeges műveletek sáv (`BulkActionBar`) `sticky` pozícionálást kapott, hogy görgetéskor is látszódjon - **Clear/X gomb:** A keresőmezőbe egy `X` gomb került, ami egy kattintással törli a keresési feltételt ## 2026-06-17 - P0 UI Card Cleanup & Custom Tag 500 Fix ### 🎯 Cél Három kritikus hiba javítása: (1) "Nincs kategória" fantom badge eltüntetése a provider kártyákról, (2) Telefon/Weboldal ikonok megjelenítése a kártyákon, (3) 500-as hiba javítása custom tag mentéskor. ### 🔧 Változtatások **1. FRONTEND - [`ServiceFinderView.vue`](frontend/src/views/ServiceFinderView.vue:367):** - **"Nincs kategória" javítás:** A `v-if="provider.category"` feltétel helyett `v-if="provider.categories && provider.categories.length > 0"` lett beállítva. Ha a `categories` array üres, de a régi `category` string létezik, azt használja. Csak ha egyik sincs, akkor jelenik meg a "Nincs kategória" felirat. - **Telefon/Web ikonok:** Az address blokk után egy új contact info sor került be, amely a `contact_phone` mezőhöz telefon ikont + linket (`tel:`), a `website` mezőhöz weboldal ikont + linket (`target="_blank"`) jelenít meg. - **TypeScript interface bővítés:** A `ProviderSearchResult` interfész kibővítve a hiányzó mezőkkel: `contact_phone`, `contact_email`, `website`, `tags`, `address_zip`, `address_street_name`, `address_street_type`, `address_house_number`. **2. BACKEND - [`provider_service.py`](backend/app/services/provider_service.py:661):** - **`_slugify()` függvény:** Új segédfüggvény, amely biztonságos slug-ot generál magyar ékezetes karakterekből (á→a, é→e, í→i, ó→o, ö→o, ő→o, ú→u, ü→u, ű→u), majd nem-alfanumerikus karaktereket alulvonásra cserél. - **`_create_new_tags()` javítás:** - `try-except` blokkba csomagolva a teljes beszúrási logika - `logger.error(..., exc_info=True)` hibanaplózás hozzáadva - `parent_id=None` és `path=None` explicit beállítva - A kulcs generálás most a `_slugify()` függvényt használja - Egyetlen hibás címke nem szakítja meg a teljes folyamatot (`continue`) ### ✅ Eredmény - "Nincs kategória" fantom badge megszűnt: a feltétel most a `categories` tömböt ellenőrzi - Telefon és weboldal linkek megjelennek a kártyákon (ha vannak) - Custom tag mentés 500 helyett try-except blokkban fut, hibanaplózással - Python szintaxis ellenőrzés: OK ## 2026-06-17 - P0 UI Overhaul: Plus Code, Universal Categories, Detail Modal ### 🎯 Cél Három területet fed le: (1) Plus Code integráció a backendben és adatbázisban, (2) Univerzális kategóriák megjelenítése a ProviderEditModal és QuickAdd modalokban, (3) ProviderDetailModal gazdag újraírása kategória chipekkel, kontakt grid-del és navigációs gombbal. ### 🔧 Változtatások **1. BACKEND - Plus Code mező:** - [`Organization`](backend/app/models/marketplace/organization.py:86) model: `plus_code: Mapped[Optional[str]] = mapped_column(String(20))` - [`ProviderSearchResult`](backend/app/schemas/provider.py:115): `plus_code: Optional[str] = None` - [`ProviderQuickAddIn`](backend/app/schemas/provider.py:148): `plus_code: Optional[str] = Field(None, max_length=20)` - [`ProviderUpdateIn`](backend/app/schemas/provider.py:180): `plus_code: Optional[str] = Field(None, max_length=20)` - [`provider_service.py`](backend/app/services/provider_service.py:262): plus_code hozzáadva a search SELECT-hez, quick_add Organization creation-höz, és update null-safety checkhez - `sync_engine` sikeresen lefuttatva, a `plus_code` oszlop létrejött **2. FRONTEND - Univerzális kategóriák:** - [`ProviderEditModal.vue`](frontend/src/components/provider/ProviderEditModal.vue): `allLevel1Categories` computed property, amely a checked Level 0 szülők Level 1 gyermekeit gyűjti össze deduplikálva - [`ProviderQuickAddModal.vue`](frontend/src/components/provider/ProviderQuickAddModal.vue): Ugyanaz a `allLevel1Categories` logika - Plus Code input mező hozzáadva mindkét modal "Alapadatok" tabjához **3. FRONTEND - Detail Modal Rework:** - [`ProviderDetailModal.vue`](frontend/src/components/provider/ProviderDetailModal.vue): Teljes újraírás - Kategória chipek (szintenként eltérő színnel: Level0=lila, Level1=kék, Level2=teal, Level3=szürke) - Kontakt grid: Telefon (tel: link), Email (mailto: link), Weboldal (_blank, external icon) - Helyszín szekció: cím + plus_code + "Navigáció" gomb (Google Maps URL) - Hiányzó adatok esetén i18n fallback szövegek **4. i18n:** - [`en.ts`](frontend/src/i18n/en.ts): plus_code és detail modal kulcsok - [`hu.ts`](frontend/src/i18n/hu.ts): plus_code és detail modal magyar fordítások ### ✅ Eredmény - Backend Python import ellenőrzés: OK (provider.py, provider_service.py, providers.py endpoints) - Frontend Vite build: OK (87 modules, 6.07s) - Adatbázis sync_engine: OK (plus_code oszlop létrejött) ## 2026-06-17 - P0 Triage Fix: Data Persistence & UNION ALL Column Mismatch ### 🎯 Cél Két kritikus hiba javítása a Provider Search/Update folyamatban: 1. **Data Persistence Black Hole**: Organization ID 4859 (Shell Dunakeszi) `plus_code` és `contact_phone` mezői nem perzisztáltak mentés után 2. **UNION ALL 500 error**: `CompoundSelect must have identical numbers of columns` hiba a search végponton ### 🔧 Változtatások **1. BACKEND - [`provider_service.py`](backend/app/services/provider_service.py:445):** - `plus_code` hozzáadva a `ProviderSearchResult` konstruktorhoz (`getattr(row, "plus_code", None)`) - a mező SELECT-ben volt, de a Python objektumba nem került át - `plus_code` oszlop (`literal(None).label("plus_code")`) hozzáadva a `UNION ALL` második (`staging_stmt`) és harmadik (`crowd_stmt`) ágához, hogy a 15 oszlopszám konzisztens legyen - **P0 CRITICAL BUGFIX**: Ha nincs `ServiceProfile` rekord az Organization-höz, a `update_provider` most létrehozza azt (fingerprint + location + contact adatokkal), ahelyett hogy csak logolná a hiányt és eldobná a contact/category adatokat - `ServiceStatus` import hozzáadva a provider_service.py-hoz **2. FRONTEND - [`ProviderEditModal.vue`](frontend/src/components/provider/ProviderEditModal.vue:617):** - `allLevel1Categories` szétbontva `vehicleLevel1Categories`-re (Level 0 checkboxoktól függő) és `universalLevel1Categories`-re (mindig látható, `categoryTree.value.filter(c => c.level === 1)`) - Új UI blokk "Iparágak és Univerzális Szolgáltatások" címmel, amber színű dashed border-rel ### ✅ Verifikáció - `plus_code=8FVX+3W`, `contact_phone=+36 20 123 4567`, `contact_email=shell.dunakeszi@example.com` sikeresen mentve és visszaolvasva ID 4859-hez - API `/api/v1/providers/search` hibátlanul fut (nincs 500-as UNION ALL hiba) - Adatbázis szinten ellenőrizve: `fleet.organizations.plus_code` és `marketplace.service_profiles.contact_phone/contact_email` helyesen perzisztálva ## 2026-06-17 - P0 Ownership & Access Control Fix: OrganizationMember + owner_id ### 🎯 Cél Két P0 kritikus hiba javítása a Provider Quick-Add és Update folyamatban: 1. **Ownerless Providers**: A `quick_add_provider` `owner_id=None`-t használt, így az újonnan létrehozott szolgáltatóknak nem volt tulajdonosa 2. **Missing OrganizationMember**: A 6-lépéses folyamat 5. lépésnél megállt - nem jött létre `OrganizationMember` rekord, így senki sem volt kapcsolatban a céggel 3. **No Access Control**: A `update_provider` végpont bárki által hívható volt - nem ellenőrizte, hogy a hívó user jogosult-e szerkeszteni az adott szervezetet ### 🔧 Változtatások **1. BACKEND - [`provider_service.py`](backend/app/services/provider_service.py:468):** - **`owner_id=None` → `owner_id=user_id`** (531. sor): A létrehozott Organization most a hitelesített user-hez tartozik - **6. 👤 ORGANIZATION MEMBER LÉTREHOZÁSA** (585-600. sor): Teljesen új blokk a gamifikáció előtt: ```python member = OrganizationMember( organization_id=org.id, user_id=user_id, role=OrgUserRole.OWNER, is_permanent=True, is_verified=True, ) db.add(member) await db.flush() ``` - **🔐 ACCESS CONTROL ELLENŐRZÉS** (841-863. sor): A `update_provider` függvény elején új blokk, amely ellenőrzi, hogy a user rendelkezik-e OWNER vagy ADMIN szerepkörrel az adott Organization-ben. Ha nem, `PermissionError`-t dob. **2. BACKEND - [`providers.py`](backend/app/api/v1/endpoints/providers.py:311):** - `PermissionError` → `HTTPException(403)` kezelés hozzáadva a `update_service_provider` végponthoz ### ✅ Verifikáció - `owner_id=2` (admin user) sikeresen beállítva a létrehozott Organization-ben - `OrganizationMember(user_id=2, role=OWNER)` rekord sikeresen létrejött - Admin user sikeresen frissítheti a provider adatokat (200 OK) - Érvénytelen token esetén 401 Unauthorized - Docker konténer újraépítve: `docker compose up -d --build sf_api` - Tesztadatok (org 59, 60, 61) tisztítva ## 2026-06-17 - P0 Critical Bugfix: Quick-Add Provider 422 category_id null ### 🎯 Cél A `POST /api/v1/providers/quick-add` endpoint 422-es hibát dobott, amikor a frontend `category_id: null`-t küldött. A 4-level kategória rendszer bevezetésével a frontend már a `category_ids` tömböt használja, de a backend `ProviderQuickAddIn` séma továbbra is kötelező `int`-ként várta a `category_id`-t. ### 🔧 Változtatások **1. BACKEND - [`provider.py`](backend/app/schemas/provider.py:135):** - `ProviderQuickAddIn.category_id` típusa `int` → `Optional[int] = None` (opcionális) - Új mezők: `category_ids: Optional[List[int]]` és `new_tags: Optional[List[str]]` a 4-level kategória rendszer támogatásához **2. BACKEND - [`provider_service.py`](backend/app/services/provider_service.py:468):** - `quick_add_provider()` most már kezeli a `category_id=None` esetet (kihagyja az elsődleges kategória lekérdezést) - A `category_ids` és `new_tags` mezők feldolgozása: ServiceExpertise kapcsolatok létrehozása a 4-level kategória rendszerből - Deduplikáció: az összes kategória ID egyesítve, duplikátumok eltávolítva **3. FRONTEND - [`ProviderQuickAddModal.vue`](frontend/src/components/provider/ProviderQuickAddModal.vue:781):** - `phone` → `contact_phone` és `email` → `contact_email` mezőnevek javítva (illeszkedés a backend Pydantic sémához) ### ✅ Teszt eredmény - A pontosan reprodukált hiba (Bokebo Kft., category_id=null, category_ids=[149]) **HTTP 201** választ ad - Adatbázisban: Organization létrejött, ServiceProfile létrejött, ServiceExpertise kapcsolat a 149-es kategóriával létrejött - Gamification: 500 pont jóváírva ## 2026-06-17: Bug investigation - Quick-add provider cégek megjelennek a Cégeim menüben **Kártya:** #266 **Szerepkör:** Architect **Állapot:** Tervezés kész ### Felfedezett hibák 1. **`GET /organizations/my` endpoint** (`backend/app/api/v1/endpoints/organizations.py:183-186`): Nincs `org_type` szűrés, minden szervezetet visszaad, ahol a user tag az `OrganizationMember` táblában. 2. **`HeaderCompanySwitcher.vue:142-146`**: A `companyOrganizations` computed property csak az `individual` típust szűri ki, a `service_provider` típusú szervezeteket nem. 3. **`quick_add_provider()`** (`backend/app/services/provider_service.py:638-646`): Létrehoz `OrganizationMember`-et `role=OWNER`-rel, ami miatt a `GET /my` visszaadja a szolgáltatót. ### Javítási terv 1. `organizations.py:183-186`: `org_type` szűrés hozzáadása (csak `business`, `fleet_owner`, `individual`) 2. `organizations.py:193-206`: `owner_id` mező hozzáadása a response-hoz 3. `HeaderCompanySwitcher.vue:142-146`: `service_provider` és `service` típusok kiszűrése 4. Adatbázis audit: hiányzó `owner_id`-k ellenőrzése a régi service_providereknél ### Kapcsolódó fájlok - `plans/logic_spec_provider_cegeim_bugfix.md` - Részletes logic_spec ## 2026-06-17: Bugfix implementáció - Quick-add provider cégek a Cégeim menüben (#266) **Szerepkör:** Code (Fast Coder) **Állapot:** Implementálva és tesztelve ### Végrehajtott módosítások 1. **`backend/app/api/v1/endpoints/organizations.py:183-186`** — `GET /my` endpoint: - Hozzáadva `org_type` szűrés: csak `business`, `fleet_owner`, `individual` típusú szervezetek visszaadása - `owner_id` mező hozzáadva a response dict-hez 2. **`frontend/src/components/header/HeaderCompanySwitcher.vue:142-146`** — `companyOrganizations` computed: - `service_provider` és `service` típusok kiszűrése (biztonsági réteg) ### Verifikáció - ✅ `sync_engine.py` — 1065 elem OK, 0 hiba - ✅ Backend Python import check — OK - ✅ Frontend `npm run build` — 5.97s, 0 hiba ### 🔧 Javítás (v2) — 2026-06-17 **Probléma:** A whitelist (`in_([business, fleet_owner, individual])`) túl szigorú volt, kizárta a valódi cégeket (pl. `club` típus). **Megoldás:** 1. **`backend/app/api/v1/endpoints/organizations.py:193`** — `in_([...])` → `notin_([OrgType.service_provider, OrgType.service])` - Blacklist megközelítés: csak a service_provider és service típusokat szűrjük ki - Minden más típus (business, fleet_owner, individual, club, stb.) megjelenik ### Verifikáció - ✅ `sync_engine.py` — 1065 elem OK, 0 hiba - ✅ Backend Python import check — OK - ✅ `notin_` szintaxis ellenőrizve — OK ## 2026-06-17 - Garázsválasztó Bugfix: service_provider org-ok nem látszottak OWNER-nek sem ### 🎯 Cél A saját tulajdonú cégek (service_provider org_type) megjelenítése a garázsválasztó gombban, ha a felhasználó OWNER joggal rendelkezik. ### 🔧 Változtatások **1. BACKEND - [`organizations.py`](backend/app/api/v1/endpoints/organizations.py:177-228):** - A `GET /my` végpont most már `select(Organization, OrganizationMember.role)`-t használ, hogy a felhasználó szerepkörét is lekérdezze - A `service_provider`/`service` típusú org-ok utólagos szűrése: csak akkor jelennek meg, ha a user role = `OWNER` - A válaszban új `user_role` mező került visszaadásra **2. FRONTEND - [`HeaderCompanySwitcher.vue`](frontend/src/components/header/HeaderCompanySwitcher.vue:144-158):** - A `companyOrganizations` computed property most már a `user_role` mezőt is figyelembe veszi - `service_provider`/`service` típus csak `user_role === 'OWNER'` esetén jelenik meg **3. FRONTEND - [`organization.ts`](frontend/src/types/organization.ts:25-30):** - Új `user_role?: string` mező az `OrganizationItem` interfészben ### Verifikáció - ✅ Backend syntax check — OK - ✅ API teszt: 4 org visszatér (1 individual + 3 service_provider OWNER) - ✅ `user_role` mező jelen van a válaszban (ADMIN, OWNER) - ✅ Nincs regresszió: non-OWNER role esetén a service_provider org-ok ki vannak szűrve ## 2026-06-17: Root cause fix - quick_add_provider owner_id és role javítás (#266) ### 🔍 Felismert probléma A `quick_add_provider` függvény a crowdsourcingból felvett szolgáltatóknál `owner_id=user_id`-t állított be és `OWNER` szerepkörű tagot hozott létre. Ez hibás, mert: - A közösségi jelöléssel felvett cégeknek NINCS tulajdonosa (`owner_id=NULL`) - Aki felvesz egy céget a Service Finder-be, az NEM lesz a cég tulajdonosa - Az `OWNER` szerepkör miatt ezek a cégek megjelentek a "Cégeim" garázsválasztóban ### 🔧 Végrehajtott módosítások **1. BACKEND - [`provider_service.py`](backend/app/services/provider_service.py:541):** - `owner_id=user_id` → `owner_id=None` — crowdsourcingból felvett szolgáltatónak nincs tulajdonosa **2. BACKEND - [`provider_service.py`](backend/app/services/provider_service.py:641):** - `role=OrgUserRole.OWNER` → `role=OrgUserRole.ADMIN` — a felhasználó ADMIN jogot kap (szerkesztheti), de nem tulajdonos ### ✅ Verifikáció - ✅ Sync engine: séma konzisztens (1065 elem OK) - ✅ API teszt: `GET /api/v1/organizations/my` → 1 org (Test Company, individual) - ✅ service_provider org-ok (57, 58, 62) NEM jelennek meg a garázsválasztóban - ✅ A meglévő adatok (owner_id=2, role=OWNER) a régi kóddal jöttek létre, az új kód már helyesen hozza létre az új provider-eket ## 2026-06-17 - P1 Garage Selector Implementation & OrganizationMember Audit ### 🎯 Cél Dashboard "Garage Selector" (cégválasztó) pontosítása, hogy a bejelentkezett felhasználó azon Organization rekordokat lássa, ahol: a) Technikai tulajdonos (`owner_id`) VAGY b) Aktív tag (`OrganizationMember`) Emellett az `OrganizationMember` tábla hiányzó oszlopainak pótlása és audit jelentés készítése. ### 🔧 Változtatások **1. BACKEND - [`organizations.py`](backend/app/api/v1/endpoints/organizations.py:198):** - `get_my_organizations` query javítva: `INNER JOIN` → `LEFT JOIN` + `OR` feltétel (`owner_id` VAGY `OrganizationMember.user_id`) - `DISTINCT` hozzáadva a duplikációk elkerülésére - `user_role` mező visszaadása a frontend számára - `_get_user_role()` segédfüggvény implementálva **2. BACKEND - [`organization.py`](backend/app/models/marketplace/organization.py:195):** - `OrganizationMember` modellhez hozzáadva: `status` (String(20)), `created_at`, `updated_at` oszlopok - Ezek az oszlopok hiányoztak az adatbázisból, de a kód már hivatkozott rájuk **3. ADATBÁZIS - `sync_engine`:** - 3 hiányzó oszlop sikeresen hozzáadva a `fleet.organization_members` táblához **4. DOKUMENTÁCIÓ - [`organization_member_audit_report_2026-06-17.md`](docs/organization_member_audit_report_2026-06-17.md):** - Részletes audit jelentés az OrganizationMember tábláról - Hiányzó API végpontok azonosítása (tagkezelés, meghívókezelés) - Javasolt javítási sorrend ### ✅ Eredmény - `GET /api/v1/organizations/my` helyesen adja vissza a tulajdonosi és tagsági viszonyokat - `user_role` mező elérhető a frontend számára - Adatbázis séma konzisztens a kóddal - Audit jelentés elkészítve a docs mappában ## 2026-06-17 - P0 Garage Selector Fix & Team Management API Implementation ### 🎯 Cél A P0 Garage Selector hiba végleges javítása (a `GET /organizations/my` 500-as hibát dobott JSON oszlopok miatt) és a hiányzó Team Management API végpontok implementálása. ### 🔧 Változtatások **1. BACKEND - [`organization.py`](backend/app/models/marketplace/organization.py:187-190):** - `OrganizationMember` modellhez hozzáadva: `invited_email` (String(255)) és `expires_at` (DateTime(timezone=True)) oszlopok - `OrgUserRole` enum szinkronizálva az adatbázisban lévő értékekkel: `OWNER, ADMIN, MANAGER, MEMBER, AGENT` - `default=OrgUserRole.DRIVER` → `default=OrgUserRole.MEMBER` **2. BACKEND - [`organizations.py`](backend/app/api/v1/endpoints/organizations.py:199-218):** - **`GET /organizations/my` SQL javítás:** A `DISTINCT` a teljes Organization modellen JSON oszlopok miatt hibát dobott (`could not identify an equality operator for type json`) - **Megoldás:** Subquery approach: először csak az ID-kat szedjük DISTINCT-tel, majd a második query-ben `selectinload(Organization.members)`-szel töltjük be a teljes objektumokat - `selectinload` import hozzáadva a `sqlalchemy.orm`-ból **3. BACKEND - [`organizations.py`](backend/app/api/v1/endpoints/organizations.py:326-607):** - **`GET /{org_id}/members`** — Tagok listázása (user email + role + status) - **`POST /{org_id}/invitations`** — Meghívó küldése (invited_email, expires_at=+7 nap) - **`PATCH /{org_id}/members/{member_id}`** — Szerepkör módosítása (utolsó OWNER védelme) - **`DELETE /{org_id}/members/{member_id}`** — Tag eltávolítása / meghívó visszavonása - **`_check_org_admin_access()`** — Segédfüggvény: csak OWNER/ADMIN férhet hozzá - Pydantic modellek: `MemberResponse`, `MemberRoleUpdate`, `InvitationCreate` - Régi duplikált `POST /invitations` és `POST /invitations/{token}/accept` végpontok eltávolítva **4. ADATBÁZIS - `sync_engine`:** - 2 új oszlop (`invited_email`, `expires_at`) sikeresen hozzáadva a `fleet.organization_members` táblához ### ✅ Teszt eredmény - ✅ `GET /api/v1/organizations/my` → **200 OK** (1 org: Test Company, user_role: ADMIN) - ✅ `GET /api/v1/organizations/1/members` → **200 OK** (1 member: admin@profibot.hu) - ✅ `POST /api/v1/organizations/1/invitations` → **201 Created** (invited_email, expires_at, role=MANAGER) - ✅ `PATCH /api/v1/organizations/1/members/25` → **200 OK** (role MANAGER → ADMIN) - ✅ `DELETE /api/v1/organizations/1/members/25` → **200 OK** (invitation revoked) ## 2026-06-17 - Team Management Modul Refaktorálás (Dynamic RBAC, Settings, i18n) ### 🎯 Cél A Team Management modul teljes refaktorálása: hardcoded `OrgUserRole` Enum kiváltása adatbázis-vezérelt `OrgRole` modellel, hardcoded 7 napos meghívási lejárat kiváltása dinamikus `Organization.settings` JSONB mezővel, és az összes hardcoded magyar szöveg kiváltása i18n kulcsokkal a `TranslationService.get_text()` segítségével. ### 🔧 Változtatások **1. MODELL - [`organization.py`](backend/app/models/marketplace/organization.py:34):** - **`OrgRole`** új modell létrehozva a `fleet.org_roles` táblában (id, name_key, display_name, description, is_system, priority, is_active, created_at) - **`Organization.settings`** JSONB oszlop hozzáadva alapértelmezett értékekkel: `{"invite_expiry_days": 7, "max_members": 50, "allow_public_join": false}` - **`OrganizationMember.role`** típusa megváltoztatva `PG_ENUM(OrgUserRole)`-ról `String(50)`-re, alapértelmezett `"MEMBER"` **2. MODELL EXPORT - [`__init__.py`](backend/app/models/__init__.py:1):** - `OrgRole` hozzáadva az importokhoz és az `__all__` listához **3. API VÉGPONTOK - [`organizations.py`](backend/app/api/v1/endpoints/organizations.py:1):** - `_()` helper függvény hozzáadva a `TranslationService.get_text()` rövidítésére - `_get_org_settings()` helper hozzáadva a dinamikus beállítások olvasásához - Összes hardcoded magyar szöveg kiváltva i18n kulcsokkal (pl. `ORGANIZATION.ERROR.INVALID_TAX_FORMAT`, `ORGANIZATION.SUCCESS.ONBOARDED`, `ORGANIZATION.CLAIM.OTP_SENT`) - Összes `OrgUserRole.OWNER` / `OrgUserRole.ADMIN` Enum referencia kiváltva string literálokkal (`"OWNER"`, `"ADMIN"`) - `member.role.value` → `str(member.role)` - `timedelta(days=7)` → `timedelta(days=invite_expiry_days)` a `_get_org_settings()`-ből **4. LOCALE FÁJLOK - [`hu.json`](backend/static/locales/hu.json:1), [`en.json`](backend/static/locales/en.json:1):** - `ORGANIZATION` névtér hozzáadva mindkét nyelvhez a következő alkulcsokkal: `ERROR.*` (11 hibaüzenet), `SUCCESS.*` (5 sikerüzenet), `INVITATION.*` (3 meghívó üzenet), `JOIN_REQUEST.*` (1 csatlakozási üzenet), `CLAIM.*` (2 átvételi üzenet) **5. ADATBÁZIS SZINKRONIZÁCIÓ:** - `sync_engine.py` sikeresen lefuttatva: `fleet.org_roles` tábla létrehozva, `fleet.organizations.settings` oszlop hozzáadva ### ✅ Eredmény - Adatbázis séma frissítve (2 új elem: org_roles tábla + settings oszlop) - API végpontok mind i18n kulcsokat használnak a `TranslationService.get_text()`-en keresztül - Nincs több hardcoded `OrgUserRole` Enum a Team Management modulban - Nincs több hardcoded 7 napos lejárat - Nincs több hardcoded magyar szöveg az API válaszokban - Business onboarding teszt: ✅ PASS