céges meghívó kezelése,
This commit is contained in:
128
docs/organization_member_audit_report_2026-06-17.md
Normal file
128
docs/organization_member_audit_report_2026-06-17.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# 🏗️ OrganizationMember Audit Report & Garage Selector Implementation
|
||||
|
||||
**Dátum:** 2026-06-17
|
||||
**Készítette:** Fast Coder (Core Developer)
|
||||
**Verzió:** 1.0
|
||||
|
||||
---
|
||||
|
||||
## 1. Végrehajtott Módosítások
|
||||
|
||||
### 1.1 Backend: `get_my_organizations` végpont javítása
|
||||
|
||||
**Fájl:** [`backend/app/api/v1/endpoints/organizations.py`](../backend/app/api/v1/endpoints/organizations.py:198)
|
||||
|
||||
A lekérdezés logikája az alábbiakra változott:
|
||||
|
||||
- **RÉGI:** `INNER JOIN` az `OrganizationMember` táblán → csak azokat a szervezeteket adta vissza, ahol a felhasználónak volt member rekordja. Kizárta a tulajdonosi viszonyt (`owner_id`).
|
||||
- **ÚJ:** `LEFT JOIN` + `OR` feltétel → visszaadja azokat a szervezeteket, ahol a felhasználó:
|
||||
- a) Technikai tulajdonos (`Organization.owner_id == current_user.id`)
|
||||
- **VAGY**
|
||||
- b) Szerepel az `OrganizationMember` táblában tagként (`OrganizationMember.user_id == current_user.id`)
|
||||
|
||||
**SQL változás:**
|
||||
```python
|
||||
# RÉGI (hibás):
|
||||
select(Organization).join(OrganizationMember).where(OrganizationMember.user_id == current_user.id)
|
||||
|
||||
# ÚJ (javított):
|
||||
select(Organization).outerjoin(OrganizationMember, OrganizationMember.organization_id == Organization.id)\
|
||||
.where(or_(Organization.owner_id == current_user.id, OrganizationMember.user_id == current_user.id))\
|
||||
.distinct()
|
||||
```
|
||||
|
||||
**Válasz bővítése:** A végpont most `user_role` mezőt is visszaad, amely a felhasználó szerepkörét tartalmazza az adott szervezetben (`OWNER`, `ADMIN`, `FLEET_MANAGER`, `DRIVER`, `MECHANIC`, `RECEPTIONIST`). Ha a felhasználó a tulajdonos, de nincs member rekordja, `"OWNER"`-t ad vissza.
|
||||
|
||||
### 1.2 Backend: `OrganizationMember` modell bővítése
|
||||
|
||||
**Fájl:** [`backend/app/models/marketplace/organization.py`](../backend/app/models/marketplace/organization.py:195)
|
||||
|
||||
A modellhez az alábbi hiányzó oszlopok kerültek hozzáadásra:
|
||||
|
||||
| Oszlop | Típus | Alapértelmezés | Leírás |
|
||||
|--------|-------|----------------|--------|
|
||||
| `status` | `String(20)` | `'active'` | Tag státusza (`active`, `pending`, `inactive`) |
|
||||
| `created_at` | `DateTime(timezone=True)` | `func.now()` | Létrehozás időpontja |
|
||||
| `updated_at` | `DateTime(timezone=True)` | `onupdate=func.now()` | Utolsó módosítás időpontja |
|
||||
|
||||
Ezek az oszlopok hiányoztak az adatbázisból, de a kód már hivatkozott rájuk (pl. `organizations.py:421,481` sorokban `status="pending"`, `status="active"`), ami futási hibát okozott volna.
|
||||
|
||||
### 1.3 Adatbázis szinkronizáció
|
||||
|
||||
A `sync_engine` sikeresen hozzáadta a 3 hiányzó oszlopot a `fleet.organization_members` táblához.
|
||||
|
||||
---
|
||||
|
||||
## 2. Audit Jelentés: OrganizationMember Tábla
|
||||
|
||||
### 2.1 Oszlopok (Jelenlegi állapot a javítás után)
|
||||
|
||||
| # | Oszlop | Típus | Kötelező | Alapértelmezett | Megjegyzés |
|
||||
|---|--------|-------|----------|-----------------|------------|
|
||||
| 1 | `id` | `integer` | YES | auto-increment | PK |
|
||||
| 2 | `organization_id` | `integer` | YES | - | FK → `fleet.organizations.id` |
|
||||
| 3 | `user_id` | `integer` | NO | - | FK → `identity.users.id` (lehet NULL pending invite-nál) |
|
||||
| 4 | `person_id` | `bigint` | NO | - | FK → `identity.persons.id` |
|
||||
| 5 | `role` | `ENUM` (OrgUserRole) | YES | `DRIVER` | OWNER, ADMIN, FLEET_MANAGER, DRIVER, MECHANIC, RECEPTIONIST |
|
||||
| 6 | `permissions` | `json` | NO | `{}` | JSONB jogosultságok |
|
||||
| 7 | `is_permanent` | `boolean` | NO | `false` | Állandó vs. ideiglenes tagság |
|
||||
| 8 | `is_verified` | `boolean` | NO | `false` | Ellenőrzött tag |
|
||||
| 9 | **`status`** 🆕 | `varchar(20)` | NO | `'active'` | Tag státusza |
|
||||
| 10 | **`created_at`** 🆕 | `timestamptz` | NO | `now()` | Létrehozás dátuma |
|
||||
| 11 | **`updated_at`** 🆕 | `timestamptz` | YES | - | Módosítás dátuma |
|
||||
|
||||
### 2.2 Meghívási Folyamat (Invite Flow)
|
||||
|
||||
**Meglévő API végpontok:**
|
||||
|
||||
| Végpont | Metódus | Státusz | Leírás |
|
||||
|---------|---------|---------|--------|
|
||||
| `POST /api/v1/organizations/{org_id}/invitations` | POST | ✅ Létezik | Meghívó küldése email címre. Ha a user létezik → pending tag létrehozása. Ha nem → `VerificationToken` (`org_invite` típus) |
|
||||
| `POST /api/v1/organizations/invitations/{token}/accept` | POST | ✅ Létezik | Meghívó elfogadása token alapján (regisztráció után) |
|
||||
| `POST /api/v1/organizations/{org_id}/join-request` | POST | ✅ Létezik | Csatlakozási kérelem (ha van aktív admin) |
|
||||
| `POST /api/v1/organizations/{org_id}/claim/request` | POST | ✅ Létezik | Árva cég átvételi kérelem (OTP küldés) |
|
||||
| `POST /api/v1/organizations/{org_id}/claim/verify` | POST | ✅ Létezik | Árva cég átvétel OTP-vel |
|
||||
|
||||
**Hiányzó API végpontok (P2 - Következő iteráció):**
|
||||
|
||||
| Végpont | Metódus | Hiány | Hatás |
|
||||
|---------|---------|-------|-------|
|
||||
| `GET /api/v1/organizations/{org_id}/members` | GET | ❌ Hiányzik | Nincs lehetőség a tagok listázására |
|
||||
| `PATCH /api/v1/organizations/{org_id}/members/{member_id}/role` | PATCH | ❌ Hiányzik | Nincs lehetőség a szerepkör módosítására |
|
||||
| `DELETE /api/v1/organizations/{org_id}/members/{member_id}` | DELETE | ❌ Hiányzik | Nincs lehetőség a tag eltávolítására |
|
||||
| `GET /api/v1/organizations/{org_id}/invitations` | GET | ❌ Hiányzik | Nincs lehetőség a függő meghívók listázására |
|
||||
| `DELETE /api/v1/organizations/{org_id}/invitations/{invitation_id}` | DELETE | ❌ Hiányzik | Nincs lehetőség a meghívó visszavonására |
|
||||
|
||||
### 2.3 Jogosultságkezelés
|
||||
|
||||
- **Tag felvétele:** A `POST /invitations` végponton keresztül lehetséges (meghívó küldése). A `POST /join-request` lehetővé teszi a felhasználóknak, hogy maguk kérjenek csatlakozást.
|
||||
- **Szerepkör módosítása:** ❌ **Nincs implementálva.** Nincs PATCH végpont a tag szerepkörének módosítására.
|
||||
- **Tag eltávolítása:** ❌ **Nincs implementálva.** Nincs DELETE végpont a tag eltávolítására.
|
||||
- **Meghívó visszavonása:** ❌ **Nincs implementálva.** Nincs DELETE végpont a függő meghívók visszavonására.
|
||||
|
||||
### 2.4 Javasolt Javítási Sorrend
|
||||
|
||||
1. **P0 - KÉSZ:** `status`, `created_at`, `updated_at` oszlopok hozzáadva az `OrganizationMember` modellhez
|
||||
2. **P0 - KÉSZ:** `get_my_organizations` javítva `OR` logikára + `user_role` visszaadása
|
||||
3. **P1 - JELEN FELADAT:** Tagkezelő API végpontok implementálása (list, role change, remove)
|
||||
4. **P2 - KÖVETKEZŐ:** Meghívókezelő API végpontok (list pending, revoke)
|
||||
|
||||
---
|
||||
|
||||
## 3. Frontend Állapot
|
||||
|
||||
A frontend oldalon **nem volt szükség változtatásra**, mivel:
|
||||
|
||||
1. A [`HeaderCompanySwitcher.vue`](../frontend/src/components/header/HeaderCompanySwitcher.vue:132) már használja az `authStore.fetchMyOrganizations()` hívást, ami a `/organizations/my` végpontot hívja.
|
||||
2. A `companyOrganizations` computed property (144. sor) megfelelően szűri az `individual`, `service_provider`, `service` típusokat.
|
||||
3. A [`authStore.switchOrganization()`](../frontend/src/stores/auth.ts:631) metódus már implementálva van a `PATCH /users/me/active-organization` hívással.
|
||||
4. Az [`OrganizationItem` típus](../frontend/src/types/organization.ts:5) már tartalmazza a `user_role` mezőt (nem kötelező).
|
||||
|
||||
---
|
||||
|
||||
## 4. Teszt Eredmények
|
||||
|
||||
- ✅ `sync_engine` sikeresen lefutott - 3 hiányzó oszlop hozzáadva
|
||||
- ✅ `GET /api/v1/organizations/my` végpont működik, visszaadja a `user_role` mezőt
|
||||
- ✅ A végpont helyesen szűri a `service_provider` típusú szervezeteket
|
||||
- ✅ Az adatbázis séma konzisztens a kóddal
|
||||
Reference in New Issue
Block a user