szolgáltatók beálltásai, szerkesztése , létrehozása
This commit is contained in:
194
docs/database_address_audit_2026-06-17.md
Normal file
194
docs/database_address_audit_2026-06-17.md
Normal file
@@ -0,0 +1,194 @@
|
||||
# 🔍 Deep Dive Audit Jelentés — Címek, API sémák & Autónyíri Kft. (ID 58)
|
||||
|
||||
**Dátum:** 2026-06-17
|
||||
**Auditor:** Architect Mode
|
||||
**Cél:** A cím szétdarabolás, kapcsolatfelvételi mezők és API sémák állapotának felmérése
|
||||
|
||||
---
|
||||
|
||||
## 1. ADATBÁZIS SÉMA AUDIT — Organization modell
|
||||
|
||||
**Fájl:** [`backend/app/models/marketplace/organization.py`](backend/app/models/marketplace/organization.py)
|
||||
|
||||
### 1.1 Cím mezők az `Organization` táblában (`fleet.organizations`)
|
||||
|
||||
A modell **rendelkezik atomizált címmezőkkel**:
|
||||
|
||||
| Mező | Típus | Hossz | Leírás |
|
||||
|------|-------|-------|--------|
|
||||
| `address_id` | PG_UUID, FK→`system.addresses.id` | - | Opcionális hivatkozás a központi cím táblára |
|
||||
| `address_zip` | String | 10 | Irányítószám |
|
||||
| `address_city` | String | 100 | Város |
|
||||
| `address_street_name` | String | 150 | **Utca név** (pl. "Egressy u.") |
|
||||
| `address_street_type` | String | 50 | **Közterület típus** (pl. "utca", "út", "tér") — jelenleg null |
|
||||
| `address_house_number` | String | 20 | **Házszám** (pl. "4.") — jelenleg null |
|
||||
| `address_hrsz` | String | 50 | Helyrajzi szám |
|
||||
|
||||
**Megjegyzés:** A `Branch` modell még tovább bontja: `stairwell`, `floor`, `door` — ezek az `Organization`-ben **nincsenek** implementálva, de a `CorpOnboardIn` séma tartalmazza őket.
|
||||
|
||||
### 1.2 Kapcsolatfelvételi mezők
|
||||
|
||||
**Az `Organization` modell NEM tartalmazza a következőket:**
|
||||
- ❌ `contact_phone`
|
||||
- ❌ `contact_email`
|
||||
- ❌ `website`
|
||||
|
||||
**Ezek a `ServiceProfile` modellben vannak** ([`backend/app/models/marketplace/service.py`](backend/app/models/marketplace/service.py:66)):
|
||||
|
||||
| Mező | Típus | Tábla |
|
||||
|------|-------|-------|
|
||||
| `contact_phone` | String | `marketplace.service_profiles` |
|
||||
| `contact_email` | String | `marketplace.service_profiles` |
|
||||
| `website` | String | `marketplace.service_profiles` |
|
||||
|
||||
**Következtetés:** A kapcsolatfelvételi adatok **szét vannak szórva** két tábla között. Az Organization-ben tárolódnak a címadatok, míg a ServiceProfile-ban a telefon/email/weboldal. Ez egy **1:1 kapcsolat** `organization_id`-n keresztül.
|
||||
|
||||
---
|
||||
|
||||
## 2. API SÉMA AUDIT — Provider Pydantic sémák
|
||||
|
||||
**Fájl:** [`backend/app/schemas/provider.py`](backend/app/schemas/provider.py)
|
||||
|
||||
### 2.1 CRITICAL BUG: A `ProviderQuickAddIn` és `ProviderUpdateIn` sérülékeny
|
||||
|
||||
Mindkét séma **összevont `street` mezőt** használ:
|
||||
|
||||
```python
|
||||
# provider.py sor 59
|
||||
street: Optional[str] = Field(None, max_length=255, description="Utca, házszám")
|
||||
```
|
||||
|
||||
Eközben a modell (`Organization`) **atomizált** mezőket vár:
|
||||
|
||||
```python
|
||||
# organization.py sor 83-86
|
||||
address_street_name: Mapped[Optional[str]] # Utca név
|
||||
address_street_type: Mapped[Optional[str]] # Közterület típus
|
||||
address_house_number: Mapped[Optional[str]] # Házszám
|
||||
```
|
||||
|
||||
**A `quick_add_provider()` függvény** ([`provider_service.py:403`](backend/app/services/provider_service.py:403)) a teljes `street` sztringet az `address_street_name`-be tömöríti:
|
||||
|
||||
```python
|
||||
org.address_street_name = data.street, # "Egressy u. 4." → address_street_name
|
||||
```
|
||||
|
||||
**Következmény:** `address_street_type` és `address_house_number` **mindig `null`** maradnak a crowdsource-olt szolgáltatóknál!
|
||||
|
||||
### 2.2 A `ProviderSearchResult` séma hiányosságai
|
||||
|
||||
A `ProviderSearchResult` ([`provider.py:21`](backend/app/schemas/provider.py:21)) **nem tartalmazza az atomizált címmezőket**:
|
||||
- ❌ `address_street_name` — hiányzik
|
||||
- ❌ `address_street_type` — hiányzik
|
||||
- ❌ `address_house_number` — hiányzik
|
||||
- ❌ `address_hrsz` — hiányzik
|
||||
- ✅ `address_zip` — van
|
||||
- ⚠️ `address` — generic string (összefűzött)
|
||||
- ⚠️ `city` — generic string
|
||||
|
||||
### 2.3 A `CorpOnboardIn` séma (organization.py) helyes
|
||||
|
||||
A [`CorpOnboardIn`](backend/app/schemas/organization.py:10) **helyesen tartalmazza** az összes atomizált mezőt:
|
||||
`address_zip`, `address_city`, `address_street_name`, `address_street_type`, `address_house_number`, `address_stairwell`, `address_floor`, `address_door`, `address_hrsz`
|
||||
|
||||
Az [`OrganizationUpdate`](backend/app/schemas/organization.py:41) is helyes.
|
||||
|
||||
---
|
||||
|
||||
## 3. NYERS ADAT — Autónyíri Kft. (ID 58)
|
||||
|
||||
### 3.1 Organization rekord
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 58,
|
||||
"name": "Autónyíri Kft.",
|
||||
"full_name": "Autónyíri Kft.",
|
||||
"org_type": "service_provider",
|
||||
"status": "pending_verification",
|
||||
"is_verified": false,
|
||||
"is_active": true,
|
||||
"is_deleted": false,
|
||||
"tax_number": null,
|
||||
"reg_number": null,
|
||||
"country_code": "HU",
|
||||
"language": "hu",
|
||||
"default_currency": "HUF",
|
||||
"address_id": null,
|
||||
"address_zip": null,
|
||||
"address_city": "Dunakeszi",
|
||||
"address_street_name": "Egressy u. 4.",
|
||||
"address_street_type": null,
|
||||
"address_house_number": null,
|
||||
"address_hrsz": null,
|
||||
"first_registered_at": "2026-06-16 23:16:23",
|
||||
"lifecycle_index": 1,
|
||||
"subscription_plan": "FREE",
|
||||
"owner_id": 2,
|
||||
"legal_owner_id": null,
|
||||
"folder_slug": "84632013004e",
|
||||
"aliases": [],
|
||||
"tags": [],
|
||||
"external_integration_config": {},
|
||||
"visual_settings": {"theme": "default", "primary_color": null, "wall_logo_url": null}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 ServiceProfile rekord
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 3,
|
||||
"organization_id": 58,
|
||||
"status": "ghost",
|
||||
"contact_phone": null,
|
||||
"contact_email": null,
|
||||
"website": null,
|
||||
"bio": null,
|
||||
"is_verified": false,
|
||||
"trust_score": 30,
|
||||
"rating": null,
|
||||
"specialization_tags": {"primary_category": "auto_szerelo"}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 Branch rekord
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "3b80ee85-7712-4b17-b992-d62dcefdf5e2",
|
||||
"name": "Autónyíri Kft.",
|
||||
"is_main": true,
|
||||
"status": "active",
|
||||
"city": "Dunakeszi",
|
||||
"street_name": "Egressy u. 4.",
|
||||
"street_type": null,
|
||||
"house_number": null,
|
||||
"postal_code": null
|
||||
}
|
||||
```
|
||||
|
||||
### 3.4 Megállapítások az ID=58-ról
|
||||
|
||||
1. **Cím szétdarabolás hiánya:** `address_street_name` = "Egressy u. 4." — a teljes utca+házszám egyben. A `street_type` és `house_number` feldolgozatlan.
|
||||
2. **Nincs kapcsolatfelvételi adat:** `contact_phone`, `contact_email`, `website` — mind `null` a ServiceProfile-ban.
|
||||
3. **Nincs adószám:** `tax_number` = null — bár ez egy Kft.
|
||||
4. **Crowdsource-olt rekord:** `external_integration_config` = `{}` (üres) — a source nincs beállítva, bár a kód logikája szerint "crowdsourced" kéne legyen.
|
||||
|
||||
---
|
||||
|
||||
## 4. ÖSSZEFOGLALÓ — Feltárt problémák
|
||||
|
||||
| # | Probléma | Hatás | Súlyosság |
|
||||
|---|----------|-------|-----------|
|
||||
| P1 | `ProviderQuickAddIn` és `ProviderUpdateIn` összevont `street` mezőt használ atomizált `address_street_name`/`_type`/`_house_number` helyett | A cím soha nem kerül szétdarabolásra. A `street_type` és `house_number` mindig `null` marad. | 🔴 MAGAS |
|
||||
| P2 | `ProviderSearchResult` séma nem tartalmazza az atomizált címmezőket | A frontend nem tudja megjeleníteni a szétdarabolt címet. | 🟠 KÖZEPES |
|
||||
| P3 | Kapcsolatfelvételi adatok (telefon, email, weboldal) a ServiceProfile-ban vannak, de a gyors felvételkor üresen maradnak | Az Autónyíri Kft.-nek nincs elérhetősége az adatbázisban. | 🟠 KÖZEPES |
|
||||
| P4 | `OrganizationResponse` séma nem adja vissza a címmezőket | A frontend `OrganizationUpdate`-on keresztül írhat címet, de `OrganizationResponse`-on keresztül nem olvassa vissza. | 🟡 ALACSONY |
|
||||
| P5 | A `Branch` modellben is hiányzik a `street_type`/`house_number` az autónyíris rekordnál | A Branch címe is strukturálatlan | 🟡 ALACSONY |
|
||||
|
||||
### Javasolt javítási sorrend:
|
||||
1. **P1:** A `ProviderQuickAddIn` és `ProviderUpdateIn` sémák kiterjesztése atomizált mezőkkel (`address_street_name`, `address_street_type`, `address_house_number`)
|
||||
2. **P2:** A `ProviderSearchResult` kibővítése az atomizált címmezőkkel
|
||||
3. **P3:** A frontend űrlapok kiegészítése telefonszám, email és weboldal mezőkkel a gyors felvételnél
|
||||
4. **P5:** A Branch létrehozásánál a `street_type` és `house_number` mezők feltöltése
|
||||
540
docs/database_schema_audit_partner_models_2026-06-16.md
Normal file
540
docs/database_schema_audit_partner_models_2026-06-16.md
Normal file
@@ -0,0 +1,540 @@
|
||||
# 🏗️ Teljes Adatbázis Séma Audit & Partner Modell Felfedezés
|
||||
|
||||
**Dátum:** 2026-06-16
|
||||
**Auditor:** Rendszer-Architect (DeepSeek Reasoner)
|
||||
**Cél:** Partner/Szolgáltató modellek azonosítása és a teljes adatbázis térkép elkészítése
|
||||
|
||||
---
|
||||
|
||||
## 1. 🔍 CÉLTUDATOS KERESÉS: Cégek / Partnerek / Szolgáltatók
|
||||
|
||||
### 1.1. Találatok összefoglalása
|
||||
|
||||
| Keresőszó | Találat | Modell | Séma |
|
||||
|-----------|---------|--------|------|
|
||||
| **Company** | ✅ VAN | `Organization` | `fleet.organizations` |
|
||||
| **Partner** | ✅ RÉSZBEN | `Organization.is_affiliate_partner` | `fleet.organizations` |
|
||||
| **Vendor** | ❌ NINCS | - | - |
|
||||
| **ServiceProvider** | ✅ VAN | `ServiceProvider` (régi) | `marketplace.service_providers` |
|
||||
| **ServiceProfile** | ✅ VAN | `ServiceProfile` (új) | `marketplace.service_profiles` |
|
||||
| **Contact/Person** | ✅ VAN | `Person` | `identity.persons` |
|
||||
| **Tenant** | ❌ NINCS | - | - |
|
||||
| **Business** | ✅ VAN | `Organization` (org_type=business) | `fleet.organizations` |
|
||||
| **Branch/Location** | ✅ VAN | `Branch` | `fleet.branches` |
|
||||
|
||||
### 1.2. Fő következtetés
|
||||
|
||||
**NINCS dedikált "Partner" vagy "Szolgáltató" modell.**
|
||||
A rendszer **két különböző, egymástól független** entitáskészlettel dolgozik:
|
||||
|
||||
1. **`fleet.organizations`** - Szervezetek (Cégek, Flották, Egyéni vállalkozók)
|
||||
2. **`marketplace.service_providers`** + **`marketplace.service_profiles`** - Szerviz szolgáltatók
|
||||
|
||||
Ez a két világ **gyengén kapcsolódik** egymáshoz: a `ServiceProfile` hivatkozhat egy `Organization`-ra, de ez opcionális.
|
||||
|
||||
---
|
||||
|
||||
## 2. 📋 MEGLÉVŐ MODELLEK RÉSZLETES ELEMZÉSE
|
||||
|
||||
### 2.1. `fleet.organizations` (Organization modell)
|
||||
|
||||
**Fájl:** `backend/app/models/marketplace/organization.py`
|
||||
**Tábla:** `fleet.organizations`
|
||||
|
||||
**Oszlopok csoportosítva:**
|
||||
|
||||
#### 🏢 Alapadatok
|
||||
| Oszlop | Típus | Kötelező? | Megjegyzés |
|
||||
|--------|-------|-----------|------------|
|
||||
| `id` | `INTEGER` | ✅ | PK |
|
||||
| `name` | `VARCHAR(255)` | ✅ | Cégnév |
|
||||
| `full_name` | `VARCHAR` | ✅ | Teljes cégnév |
|
||||
| `display_name` | `VARCHAR(50)` | ❌ | Rövid megjelenítési név |
|
||||
| `folder_slug` | `VARCHAR(12)` | ✅ | **UNIQUE** Rendszer azonosító |
|
||||
| `org_type` | `ENUM(OrgType)` | ✅ | `individual`, `service`, `service_provider`, `fleet_owner`, `club`, `business` |
|
||||
|
||||
#### 📍 Cím adatok (Denormalizált)
|
||||
| Oszlop | Típus |
|
||||
|--------|-------|
|
||||
| `address_id` | `UUID (FK → system.addresses.id)` |
|
||||
| `address_zip`, `address_city`, `address_street_name`, `address_street_type`, `address_house_number`, `address_hrsz` | `VARCHAR` |
|
||||
| `country_code` | `VARCHAR(2)` → default "HU" |
|
||||
| `language` | `VARCHAR(5)` → default "hu" |
|
||||
|
||||
#### 🆔 Adóazonosítók
|
||||
| Oszlop | Típus | Megjegyzés |
|
||||
|--------|-------|------------|
|
||||
| `tax_number` | `VARCHAR(20)` | **UNIQUE** Adószám |
|
||||
| `reg_number` | `VARCHAR(50)` | Cégjegyzékszám |
|
||||
|
||||
#### 🛡️ Életút / Biztonság
|
||||
| Oszlop | Típus | Megjegyzés |
|
||||
|--------|-------|------------|
|
||||
| `legal_owner_id` | `BIGINT (FK → identity.persons.id)` | Jogi képviselő (Person) |
|
||||
| `owner_id` | `INTEGER (FK → identity.users.id)` | Technikai tulajdonos (User) |
|
||||
| `first_registered_at` | `TIMESTAMPTZ` | Első regisztráció (örök) |
|
||||
| `current_lifecycle_started_at` | `TIMESTAMPTZ` | Aktuális életciklus kezdete |
|
||||
| `lifecycle_index` | `INTEGER` | Hányadik életciklus |
|
||||
| `is_deleted` | `BOOLEAN` | Soft delete flag |
|
||||
| `is_active` | `BOOLEAN` | Aktív flag |
|
||||
| `is_anonymized` | `BOOLEAN` | Anonimizált flag |
|
||||
| `is_verified` | `BOOLEAN` | KYC verifikáció |
|
||||
|
||||
#### 💰 Partner / Értékesítés
|
||||
| Oszlop | Típus | Megjegyzés |
|
||||
|--------|-------|------------|
|
||||
| `is_affiliate_partner` | `BOOLEAN` | **PARTNER FLAG** → `false` default |
|
||||
| `subscription_plan` | `VARCHAR(30)` | "FREE", "PREMIUM", stb. |
|
||||
| `base_asset_limit` | `INTEGER` | Eszköz limit |
|
||||
| `is_ownership_transferable` | `BOOLEAN` | Átruházható-e |
|
||||
|
||||
#### ⚙️ Konfiguráció
|
||||
| Oszlop | Típus |
|
||||
|--------|-------|
|
||||
| `notification_settings` | `JSON` |
|
||||
| `external_integration_config` | `JSON` |
|
||||
| `visual_settings` | `JSONB` |
|
||||
|
||||
#### 🔗 Kapcsolatok (Relationships)
|
||||
```python
|
||||
Organization
|
||||
├── assets: List[AssetAssignment] # Jármű hozzárendelések
|
||||
├── members: List[OrganizationMember] # Tagok (User/Person)
|
||||
├── owner: User # Technikai tulajdonos
|
||||
├── financials: List[OrganizationFinancials] # Pénzügyi adatok
|
||||
├── service_profile: ServiceProfile # Opcionális szerviz profil (1:1)
|
||||
├── branches: List[Branch] # Telephelyek
|
||||
├── legal_owner: Person # Jogi képviselő
|
||||
└── vehicle_costs: List[VehicleCost] # Jármű költségek
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2.2. `marketplace.service_providers` (ServiceProvider modell - RÉGI)
|
||||
|
||||
**Fájl:** `backend/app/models/marketplace/service.py`
|
||||
**Tábla:** `marketplace.service_providers`
|
||||
|
||||
| Oszlop | Típus | Megjegyzés |
|
||||
|--------|-------|------------|
|
||||
| `id` | `INTEGER` | PK |
|
||||
| `name` | `VARCHAR` | ✅ Név |
|
||||
| `address` | `VARCHAR` | ✅ Cím (egyszerű szöveg) |
|
||||
| `category` | `VARCHAR` | ❌ Kategória |
|
||||
| `status` | `USER-DEFINED` | ✅ Státusz (ENUM) |
|
||||
| `source` | `USER-DEFINED` | ✅ Forrás (ENUM) |
|
||||
| `validation_score` | `INTEGER` | ✅ Validációs pontszám |
|
||||
| `evidence_image_path` | `VARCHAR` | ❌ Kép bizonyíték |
|
||||
| `added_by_user_id` | `INTEGER` | ❌ Ki adta hozzá |
|
||||
| `created_at` | `TIMESTAMPTZ` | Létrehozás |
|
||||
|
||||
> ⚠️ **Ez a tábla egy régebbi verzió. Nem használja a `ServiceProfile` modell, hanem külön kezelendő.**
|
||||
|
||||
---
|
||||
|
||||
### 2.3. `marketplace.service_profiles` (ServiceProfile modell - ÚJ)
|
||||
|
||||
**Fájl:** `backend/app/models/marketplace/service.py`
|
||||
**Tábla:** `marketplace.service_profiles`
|
||||
|
||||
| Oszlop | Típus | Megjegyzés |
|
||||
|--------|-------|------------|
|
||||
| `id` | `INTEGER` | PK |
|
||||
| `organization_id` | `INTEGER (FK → fleet.organizations.id)` | **UNIQUE** - Kapcsolat a szervezethez |
|
||||
| `parent_id` | `INTEGER (FK → self)` | Hierarchia (pl. franchise) |
|
||||
| `fingerprint` | `VARCHAR(255)` | **UNIQUE INDEX** - Robot által generált |
|
||||
| `location` | `GEOMETRY(POINT)` | PostGIS hely |
|
||||
| `status` | `ENUM(ServiceStatus)` | `ghost`, `active`, `flagged`, `suspended` |
|
||||
| `google_place_id` | `VARCHAR(100)` | **UNIQUE** Google Places azonosító |
|
||||
| `trust_score` | `INTEGER` | Trust engine pontszám |
|
||||
| `is_verified` | `BOOLEAN` | Verifikált szolgáltató |
|
||||
| `vibe_analysis` | `JSONB` | AI hangulatelemzés |
|
||||
| `social_links` | `JSONB` | Közösségi média linkek |
|
||||
| `specialization_tags` | `JSONB` | Specializációs címkék |
|
||||
| `opening_hours` | `JSONB` | Nyitvatartás |
|
||||
| `contact_phone` | `VARCHAR` | Telefon |
|
||||
| `contact_email` | `VARCHAR` | Email |
|
||||
| `website` | `VARCHAR` | Weboldal |
|
||||
| `bio` | `TEXT` | Leírás |
|
||||
| `rating_overall` | `FLOAT` | Átfogó értékelés |
|
||||
| `rating_verified_count` | `INTEGER` | Verified review-ok száma |
|
||||
|
||||
#### 🔗 Kapcsolatok
|
||||
```python
|
||||
ServiceProfile
|
||||
├── organization: Organization # 1:1 kapcsolat
|
||||
├── expertises: List[ServiceExpertise] # Szakmai címkék
|
||||
└── reviews: List[ServiceReview] # Vélemények
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2.4. `marketplace.service_reviews` (Verified Service Reviews)
|
||||
|
||||
**Tábla:** `marketplace.service_reviews`
|
||||
|
||||
| Oszlop | Típus | Megjegyzés |
|
||||
|--------|-------|------------|
|
||||
| `id` | `INTEGER` | PK |
|
||||
| `service_id` | `INTEGER (FK → marketplace.service_profiles.id)` | Melyik szerviz |
|
||||
| `user_id` | `INTEGER (FK → identity.users.id)` | Ki írta |
|
||||
| `transaction_id` | `UUID` | **UNIQUE** - Tranzakció azonosító |
|
||||
| `price_rating` | `INTEGER (1-5)` | Ár értékelés |
|
||||
| `quality_rating` | `INTEGER (1-5)` | Minőség értékelés |
|
||||
| `time_rating` | `INTEGER (1-5)` | Idő értékelés |
|
||||
| `communication_rating` | `INTEGER (1-5)` | Kommunikáció értékelés |
|
||||
| `comment` | `TEXT` | Szöveges vélemény |
|
||||
| `is_verified` | `BOOLEAN` | Tranzakcióhoz kötött |
|
||||
| `created_at`/`updated_at` | `TIMESTAMPTZ` | Audit |
|
||||
|
||||
---
|
||||
|
||||
### 2.5. `marketplace.ratings` (Általános értékelések)
|
||||
|
||||
**Tábla:** `marketplace.ratings`
|
||||
|
||||
| Oszlop | Típus | Megjegyzés |
|
||||
|--------|-------|------------|
|
||||
| `id` | `INTEGER` | PK |
|
||||
| `author_id` | `INTEGER` | Ki írta |
|
||||
| `target_organization_id` | `INTEGER` | Cél szervezet (opcionális) |
|
||||
| `target_user_id` | `INTEGER` | Cél felhasználó (opcionális) |
|
||||
| `target_branch_id` | `UUID` | Cél telephely (opcionális) |
|
||||
| `score` | `NUMERIC` | Pontszám |
|
||||
| `comment` | `TEXT` | Szöveges |
|
||||
| `images` | `JSONB` | Képek |
|
||||
| `is_verified` | `BOOLEAN` | Verifikált |
|
||||
|
||||
---
|
||||
|
||||
### 2.6. `fleet.branches` (Telephelyek)
|
||||
|
||||
**Tábla:** `fleet.branches`
|
||||
|
||||
| Oszlop | Típus | Megjegyzés |
|
||||
|--------|-------|------------|
|
||||
| `id` | `UUID` | PK |
|
||||
| `organization_id` | `INTEGER (FK → fleet.organizations.id)` | ✅ Melyik szervezethez |
|
||||
| `address_id` | `UUID (FK → system.addresses.id)` | ❌ Cím (strukturált) |
|
||||
| `name` | `VARCHAR(100)` | ✅ Telephely név |
|
||||
| `is_main` | `BOOLEAN` | Központi telephely |
|
||||
| `postal_code`, `city`, `street_name`, stb. | `VARCHAR` | Denormalizált cím |
|
||||
| `location` | `GEOMETRY(POINT)` | PostGIS |
|
||||
| `opening_hours` | `JSONB` | Nyitvatartás |
|
||||
| `branch_rating` | `FLOAT` | Telephely értékelés |
|
||||
| `status` | `VARCHAR(30)` | `active`, `inactive` |
|
||||
| `is_deleted` | `BOOLEAN` | Soft delete |
|
||||
|
||||
---
|
||||
|
||||
## 3. 🗺️ TELJES ADATBÁZIS TÉRKÉP (Minden séma és tábla)
|
||||
|
||||
### 3.1. Identity séma (Személyek, Felhasználók, Hitelesítés)
|
||||
| Tábla | Leírás | Státusz |
|
||||
|-------|--------|---------|
|
||||
| `identity.persons` | Természetes személyek (DNS szint) | ✅ **Aktív** |
|
||||
| `identity.users` | Technikai fiókok (bejelentkezés) | ✅ **Aktív** |
|
||||
| `identity.wallets` | Pénztárcák (Triple Wallet) | ✅ **Aktív** |
|
||||
| `identity.active_vouchers` | Aktív voucher-ek | ✅ **Aktív** |
|
||||
| `identity.user_trust_profiles` | Trust score profilok | ✅ **Aktív** |
|
||||
| `identity.verification_tokens` | Email/telefon verifikáció | ✅ **Aktív** |
|
||||
| `identity.one_time_passwords` | OTP kódok | ✅ **Aktív** |
|
||||
| `identity.social_accounts` | Közösségi média kapcsolatok | ✅ **Aktív** |
|
||||
| `identity.devices` | Eszköz fingerprint | ✅ **Aktív** |
|
||||
| `identity.user_device_links` | User-Eszköz kapcsolatok | ✅ **Aktív** |
|
||||
|
||||
### 3.2. Fleet séma (Szervezetek, Flották)
|
||||
| Tábla | Leírás | Státusz |
|
||||
|-------|--------|---------|
|
||||
| `fleet.organizations` | Szervezetek (cégek, flották, szolgáltatók) | ✅ **Aktív** |
|
||||
| `fleet.organization_members` | Tagságok (User/Person → Organization) | ✅ **Aktív** |
|
||||
| `fleet.organization_financials` | Pénzügyi adatok (éves) | ✅ **Aktív** |
|
||||
| `fleet.branches` | Telephelyek | ✅ **Aktív** |
|
||||
| `fleet.asset_assignments` | Jármű hozzárendelések | ✅ **Aktív** |
|
||||
| `fleet.org_sales_assignments` | Értékesítési hozzárendelések | ✅ **Aktív** |
|
||||
|
||||
### 3.3. Vehicle séma (Járművek, Katalógus)
|
||||
| Tábla | Leírás | Státusz |
|
||||
|-------|--------|---------|
|
||||
| `vehicle.vehicle_model_definitions` | Jármű modellek (MDM) | ✅ **Aktív** |
|
||||
| `vehicle.vehicle_catalog` | Katalógus sablonok | ✅ **Aktív** |
|
||||
| `vehicle.assets` | Fizikai eszközök (Digital Twin) | ✅ **Aktív** |
|
||||
| `vehicle.vehicle_types` | Jármű típusok | ✅ **Aktív** |
|
||||
| `vehicle.feature_definitions` | Felszereltség elemek | ✅ **Aktív** |
|
||||
| `vehicle.model_feature_maps` | Modell-Felszereltség kapcsolatok | ✅ **Aktív** |
|
||||
| `vehicle.dict_body_types` | Karosszéria típus szótár | ✅ **Aktív** |
|
||||
| `vehicle.cost_categories` | Költségkategóriák | ✅ **Aktív** |
|
||||
| `vehicle.costs` | Jármű költségek (TCO) | ✅ **Aktív** |
|
||||
| `vehicle.vehicle_expenses` | Jármű kiadások (jelentésekhez) | ✅ **Aktív** |
|
||||
| `vehicle.odometer_readings` | Kilométeróra állások | ✅ **Aktív** |
|
||||
| `vehicle.vehicle_ownership_history` | Tulajdonos történet | ✅ **Aktív** |
|
||||
| `vehicle.vehicle_transfer_requests` | Átruházási kérelmek | ✅ **Aktív** |
|
||||
| `vehicle.catalog_discovery` | Katalógus felfedező várólista | ✅ **Aktív** |
|
||||
| `vehicle.gb_catalog_discovery` | UK piaci felfedező | ✅ **Aktív** |
|
||||
| `vehicle.auto_data_crawler_queue` | Crawler várólista | ✅ **Aktív** |
|
||||
| `vehicle.vehicle_logbook` | Jármű naplókönyv | ✅ **Aktív** |
|
||||
| `vehicle.motorcycle_specs` | Motorkerékpár specifikációk | ✅ **Aktív** |
|
||||
| `vehicle.external_reference_library` | Külső referencia könyvtár | ✅ **Aktív** |
|
||||
| `vehicle.reference_lookup` | Referencia kereső | ✅ **Aktív** |
|
||||
| `vehicle.vehicle_user_ratings` | Felhasználói jármű értékelések | ✅ **Aktív** |
|
||||
| `vehicle.asset_costs` | Eszköz költségek | ✅ **Aktív** |
|
||||
| `vehicle.asset_events` | Eseménynapló | ✅ **Aktív** |
|
||||
| `vehicle.asset_financials` | Pénzügyi adatok | ✅ **Aktív** |
|
||||
| `vehicle.asset_inspections` | Ellenőrzések | ✅ **Aktív** |
|
||||
| `vehicle.asset_reviews` | Eszköz vélemények | ✅ **Aktív** |
|
||||
| `vehicle.asset_telemetry` | Telemetria adatok | ✅ **Aktív** |
|
||||
|
||||
### 3.4. Marketplace séma (Piactér, Szervizek)
|
||||
| Tábla | Leírás | Státusz |
|
||||
|-------|--------|---------|
|
||||
| `marketplace.service_providers` | Szolgáltatók (RÉGI, egyszerű) | ⚠️ **Használaton kívül?** |
|
||||
| `marketplace.service_profiles` | Szerviz profilok (ÚJ) | ✅ **Aktív** |
|
||||
| `marketplace.service_reviews` | Verifikált vélemények | ✅ **Aktív** |
|
||||
| `marketplace.expertise_tags` | Szakmai címkék | ✅ **Aktív** |
|
||||
| `marketplace.service_expertises` | Szerviz-Szakma kapcsolatok | ✅ **Aktív** |
|
||||
| `marketplace.service_specialties` | Specializációk (hierarchikus) | ✅ **Aktív** |
|
||||
| `marketplace.service_staging` | Robot által gyűjtött adatok | ✅ **Aktív** |
|
||||
| `marketplace.discovery_parameters` | Robot keresési paraméterek | ✅ **Aktív** |
|
||||
| `marketplace.service_requests` | Szervizigények | ✅ **Aktív** |
|
||||
| `marketplace.ratings` | Általános értékelések | ✅ **Aktív** |
|
||||
| `marketplace.votes` | Szavazatok | ✅ **Aktív** |
|
||||
| `marketplace.costs` | Költségnapló (Trust Engine) | ✅ **Aktív** |
|
||||
|
||||
### 3.5. Finance séma (Pénzügyek)
|
||||
| Tábla | Leírás | Státusz |
|
||||
|-------|--------|---------|
|
||||
| `finance.credit_logs` | Hitel napló | ✅ **Aktív** |
|
||||
| `finance.exchange_rates` | Árfolyamok | ✅ **Aktív** |
|
||||
| `finance.issuers` | Kibocsátók | ✅ **Aktív** |
|
||||
| `finance.org_subscriptions` | Szervezeti előfizetések | ✅ **Aktív** |
|
||||
| `finance.user_subscriptions` | Felhasználói előfizetések | ✅ **Aktív** |
|
||||
| `finance.payment_intents` | Fizetési szándékok | ✅ **Aktív** |
|
||||
| `finance.withdrawal_requests` | Kifizetési kérelmek | ✅ **Aktív** |
|
||||
|
||||
### 3.6. System séma (Rendszeradatok)
|
||||
| Tábla | Leírás | Státusz |
|
||||
|-------|--------|---------|
|
||||
| `system.addresses` | Strukturált címek | ✅ **Aktív** |
|
||||
| `system.documents` | Dokumentumok | ✅ **Aktív** |
|
||||
| `system.translations` | Többnyelvű fordítások | ✅ **Aktív** |
|
||||
| `system.system_parameters` | Rendszer paraméterek | ✅ **Aktív** |
|
||||
| `system.internal_notifications` | Belső értesítések | ✅ **Aktív** |
|
||||
| `system.pending_actions` | Függőben lévő műveletek | ✅ **Aktív** |
|
||||
| `system.service_catalog` | Szolgáltatás katalógus | ✅ **Aktív** |
|
||||
| `system.subscription_tiers` | Előfizetési szintek | ✅ **Aktív** |
|
||||
| `system.service_staging` | Szolgáltatás staging | ⚠️ **Duplikáció?** |
|
||||
| `system.staged_vehicle_data` | Jármű adat staging | ✅ **Aktív** |
|
||||
| `system.geo_postal_codes` | Irányítószám adatok | ✅ **Aktív** |
|
||||
| `system.geo_streets` | Utcák | ✅ **Aktív** |
|
||||
| `system.geo_street_types` | Utca típusok | ✅ **Aktív** |
|
||||
| `system.competitions_deprecated` | Versenyek (DEPR) | ❌ **Deprecated** |
|
||||
| `system.user_scores_deprecated` | Pontszámok (DEPR) | ❌ **Deprecated** |
|
||||
| `system.service_staging_deprecated` | Staging (DEPR) | ❌ **Deprecated** |
|
||||
| `system.system_data_completion_weights` | Adatteljességi súlyok | ✅ **Aktív** |
|
||||
|
||||
### 3.7. Audit séma (Naplózás)
|
||||
| Tábla | Leírás | Státusz |
|
||||
|-------|--------|---------|
|
||||
| `audit.audit_logs` | Általános audit napló | ✅ **Aktív** |
|
||||
| `audit.financial_ledger` | Pénzügyi főkönyv | ✅ **Aktív** |
|
||||
| `audit.operational_logs` | Működési napló | ✅ **Aktív** |
|
||||
| `audit.process_logs` | Folyamat napló | ✅ **Aktív** |
|
||||
| `audit.security_audit_logs` | Biztonsági audit napló | ✅ **Aktív** |
|
||||
|
||||
### 3.8. Gamification séma (Játékosítás)
|
||||
| Tábla | Leírás | Státusz |
|
||||
|-------|--------|---------|
|
||||
| `gamification.badges` | Jelvények | ✅ **Aktív** |
|
||||
| `gamification.competitions` | Versenyek | ✅ **Aktív** |
|
||||
| `gamification.level_configs` | Szint konfigurációk | ✅ **Aktív** |
|
||||
| `gamification.point_rules` | Pont szabályok | ✅ **Aktív** |
|
||||
| `gamification.points_ledger` | Pont főkönyv | ✅ **Aktív** |
|
||||
| `gamification.seasonal_competitions` | Szezonális versenyek | ✅ **Aktív** |
|
||||
| `gamification.seasons` | Szezonok | ✅ **Aktív** |
|
||||
| `gamification.user_badges` | Felhasználói jelvények | ✅ **Aktív** |
|
||||
| `gamification.user_contributions` | Felhasználói hozzájárulások | ✅ **Aktív** |
|
||||
| `gamification.user_scores` | Felhasználói pontszámok | ✅ **Aktív** |
|
||||
| `gamification.user_stats` | Felhasználói statisztikák | ✅ **Aktív** |
|
||||
|
||||
---
|
||||
|
||||
## 4. 🔗 KAPCSOLATOK TÉRKÉP (Entity Relationship)
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
PERSON ||--o{ USER : "has"
|
||||
PERSON ||--o{ ORGANIZATION_MEMBER : "member of"
|
||||
PERSON ||--o{ ORGANIZATION : "legal owner of"
|
||||
USER ||--o{ ORGANIZATION : "technical owner of"
|
||||
USER ||--o{ SERVICE_REVIEW : "writes"
|
||||
USER ||--o{ SERVICE_REQUEST : "creates"
|
||||
USER ||--o{ VEHICLE_USER_RATING : "rates"
|
||||
ORGANIZATION ||--o{ ORGANIZATION_MEMBER : "has members"
|
||||
ORGANIZATION ||--o{ BRANCH : "has locations"
|
||||
ORGANIZATION ||--o| SERVICE_PROFILE : "optional service"
|
||||
ORGANIZATION ||--o{ ASSET_ASSIGNMENT : "owns vehicles"
|
||||
ORGANIZATION ||--o{ VEHICLE_COST : "pays costs"
|
||||
SERVICE_PROFILE ||--o{ SERVICE_REVIEW : "receives"
|
||||
SERVICE_PROFILE ||--o{ SERVICE_EXPERTISE : "specializes"
|
||||
SERVICE_PROFILE ||--o{ BRANCH : "operates"
|
||||
BRANCH ||--o{ RATING : "rated by"
|
||||
BRANCH ||--o{ SERVICE_REQUEST : "receives requests"
|
||||
VEHICLE_MODEL_DEFINITION ||--o{ ASSET_CATALOG : "has variants"
|
||||
VEHICLE_MODEL_DEFINITION ||--o{ VEHICLE_COST : "has costs"
|
||||
VEHICLE_MODEL_DEFINITION ||--o{ VEHICLE_USER_RATING : "rated by users"
|
||||
ASSET_CATALOG ||--o{ ASSET : "defines"
|
||||
ASSET ||--o{ ASSET_EVENT : "has events"
|
||||
ASSET ||--o{ SERVICE_REQUEST : "referenced in"
|
||||
ADDRESS ||--o{ PERSON : "lives at"
|
||||
ADDRESS ||--o{ ORGANIZATION : "located at"
|
||||
ADDRESS ||--o{ BRANCH : "address"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 💡 JAVASLATOK a "Közösségi Kereső" funkciókhoz
|
||||
|
||||
### 5.1. Jelenlegi hiányosságok
|
||||
|
||||
1. **Nincs dedikált "Partner" entitás** - A `fleet.organizations`-ban az `is_affiliate_partner` egy egyszerű boolean, nincs hozzá partner-specifikus adat (pl. jutalék ráta, partner kategória, szerződés állapota).
|
||||
2. **`ServiceProvider` (régi) és `ServiceProfile` (új) kettősség** - A régi `marketplace.service_providers` tábla használaton kívülinek tűnik, de még létezik.
|
||||
3. **Nincs "aliases" (álnév) támogatás** - Egyik táblában sincs JSONB aliases mező.
|
||||
4. **Kategória rendszer hiányos** - A `marketplace.expertise_tags` és `marketplace.service_specialties` párhuzamos címke rendszert alkot.
|
||||
|
||||
### 5.2. Javasolt bővítés: `Organization` kiegészítése (AJÁNLOTT)
|
||||
|
||||
Ahelyett, hogy új `Partner` táblát hoznánk létre, bővítsük a meglévő `fleet.organizations` táblát az alábbi JSONB oszlopokkal:
|
||||
|
||||
```python
|
||||
# Javasolt új mezők az Organization modellben
|
||||
class Organization(Base):
|
||||
# ... meglévő mezők ...
|
||||
|
||||
# ÚJ: Partnerek / Közösségi kereső
|
||||
aliases: Mapped[dict] = mapped_column(
|
||||
JSONB, server_default=text("'[]'::jsonb"),
|
||||
comment="Álnevek / alternatív nevek (pl. 'AutoShop Kft.', 'Autóshop')"
|
||||
)
|
||||
is_verified: Mapped[bool] = mapped_column(
|
||||
Boolean, server_default=text("false"),
|
||||
comment="Hivatalosan verifikált szervezet"
|
||||
)
|
||||
verification_level: Mapped[str] = mapped_column(
|
||||
String(20), server_default=text("'basic'"),
|
||||
comment="Verifikációs szint: basic, email, phone, kyc, premium"
|
||||
)
|
||||
partner_category: Mapped[str] = mapped_column(
|
||||
String(50), server_default=text("'none'"),
|
||||
comment="Partner kategória: none, basic, silver, gold, platinum"
|
||||
)
|
||||
commission_rate: Mapped[Optional[float]] = mapped_column(
|
||||
Numeric(5, 2), nullable=True,
|
||||
comment="Jutalék ráta (%-ban)"
|
||||
)
|
||||
service_radius_km: Mapped[Optional[int]] = mapped_column(
|
||||
Integer, nullable=True,
|
||||
comment="Szolgáltatási körzet (km)"
|
||||
)
|
||||
tags: Mapped[dict] = mapped_column(
|
||||
JSONB, server_default=text("'[]'::jsonb"),
|
||||
comment="Címkék a közösségi kereséshez"
|
||||
)
|
||||
search_keywords: Mapped[dict] = mapped_column(
|
||||
JSONB, server_default=text("'{}'::jsonb"),
|
||||
comment="Kereső kulcsszavak több nyelven"
|
||||
)
|
||||
social_profiles: Mapped[dict] = mapped_column(
|
||||
JSONB, server_default=text("'{}'::jsonb"),
|
||||
comment="Közösségi média profilok (Facebook, Instagram, Google Business)"
|
||||
)
|
||||
contact_persons: Mapped[dict] = mapped_column(
|
||||
JSONB, server_default=text("'[]'::jsonb"),
|
||||
comment="Kapcsolattartó személyek adatai"
|
||||
)
|
||||
```
|
||||
|
||||
### 5.3. Alternatíva: Új `partner_profiles` tábla
|
||||
|
||||
Ha a `fleet.organizations` túl nagyra nőne, hozzunk létre egy új táblát:
|
||||
|
||||
```python
|
||||
class PartnerProfile(Base):
|
||||
"""Bővített partner profil a Közösségi Keresőhöz."""
|
||||
__tablename__ = "partner_profiles"
|
||||
__table_args__ = {"schema": "marketplace"}
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
organization_id: Mapped[int] = mapped_column(
|
||||
Integer, ForeignKey("fleet.organizations.id"), unique=True, nullable=False
|
||||
)
|
||||
|
||||
# --- ALAPADATOK ---
|
||||
aliases: Mapped[dict] = mapped_column(JSONB, server_default=text("'[]'::jsonb"))
|
||||
partner_category: Mapped[str] = mapped_column(String(50), default="none")
|
||||
|
||||
# --- VERIFIKÁCIÓ ---
|
||||
verification_level: Mapped[str] = mapped_column(String(20), default="basic")
|
||||
verified_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True))
|
||||
verified_by_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("identity.users.id"))
|
||||
|
||||
# --- KERESÉS ---
|
||||
search_keywords: Mapped[dict] = mapped_column(JSONB, server_default=text("'{}'::jsonb"))
|
||||
tags: Mapped[dict] = mapped_column(JSONB, server_default=text("'[]'::jsonb"))
|
||||
service_radius_km: Mapped[Optional[int]] = mapped_column(Integer)
|
||||
|
||||
# --- GAZDASÁGI ADATOK ---
|
||||
commission_rate: Mapped[Optional[float]] = mapped_column(Numeric(5, 2))
|
||||
contract_start: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True))
|
||||
contract_end: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True))
|
||||
|
||||
# --- KAPCSOLATOK ---
|
||||
social_profiles: Mapped[dict] = mapped_column(JSONB, server_default=text("'{}'::jsonb"))
|
||||
contact_persons: Mapped[dict] = mapped_column(JSONB, server_default=text("'[]'::jsonb"))
|
||||
|
||||
# --- AUDIT ---
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), onupdate=func.now())
|
||||
```
|
||||
|
||||
### 5.4. Ajánlott stratégia
|
||||
|
||||
1. **Rövid táv**: Az `Organization` modell bővítése JSONB mezőkkel (`aliases`, `tags`, `search_keywords`, `social_profiles`). Ez azonnal használható, nincs szükség új táblára.
|
||||
2. **Közép táv**: Ha a partnerek száma eléri a 10.000+ rekordot, hozzuk létre a dedikált `partner_profiles` táblát az `marketplace` sémában.
|
||||
3. **Hosszú táv**: A régi `marketplace.service_providers` tábla archiválása/eltávolítása, mivel a `ServiceProfile` és a bővített `Organization` lefedi a funkcióit.
|
||||
|
||||
### 5.5. Megjegyzések a "Céges nyilvántartás" funkcióról
|
||||
|
||||
A rendelkezésre álló kód és adatbázis alapján:
|
||||
|
||||
- ✅ **Van "Céges nyilvántartás"** → `fleet.organizations` tábla
|
||||
- ✅ **Van tagságkezelés** → `fleet.organization_members` tábla (User/Person + role)
|
||||
- ✅ **Van telephelykezelés** → `fleet.branches` tábla (PostGIS támogatással)
|
||||
- ✅ **Van szolgáltatói profil** → `marketplace.service_profiles` tábla
|
||||
- ✅ **Van értékelési rendszer** → `marketplace.service_reviews` (verifikált) + `marketplace.ratings` (általános)
|
||||
- ❌ **NINCS dedikált partner modell** - Az `is_affiliate_partner` boolean nem elegendő
|
||||
- ❌ **NINCS keresőoptimalizált adat** (aliases, tags, keywords)
|
||||
|
||||
---
|
||||
|
||||
## 6. ⚠️ FIGYELMEZTETÉSEK
|
||||
|
||||
### 6.1. Duplikált táblák
|
||||
- `marketplace.service_staging` és `system.service_staging` - Valószínűleg csak egy kellene.
|
||||
- `marketplace.costs` és `vehicle.costs` - Két külön költség tábla, különböző sémákban.
|
||||
- `system.competitions_deprecated` → `gamification.competitions`
|
||||
- `system.user_scores_deprecated` → `gamification.user_scores`
|
||||
|
||||
### 6.2. Kettős modell architektúra
|
||||
- `marketplace.service_providers` (régi, egyszerű) vs `marketplace.service_profiles` (új, komplex)
|
||||
- A régi tábla használata nem javasolt új fejlesztésekhez.
|
||||
|
||||
### 6.3. Soft delete következetlenség
|
||||
- `fleet.organizations`: `is_deleted` + `is_active` boolean mezők
|
||||
- `marketplace.service_profiles`: státusz alapú (`ghost`, `active`, `flagged`, `suspended`)
|
||||
- `identity.persons`: `deleted_at` datetime mező
|
||||
- `identity.users`: `is_active` boolean
|
||||
- **Hiányzik egy egységes soft-delete stratégia az egész rendszerben.**
|
||||
|
||||
---
|
||||
|
||||
**Jelentés vége.** A javasolt bővítések implementálása előtt egyeztetés szükséges a Vezető Tervezővel.
|
||||
133
docs/expertise_tag_masterlist_analysis_2026-06-17.md
Normal file
133
docs/expertise_tag_masterlist_analysis_2026-06-17.md
Normal file
@@ -0,0 +1,133 @@
|
||||
# 📊 ExpertiseTag Mesterlista — Többszintű Kategória Elemzés
|
||||
|
||||
**Dátum:** 2026-06-17
|
||||
**Szerző:** Rendszer-Architect
|
||||
**Cél:** Annak vizsgálata, hogy az `ExpertiseTag` (`marketplace.expertise_tags`) tábla `category` mezője alkalmas-e többszintű kategória tárolására, és ha igen, milyen módszerekkel tölthetők fel rá adatok.
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Vizsgált Modell
|
||||
|
||||
Az `ExpertiseTag` modell az alábbi mezőkkel rendelkezik:
|
||||
|
||||
| Mező | Típus | Leírás |
|
||||
|------|-------|--------|
|
||||
| `id` | `Integer` (PK) | Elsődleges kulcs |
|
||||
| `key` | `String(50)` (unique, index) | Egyedi azonosító kulcs |
|
||||
| `name_hu` | `String(100)` (nullable) | Magyar név |
|
||||
| `name_en` | `String(100)` (nullable) | Angol név |
|
||||
| `category` | **`String(30)`** (index) | Kategória csoportosító címke |
|
||||
| `is_official` | `Boolean` | Hivatalos-e |
|
||||
| `suggested_by_id` | `BigInteger` (FK) | Ki javasolta |
|
||||
| `discovery_points` | `Integer` | Felfedezési pontok |
|
||||
| `search_keywords` | `JSONB` | Keresőkulcsszavak |
|
||||
| `usage_count` | `Integer` | Használati számláló |
|
||||
| `icon` | `String(50)` (nullable) | Ikon neve |
|
||||
| `description` | `Text` (nullable) | Leírás |
|
||||
|
||||
---
|
||||
|
||||
## ❌ 1. Válasz: Alkalmas-e a `category` mező többszintű tárolásra?
|
||||
|
||||
### **NEM, a jelenlegi implementáció NEM alkalmas többszintű hierarchia tárolására.**
|
||||
|
||||
| Követelmény | Jelenlegi állapot | Probléma |
|
||||
|-------------|-------------------|----------|
|
||||
| Hierarchikus kapcsolat | ❌ Nincs `parent_id` mező | Nem lehet szülő-gyermek viszonyt ábrázolni |
|
||||
| Szintek száma | ❌ Nincs `level` mező | Nem tudjuk, hány szint mélyen van egy kategória |
|
||||
| Útvonal (path) | ❌ Nincs `path` / `ltree` mező | Nem lehet gyorsan lekérdezni a teljes útvonalat |
|
||||
| Rekurzív lekérdezés | ❌ Nincs `lft`/`rgt` (nested set) | CTE-vel lehetne, de lassú nagy adathalmazon |
|
||||
| Mező hossza | ⚠️ Csak `String(30)` | "vehicle_service" már 15 karakter; kevés a bővítésre |
|
||||
|
||||
A jelenlegi `category` mező **csak egy lapos csoportosító címke** — hasonló egy `tag`-hez, nem pedig egy hierarchikus kategória struktúrához.
|
||||
|
||||
---
|
||||
|
||||
## 🗄️ 2. Jelenlegi Adatbázis Állapot
|
||||
|
||||
Lekérdezés alapján a tábla **11 rekordot** tartalmaz, **8 distinct category** értékkel:
|
||||
|
||||
| ID | Key | Category |
|
||||
|----|-----|----------|
|
||||
| 1 | `auto_szerelo` | `vehicle_service` |
|
||||
| 2 | `motor_szerelo` | `vehicle_service` |
|
||||
| 3 | `gumiszerviz` | `vehicle_service` |
|
||||
| 4 | `karosszerialakatos` | `body_paint` |
|
||||
| 5 | `fényező` | `body_paint` |
|
||||
| 6 | `autómentő` | `roadside` |
|
||||
| 7 | `benzinkút` | `fuel` |
|
||||
| 8 | `alkatrész_kereskedés` | `parts` |
|
||||
| 9 | `vizsgaállomás` | `inspection` |
|
||||
| 10 | `autókozmetika` | `detailing` |
|
||||
| 11 | `egyéb` | `other` |
|
||||
|
||||
---
|
||||
|
||||
## 🔄 3. Adatfeltöltési Lehetőségek — Összehasonlítás
|
||||
|
||||
| Módszer | Leírás | Korlátok |
|
||||
|---------|--------|----------|
|
||||
| **1️⃣ Seed Script** | Egyszeri batch betöltés. Idempotens. 11 alap kategória hardcode-olva. | Csak egyszer futtatható; nem lehet módosítani futás után. |
|
||||
| **2️⃣ Direkt SQL INSERT** | `INSERT INTO marketplace.expertise_tags ...` | Nincs validáció, séma integritás ellenőrzés. |
|
||||
| **3️⃣ API (létező): `GET /categories`** | **Csak OLVASÁS** — listázza a meglévő címkéket. | Nincs POST/PUT/DELETE végpont. |
|
||||
| **4️⃣ Admin UI** (`admin_ui.py`) | Csak jármű HITL modelljavításra fókuszál. | Nincs ExpertiseTag menedzsment. |
|
||||
|
||||
### Hiányzó API végpontok:
|
||||
- ❌ `POST /api/v1/admin/categories` — Új szakmai címke létrehozása
|
||||
- ❌ `PUT /api/v1/admin/categories/{id}` — Meglévő címke szerkesztése
|
||||
- ❌ `DELETE /api/v1/admin/categories/{id}` — Címke törlése
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ 4. Ajánlott Tervezés Többszintű Kategóriához
|
||||
|
||||
### 4.1. Új mezők az ExpertiseTag modellben
|
||||
|
||||
```python
|
||||
parent_id: Mapped[Optional[int]] = mapped_column(
|
||||
Integer, ForeignKey("marketplace.expertise_tags.id")
|
||||
)
|
||||
level: Mapped[int] = mapped_column(Integer, default=0)
|
||||
path: Mapped[Optional[str]] = mapped_column(String(200))
|
||||
```
|
||||
|
||||
### 4.2. Tipikus hierarchia példa
|
||||
|
||||
```
|
||||
Level 0 vehicle_service
|
||||
Level 1 (parent->child) ├── auto_szerelo
|
||||
├── motor_szerelo
|
||||
└── gumiszerviz
|
||||
Level 2 (sub-child) └── auto_szerelo/diagnosztika
|
||||
```
|
||||
|
||||
### 4.3. Javasolt admin API bővítés
|
||||
|
||||
```
|
||||
POST /api/v1/admin/categories # Új címke
|
||||
PUT /api/v1/admin/categories/{id} # Szerkesztés
|
||||
DELETE /api/v1/admin/categories/{id} # Törlés (soft-delete)
|
||||
GET /api/v1/admin/categories/tree # Hierarchikus fa
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 5. Összefoglalás
|
||||
|
||||
1. A `category` mező (`String(30)`) **lapos, nem hierarchikus** — nem alkalmas többszintű tárolásra
|
||||
2. Jelenleg **nincs CRUD API** a címkék kezelésére (csak `GET /categories`)
|
||||
3. **Nincs admin UI** a szakmai címkék menedzselésére
|
||||
4. A seed script az egyetlen adatbetöltési mód
|
||||
|
||||
### Ajánlott roadmap:
|
||||
|
||||
| Lépés | Feladat |
|
||||
|-------|---------|
|
||||
| 1️⃣ | `logic_spec` készítése a hierarchikus kategória rendszerhez |
|
||||
| 2️⃣ | Alembic migráció — `parent_id`, `level`, `path` mezők |
|
||||
| 3️⃣ | CRUD API végpontok létrehozása |
|
||||
| 4️⃣ | Admin UI integráció |
|
||||
| 5️⃣ | Seed script frissítése hierarchikus adatokkal |
|
||||
|
||||
### Kritikus hibajavítás:
|
||||
A `search_providers()` SQL lekérdezés **NEM JOIN-ol** az `ExpertiseTag` táblára, így a `category` mindig `None` a keresési eredményekben. Ez azonnali javítást igényel.
|
||||
232
docs/full_stack_disconnect_analysis_2026-06-16.md
Normal file
232
docs/full_stack_disconnect_analysis_2026-06-16.md
Normal file
@@ -0,0 +1,232 @@
|
||||
# 🚨 Full Stack Disconnect Analysis — "Extrák" Hiányzó Checkbox Grid
|
||||
|
||||
**Dátum:** 2026-06-16
|
||||
**Elemző:** Rendszer-Architect
|
||||
**Scope:** VehicleFormModal (Frontend) ↔ Asset Schema (Backend) ↔ Asset DB Model (PostgreSQL)
|
||||
|
||||
---
|
||||
|
||||
## 🔍 1. FRONTEND VIZSGÁLAT — VehicleFormModal.vue
|
||||
|
||||
### Jelenlegi lépések (line 870-875):
|
||||
| Index | Lépés neve | Tartalom |
|
||||
|-------|------------|----------|
|
||||
| 0 | **Azonosítás** | Kategória, VIN, Rendszám |
|
||||
| 1 | **Alapadatok** | Márka, Modell, Évjárat, Üzemanyag, **Kivitel/Felszereltség (összemosva)**, Becenév, Km óra |
|
||||
| 2 | **Műszaki** | Hengerűrtartalom, Teljesítmény kW, Hajtás, Váltó, Karosszéria (body_type), Klíma, Ajtók, Ülések, EV blokk, Okmányadatok |
|
||||
| 3 | **Extrák** | Saját besorolás, Saját megjegyzés + Features checkbox grid (csak `personal` esetén!) |
|
||||
|
||||
### Step 3 ("Extrák") valós tartalma (line 684-764):
|
||||
```html
|
||||
<div v-if="step === 3" class="space-y-4">
|
||||
<p>Itt adhatsz hozzá extra információkat a járművedhez.</p>
|
||||
<!-- Saját besorolás (condition) select -->
|
||||
<!-- Saját megjegyzés (notes) input -->
|
||||
|
||||
<!-- Features / Extrák - CSAK personal járműveknél -->
|
||||
<div v-if="form.vehicle_class === 'personal'" class="pt-2">
|
||||
<!-- Technical, Interior, Exterior, Multimedia, Other checkbox groups -->
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
### ⚠️ Kritikus probléma:
|
||||
A **75+ checkbox** csak akkor jelenik meg, ha a felhasználó `personal` (személyautó) kategóriát választott. Minden más járműosztálynál (motorcycle, light_commercial, commercial, work_machine, trailer, bus, camper, boat, aircraft, other) a Step 3 tényleg **üres** — csak "Saját besorolás" és "Saját megjegyzés" látszik. Ez magyarázza a képernyőképen látott üres felületet!
|
||||
|
||||
### A features tömörítve individual_equipment.car_specs.features-ként megy a backendbe
|
||||
|
||||
### Mely fájlba lettek a checkboxok?
|
||||
A checkbox grid a VehicleFormModal.vue fájlban van (line 710-763), de **nem kapta meg a saját dedikált komponensét**, és **nincs külön "Extrák" almappája a kategóriáknak** (Beltér/Kültér/Multimédia/Egyéb). Minden egy `form.features` string tömbben van tárolva, nem pedig strukturált JSONB-ként.
|
||||
|
||||
---
|
||||
|
||||
## 🗄️ 2. ADATBÁZIS & SÉMA VIZSGÁLAT
|
||||
|
||||
### Tervező által kért mezők vs Valós állapot
|
||||
|
||||
#### ✅ Azonosítás
|
||||
| Kért mező | Backend (DB Model) | Pydantic Schema | Frontend Form | Státusz |
|
||||
|-----------|-------------------|-----------------|---------------|---------|
|
||||
| Márka | Asset.brand ✅ | AssetCreate.brand ✅ | form.brand ✅ | ✅ OK |
|
||||
| Modell | Asset.model ✅ | AssetCreate.model ✅ | form.model ✅ | ✅ OK |
|
||||
| Típusjel | ❌ **NINCS** | ❌ **NINCS** | ❌ **NINCS** | ❌ **HIÁNYZIK** |
|
||||
|
||||
> **"Típusjel"** — ez a mező sehol nem létezik önálló entitásként. A `trim_level` ("Kivitel / Felszereltség") próbálja helyettesíteni, de a Tervező szerint a Típusjel (pl. "320i", "X5 xDrive30d") külön fogalom.
|
||||
|
||||
#### ✅ Általános
|
||||
| Kért mező | Backend | Schema | Frontend | Státusz |
|
||||
|-----------|---------|--------|----------|---------|
|
||||
| Km óra állás | current_mileage ✅ | ✅ | ✅ | ✅ OK |
|
||||
| Évjárat | year_of_manufacture ✅ | ✅ | ✅ | ✅ OK |
|
||||
| Kivitel (Karosszéria) | ❌ body_type a JSONB-ben | ❌ nincs külön mező | form.body_type (Step 2-ben!) | ❌ **ROSSZ helyen** |
|
||||
| Állapot | condition_score ✅ | ❌ **NINCS a sémában** | form.condition (string!) | ⚠️ **Inkonzisztens** |
|
||||
|
||||
> **"Kivitel (Karosszéria)"** — a `body_type` mező létezik a JSONB-ben (individual_equipment.car_specs.body_type), de a **"Műszaki" (Step 2)** fül alatt van, nem az alapadatok között. A Tervező szerint az Általános adatoknál kellene lennie, külön a "Felszereltségtől".
|
||||
|
||||
#### ✅ Műszaki
|
||||
| Kért mező | Backend | Schema | Frontend | Státusz |
|
||||
|-----------|---------|--------|----------|---------|
|
||||
| Üzemanyag | fuel_type ✅ | ✅ | ✅ | ✅ OK |
|
||||
| Hengerűrtartalom (cm³) | engine_capacity ✅ | ✅ | ✅ | ✅ OK |
|
||||
| Teljesítmény (kW/LE) | power_kw ✅ | ✅ | ✅ (HP display) | ✅ OK |
|
||||
| **Nyomaték (Nm)** | torque_nm ✅ **DB-ben** | ✅ AssetCreate.torque_nm | ❌ **NINCS input mező!** | ❌ **HIÁNYZIK** |
|
||||
|
||||
> **Nyomaték (torque_nm)** — a legkritikusabb hiányzó mező! A backend modellben (Asset.py sor 97) benne van, a Pydantic sémában (AssetCreate.torque_nm sor 151) benne van, de a frontend űrlapban **SEHOL** nincs input mező a Nyomaték megadására. Amikor a felhasználó elmenti az űrlapot, a torque_nm egyszerűen null marad.
|
||||
|
||||
#### ✅ Hajtáslánc
|
||||
| Kért mező | Backend | Schema | Frontend | Státusz |
|
||||
|-----------|---------|--------|----------|---------|
|
||||
| Sebességváltó | transmission_type ✅ | ✅ | ✅ | ✅ OK |
|
||||
| Hajtás | drive_type ✅ | ✅ | ✅ | ✅ OK |
|
||||
|
||||
#### ✅ Kényelem
|
||||
| Kért mező | Backend | Schema | Frontend | Státusz |
|
||||
|-----------|---------|--------|----------|---------|
|
||||
| Klíma fajtája | JSONB-ben (ac_type) | ❌ nincs külön mező | form.ac_type ✅ | ⚠️ JSONB-be van rejtve |
|
||||
|
||||
#### ✅ Okmányok
|
||||
| Kért mező | Backend | Schema | Frontend | Státusz |
|
||||
|-----------|---------|--------|----------|---------|
|
||||
| Forgalmi szám | JSONB-ben | ❌ nincs külön mező | ✅ | ⚠️ JSONB-ben |
|
||||
| Törzskönyv szám | JSONB-ben | ❌ nincs külön mező | ✅ | ⚠️ JSONB-ben |
|
||||
| Műszaki lejárat | JSONB-ben | ❌ nincs külön mező | ✅ | ⚠️ JSONB-ben |
|
||||
| Okmány lejárat | JSONB-ben | ❌ nincs külön mező | ✅ | ⚠️ JSONB-ben |
|
||||
|
||||
#### ✅ Extrák (JSONB)
|
||||
| Kért mező | Backend | Schema | Frontend | Státusz |
|
||||
|-----------|---------|--------|----------|---------|
|
||||
| Beltér | JSONB car_specs.features | individual_equipment | ✅ (checkbox) | ✅ OK |
|
||||
| Kültér | JSONB car_specs.features | individual_equipment | ✅ (checkbox) | ✅ OK |
|
||||
| Multimédia | JSONB car_specs.features | individual_equipment | ✅ (checkbox) | ✅ OK |
|
||||
| Egyéb | JSONB car_specs.features | individual_equipment | ✅ (checkbox) | ✅ OK |
|
||||
|
||||
### További hiányzó mezők a frontendről (de backendben léteznek):
|
||||
| Mező | DB Oszlop | Pydantic Schema | Frontend Input | Státusz |
|
||||
|------|-----------|----------------|---------------|---------|
|
||||
| curb_weight (saját tömeg) | ✅ | ✅ | ❌ | **HIÁNYZIK** |
|
||||
| max_weight (össztömeg) | ✅ | ✅ | ❌ | **HIÁNYZIK** |
|
||||
| cargo_volume_x (raktér hossz) | ✅ | ✅ | ❌ | **HIÁNYZIK** |
|
||||
| cargo_volume_y (raktér szél.) | ✅ | ✅ | ❌ | **HIÁNYZIK** |
|
||||
| roof_type (tető típus) | ✅ | ✅ | ❌ | **HIÁNYZIK** |
|
||||
| audio_system_type (hangi) | ✅ | ✅ | ❌ | **HIÁNYZIK** |
|
||||
|
||||
---
|
||||
|
||||
## 🌐 3. API VÁLASZ VIZSGÁLAT
|
||||
|
||||
### GET /assets/vehicles/{id} (assets.py line 290-337)
|
||||
|
||||
A végpont az AssetResponse Pydantic modellt használja (response_model=AssetResponse). A from_attributes=True miatt az ORM Asset objektum automatikusan Pydantic-ként szerializálódik.
|
||||
|
||||
**A JSON válasz tartalmazza:**
|
||||
- Az összes "sima" oszlopot (brand, model, engine_capacity, power_kw, torque_nm, transmission_type, drive_type, stb.)
|
||||
- Az individual_equipment JSONB mezőt teljes egészében (benne car_specs, ev_specs, dates, documents)
|
||||
- A catalog kapcsolódó objektumot (ha van)
|
||||
|
||||
**A frontend populateForm() (line 1162-1215) helyesen olvassa vissza a JSONB-t**, de a torque_nm sosem kerül beolvasásra, mert nincs hozzá input mező.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 4. ÖSSZEGZÉS: A KAPCSOLAT MEGSZAKADÁSI PONTOK
|
||||
|
||||
### 1. 🔴 **Nyomaték (torque_nm) — Backend adat, frontend nélkül**
|
||||
- **Hol:** DB Asset.torque_nm sor 97, Schema AssetCreate.torque_nm sor 151
|
||||
- **Probléma:** A backend tárolja és a Pydantic séma támogatja, de a VehicleFormModal.vue egyetlen lépésében sincs input mező.
|
||||
- **Következmény:** A flottavezetők soha nem adják meg a nyomatékot, a "Thick Digital Twin" koncepció adathiányos.
|
||||
|
||||
### 2. 🟠 **"Típusjel" mező teljes hiánya**
|
||||
- **Hol:** Sehol az egész stack-ben
|
||||
- **Probléma:** A Tervező által kért Típusjel (pl. "320i", "X5 xDrive30d") fogalma nem létezik. Csak a trim_level van.
|
||||
|
||||
### 3. 🟠 **"Kivitel" és "Felszereltség" összemosása**
|
||||
- **Hol:** VehicleFormModal.vue Step 1 (line 376-409)
|
||||
- **Probléma:** A trim_level egyszerre próbálja lefedni a karosszéria kivitelt ÉS a felszereltségi szintet.
|
||||
|
||||
### 4. 🟡 **Features checkbox grid csak personal osztálynál**
|
||||
- **Hol:** VehicleFormModal.vue line 711
|
||||
- **Probléma:** v-if="form.vehicle_class === 'personal'" — más osztályoknál tényleg üres az Extrák fül.
|
||||
|
||||
### 5. 🟡 **Hiányzó fizikai méret és tömeg mezők**
|
||||
- curb_weight, max_weight, cargo_volume_x, cargo_volume_y — backendben vannak, de nincsenek a formban.
|
||||
|
||||
### 6. 🟡 **Okmányadatok JSONB-be rejtve**
|
||||
- mot_expiry, document_expiry, reg_cert_number, title_cert_number a JSONB-ben, nem dedikált oszlopokban.
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ 5. JAVASLAT: 7 LÉPÉSES ÚJ ŰRLAPSTRUKTÚRA
|
||||
|
||||
```
|
||||
Step 0: 🚗 AZONOSÍTÁS
|
||||
- Kategória (vehicle_class)
|
||||
- Márka (brand)
|
||||
- Modell (model)
|
||||
- Típusjel (type_designation) ⬅️ ÚJ!
|
||||
- Rendszám (license_plate)
|
||||
- Alvázszám (vin)
|
||||
|
||||
Step 1: 📋 ÁLTALÁNOS ADATOK
|
||||
- Évjárat (year_of_manufacture)
|
||||
- Km óra állás (current_mileage)
|
||||
- Kivitel / Karosszéria (body_type) ⬅️ Külön!
|
||||
- Állapot / Saját besorolás (condition)
|
||||
|
||||
Step 2: ⚙️ MŰSZAKI ADATOK
|
||||
- Üzemanyag (fuel_type)
|
||||
- Hengerűrtartalom (engine_capacity)
|
||||
- Teljesítmény (power_kw) + LE kijelzés
|
||||
- Nyomaték (torque_nm) ⬅️ ÚJ!
|
||||
- Hengerelrendezés (cylinder_layout)
|
||||
|
||||
Step 3: 🔧 HAJTÁSLÁNC
|
||||
- Sebességváltó (transmission_type)
|
||||
- Hajtás (drive_type)
|
||||
|
||||
Step 4: 🌡️ KÉNYELEM & KLÍMA
|
||||
- Klíma fajtája (ac_type)
|
||||
- Tető típus (roof_type) ⬅️ ÚJ!
|
||||
- Hangrendszer (audio_system_type) ⬅️ ÚJ!
|
||||
- Ajtók száma (door_count)
|
||||
- Ülések száma (seat_count)
|
||||
|
||||
Step 5: 📄 OKMÁNYOK
|
||||
- Műszaki érvényesség (mot_expiry)
|
||||
- Okmány érvényesség (document_expiry)
|
||||
- Forgalmi szám (registration_cert_number)
|
||||
- Törzskönyv szám (title_cert_number)
|
||||
|
||||
Step 6: ✨ EXTRÁK (Felszereltség) - Dedikált komponens!
|
||||
- Beltér (interior features)
|
||||
- Kültér (exterior features)
|
||||
- Multimédia (multimedia features)
|
||||
- Technikai (technical features)
|
||||
- Egyéb (other features)
|
||||
- Súly & Méretek (curb_weight, max_weight, cargo)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 HIÁNYZÓ MEZŐK MASTER LIST
|
||||
|
||||
| # | Mező | DB/Séma | Frontend | Javasolt lépés |
|
||||
|---|------|---------|----------|----------------|
|
||||
| 1 | torque_nm | ✅ Van | ❌ NINCS | Step 2 |
|
||||
| 2 | type_designation | ❌ NINCS | ❌ NINCS | Step 0 |
|
||||
| 3 | curb_weight | ✅ Van | ❌ NINCS | Step 6 |
|
||||
| 4 | max_weight | ✅ Van | ❌ NINCS | Step 6 |
|
||||
| 5 | cargo_volume_x | ✅ Van | ❌ NINCS | Step 6 |
|
||||
| 6 | cargo_volume_y | ✅ Van | ❌ NINCS | Step 6 |
|
||||
| 7 | roof_type | ✅ Van | ❌ NINCS | Step 4 |
|
||||
| 8 | audio_system_type | ✅ Van | ❌ NINCS | Step 4 |
|
||||
|
||||
---
|
||||
|
||||
## ⚡ AZONNALI TEENDŐK (Prioritási sorrendben)
|
||||
|
||||
1. **🟢 FRONTEND:** Add hozzá a `torque_nm` input mezőt a "Műszaki" (Step 2) lépéshez. Ez 5 perc fejlesztés és a legnagyobb adatveszteséget szünteti meg.
|
||||
|
||||
2. **🟡 FRONTEND:** Bontsd ki a features checkbox grid-et egy külön Vue komponensbe (`VehicleFeaturesGrid.vue`), és engedélyezd MINDEN járműosztálynál, ne csak personal-nál.
|
||||
|
||||
3. **🟡 FRONTEND+SCHEMA:** Válaszd szét a "Kivitel" (body_type) és "Felszereltség" (trim_level) fogalmakat.
|
||||
|
||||
4. **🔴 ARCHITECT TERV:** Készíts `logic_spec` dokumentációt az űrlap teljes átépítéséhez a fenti 7 lépéses struktúra alapján.
|
||||
131
docs/gamification_penalty_system_reconnaissance_2026-06-17.md
Normal file
131
docs/gamification_penalty_system_reconnaissance_2026-06-17.md
Normal file
@@ -0,0 +1,131 @@
|
||||
# Gamification Penalty System — Adatbázis Felderítési Jelentés
|
||||
|
||||
**Dátum:** 2026-06-17
|
||||
**Cél:** A 3-szintű Büntetési Mátrix (Penalty System) és Árnyéktiltás (Shadowban) bevezetésének adatbázis-struktúra előfeltérképezése
|
||||
|
||||
---
|
||||
|
||||
## 1. FELADAT: Büntetési Szint (Penalty Level) — Meglévő Struktúra
|
||||
|
||||
### ✅ Megállapítás: A büntetési infrastruktúra NAGYRÉSZT KÉSZ
|
||||
|
||||
A Vezető Tervező örömére: a rendszer **már tartalmazza** a büntetési pontrendszer alapjait. Az alábbi táblák és mezők **már léteznek** az adatbázisban és a modellekben:
|
||||
|
||||
#### backend/app/models/gamification/gamification.py
|
||||
|
||||
| Tábla (séma) | Mező | Típus | Státusz |
|
||||
|---|---|---|---|
|
||||
| gamification.user_stats | penalty_points | Integer (server_default=0) | ✅ Létezik |
|
||||
| gamification.user_stats | restriction_level | Integer (server_default=0) | ✅ Létezik |
|
||||
| gamification.user_stats | penalty_quota_remaining | Integer (default=3) | ✅ Létezik |
|
||||
| gamification.user_stats | banned_until | DateTime(timezone=True) | ✅ Létezik |
|
||||
| gamification.user_stats | current_level | Integer (default=1) | ✅ Létezik |
|
||||
| gamification.level_configs | level_number | Integer (unique) | ✅ Létezik (támogat negatív értékeket!) |
|
||||
| gamification.level_configs | is_penalty | Boolean (default=False) | ✅ Létezik |
|
||||
| gamification.level_configs | min_points | Integer | ✅ Létezik |
|
||||
| gamification.level_configs | rank_name | String | ✅ Létezik |
|
||||
| gamification.points_ledger | penalty_change | Integer (server_default=0) | ✅ Létezik |
|
||||
| identity.persons | penalty_points | Integer (default=-1) | ✅ Létezik |
|
||||
| identity.persons | social_reputation | Numeric(3,2) | ✅ Létezik |
|
||||
| identity.persons | lifetime_xp | BigInteger (default=-1) | ✅ Létezik |
|
||||
| identity.user_trust_profiles | trust_score | Integer (default=0) | ✅ Létezik |
|
||||
| identity.user_trust_profiles | identity_risk_flag | Boolean (default=False) | ✅ Létezik |
|
||||
|
||||
### ⚠️ HIÁNYZIK: penalty_level (a 3-szintű büntetési mátrix maga)
|
||||
|
||||
A restriction_level mező hasonló koncepció, de jelenleg nincs dedikált penalty_level (Integer, -1 / -2 / -3) mező.
|
||||
|
||||
### Javaslat az új mezők helyére
|
||||
|
||||
A gamification.user_stats táblába érdemes beilleszteni:
|
||||
|
||||
```
|
||||
PenaltyLevel: Integer, server_default=0 (-1=Figyelmeztetés, -2=Korlátozás, -3=Árnyéktiltás)
|
||||
GoodDeedsCount: Integer, server_default=0 (Jóvátételi cselekedetek számlálója)
|
||||
ShadowBannedUntil: DateTime(timezone=True), nullable=True (Látszólagos tiltás vége)
|
||||
```
|
||||
|
||||
**Indoklás:** A user_stats tábla már most is tartalmazza a penalty_points, restriction_level, penalty_quota_remaining és banned_until mezőket — ez a természetes helye minden büntetési információnak. A Person tábla (identity.persons) szintén rendelkezik penalty_points mezővel, de ott ez a személy szintű, nem a gamification profil része.
|
||||
|
||||
---
|
||||
|
||||
## 2. FELADAT: Hibajelentés (Report) Tábla
|
||||
|
||||
### ❌ Megállapítás: NINCS dedikált report/abuse tábla
|
||||
|
||||
Az adatbázisban és a modellek között **NEM található** olyan tábla, amelynek neve report, abuse, flag, ticket, moderation_content vagy data_correction lenne. A PostgreSQL information_schema lekérdezés nulla találatot adott.
|
||||
|
||||
### Ami KÖZELÍT
|
||||
|
||||
| Tábla | Kapcsolat | Korlát |
|
||||
|---|---|---|
|
||||
| marketplace.service_providers | status mező ModerationStatus enumnak | Ez a beküldött szolgáltatók moderálására való, **nem** a visszaélés-jelentésre |
|
||||
| marketplace.service_profiles | flagged státusz a ServiceStatus enumban | Szolgáltatók flag-elésére |
|
||||
| gamification.user_contributions | contribution_type = 'report_abuse' | Naplózza, hogy ki jelentett, de **nincs dedikált jelentés adattábla** |
|
||||
|
||||
### Javaslat: Új user_reports tábla létrehozása
|
||||
|
||||
Javasolt séma a gamification sémában (ahol a user_contributions is van):
|
||||
|
||||
```
|
||||
user_reports tábla (gamification séma):
|
||||
- id Integer (PK)
|
||||
- reporter_id Integer FK->identity.users.id
|
||||
- target_type String(50) ('service_profile', 'review', 'vehicle', 'user')
|
||||
- target_id Integer
|
||||
- reason_category String(50) ('fake_service', 'wrong_data', 'spam', 'abuse', 'other')
|
||||
- description Text (nullable)
|
||||
- evidence_data JSONB (nullable)
|
||||
- status String(20) default='pending' ('pending','verified','dismissed','action_taken')
|
||||
- reviewed_by Integer FK->identity.users.id (nullable)
|
||||
- resolution Text (nullable)
|
||||
- created_at DateTime
|
||||
- resolved_at DateTime (nullable)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. FELADAT: Adminisztrációs Szabályok (System Parameters)
|
||||
|
||||
### ✅ Megállapítás: A rendszer RENDELKEZIK dinamikus paraméter táblával
|
||||
|
||||
A system.system_parameters tábla **már létezik** és kifejezetten alkalmas a büntetési szabályok adminisztrációjára.
|
||||
|
||||
| Oszlop | Típus | Leírás |
|
||||
|---|---|---|
|
||||
| key | VARCHAR | Paraméter kulcs (pl. penalty_level_1_quota) |
|
||||
| category | VARCHAR | Kategorizálás (pl. penalty_system) |
|
||||
| value | JSONB | A paraméter értéke (JSON, bármi lehet) |
|
||||
| scope_level | VARCHAR | Hatáskör: global, country, region, organization, user |
|
||||
| scope_id | VARCHAR | A hatáskör azonosítója |
|
||||
| is_active | BOOLEAN | Aktív-e |
|
||||
| description | VARCHAR | Emberi leírás |
|
||||
|
||||
### Javasolt paraméterkulcsok a büntetési rendszerhez
|
||||
|
||||
| key | category | value (JSON) |
|
||||
|---|---|---|
|
||||
| penalty_level_1_threshold | penalty_system | {"min_bad_actions": 2, "quota_reduction": 1} |
|
||||
| penalty_level_2_threshold | penalty_system | {"min_bad_actions": 5, "xp_multiplier": 0.5} |
|
||||
| penalty_level_3_threshold | penalty_system | {"min_bad_actions": 10, "shadowban": true, "max_actions_per_day": 1} |
|
||||
| penalty_action_points | penalty_system | {"fake_service_submission": 10, "fake_review": 15, "spam_comment": 5} |
|
||||
| penalty_good_deed_recovery | penalty_system | {"points_per_good_deed": -3, "max_recovery_per_day": 1} |
|
||||
|
||||
> **Előny:** A scope_level oszlop lehetővé teszi, hogy **ország-specifikus** vagy akár **felhasználó-specifikus** büntetési szabályokat állítsunk be, anélkül hogy a kódot módosítani kellene.
|
||||
|
||||
---
|
||||
|
||||
## Összefoglaló táblázat
|
||||
|
||||
| Feladat | Státusz | Megjegyzés |
|
||||
|---|---|---|
|
||||
| **1. Büntetési szint helye** | ✅ **Alap infrastruktúra kész** | user_stats.penalty_points, restriction_level, penalty_quota_remaining, banned_until, level_configs.is_penalty — mind létezik. HIÁNYZIK: dedikált penalty_level és good_deeds_count mező |
|
||||
| **2. Hibajelentés tábla** | ❌ **NINCS** | Egyetlen dedikált report/abuse tábla sem létezik. A user_contributions.contribution_type = 'report_abuse' csak naplóz, nem tárol jelentéseket. **Teljesen új tábla kell** |
|
||||
| **3. Adminisztrációs szabályok** | ✅ **Alkalmas** | system.system_parameters JSONB-alapú, scoped paraméter tábla kiválóan megfelel a dinamikus szabályok tárolására. Új paramétereket kell csak beszúrni |
|
||||
|
||||
## Következő lépések (ajánlott sorrend)
|
||||
|
||||
1. **Új mezők hozzáadása** gamification.user_stats-hoz: penalty_level, good_deeds_count, shadow_banned_until
|
||||
2. **Új tábla létrehozása:** gamification.user_reports (vagy gamification.content_reports)
|
||||
3. **Rendszerparaméterek feltöltése:** system.system_parameters büntetési szabályokkal
|
||||
4. **Penalty Engine service** megírása, ami a level_configs táblából és a system_parameters-ből olvassa a szabályokat, és automatikusan lépteti a penalty_level-et
|
||||
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 |
|
||||
160
docs/service_book_schema_audit.md
Normal file
160
docs/service_book_schema_audit.md
Normal file
@@ -0,0 +1,160 @@
|
||||
# 🔍 Digitális Szerviznapló (Service Book) Architektúra Audit
|
||||
|
||||
**Dátum:** 2026-06-15
|
||||
**Auditor:** Fast Coder (Core Developer)
|
||||
**Cél:** A Vezető Tervező részére készült mélyreható elemzés a Szerviz események, Javítások és Okmány lejáratok adatbázis-szintű előkészítettségéről.
|
||||
|
||||
---
|
||||
|
||||
## 1. Összefoglaló
|
||||
|
||||
A rendszer **rendelkezik dedikált táblákkal** a Digitális Szerviznaplóhoz, de azok **részben előkészítettek**, részben pedig a `JSONB` mezőkbe vannak integrálva. Nincs külön `ServiceEvent` vagy `Document` tábla — a szerviz eseményeket az [`AssetEvent`](../backend/app/models/vehicle/asset.py:395) modell kezeli, a dokumentumokat (biztosítás, műszaki) pedig az [`Asset.individual_equipment`](../backend/app/models/vehicle/asset.py:114) JSONB mező.
|
||||
|
||||
---
|
||||
|
||||
## 2. Táblaszerkezet Áttekintés
|
||||
|
||||
### 2.1. `vehicle.asset_events` — Digitális Szervizkönyv (Fő tábla)
|
||||
|
||||
**Modell:** [`AssetEvent`](../backend/app/models/vehicle/asset.py:395)
|
||||
**Tábla:** `vehicle.asset_events`
|
||||
|
||||
| Mező | Típus | Leírás |
|
||||
|------|-------|--------|
|
||||
| `id` | UUID (PK) | Elsődleges kulcs |
|
||||
| `asset_id` | UUID (FK → `vehicle.assets.id`) | Jármű hivatkozás |
|
||||
| `user_id` | Integer (FK → `identity.users.id`) | Ki végezte a műveletet |
|
||||
| `organization_id` | Integer (FK → `fleet.organizations.id`) | Szervezet |
|
||||
| `event_type` | String(50) | Esemény típusa (lásd `AssetEventTypeEnum`) |
|
||||
| `odometer_reading` | Integer (nullable) | Km óra állás az eseménykor |
|
||||
| `description` | Text (nullable) | Leírás |
|
||||
| `cost_id` | UUID (FK → `vehicle.asset_costs.id`, nullable) | Kapcsolódó költség |
|
||||
| `event_date` | DateTime | Esemény dátuma |
|
||||
| `created_at` / `updated_at` | DateTime | Időbélyegek |
|
||||
|
||||
**Támogatott eseménytípusok** ([`AssetEventTypeEnum`](../backend/app/models/vehicle/asset.py:383)):
|
||||
- `SERVICE` — Szerviz
|
||||
- `REPAIR` — Javítás
|
||||
- `ACCIDENT` — Baleset
|
||||
- `INSPECTION` — Műszaki vizsga
|
||||
- `TIRE_CHANGE` — Gumi csere
|
||||
- `MAINTENANCE` — Karbantartás
|
||||
- `UPGRADE` — Fejlesztés
|
||||
- `RECALL` — Visszahívás
|
||||
|
||||
**Kapcsolatok:**
|
||||
- `asset` → [`Asset`](../backend/app/models/vehicle/asset.py:69) (Many-to-One)
|
||||
- `user` → [`User`](../backend/app/models/identity/user.py) (Many-to-One)
|
||||
- `organization` → [`Organization`](../backend/app/models/marketplace/organization.py) (Many-to-One)
|
||||
- `cost` → [`AssetCost`](../backend/app/models/vehicle/asset.py:246) (Many-to-One)
|
||||
|
||||
### 2.2. `vehicle.odometer_readings` — Km óra állás történet
|
||||
|
||||
**Modell:** [`OdometerReading`](../backend/app/models/vehicle/asset.py:353)
|
||||
**Tábla:** `vehicle.odometer_readings`
|
||||
|
||||
| Mező | Típus | Leírás |
|
||||
|------|-------|--------|
|
||||
| `id` | UUID (PK) | Elsődleges kulcs |
|
||||
| `asset_id` | UUID (FK → `vehicle.assets.id`) | Jármű |
|
||||
| `reading` | Integer | Km óra állás |
|
||||
| `recorded_at` | DateTime | Rögzítés ideje |
|
||||
| `source` | String(30) | Forrás: `manual`, `api`, `telemetry` |
|
||||
| `cost_id` | UUID (FK → `vehicle.asset_costs.id`, nullable) | Kapcsolódó költség |
|
||||
|
||||
### 2.3. `vehicle.asset_costs` — Költségnapló
|
||||
|
||||
**Modell:** [`AssetCost`](../backend/app/models/vehicle/asset.py:246)
|
||||
**Tábla:** `vehicle.asset_costs`
|
||||
|
||||
A költségek `data` JSONB mezőjében tárolódnak a szerviz specifikus adatok:
|
||||
- `odometer` — km óra állás a költségkor
|
||||
- `description` — leírás
|
||||
- `type` — típus (pl. `maintenance`)
|
||||
- `invoice_number` — számlaszám
|
||||
|
||||
### 2.4. `vehicle.assets.individual_equipment` — JSONB (Okmányok, Biztosítás)
|
||||
|
||||
**Mező:** [`Asset.individual_equipment`](../backend/app/models/vehicle/asset.py:114) — JSONB
|
||||
|
||||
Itt tárolódnak a **dokumentum lejáratok** és egyéb jármű specifikus adatok:
|
||||
- `insurance_due_date` — Biztosítás fordulónap
|
||||
- `insurance_premium` — Biztosítás díja
|
||||
- `mot_due_date` — Műszaki vizsga lejárata
|
||||
- `tire_change_date` — Gumicsere időpont
|
||||
- `tire_change_description` — Gumicsere leírás
|
||||
- `avg_consumption` — Átlagos fogyasztás
|
||||
- `avg_cost_per_km` — Átlagos km költség
|
||||
- `is_primary` — Elsődleges jármű flag
|
||||
- `color` — Szín
|
||||
- `next_service_days` — Következő szerviz napokban
|
||||
|
||||
---
|
||||
|
||||
## 3. Hiányosságok és Javaslatok
|
||||
|
||||
### 3.1. Dedikált `service_book` tábla hiánya
|
||||
|
||||
**Jelenlegi állapot:** Az [`AssetEvent`](../backend/app/models/vehicle/asset.py:395) modell egy generalista eseménytábla, amely minden típusú eseményt (szerviz, javítás, baleset, műszaki) egy táblában kezel. Nincs külön `ServiceEvent` tábla.
|
||||
|
||||
**Javaslat:** Az `AssetEvent` megfelelő a Digitális Szerviznaplóhoz, de érdemes lehet:
|
||||
- `service_provider` (Integer, FK → `marketplace.service_providers.id`) mező hozzáadása a szervizpartner azonosításához
|
||||
- `parts_cost` / `labor_cost` bontás a költségekhez
|
||||
- `warranty_claim` (Boolean) mező a garanciális javításokhoz
|
||||
|
||||
### 3.2. Dokumentumok tárolása
|
||||
|
||||
**Jelenlegi állapot:** A biztosítás, műszaki vizsga és gumicsere adatok az [`individual_equipment`](../backend/app/models/vehicle/asset.py:114) JSONB mezőben vannak. Nincs dedikált `Document` tábla a jármű dokumentumokhoz.
|
||||
|
||||
**Javaslat:** Hozz létre egy `vehicle.vehicle_documents` táblát az alábbi mezőkkel:
|
||||
- `id` (UUID, PK)
|
||||
- `asset_id` (UUID, FK → `vehicle.assets.id`)
|
||||
- `document_type` (String) — pl. `insurance`, `mot`, `registration`, `service_invoice`
|
||||
- `document_number` (String) — pl. biztosítási kötvényszám
|
||||
- `issue_date` (Date)
|
||||
- `expiry_date` (Date)
|
||||
- `document_url` (String) — feltöltött fájl elérési útja
|
||||
- `notes` (Text)
|
||||
|
||||
### 3.3. Szerviz intervallumok
|
||||
|
||||
**Jelenlegi állapot:** A következő szerviz számítása a frontenden történik (`nextServiceKm = current_mileage + 15000`), nincs adatbázis szintű szervizütemezés.
|
||||
|
||||
**Javaslat:** Vezess be egy `vehicle.service_schedules` táblát:
|
||||
- `id` (UUID, PK)
|
||||
- `asset_id` (UUID, FK → `vehicle.assets.id`)
|
||||
- `schedule_type` (String) — `time_based` vagy `mileage_based`
|
||||
- `interval_km` (Integer) — km intervallum
|
||||
- `interval_days` (Integer) — nap intervallum
|
||||
- `last_service_km` (Integer) — utolsó szerviz km állása
|
||||
- `last_service_date` (Date) — utolsó szerviz dátuma
|
||||
- `next_service_km` (Integer) — következő esedékes km
|
||||
- `next_service_date` (Date) — következő esedékes dátum
|
||||
|
||||
### 3.4. API végpontok hiánya
|
||||
|
||||
**Jelenlegi állapot:** Az [`AssetEvent`](../backend/app/models/vehicle/asset.py:395) modellhez tartozik egy `POST /{asset_id}/maintenance` végpont ([`create_maintenance_record`](../backend/app/api/v1/endpoints/assets.py:580)), de nincs:
|
||||
- `GET /assets/{id}/events` — események listázása
|
||||
- `GET /assets/{id}/events/{event_id}` — egy esemény részletei
|
||||
- `PUT /assets/{id}/events/{event_id}` — esemény módosítása
|
||||
- `DELETE /assets/{id}/events/{event_id}` — esemény törlése
|
||||
|
||||
---
|
||||
|
||||
## 4. Következtetés
|
||||
|
||||
| Komponens | Státusz | Megjegyzés |
|
||||
|-----------|---------|------------|
|
||||
| Szerviz események (`AssetEvent`) | ✅ **Kész** | Dedikált tábla, 8 eseménytípussal |
|
||||
| Km óra állás (`OdometerReading`) | ✅ **Kész** | Időbeli nyomonkövetés |
|
||||
| Költségnapló (`AssetCost`) | ✅ **Kész** | JSONB adatokkal |
|
||||
| Okmány lejáratok | ⚠️ **JSONB-ben** | `individual_equipment` mezőben |
|
||||
| Szerviz intervallumok | ❌ **Hiányzik** | Frontenden számolva |
|
||||
| API végpontok | ⚠️ **Részleges** | Csak `POST /maintenance` létezik |
|
||||
| Dedikált dokumentum tábla | ❌ **Hiányzik** | Javasolt létrehozni |
|
||||
|
||||
A Digitális Szerviznapló alap infrastruktúrája készen áll, de a következő fejlesztési fázisban érdemes:
|
||||
1. Létrehozni a `vehicle_documents` táblát
|
||||
2. Létrehozni a `service_schedules` táblát
|
||||
3. Kibővíteni az API végpontokat CRUD műveletekkel
|
||||
4. Átmigrálni a JSONB adatokat a dedikált táblákba
|
||||
Reference in New Issue
Block a user