# 🔍 P0 RECONNAISSANCE — Provider Taxonomy & Vehicle Compatibility Audit **Date:** 2026-07-01 **Scope:** Backend models, schemas, admin API endpoints **Status:** READ-ONLY AUDIT COMPLETE — NO FILES MODIFIED --- ## 🏁 EXECUTIVE SUMMARY | Capability | Status | Details | |-----------|--------|---------| | **ExpertiseTag (4-level hierarchy)** | ✅ **EXISTS** | Full tree with `parent_id`, `level`, `path`, multi-language | | **Many-to-many Service→Tag link** | ✅ **EXISTS** | `ServiceExpertise` junction table with `confidence_level` | | **Vehicle types as Level-0 tags** | ✅ **EXISTS** | 6 vehicle types in taxonomy seed | | **Public API `category_ids` support** | ✅ **EXISTS** | `ProviderUpdateIn` + `ProviderQuickAddIn` accept `category_ids: List[int]` | | **Public API `ServiceExpertise` sync** | ✅ **EXISTS** | `_sync_service_expertises()` in `provider_service.py` | | **Admin API `category_ids` support** | ❌ **MISSING** | `ProviderUpdateInput` has only plain-text `category` field | | **Admin PATCH → ServiceExpertise sync** | ❌ **MISSING** | PATCH endpoint does NOT call `_sync_service_expertises()` | | **Vehicle Type Compatibility field** | ❌ **MISSING** | No `supported_vehicle_types` on any provider model | | **Vehicle Type→Provider junction table** | ❌ **MISSING** | No dedicated relationship table exists | --- ## 1️⃣ CATEGORY TAXONOMY (ExpertiseTag) — ✅ FULLY IMPLEMENTED ### Model: `ExpertiseTag` (`backend/app/models/marketplace/service.py:83`) - **Table:** `marketplace.expertise_tags` - **Multi-language:** `name_hu`, `name_en`, `name_translations` (JSONB) - **4-level hierarchy:** `parent_id`, `level` (0-3), `path` - **Self-referential tree:** `children` / `parent` relationship ### Junction: `ServiceExpertise` (`backend/app/models/marketplace/service.py:146`) - **Table:** `marketplace.service_expertises` - **Links:** `service_id` → `ServiceProfile.id` ←→ `expertise_id` → `ExpertiseTag.id` - **Extra:** `confidence_level` ### Vehicle Types in the 4-Level Taxonomy (Level 0) From `seed_expertise_taxonomy.py`: | Key | HU Name | EN Name | |-----|---------|---------| | `szemelygepjarmu` | Személygépjármű | Passenger Car | | `motor` | Motorkerékpár | Motorcycle | | `kishaszonjarmu` | Kishaszonjármű | LCV | | `nagyhaszonjarmu_kamion` | Nagyhaszonjármű (Kamion) | HGV / Truck | | `munkagep_traktor` | Munkagép / Traktor | Agricultural / Construction Machinery | | `potkocsi_utanfuto` | Pótkocsi / Utánfutó | Trailer | Plus **Universal** Level-1: Fuel Stations, Restaurants, Accommodation, Parking. --- ## 2️⃣ VEHICLE TYPE COMPATIBILITY — ❌ COMPLETELY MISSING ### `ServiceProvider` (`backend/app/models/identity/social.py:23`) - Fields: `id`, `name`, `address`, `category` (str), `city`, contact fields, status, source - **NO** `supported_vehicle_types` - **NO** vehicle type relationship ### `ServiceProfile` (`backend/app/models/marketplace/service.py:21`) - Has: `expertises` (ServiceExpertise relationship), `specialization_tags` (JSONB) - **NO** `supported_vehicle_types` ### Implicit tracking only The ONLY way vehicle type compatibility is tracked today is through the 4-level ExpertiseTag hierarchy (Level-0 tags). This is implicit, not explicit — no dedicated queryable field exists. ### `vehicle.vehicle_types` table exists but UNLINKED `VehicleType` (`backend/app/models/vehicle/vehicle_definitions.py:17`) is in the `vehicle` schema, used for catalog data. No FK link to providers. --- ## 3️⃣ ADMIN PROVIDER SCHEMAS — ⚠️ PARTIALLY IMPLEMENTED ### Public Schemas (✅ Handle `category_ids`) | Schema | `category_ids` | `new_tags` | |--------|---------------|-----------| | `ProviderQuickAddIn` (`schemas/provider.py:135`) | ✅ `Optional[List[int]]` | ✅ `Optional[List[str]]` | | `ProviderUpdateIn` (`schemas/provider.py:173`) | ✅ `Optional[List[int]]` | ✅ `Optional[List[str]]` | ### Admin Schema (❌ MISSING) | Schema | `category_ids` | `new_tags` | `supported_vehicle_types` | |--------|---------------|-----------|--------------------------| | `ProviderUpdateInput` (`admin_providers.py:123`) | ❌ **MISSING** | ❌ **MISSING** | ❌ **MISSING** | Admin `ProviderUpdateInput` only has: `name`, `city`, `address_zip`, `address_street_name`, `address_street_type`, `address_house_number`, `plus_code`, `contact_phone`, `contact_email`, `website`, plain-text `category`, `status`, `validation_score`. ### Admin PATCH (`admin_providers.py:1072`) — No ServiceExpertise sync The `update_provider()` function sets fields via `setattr` and logs to AuditLog, but **never** calls `_sync_service_expertises()`. Compare with public endpoint in `provider_service.py:1070` which: 1. Collects `category_ids` + `new_tag_ids` 2. Creates new `ExpertiseTag` for `new_tags` 3. Calls `_sync_service_expertises()` at line 1094 --- ## 4️⃣ REQUIRED BACKEND CHANGES BEFORE FRONTEND MATRIX UI ### 🔴 P0 — MUST FIX: Admin `ProviderUpdateInput` schema **File:** `backend/app/api/v1/endpoints/admin_providers.py:123` Add: `category_ids: Optional[List[int]]`, `new_tags: Optional[List[str]]` ### 🔴 P0 — MUST FIX: Admin PATCH endpoint **File:** `backend/app/api/v1/endpoints/admin_providers.py:1072` Add `ServiceExpertise` sync after field updates. ### 🔴 P0 — MUST CREATE: Vehicle Type Compatibility Model New junction table `marketplace.provider_vehicle_types` linking `service_provider_id` to `expertise_tags.id` (Level-0 vehicle type tags). ### 🟡 P1 — ADD: `supported_vehicle_type_ids` to ProviderUpdateInput List of Level-0 ExpertiseTag IDs. ### 🟡 P1 — ADD: Categories + Vehicle Types to ProviderDetail response Add `supported_vehicle_types: List[dict]` and `categories: List[dict]` fields. ### 🟢 P2 — ADD: Frontend Edit Page `/providers/[id]/edit` Tabbed matrix layout: Basic Info | Categories (4-level tree) | Vehicle Types | Location --- ## 5️⃣ DATA FLOW COMPARISON ``` CURRENT STATE: ServiceProvider ──category(str)──→ [plain text, no relationship] │ └──ServiceProfile──ServiceExpertise──ExpertiseTag (public API only) TARGET STATE: ServiceProvider ──category_ids──→ ServiceExpertise──ExpertiseTag (service categories) │ └──supported_vehicle_type_ids──→ ProviderVehicleType──ExpertiseTag (Level-0 types) ``` --- ## 6️⃣ KEY TAKEAWAYS 1. **ExpertiseTag hierarchy is production-ready** — 6 vehicle types at Level-0, full multi-language. 2. **Public API already handles `category_ids`** — admin PATCH is the gap. 3. **Vehicle type compatibility is entirely new** — reuse Level-0 ExpertiseTags as vehicle type references. 4. **`category` varchar field is deprecated** — admin PATCH needs to catch up to structured ServiceExpertise.