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

470 lines
20 KiB
Markdown

# 🔧 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
```mermaid
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):**
```python
# 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:**
```python
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:
```python
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":
```javascript
{
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)
```python
"""
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:
```python
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:
```python
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ése**`GAMIFICATION_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ás**`final_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ás**`PointsLedger` rekord létrehozása
#### Master Config Alapértékek
```json
{
"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 >= 30``ServiceProfile.trust_score = 50` (megbízhatónak jelölve)
- `validation_score >= 70``ServiceProfile.trust_score = 80` (nagyon megbízható)
- `validation_score >= 100``ServiceProfile.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_DISCOVERY`**25 XP** (ha a point_rules-ban van)
5. Gamification: `USE_UNVERIFIED_PROVIDER`**200 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_CONFIRMATION`**50 XP** (új szabály)
5. Gamification: `USE_UNVERIFIED_PROVIDER`**200 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_USE`**100 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)
6. **Trigram similarity index** a `service_providers.name` oszlopon a jobb fuzzy match-hez
7. **Duplikáció detektálás** — ha két user ugyanazt a provider-t tölti fel, merge logika
8. **Bulk import** CSV-ből a meglévő provider-ek batch feltöltésére
9. **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)
10. **Provider reputation score** — az AssetCost tranzakciókból számolt automata reputáció
11. **Automata ServiceProfile upgrade** — ha egy provider-nek X db sikeres tranzakciója van
12. **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ő.*