Files
service-finder/plans/p0_vehicle_card_fix_plan.md
2026-06-23 21:11:21 +00:00

11 KiB

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

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).


2.2 VehicleCardStandard.vue - 5 adatkötés javítás

Fájl: 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
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):

<img v-if="vehicle.image_url" :src="vehicle.image_url" alt="" class="..." />
<template v-else>
  <svg ... ></svg>  <!-- Meglévő placeholder SVG változatlan -->
</template>

2.2.b - Country (62. sor):

<span class="...">{{ vehicle.registration_country || vehicle.countryCode || vehicle.country_code || '—' }}</span>

2.2.c - Engine (95. sor):

<span class="...">{{ vehicle.power_kw ? vehicle.power_kw + ' kW' : '?' }} / {{ vehicle.engine_capacity ? vehicle.engine_capacity + ' cm³' : '?' }}</span>

2.2.d - Color (103. sor):

<span class="...">{{ vehicle.individual_equipment?.color || 'N/A' }}</span>

2.3 VehicleDetailModal.vue - TechData Tab integráció

Fájl: frontend/src/components/vehicle/VehicleDetailModal.vue

Háttér

A 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):

<button @click="activeTab = 'techdata'" :class="activeTab === 'techdata' ? '...' : '...'">
  {{ $t('vehicle.techData') || 'Műszaki adatok' }}
</button>

b) Tab content blokk hozzáadása (a servicebook tab után, ~736. sor után):

<div v-if="activeTab === 'techdata'" class="space-y-5">
  <TechDataTab />
</div>

c) Import hozzáadása (script section):

import TechDataTab from '@/components/vehicles/tabs/TechDataTab.vue';

d) provide/inject kompatibilitás biztosítása: A TechDataTab.vue inject<computed<Vehicle | null>>('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 is ugyanezt az inject-es mintát használja, a legegyszerűbb megoldás a provide hozzáadása a VehicleDetailModal.vue-hoz:

// 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
GET /api/v1/assets/vehicles/{id}/insurance List[VehicleInsurancePolicyResponse] assets.py:1314
GET /api/v1/assets/vehicles/{id}/tax List[VehicleTaxObligationResponse] assets.py:1376

Store metódusok (már léteznek, VERIFIKÁLVA):

Metódus Param Visszatérés
fetchAssetFinancials(assetId) string Promise<AssetFinancials | null>
fetchInsurancePolicies(assetId) string Promise<VehicleInsurancePolicy[]>
fetchTaxObligations(assetId) string Promise<VehicleTaxObligation[]>

Tervezett módosítások a VehicleDetailModal.vue-ban:

a) Új state változók (script setup):

const assetFinancials = ref<AssetFinancials | null>(null);
const insurancePolicies = ref<VehicleInsurancePolicy[]>([]);
const taxObligations = ref<VehicleTaxObligation[]>([]);
const financeLoading = ref(false);

b) Párhuzamos API hívás a loadFinanceData függvényben (~944. sor környékén):

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É:

<div v-if="activeTab === 'finance'" class="space-y-5">
  
  <!-- 1. ÚJ: Beszerzés & Lízing szekció -->
  <div v-if="assetFinancials" class="...">
    <h3>{{ $t('vehicle.financials.title') }}</h3>
    <div class="grid grid-cols-2 gap-3">
      <div>...purchase_price...</div>
      <div>...leasing...residual_value...</div>
    </div>
  </div>

  <!-- 2. ÚJ: Biztosítások szekció -->
  <div v-if="insurancePolicies.length" class="...">
    <h3>{{ $t('vehicle.insurance.title') }}</h3>
    <div v-for="policy in insurancePolicies" :key="policy.id">
      {{ policy.insurance_type }} - {{ policy.premium_amount }} - {{ policy.expiry_date }}
    </div>
  </div>

  <!-- 3. ÚJ: Adók szekció -->
  <div v-if="taxObligations.length" class="...">
    <h3>{{ $t('vehicle.tax.title') }}</h3>
    <div v-for="tax in taxObligations" :key="tax.id">
      {{ tax.tax_type }} - {{ tax.amount }} - {{ tax.payment_status }}
    </div>
  </div>

  <!-- 4. MEGLÉVŐ: Költségek szekció (változatlan) -->
  <div v-if="!costsLoading">
    <!-- ... existing costs content ... -->
  </div>
</div>

d) Importok hozzáadása:

import type { AssetFinancials, VehicleInsurancePolicy, VehicleTaxObligation } from '@/types/vehicle';

3. Függőségi Térkép

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.