# P0 Végrehajtási Terv: Vehicle Components & Modal Javítások **Státusz:** Tervezés alatt **Dátum:** 2026-06-21 **Architect:** Rendszer-Architect --- ## 1. Áttekintés A P0 feladat a meglévő jármű komponensek 4 problémás területének javítása az Architect modul elemzése alapján. A terv 3 fájl módosítását írja elő, új komponensek létrehozása NÉLKÜL. ### Érintett fájlok: | # | Fájl | Művelet | Hatás | |---|------|---------|-------| | 1 | `frontend/src/types/vehicle.ts` | `image_url` mező hozzáadása a `VehicleData` interfészhez | Type safety | | 2 | `frontend/src/components/vehicle/VehicleCardStandard.vue` | 5 adatkötés javítás | UI adatok helyes megjelenítése | | 3 | `frontend/src/components/vehicle/VehicleDetailModal.vue` | 5. tab (TechData) integráció + Pénzügyek tab bővítés | Teljes TCO láthatóság | --- ## 2. Részletes Módosítási Terv ### 2.1 `VehicleData` típus bővítése **Fájl:** [`frontend/src/types/vehicle.ts`](frontend/src/types/vehicle.ts:10) ```typescript export interface VehicleData { // ... existing fields ... image_url?: string | null; // ÚJ mező a kép URL tárolására } ``` **Indoklás:** A `VehicleCardStandard.vue` `:src="vehicle.image_url"`-t használna, de a `VehicleData` interfészből hiányzik ez a mező. A backend már visszaadhat `image_url`-t az `AssetResponse`-ben (lásd [`assets.py:386`](backend/app/api/v1/endpoints/assets.py:386)). --- ### 2.2 `VehicleCardStandard.vue` - 5 adatkötés javítás **Fájl:** [`frontend/src/components/vehicle/VehicleCardStandard.vue`](frontend/src/components/vehicle/VehicleCardStandard.vue) | # | Probléma | Javítás | Sor | |---|----------|---------|-----| | 1 | `is_primary` csillag gomb (megvan, de nincs szöveges badge) | **Nem változtatunk** - a meglévő star toggle működik, a feladat csak a data bindings-okról szól | 119-131 | | 2 | `color` mező: `vehicle.individual_equipment?.color \|\| vehicle.color \|\| '—'` | Lecserélés erre: `vehicle.individual_equipment?.color \|\| 'N/A'` | 103 | | 3 | `engine` mező: `vehicle.engine \|\| vehicle.fuel_type \|\| '—'` | Lecserélés erre: `` `${vehicle.power_kw || '?'} kW / ${vehicle.engine_capacity || '?'} cm³` `` | 95 | | 4 | `country_code` mező: `vehicle.countryCode \|\| vehicle.country_code` | **Hozzáadás** `registration_country` használatával | 62 | | 5 | `image` mező: `vehicle.image` | Lecserélés `vehicle.image_url`-re, fallback SVG placeholder | 9-10 | **Részletes módosítások:** **2.2.a - Image (9-10. sor):** ```html ``` **2.2.b - Country (62. sor):** ```html {{ vehicle.registration_country || vehicle.countryCode || vehicle.country_code || '—' }} ``` **2.2.c - Engine (95. sor):** ```html {{ vehicle.power_kw ? vehicle.power_kw + ' kW' : '?' }} / {{ vehicle.engine_capacity ? vehicle.engine_capacity + ' cm³' : '?' }} ``` **2.2.d - Color (103. sor):** ```html {{ vehicle.individual_equipment?.color || 'N/A' }} ``` --- ### 2.3 `VehicleDetailModal.vue` - TechData Tab integráció **Fájl:** [`frontend/src/components/vehicle/VehicleDetailModal.vue`](frontend/src/components/vehicle/VehicleDetailModal.vue) #### Háttér A [`TechDataTab.vue`](frontend/src/components/vehicles/tabs/TechDataTab.vue) LÉTEZIK (279 sor), de **NINCS integrálva** a modálba. Jelenleg 4 tab van (`basics`, `finance`, `alerts`, `servicebook`). #### Megoldás: 5. tab hozzáadása **a) Tab gomb hozzáadása (a meglévő tab gombok után, ~866-873. sor):** ```html ``` **b) Tab content blokk hozzáadása (a servicebook tab után, ~736. sor után):** ```html
``` **c) Import hozzáadása (script section):** ```typescript import TechDataTab from '@/components/vehicles/tabs/TechDataTab.vue'; ``` **d) `provide/inject` kompatibilitás biztosítása:** A [`TechDataTab.vue`](frontend/src/components/vehicles/tabs/TechDataTab.vue:107) `inject>('vehicle')`-t használ. A `VehicleDetailModal.vue`-ban a `vehicle` computed property már létezik. A provide-ot a modal szülőjének (vagy a modal-nak magának) kell biztosítania. **Megvizsgálandó:** A `VehicleDetailModal.vue` jelenleg `props`-on keresztül kapja a vehicle adatokat. Ha a `TechDataTab.vue` `inject('vehicle')`-t vár, akkor vagy: - Biztosítani kell a `provide('vehicle', computed(...))`-t a modalban, VAGY - Át kell alakítani a TechDataTab-et, hogy elfogadjon egy prop-ot is. **Ajánlás:** Mivel a [`OverviewTab.vue`](frontend/src/components/vehicles/tabs/OverviewTab.vue) is ugyanezt az `inject`-es mintát használja, a legegyszerűbb megoldás a `provide` hozzáadása a `VehicleDetailModal.vue`-hoz: ```typescript // A script setup blokkban import { provide, computed } from 'vue'; const vehicle = computed(() => props.vehicle || null); provide('vehicle', vehicle); ``` --- ### 2.4 `VehicleDetailModal.vue` - Pénzügyek Tab bővítés #### Jelenlegi állapot A `finance` tab (282-436. sor) csak `GET /assets/{id}/costs`-t hív (944-957. sor) és két részből áll: non-premium esetén egyszerű lista, premium esetén chart. #### Bővítés: 3 új API hívás párhuzamosan **Backend endpointok (már léteznek, VERIFIKÁLVA):** | Endpoint | Visszatérési típus | Helye | |----------|-------------------|-------| | `GET /api/v1/assets/vehicles/{id}/financials` | `AssetFinancialsResponse` | [`assets.py:1245`](backend/app/api/v1/endpoints/assets.py:1245) | | `GET /api/v1/assets/vehicles/{id}/insurance` | `List[VehicleInsurancePolicyResponse]` | [`assets.py:1314`](backend/app/api/v1/endpoints/assets.py:1314) | | `GET /api/v1/assets/vehicles/{id}/tax` | `List[VehicleTaxObligationResponse]` | [`assets.py:1376`](backend/app/api/v1/endpoints/assets.py:1376) | **Store metódusok (már léteznek, VERIFIKÁLVA):** | Metódus | Param | Visszatérés | |---------|-------|-------------| | `fetchAssetFinancials(assetId)` | `string` | `Promise` | [`vehicle.ts:318`](frontend/src/stores/vehicle.ts:318) | | `fetchInsurancePolicies(assetId)` | `string` | `Promise` | [`vehicle.ts:346`](frontend/src/stores/vehicle.ts:346) | | `fetchTaxObligations(assetId)` | `string` | `Promise` | [`vehicle.ts:388`](frontend/src/stores/vehicle.ts:388) | #### Tervezett módosítások a `VehicleDetailModal.vue`-ban: **a) Új state változók (script setup):** ```typescript const assetFinancials = ref(null); const insurancePolicies = ref([]); const taxObligations = ref([]); const financeLoading = ref(false); ``` **b) Párhuzamos API hívás a `loadFinanceData` függvényben (~944. sor környékén):** ```typescript async function loadFinanceData() { financeLoading.value = true; try { const vehicleId = props.vehicle?.id?.toString(); if (!vehicleId) return; // Promise.all a 3 új híváshoz const [financials, policies, taxes] = await Promise.all([ vehicleStore.fetchAssetFinancials(vehicleId), vehicleStore.fetchInsurancePolicies(vehicleId), vehicleStore.fetchTaxObligations(vehicleId), ]); assetFinancials.value = financials; insurancePolicies.value = policies; taxObligations.value = taxes; // Meglévő costs betöltés változatlan await loadCosts(); } catch (err) { console.error('Failed to load finance data:', err); } finally { financeLoading.value = false; } } ``` **c) Template bővítés - új szekciók a meglévő "Költségek" szekció ELÉ:** ```html

