Files
service-finder/plans/logic_spec_service_provider_discovery_admin.md
2026-07-01 02:27:38 +00:00

20 KiB

🔧 Logic Spec: Service Provider Discovery & Admin Integration

Verzió: 1.1
Dátum: 2026-06-30
Állapot: Tervezet (Architect Review)
Kapcsolódó Mérföldkő: Service Finder Marketplace & Expense Integration


1. 🎯 Modul Célja és Masterbook 2.0 Illeszkedés

Cél

A rendszer jelenleg három párhuzamos szolgáltatói adatforrással dolgozik:

  1. Crowdsourced (marketplace.service_providers) — Közösség által beküldött, moderálandó
  2. Robot-hunted (marketplace.service_staging) — Automata felderítésből
  3. Szervezeti (fleet.organizations) — Hivatalos garázs/szerviz profilok

A jelenlegi hiányosság: Nincs automatikus felderítés, amikor egy felhasználó költséget rögzít és egy ismeretlen szolgáltatói névvel találkozik. Emellett nincs admin felület a crowdsourced szolgáltatók moderálására.

Masterbook 2.0 Illeszkedés

  • P0 Hybrid Vendor Refactor — már megalapozta a ServiceProvider modellt és a quick_add_provider() szolgáltatást
  • Gross-First Könyvelés — a költség rögzítés az expense creation flow része
  • Triple Wallet / Gamification — a felderítés pontozható (XP a discovered provider-ekért)
  • Dual Control (Moderation) — a feltöltött/felderített szolgáltatóknak moderáción kell átesniük

2. 📊 Existing Module Map — Teljes Körkép

2.1 Modellek

Modell Tábla (Schema) Fájl Cél
ServiceProvider marketplace.service_providers identity/social.py:22 Crowdsourced providers, moderációval
ServiceProfile marketplace.service_profiles marketplace/service.py:21 Enriched profile (trust score, location)
ServiceStaging marketplace.service_staging marketplace/service.py:162 Robot-hunted, approval pending
ExpertiseTag marketplace.expertise_tags marketplace/service.py:83 4-level taxonomy
ServiceExpertise marketplace.service_expertise marketplace/service.py:146 Junction table
AssetCost fleet_finance.asset_costs fleet_finance/models.py:109 Költség rekord 3 vendor mezővel
Organization fleet.organizations marketplace/organization.py:73 Hivatalos garázs/szerviz szervezetek

2.2 Service Layer

Service Fájl Funkciók
search_providers() provider_service.py:138 Unified search, geo-filter, trust score
quick_add_provider() provider_service.py:473 Gyors ServiceProvider létrehozás + gamification
update_provider() provider_service.py:804 Provider adatok frissítése
CostService.record_cost() cost_service.py:23 Teljes költségrögzítés

2.3 API Endpointok

Végpont Prefix Fájl Funkció
GET /providers/search /providers providers.py:184 Unified service search
POST /providers/quick-add /providers providers.py:243 Quick add provider
PUT /providers/{id} /providers providers.py:279 Update provider
POST /expenses/ /expenses expenses.py:439 Create expense (hook pont!)
GET /categories/tree /providers providers.py:46 Category tree
POST /admin/services/{staging_id}/approve /admin admin.py:238 Staged service approval
GET/POST/PUT admin/gamification/... /admin/gamification admin_gamification.py:1 Gamification admin
GET/PATCH admin/organizations/... /admin/organizations admin_organizations.py:1 Organization CRM

2.4 Frontend Admin (Hiányzó oldalak)

