7.5 KiB
🏗️ Logic Spec: P1 Garage Selector & OrganizationMember Audit
1. Modul Célja és Masterbook 2.0 Illeszkedés
Cél: A Dashboard "Garage Selector" (cégválasztó) pontosítása, hogy a bejelentkezett felhasználó:
- a) Szerepeljen azon Organization rekordok között, ahol technikai tulajdonos (
owner_id) - b) Szerepeljen azon Organization rekordok között, ahol aktív
OrganizationMember
Emellett az OrganizationMember tábla és a meghívási folyamat teljes auditja.
Masterbook 2.0 illeszkedés: B2B szervezetkezelés (11-es Epic), B2B szerepkörök és szervezeti hierarchia.
2. Adatmodell Elemzés
2.1 OrganizationMember tábla (aktuális séma)
| Oszlop | Típus | Kötelező | Megjegyzés |
|---|---|---|---|
id |
integer PK | YES | Auto-increment |
organization_id |
integer FK -> fleet.organizations.id | YES | |
user_id |
integer FK -> identity.users.id | NO | Lehet NULL (pending invite) |
person_id |
bigint FK -> identity.persons.id | NO | |
role |
ENUM (OrgUserRole) | YES | OWNER, ADMIN, FLEET_MANAGER, DRIVER, MECHANIC, RECEPTIONIST |
permissions |
JSONB | NO (default {}) |
|
is_permanent |
boolean | NO (default false) | |
is_verified |
boolean | NO (default false) |
2.2 🔴 HIÁNYZÓ OSZLOPOK (Kritikus)
statusVARCHAR - A kód használja (status="pending",status="active"a organizations.py:421,481 sorokban), de az adatbázisban NINCS ilyen oszlop! Ez futási hibát okoz az invite/join folyamatokban.joined_atTIMESTAMP - Nincs nyomon követve, mikor csatlakozott a tag.expires_at/valid_untilTIMESTAMP - Nincs lejárati dátum (pl. ideiglenes hozzáféréshez).created_atTIMESTAMP - Hiányzik a tag rekord létrehozási dátuma.updated_atTIMESTAMP - Hiányzik a módosítás dátuma.
2.3 🟢 MEGLÉVŐ, HELYESEN MŰKÖDŐ
roleENUM - Jól definiált, 6 szerepkörrel.user_id+person_idkettős hivatkozás - Támogatja a "Dual Entity" modellt.is_permanent- Alkalmas az állandó vs. ideiglenes tagság megkülönböztetésére.
3. Backend Módosítás: get_my_organizations Fix
3.1 Probléma
Jelenleg a GET /api/v1/organizations/my lekérdezés (organizations.py:192) csak INNER JOIN-t használ az OrganizationMember táblával. Ez kizárja azokat az eseteket, ahol a felhasználó owner_id (technikai tulajdonos), de az OrganizationMember rekord nem található.
3.2 Megoldás
Használjunk LEFT JOIN-t OR feltétellel:
from sqlalchemy import or_
stmt = (
select(Organization)
.outerjoin(OrganizationMember, OrganizationMember.organization_id == Organization.id)
.where(
or_(
Organization.owner_id == current_user.id,
OrganizationMember.user_id == current_user.id
)
)
.where(Organization.org_type.notin_([OrgType.service_provider, OrgType.service]))
.where(Organization.is_deleted == False)
.distinct()
)
3.3 Válasz bővítése
A frontend számára szükséges a user_role mező:
user_role = None
for member in o.members:
if member.user_id == current_user.id:
user_role = member.role.value if hasattr(member.role, 'value') else str(member.role)
break
4. Frontend Módosítások
4.1 HeaderCompanySwitcher.vue - Jelenlegi állapot
A komponens már használja az authStore.myOrganizations adatokat, és szűri a companyOrganizations computed property-ben az individual, service_provider, service típusokat. Ez rendben van.
4.2 Szükséges változtatások
- Nincs változtatás szükséges a frontend logikában - a
fetchMyOrganizations()már meghívja a/organizations/myvégpontot, és acompanyOrganizationscomputed property megfelelően szűr. - OrganizationItem típus (
frontend/src/types/organization.ts) - már tartalmazza auser_rolemezőt (nem kötelező).
4.3 Aktív szervezet kiválasztás
A switchOrganization metódus (frontend/src/stores/auth.ts:631) már implementálva van, a PATCH /users/me/active-organization hívással. A frontend globális állapota frissül a user.value.active_organization_id mezővel.
5. Audit Jelentés: OrganizationMember & Invite Flow
5.1 Meglévő API Végpontok
| Végpont | Metódus | Státusz | Leírás |
|---|---|---|---|
| POST /organizations/{org_id}/invitations | POST | Letezik | Meghívó küldése email címre |
| POST /organizations/invitations/{token}/accept | POST | Letevezik | Meghívó elfogadása token alapján |
| POST /organizations/{org_id}/join-request | POST | Letevezik | Csatlakozási kérelem (ha van admin) |
| POST /organizations/{org_id}/claim/request | POST | Letevezik | Árva cég átvételi kérelem |
| POST /organizations/{org_id}/claim/verify | POST | Letevezik | Árva cég átvétel OTP-vel |
5.2 🔴 HIÁNYZÓ VÉGPONTOK (Kritikus)
| Végpont | Hiány | Hatás |
|---|---|---|
| GET /organizations/{org_id}/members | Nincs | Nincs lehetőség a tagok listázására |
| PATCH /organizations/{org_id}/members/{member_id}/role | Nincs | Nincs lehetőség a szerepkör módosítására |
| DELETE /organizations/{org_id}/members/{member_id} | Nincs | Nincs lehetőség a tag eltávolítására |
| GET /organizations/{org_id}/invitations | Nincs | Nincs lehetőség a függő meghívók listázására |
| DELETE /organizations/{org_id}/invitations/{invitation_id} | Nincs | Nincs lehetőség a meghívó visszavonására |
5.3 🔴 Kritikus Adatbázis Probléma
Az OrganizationMember modellben és az adatbázisban HIÁNYZIK a status oszlop, de a kód (organizations.py:421 és organizations.py:481) hivatkozik rá (status="pending", status="active"). Ez a meghívási folyamatban futási hibát okoz!
5.4 Meghívási Folyamat Ábrája
OWNER/ADMIN -> POST /invitations -> Van-e user?
|-> Igen -> Letrehoz OrganizationMember (user_id=target)
|-> Nem -> Letrehoz VerificationToken (token_type=org_invite)
|-> Email ertesites
|
Regisztracio utan -> POST /invitations/{token}/accept
-> Token validalas
-> Letezik-e mar tag?
|-> Igen -> Frissiti a szerepkört
|-> Nem -> Letrehozza a tag rekordot
-> Done
5.5 Javasolt Javítási Sorrend
- P0 - AZONNAL:
statusoszlop hozzáadása azOrganizationMembermodellhez és az adatbázishoz (sync_engine). - P0 - AZONNAL: Dátum oszlopok (
created_at,updated_at) hozzáadása. - P1 - JELEN FELADAT:
get_my_organizationsjavításaORlogikára. - P2 - KOVETKEZO: Tagkezelő API végpontok implementálása (list, role change, remove).
- P2 - KOVETKEZO: Meghívókezelő API végpontok (list pending, revoke).
6. Végrehajtási Terv
6.1 Backend változtatások (Code mód)
backend/app/models/marketplace/organization.py-OrganizationMembermodellbe hozzáadni:status,created_at,updated_atbackend/app/api/v1/endpoints/organizations.py-get_my_organizationsquery javításaORlogikára +DISTINCT+user_rolevisszaadása
6.2 Frontend változtatások (Code mód)
- Nincs szükség változtatásra - a frontend már helyesen használja az API-t.
6.3 Adatbázis szinkron
- Futtatni:
docker exec sf_api python3 -m app.scripts.sync_engine
7. Jóváhagyás
Kérem a felhasználó jóváhagyását a fenti tervhez! A jóváhagyás után:
- Létrehozom a Gitea feladatkártyákat
- Váltok Code módba a megvalósításhoz