szolgáltatók beálltásai, szerkesztése , létrehozása
This commit is contained in:
223
docs/provider_services_category_analysis_2026-06-17.md
Normal file
223
docs/provider_services_category_analysis_2026-06-17.md
Normal file
@@ -0,0 +1,223 @@
|
||||
# Szolgáltatók Szolgáltatásainak (Category/Specialization) Adatfolyam Elemzése
|
||||
|
||||
**Dátum:** 2026-06-17
|
||||
**Készítette:** Rendszer-Architect
|
||||
**Cél:** A szolgáltatók kategóriáinak és szolgáltatásainak teljes verem (adatbázis → backend → frontend) adatfolyamának feltérképezése.
|
||||
|
||||
---
|
||||
|
||||
## Összefoglalás
|
||||
|
||||
A vizsgálat során kiderült, hogy a szolgáltatók kategóriáinak (category) adatfolyama **megszakadt** a backend és a frontend között. A `search_providers()` SQL lekérdezése nem csatlakoztatja a `ServiceExpertise` → `ExpertiseTag` láncot, ezért a `category` mező minden keresési találatnál `None`. Emiatt a frontenden minden kártyán a "Nincs kategória" placeholder látszik, és a detail modalban a kategória blokk teljesen láthatatlan.
|
||||
|
||||
---
|
||||
|
||||
## 1. Adatbázis Réteg
|
||||
|
||||
### 1.1. Érintett Táblák
|
||||
|
||||
| Tábla | Séma | Szerep | Category-t tartalmaz? |
|
||||
|-------|------|--------|----------------------|
|
||||
| ExpertiseTag | marketplace.expertise_tags | Mesterlista - szakmai címkék | Igen - key, name_hu, name_en, category |
|
||||
| ServiceExpertise | marketplace.service_expertises | Kapcsolótábla - service / expertise | Csak FK (service_id, expertise_id) |
|
||||
| ServiceProfile | marketplace.service_profiles | Szerviz szolgáltató profilja | JSONB-ben: specialization_tags.primary_category |
|
||||
| Organization | fleet.organizations | Szervezet (nincs közvetlen category) | Nincs category mező |
|
||||
|
||||
### 1.2. Kapcsolatok
|
||||
|
||||
```
|
||||
ExpertiseTag (marketplace.expertise_tags)
|
||||
^ expertise_id
|
||||
ServiceExpertise (marketplace.service_expertises)
|
||||
^ service_id
|
||||
ServiceProfile (marketplace.service_profiles)
|
||||
^ organization_id (unique)
|
||||
Organization (fleet.organizations)
|
||||
```
|
||||
|
||||
### 1.3. ExpertiseTag Tábla Szerkezete
|
||||
|
||||
| Mezo | Típus | Leírás |
|
||||
|------|-------|--------|
|
||||
| id | Integer (PK) | |
|
||||
| key | String(50), unique | Pl. "auto_szerelo", "gumiszerviz" |
|
||||
| name_hu | String(100) | Magyar név, pl. "Autószerelő" |
|
||||
| name_en | String(100) | Angol név, pl. "Car mechanic" |
|
||||
| category | String(30) | Csoportosító, pl. "auto" |
|
||||
| is_official | Boolean | Hivatalos-e |
|
||||
| search_keywords | JSONB | Keresőkulcsszavak |
|
||||
| icon | String(50) | Ikon neve |
|
||||
|
||||
### 1.4. ServiceProfile.specialization_tags JSONB Szerkezet
|
||||
|
||||
```json
|
||||
{
|
||||
"primary_category": "auto_szerelo",
|
||||
"user_tags": ["olajcsere", "fék", "klíma"]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Backend API Réteg
|
||||
|
||||
### 2.1. GET /categories (Muködik)
|
||||
|
||||
**Végpont:** backend/app/api/v1/endpoints/providers.py:30
|
||||
|
||||
**Séma:** backend/app/schemas/provider.py:14 - ExpertiseCategoryOut
|
||||
|
||||
Visszaadja az összes ExpertiseTag rekordot. Használja a ProviderQuickAddModal a category_id kiválasztáshoz.
|
||||
|
||||
### 2.2. GET /search (KRITIKUS HIBA)
|
||||
|
||||
**Végpont:** backend/app/api/v1/endpoints/providers.py:60
|
||||
|
||||
**Szolgáltatás:** backend/app/services/provider_service.py:130 - search_providers()
|
||||
|
||||
**Séma:** backend/app/schemas/provider.py:25 - ProviderSearchResult
|
||||
|
||||
```python
|
||||
class ProviderSearchResult(BaseModel):
|
||||
id: int
|
||||
name: str
|
||||
category: Optional[str] = None # DEFAULT: None!
|
||||
specialization: List[str] = Field(default_factory=list)
|
||||
```
|
||||
|
||||
#### A HIBA: Az org_stmt SELECT nem tartalmazza a category-t
|
||||
|
||||
A provider_service.py:194-225 sorokban az org_stmt SELECT listája:
|
||||
|
||||
```python
|
||||
org_stmt = select(
|
||||
Organization.id.label("id"),
|
||||
Organization.name.label("name"),
|
||||
# ... címmezok ...
|
||||
ServiceProfile.specialization_tags.label("specialization_tags"),
|
||||
case(...).label("source"),
|
||||
# HIÁNYZIK: LEFT JOIN a ServiceExpertise / ExpertiseTag láncon
|
||||
# HIÁNYZIK: category lekeres
|
||||
).outerjoin(ServiceProfile, ...)
|
||||
```
|
||||
|
||||
#### Eredmény: A ProviderSearchResult építésekor (318-342. sor) a category soha nincs beállítva
|
||||
|
||||
```python
|
||||
for row in rows:
|
||||
results.append(
|
||||
ProviderSearchResult(
|
||||
id=row.id,
|
||||
name=row.name,
|
||||
# category itt NINCS paraméterként! -> default: None
|
||||
tags=tags_list,
|
||||
source=row.source,
|
||||
is_verified=row.is_verified,
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### 2.3. POST /quick-add (Muködik)
|
||||
|
||||
**Végpont:** backend/app/api/v1/endpoints/providers.py:98
|
||||
|
||||
Helyesen hozza létre a ServiceExpertise kapcsolatot:
|
||||
|
||||
```python
|
||||
expertise = ServiceExpertise(
|
||||
service_id=profile.id,
|
||||
expertise_id=data.category_id,
|
||||
confidence_level=50,
|
||||
)
|
||||
db.add(expertise)
|
||||
```
|
||||
|
||||
### 2.4. PUT /{provider_id} - NEM kezeli a category-t
|
||||
|
||||
A ProviderUpdateIn séma **NEM tartalmaz category_id-t**, csak name, címmezok, contact_phone, email, website, tags.
|
||||
|
||||
---
|
||||
|
||||
## 3. Frontend Réteg
|
||||
|
||||
### 3.1. Kártya (ServiceFinderView.vue)
|
||||
|
||||
**Category badge (263-277. sor):**
|
||||
```vue
|
||||
<span v-if="provider.category">...SOHA nem fut le, mert category = None...</span>
|
||||
<span v-else>...MINDEN kártyán "Nincs kategória"...</span>
|
||||
```
|
||||
|
||||
**Specialization chips (244-261. sor):** A provider.specialization lista megjelenik, ha van benne adat.
|
||||
|
||||
### 3.2. Detail Modal (ProviderDetailModal.vue)
|
||||
|
||||
**Category blokk (42-52. sor):** v-if="provider.category" mindig false -> a blokk láthatatlan.
|
||||
|
||||
### 3.3. Edit Modal (ProviderEditModal.vue)
|
||||
|
||||
**HIÁNYZIK:** Nincs kategória kiválasztó mező! Csak name, címmezok, phone, email, website, tagsInput.
|
||||
|
||||
### 3.4. Quick-Add Modal (ProviderQuickAddModal.vue)
|
||||
|
||||
Tartalmaz category_id kiválasztó dropdown-ot, ami a GET /categories-ból tölti az adatokat.
|
||||
|
||||
---
|
||||
|
||||
## 4. Fejlesztési Javaslatok
|
||||
|
||||
### #1 (KRITIKUS) - Category lekerese a search API-ban
|
||||
|
||||
**Probléma:** A search_providers() nem tolti be a category-t.
|
||||
|
||||
**Megoldás:** Correlated subquery hozzaadasa:
|
||||
|
||||
```python
|
||||
category_subquery = (
|
||||
select(ExpertiseTag.name_hu)
|
||||
.select_from(ServiceExpertise)
|
||||
.join(ExpertiseTag, ServiceExpertise.expertise_id == ExpertiseTag.id)
|
||||
.where(ServiceExpertise.service_id == ServiceProfile.id)
|
||||
.limit(1)
|
||||
.correlate(ServiceProfile)
|
||||
.label("category")
|
||||
)
|
||||
```
|
||||
|
||||
**Erintett fajlok:**
|
||||
- backend/app/services/provider_service.py:194 - org_stmt SELECT kiegeszitese
|
||||
- backend/app/services/provider_service.py:326 - ProviderSearchResult epitesekor category atadasa
|
||||
|
||||
### #2 (HIÁNYZÓ FUNKCIÓ) - Kategoria kivalaszto az Edit Modalban
|
||||
|
||||
**Probléma:** Az EditModal nem tartalmaz kategoria kivalasztot.
|
||||
|
||||
**Megoldás:** Kategoria dropdown hozzaadasa, ami betolti a GET /categories adatait.
|
||||
|
||||
**Erintett fajlok:**
|
||||
- frontend/src/components/provider/ProviderEditModal.vue - uj kategoria kivalaszto
|
||||
- backend/app/schemas/provider.py:89 - ProviderUpdateIn kiegeszitese category_id mezovel
|
||||
- backend/app/services/provider_service.py:497 - update_provider() kiegeszitese ServiceExpertise kezelessel
|
||||
|
||||
### #3 (HIÁNYZÓ FUNKCIÓ) - Category szuro implementalasa
|
||||
|
||||
**Probléma:** A search_providers() fuggveny elfogadja a category parametert, de nem hasznalja a szureshez.
|
||||
|
||||
### #4 (ADAT INTEGRITÁS) - Category fogalmanak tisztazasa
|
||||
|
||||
Javaslat: A category mezo a ProviderSearchResult-ban az ExpertiseTag.name_hu erteket tartalmazza (a felhasznalo szamara ertelmes nevet), nem pedig a technikai category csoportosítót.
|
||||
|
||||
---
|
||||
|
||||
## 5. Érintett Fájlok Listája
|
||||
|
||||
| Fájl | Szerep | Status |
|
||||
|------|--------|--------|
|
||||
| backend/app/models/marketplace/service.py | Adatbázis modellek | OK |
|
||||
| backend/app/schemas/provider.py | Pydantic sémák | OK (de hianyzik category_id a ProviderUpdateIn-bol) |
|
||||
| backend/app/services/provider_service.py | Üzleti logika | HIBA: hianyzik a category JOIN |
|
||||
| backend/app/api/v1/endpoints/providers.py | API végpontok | OK |
|
||||
| frontend/src/views/ServiceFinderView.vue | Kereso nézet | OK (de category = None) |
|
||||
| frontend/src/components/provider/ProviderDetailModal.vue | Detail modal | OK (de category blokk rejtve) |
|
||||
| frontend/src/components/provider/ProviderEditModal.vue | Edit modal | HIANYZIK a kategoria kivalaszto |
|
||||
| frontend/src/components/provider/ProviderQuickAddModal.vue | Gyors felvetel | OK |
|
||||
Reference in New Issue
Block a user