Jelenlegi admin oldalak: frontend_admin/pages/

  • dashboard, users, persons, garages, packages, permissions
  • gamification/* (9 oldal)
  • NINCS: providers/, services/, marketplace/ oldal

3. 🔄 Auto-Discovery Flow: Expense → Provider Creation

3.1 Trigger Flow Diagram

flowchart TD
    A[POST /expenses/] --> B{external_vendor_name\nmegadva?}
    B -->|Nem| C[Normál költség rögzítés]
    B -->|Igen| D{service_provider_id\nmegadva?}
    D -->|Igen| E[Link meglévő providerhez]
    D -->|Nem| F[Név egyeztetés\nServiceProvider táblában]
    F --> G{Találat?}
    G -->|Igen, pontosan| H[Auto-link meglévőhöz]
    G -->|Igen, hasonló| I[Lehetőség: auto-link\nvagy új pending]
    G -->|Nem| J[Új ServiceProvider létrehozása]
    J --> K[status=pending\nsource=import\nvalidation_score=0]
    K --> L[added_by_user_id =\nköltséget rögzítő user]
    L --> M[Gamification XP jutalmazás]
    M --> N[AssetCost.service_provider_id \n= új provider.id]
    N --> O[Commit + response]

3.2 Implementációs Részletek

Hook pont: expenses.py:566-588 — Az AssetCost példányosítás előtt

Logikai lépések a create_expense-ben (a try blokk előtt):

# P0 SERVICE PROVIDER AUTO-DISCOVERY
resolved_service_provider_id = expense.service_provider_id

if expense.external_vendor_name and not expense.service_provider_id:
    # 1. Fuzzy match keresés
    from app.services.provider_service import find_or_create_provider_by_name
    result = await find_or_create_provider_by_name(
        db=db,
        name=expense.external_vendor_name,
        added_by_user_id=current_user.id,
    )
    resolved_service_provider_id = result.id

find_or_create_provider_by_name() logika:

async def find_or_create_provider_by_name(
    db: AsyncSession,
    name: str,
    added_by_user_id: int,
) -> ServiceProvider:
    """
    1. Exact match keresés (ILIKE)
    2. Fuzzy match (trigram similarity, pl. pg_trgm)
    3. Ha nincs találat -> új ServiceProvider létrehozása:
       - status = "pending"
       - source = "import" (API import forrás)
       - validation_score = 0
       - added_by_user_id = a költséget rögzítő user
    4. Gamification XP award (pl. SERVICE_PROVIDER_DISCOVERY)
    """

3.3 Adatbázis Módosítás

Nincs új tábla! A meglévő ServiceProvider modell minden szükséges mezőt tartalmaz:

  • name, address (opcionális, az expense-ből nem jön)
  • status -> pending (alapértelmezett)
  • source -> import (új value a SourceType enum-ban, már létezik: manual, ocr, import)
  • validation_score -> 0
  • added_by_user_id -> a költséget rögzítő user ID-ja

Csak a SourceType enum ellenőrzése: A jelenlegi érték api_import = "import" — ez megfelelő.


4. 🏛️ Admin Interface Integration

4.1 Backend Endpointok (admin/providers/)

Végpont Metódus Cél
GET /admin/providers LIST Szolgáltatók listázása szűréssel (status, source, search)
GET /admin/providers/{id} GET Részletes nézet
POST /admin/providers/{id}/approve POST Provider jóváhagyása (pending -> approved)
POST /admin/providers/{id}/reject POST Provider elutasítása (pending -> rejected)
POST /admin/providers/{id}/flag POST Provider megjelölése (approved -> flagged)
DELETE /admin/providers/{id} DELETE Provider törlése (soft delete)
GET /admin/providers/stats GET Statisztikák (pending count, total, etc.)

Új fájl: backend/app/api/v1/endpoints/admin_providers.py

Router regisztráció: api.py:48 — hozzáadni:

from app.api.v1.endpoints import admin_providers
api_router.include_router(admin_providers.router, prefix="/admin/providers", tags=["Admin Provider Moderation"])

4.2 Frontend Admin Oldalak

Új oldalak: frontend_admin/pages/providers/

Oldal Útvonal Funkció
Providers List /providers Lista szűréssel (pending/approved/rejected), keresés
Provider Detail /providers/[id] Részletes adatok, moderációs akciók
Pending Queue /providers/pending Csak a pending provider-ek (moderációs sor)

Sidebar menü módosítás: frontend_admin/layouts/default.vue:324 — Új menücsoport "Szolgáltatók":

{
    title: 'Szolgáltatók',
    items: [
        {
            label: 'Szolgáltatók',
            icon: '...',
            children: [
                {
                    path: '/providers',
                    label: 'Összes szolgáltató',
                    icon: '...',
                },
                {
                    path: '/providers/pending',
                    label: 'Jóváhagyásra váró',
                    icon: '...',
                },
            ],
        },
    ],
},

4.3 Admin Endpoint Minta (admin_providers.py)

"""
Admin Provider Moderation API

Végpontok:
    GET    /admin/providers                    — Szolgáltatók listázása
    GET    /admin/providers/{id}               — Részletes adatok
    POST   /admin/providers/{id}/approve       — Jóváhagyás (-> approved)
    POST   /admin/providers/{id}/reject        — Elutasítás (-> rejected)
    POST   /admin/providers/{id}/flag          — Megjelölés (-> flagged)
    DELETE /admin/providers/{id}               — Törlés (soft delete)
    GET    /admin/providers/stats              — Statisztikák
"""

5. 📝 Adatmodell és Alembic Terv

5.1 Meglévő Modell — Nincs Változás

A ServiceProvider modell már tartalmazza az összes szükséges mezőt. Nincs szükség új migrációra.

Ellenőrizendő: A SourceType enum tartalmazzon import értéket:

class SourceType(str, enum.Enum):
    manual = "manual"
    ocr = "ocr"
    api_import = "import"

5.2 Twin-technika (Többnyelvűség)

A ServiceProvider modellben nincs i18n mező (a név nem lesz fordítva). A kategóriák (ExpertiseTag) már támogatják a többnyelvűséget a name_hu, name_en mezőkkel.

5.3 Soft-delete

A ServiceProvider modell jelenleg nem támogatja a soft-delete-t. Ha szükséges, lehet hozzáadni:

is_deleted: Mapped[bool] = mapped_column(Boolean, default=False)
deleted_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True))

6. ⚙️ Admin Kontroll (Global/Country/Region/User)

A provider moderációhoz az alábbi SystemParameter változók javasoltak:

Paraméter Scope Default Leírás
PROVIDER_AUTO_APPROVE_TRUSTED_USERS global false Megbízható user-ek provider-ei auto-approved
PROVIDER_MAX_PENDING_PER_USER global 10 Maximum függőben lévő provider per user
PROVIDER_REQUIRE_VALIDATION_SCORE global 3 Minimum validation score az auto-approve-hoz
PROVIDER_DISCOVERY_XP global/gamification 25 XP jutalom provider felfedezésért

7. 🌍 Geo-Logika és Service Finder Algoritmus

7.1 Meglévő Geo Támogatás

A ServiceProfile modell marketplace/service.py:40 már tartalmaz PostGIS location mezőt és geo-keresést. A ServiceProvider viszont NEM rendelkezik location mezővel — csak szöveges címmel.

7.2 Provider -> ServiceProfile Upgrade Path

Az auto-discovered ServiceProvider-ekből később lehet ServiceProfile-t létrehozni (admin jóváhagyással). Ez a folyamat már létezik a quick_add_provider() függvényben, ami egyszerre hozza létre a ServiceProfile-t és a ServiceProvider-t.

Javaslat: Az auto-discovery csak a ServiceProvider szintig menjen. A ServiceProfile létrehozása maradjon admin feladat.


8. 🎮 Gamification Pontrendszer Részletes Specifikáció

8.1 Meglévő Pontszabályok (point_rules tábla)

Az alábbi pontszabályok már léteznek az adatbázisban:

action_key Pont Aktív Leírás
ADD_NEW_PROVIDER 500 Új szolgáltató rögzítése a rendszerbe
USE_UNVERIFIED_PROVIDER 200 Szervizesemény/költség rögzítése olyan szolgáltatónál, aminek még nincs 5 megerősítése
UPDATE_PROVIDER 100 Szolgáltató adatainak szerkesztése (kategóriák, címkék frissítése)
RATE_PROVIDER 250 Szolgáltató értékelése (tagekkel)
ASSET_REGISTER 100 Jármű regisztráció
ASSET_REVIEW 75 Jármű felülvizsgálat
TEST_ACTION 100 Test point rule

8.2 Gamification Rendszer Működése

Pontozási Folyamat (process_activity())

A GamificationService.process_activity() (gamification_service.py:52) az alábbi lépéseket hajtja végre:

  1. Admin Konfiguráció BetöltéseGAMIFICATION_MASTER_CONFIG JSON a system_parameters táblából
  2. Point Rules Lekérés — Ha action_key meg van adva, a point_rules táblából olvassa a pontértékeket (admin override)
  3. Büntetés Szűrés — Ha a user büntetés alatt áll, szorzó alkalmazása
  4. XP Számításfinal_xp = int(xp_amount * multiplier)
  5. Szintszámítás — Hatványfüggvény: Level = (XP/500)^(1/1.5) + 1
  6. Social Pont → Kredit Konverzió — Minden 100 social pont = 1 kredit (Wallet.earned_credits)
  7. NaplózásPointsLedger rekord létrehozása

Master Config Alapértékek

{
  "xp_logic": {"base_xp": 500, "exponent": 1.5},
  "penalty_logic": {
    "recovery_rate": 0.5,
    "thresholds": {"level_1": 100, "level_2": 500, "level_3": 1000},
    "multipliers": {"L0": 1.0, "L1": 0.5, "L2": 0.1, "L3": 0.0}
  },
  "conversion_logic": {"social_to_credit_rate": 100},
  "level_rewards": {"credits_per_10_levels": 50}
}

Szorzók Büntetési Szintek Szerint

Szint Küszöb (penalty_points) Szorzó Hatás
L0 0 1.0 (100%) Nincs korlátozás
L1 100+ 0.5 (50%) Fele annyi XP jár
L2 500+ 0.1 (10%) Csak 10% XP
L3 1000+ 0.0 (0%) Teljes blokkolás

8.3 Javasolt Új Pontszabályok a Provider Discovery Rendszerhez

Az alábbi új action_key-ek létrehozása javasolt a point_rules táblában:

action_key Javasolt Pont Leírás
PROVIDER_DISCOVERY 25 Provider felfedezése expense rögzítéskor (external_vendor_name alapján)
PROVIDER_CONFIRMATION 50 Már létező, de nem 100%-ban megerősített provider használata másik user által
PROVIDER_VERIFIED_USE 100 Már jóváhagyott (approved) provider használata

Indoklás:

  • A PROVIDER_DISCOVERY (25 XP) alacsonyabb, mint a USE_UNVERIFIED_PROVIDER (200 XP), mert a discovery csak a név beírásáért jár, míg a használatért több jár
  • A PROVIDER_CONFIRMATION (50 XP) egy kompromisszum: a user kap valamennyi XP-t, de kevesebbet, mint aki először fedezte fel
  • A PROVIDER_VERIFIED_USE (100 XP) jutalmazza a már ellenőrzött provider-ek használatát

8.4 Megbízhatósági Érték (Trust Score) Rendszer

Jelenlegi Állapot

  • ServiceProvider.validation_score (social.py:58) — Integer, default=0. A quick_add_provider() 50-re állítja.
  • ServiceProfile.trust_score (service.py:65) — Integer, default=30. A quick_add_provider() nem állítja be expliciten.

Javasolt Trust Score Számítás

A ServiceProvider.validation_score automatikus számítása:

Esemény validation_score változás
Új provider létrehozása (discovery) 0 (alapértelmezett)
Admin jóváhagyás (approve) +50
Második user használja (confirmation) +10
Harmadik user használja +5
Minden további user +2 (max +20-ig)
ServiceReview (értékelés) +5 per review (max +30)
OCR bizonylat kapcsolódik hozzá +3

Küszöbértékek:

  • validation_score >= 30ServiceProfile.trust_score = 50 (megbízhatónak jelölve)
  • validation_score >= 70ServiceProfile.trust_score = 80 (nagyon megbízható)
  • validation_score >= 100ServiceProfile.trust_score = 100 (teljesen megbízható)

8.5 Példa: Teljes Pontozási Folyamat

Scenario 1: Új provider felfedezése

  1. User A rögzíti a költséget external_vendor_name="János Autószerviz"
  2. A rendszer nem találja a ServiceProvider táblában
  3. Létrejön: ServiceProvider(name="János Autószerviz", status=pending, source=import, validation_score=0, added_by_user_id=A)
  4. Gamification: PROVIDER_DISCOVERY25 XP (ha a point_rules-ban van)
  5. Gamification: USE_UNVERIFIED_PROVIDER200 XP (már létező szabály)
  6. Összesen: 225 XP a user-nek
  7. A provider validation_score = 0 (még nincs megerősítve)

Scenario 2: Meglévő provider megerősítése másik user által

  1. User B rögzíti a költséget external_vendor_name="János Autószerviz"
  2. A rendszer megtalálja a meglévő ServiceProvider-t (status=pending, validation_score=0)
  3. Auto-link a meglévő provider-hez
  4. Gamification: PROVIDER_CONFIRMATION50 XP (új szabály)
  5. Gamification: USE_UNVERIFIED_PROVIDER200 XP (már létező szabály)
  6. Összesen: 250 XP a user-nek
  7. A provider validation_score += 10 → most 10

Scenario 3: Már jóváhagyott provider használata

  1. Admin jóváhagyta a provider-t (validation_score = 50)
  2. User C rögzíti a költséget és kiválasztja a provider-t
  3. Gamification: PROVIDER_VERIFIED_USE100 XP
  4. A provider validation_score += 2 → most 52

8.6 Kredit Rendszer

  • Social pont → Kredit konverzió: 100 social pont = 1 kredit (Wallet.earned_credits)
  • A kredit a Wallet modellben (identity/identity.py:248) tárolódik
  • A kredit felhasználható: prémium funkciók, szolgáltatások vásárlása
  • Szintlépési jutalom: Minden 10. szintnél +50 kredit

9. 🚀 Továbbfejlesztési Javaslatok

9.1 Rövidtávú (P0 — Kötelező)

  1. Auto-discovery hook az expenses.py:439 create_expense végpontban
  2. find_or_create_provider_by_name() szolgáltatás a provider_service.py-ben
  3. Admin provider moderation endpointok — új admin_providers.py
  4. Frontend admin providers oldal — új providers/ oldalak
  5. Új point_rules létrehozása: PROVIDER_DISCOVERY (25), PROVIDER_CONFIRMATION (50), PROVIDER_VERIFIED_USE (100)

9.2 Középtávú (P1 — Javasolt)

  1. Trigram similarity index a service_providers.name oszlopon a jobb fuzzy match-hez
  2. Duplikáció detektálás — ha két user ugyanazt a provider-t tölti fel, merge logika
  3. Bulk import CSV-ből a meglévő provider-ek batch feltöltésére
  4. Trust score automatizálás — a validation_score automatikus számítása a használati statisztikák alapján

9.3 Hosszútávú (P2 — Jövőbeli)

  1. Provider reputation score — az AssetCost tranzakciókból számolt automata reputáció
  2. Automata ServiceProfile upgrade — ha egy provider-nek X db sikeres tranzakciója van
  3. Provider matching OCR-ből — ha egy OCR bizonylaton szereplő cégnév ismeretlen

10. 🔐 Biztonsági és Naplózási Szempontok

Audit Log

Minden moderációs akciót (approve, reject, flag) naplózni kell az AuditLog táblába:

  • action: "PROVIDER_APPROVED" / "PROVIDER_REJECTED" / "PROVIDER_FLAGGED"
  • entity_type: "service_provider"
  • entity_id: provider.id
  • actor_id: admin user ID
  • details: JSON with reason

RBAC

  • providers:moderate — képeség a provider moderációs endpointokhoz
  • providers:view — csak olvasási jog a provider listához

11. Jóváhagyási Pont (Architect Review)

Jelen dokumentum jóváhagyása után az alábbi Gitea kártyák kerülnek létrehozásra:

# Cím Scope Type
1 Auto-discovery hook expense creation-ben Backend Feature
2 find_or_create_provider_by_name() service Backend Feature
3 Admin provider moderation API (admin_providers.py) Backend, API Feature
4 Frontend admin providers oldal (list + detail + pending) Frontend Feature
5 Sidebar menü bővítés providers modullal Frontend Feature

Jóváhagyás után a Code módban történő implementáció megkezdhető.