Files
service-finder/plans/logic_spec_garage_selector_member_audit.md
2026-06-17 22:07:55 +00:00

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)

  1. status VARCHAR - 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.
  2. joined_at TIMESTAMP - Nincs nyomon követve, mikor csatlakozott a tag.
  3. expires_at / valid_until TIMESTAMP - Nincs lejárati dátum (pl. ideiglenes hozzáféréshez).
  4. created_at TIMESTAMP - Hiányzik a tag rekord létrehozási dátuma.
  5. updated_at TIMESTAMP - Hiányzik a módosítás dátuma.

2.3 🟢 MEGLÉVŐ, HELYESEN MŰKÖDŐ

  • role ENUM - Jól definiált, 6 szerepkörrel.
  • user_id + person_id kettő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

  1. Nincs változtatás szükséges a frontend logikában - a fetchMyOrganizations() már meghívja a /organizations/my végpontot, és a companyOrganizations computed property megfelelően szűr.
  2. OrganizationItem típus (frontend/src/types/organization.ts) - már tartalmazza a user_role mező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

  1. P0 - AZONNAL: status oszlop hozzáadása az OrganizationMember modellhez és az adatbázishoz (sync_engine).
  2. P0 - AZONNAL: Dátum oszlopok (created_at, updated_at) hozzáadása.
  3. P1 - JELEN FELADAT: get_my_organizations javítása OR logikára.
  4. P2 - KOVETKEZO: Tagkezelő API végpontok implementálása (list, role change, remove).
  5. 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)

  1. backend/app/models/marketplace/organization.py - OrganizationMember modellbe hozzáadni: status, created_at, updated_at
  2. backend/app/api/v1/endpoints/organizations.py - get_my_organizations query javítása OR logikára + DISTINCT + user_role visszaadá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:

  1. Létrehozom a Gitea feladatkártyákat
  2. Váltok Code módba a megvalósításhoz