{{ $t('vehicle.financials.title') }}

...purchase_price...
...leasing...residual_value...

{{ $t('vehicle.insurance.title') }}

{{ policy.insurance_type }} - {{ policy.premium_amount }} - {{ policy.expiry_date }}

{{ $t('vehicle.tax.title') }}

{{ tax.tax_type }} - {{ tax.amount }} - {{ tax.payment_status }}
``` **d) Importok hozzáadása:** ```typescript import type { AssetFinancials, VehicleInsurancePolicy, VehicleTaxObligation } from '@/types/vehicle'; ``` --- ## 3. Függőségi Térkép ```mermaid graph TD A[vehicle.ts - VehicleData] -->|image_url mező| B[VehicleCardStandard.vue] A -->|Vehicle típus| C[VehicleDetailModal.vue] C -->|provide vehicle| D[TechDataTab.vue] C -->|Promise.all| E[vehicleStore: fetchAssetFinancials] C -->|Promise.all| F[vehicleStore: fetchInsurancePolicies] C -->|Promise.all| G[vehicleStore: fetchTaxObligations] E --> H[assets.py: GET /vehicles/{id}/financials] F --> I[assets.py: GET /vehicles/{id}/insurance] G --> J[assets.py: GET /vehicles/{id}/tax] ``` --- ## 4. Végrehajtási Sorrend | Lépés | Fájl | Művelet | Függőség | |-------|------|---------|----------| | 1 | `types/vehicle.ts` | `image_url` hozzáadása | Nincs | | 2 | `VehicleCardStandard.vue` | 5 data binding javítás | 1. lépés (`image_url`) | | 3 | `VehicleDetailModal.vue` | TechData tab + provide hozzáadás | Nincs | | 4 | `VehicleDetailModal.vue` | Finance tab bővítés (Promise.all) | Nincs | | 5 | - | Vite build futtatás | 1-4. lépés | --- ## 5. Kockázatok és Megjegyzések 1. **TechDataTab inject függőség:** Ha a `provide` nem működik a modalban (pl. scope issue), alternatív megoldás a `TechDataTab.vue` átírása prop-alapúra. Ez azonban többletkockázat, ezért először a `provide`-os megoldást próbáljuk. 2. **`FinancialsTab.vue` átvételének elvetése:** A `FinancialsTab.vue` (709 sor) már tartalmazza a 3 API hívást, de sötét témát (bg-slate-900) használ, ami nem kompatibilis a modal világos témájával. A kód lemásolása helyett a logikát közvetlenül a `VehicleDetailModal.vue`-ba építjük be. 3. **Nincs Compact variáns:** A keresés nem talált Compact változatot, így csak a Standard kártyát kell javítani. 4. **i18n kulcsok:** A `hu.ts` és `en.ts` fájlokba új fordítási kulcsokat kell felvenni (pl. `vehicle.financials.title`, `vehicle.insurance.title`, `vehicle.tax.title`, `vehicle.techData`). --- ## 6. Jóváhagyás **Architect:** ✅ Terv elkészítve **Fejlesztő:** ⏳ Jóváhagyásra vár A terv végrehajtásához **Code módba** kell váltani.