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

10 KiB

📐 Logic Spec — Vehicle Registration Documents

Modul célja és Masterbook 2 illeszkedés

Cél: A forgalmi engedély száma, érvényességi ideje és a törzskönyv száma mezők hiányának pótlása a teljes adatfolyamban (adatbázis → API szint → Frontend UI).

Masterbook 2 illeszkedés: A Thick Asset Digital Twin filozófiába illeszkedik — minden adminisztratív adatot közvetlenül az Asset modellben tárolunk, nem JSONB-ben.


Adatmodell

Új mezők az Asset modellben

Mező Típus SQL típus Kötelező Alapértelmezett
registration_certificate_number Optional[str] VARCHAR(50) Nem None
registration_certificate_validity Optional[datetime] DateTime(timezone=True) Nem None
vehicle_registration_document_number Optional[str] VARCHAR(50) Nem None

Miért nem JSONB?

Ezek strukturált, kereshető admin adatok, amelyek:

  • Külön lekérdezhetők (WHERE registration_certificate_number = '...')
  • Indexelhetők
  • Érvényesíthetők (pl. string hossz, dátum formátum)
  • Nincsenek elrejtve a szabad formátumú JSONB-ben

1. Lépés: Adatbázis modell bővítése

Fájl: backend/app/models/vehicle/asset.py

Módosítás

Az Asset osztályhoz (a warranty mezők után, a notes előtt) hozzáadandó:

# === REGISTRATION DOCUMENTS ===
registration_certificate_number: Mapped[Optional[str]] = mapped_column(
    String(50), nullable=True, default=None,
    comment="Forgalmi engedély száma"
)
registration_certificate_validity: Mapped[Optional[datetime]] = mapped_column(
    DateTime(timezone=True), nullable=True, default=None,
    comment="Forgalmi engedély érvényességi ideje"
)
vehicle_registration_document_number: Mapped[Optional[str]] = mapped_column(
    String(50), nullable=True, default=None,
    comment="Törzskönyv száma"
)

Sync

docker exec -it sf_api python -m app.scripts.sync_engine

2. Lépés: Pydantic sémák bővítése

Fájl: backend/app/schemas/asset.py

AssetResponse (32. sor után)

# === REGISTRATION DOCUMENTS ===
registration_certificate_number: Optional[str] = Field(None, max_length=50, description="Forgalmi engedély száma")
registration_certificate_validity: Optional[datetime] = Field(None, description="Forgalmi engedély érvényességi ideje")
vehicle_registration_document_number: Optional[str] = Field(None, max_length=50, description="Törzskönyv száma")

AssetCreate (a warranty után, 233. sor környékén)

# === REGISTRATION DOCUMENTS ===
registration_certificate_number: Optional[str] = Field(None, max_length=50, description="Forgalmi engedély száma")
registration_certificate_validity: Optional[datetime] = Field(None, description="Forgalmi engedély érvényességi ideje")
vehicle_registration_document_number: Optional[str] = Field(None, max_length=50, description="Törzskönyv száma")

AssetUpdate (a warranty után, 375. sor környékén)

# === REGISTRATION DOCUMENTS ===
registration_certificate_number: Optional[str] = Field(None, max_length=50, description="Forgalmi engedély száma")
registration_certificate_validity: Optional[datetime] = Field(None, description="Forgalmi engedély érvényességi ideje")
vehicle_registration_document_number: Optional[str] = Field(None, max_length=50, description="Törzskönyv száma")

3. Lépés: Asset Service bővítése

Fájl: backend/app/services/asset_service.py

Módosítás a create_or_claim_vehicle() metódusban

A 219-es sor előtt (a first_registration_date után) az asset_fields dict-be:

# Registration Documents
'registration_certificate_number': asset_data.registration_certificate_number,
'registration_certificate_validity': asset_data.registration_certificate_validity,
'vehicle_registration_document_number': asset_data.vehicle_registration_document_number,

4. Lépés: Frontend — Vehicle Store bővítése

Fájl: frontend/src/stores/vehicle.ts

Módosítás a Vehicle interfészben (a 88-89. sor környékén)

// Registration Documents
registration_certificate_number?: string | null
registration_certificate_validity?: string | null
vehicle_registration_document_number?: string | null

5. Lépés: Frontend — VehicleFormModal bővítése

Fájl: frontend/src/components/dashboard/VehicleFormModal.vue

5a. Form state bővítése (a 1779-es sor után)

// Registration Documents
registration_certificate_number: '',
registration_certificate_validity: '',
vehicle_registration_document_number: '',

5b. Admin Tab UI bővítése (a 1006-os sor előtt, a warranty szekció után)

<!-- ════════════════════════════════════════════════════════════ -->
<!-- REGISTRATION DOCUMENTS SECTION                              -->
<!-- ════════════════════════════════════════════════════════════ -->
<div class="border-t border-slate-200 pt-4">
  <h4 class="text-sm font-semibold text-slate-700 mb-3">{{ t('vehicle.registration_documents_title') || 'Forgalmi engedély és Törzskönyv' }}</h4>
  <div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
    <div>
      <label class="mb-1.5 block text-sm font-medium text-slate-700">{{ t('vehicle.label_registration_certificate_number') || 'Forgalmi engedély száma' }}</label>
      <input
        v-model="form.registration_certificate_number"
        type="text"
        class="w-full rounded-xl border border-slate-300 bg-white px-4 py-2.5 text-sm text-slate-800 placeholder-slate-400 focus:border-sf-accent focus:outline-none focus:ring-2 focus:ring-sf-accent/20"
        :placeholder="t('vehicle.placeholder_registration_certificate_number') || 'Pl. AB-123456'"
      />
    </div>
    <div>
      <label class="mb-1.5 block text-sm font-medium text-slate-700">{{ t('vehicle.label_registration_certificate_validity') || 'Forgalmi engedély érvényessége' }}</label>
      <input
        v-model="form.registration_certificate_validity"
        type="date"
        class="w-full rounded-xl border border-slate-300 bg-white px-4 py-2.5 text-sm text-slate-800 focus:border-sf-accent focus:outline-none focus:ring-2 focus:ring-sf-accent/20"
      />
    </div>
  </div>
  <div class="mt-3">
    <label class="mb-1.5 block text-sm font-medium text-slate-700">{{ t('vehicle.label_vehicle_registration_document_number') || 'Törzskönyv száma' }}</label>
    <input
      v-model="form.vehicle_registration_document_number"
      type="text"
      class="w-full rounded-xl border border-slate-300 bg-white px-4 py-2.5 text-sm text-slate-800 placeholder-slate-400 focus:border-sf-accent focus:outline-none focus:ring-2 focus:ring-sf-accent/20"
      :placeholder="t('vehicle.placeholder_vehicle_registration_document_number') || 'Pl. 1234567890'"
    />
  </div>
</div>

5c. handleSave payload bővítése (a 2159-es sor után)

// Registration Documents
registration_certificate_number: form.registration_certificate_number || null,
registration_certificate_validity: form.registration_certificate_validity || null,
vehicle_registration_document_number: form.vehicle_registration_document_number || null,

5d. populateForm bővítése (a 2065-ös sor után)

// Registration Documents
form.registration_certificate_number = vehicle.registration_certificate_number || ''
form.registration_certificate_validity = vehicle.registration_certificate_validity || ''
form.vehicle_registration_document_number = vehicle.vehicle_registration_document_number || ''

5e. resetForm bővítése (kb. 1987-2026 sorok között)

form.registration_certificate_number = ''
form.registration_certificate_validity = ''
form.vehicle_registration_document_number = ''

6. Lépés: Frontend i18n fordítások

Fájl: frontend/src/i18n/hu.ts

label_registration_certificate_number: 'Forgalmi engedély száma',
label_registration_certificate_validity: 'Forgalmi engedély érvényessége',
label_vehicle_registration_document_number: 'Törzskönyv száma',
placeholder_registration_certificate_number: 'Pl. AB-123456',
placeholder_vehicle_registration_document_number: 'Pl. 1234567890',
registration_documents_title: 'Forgalmi engedély és Törzskönyv',

Fájl: frontend/src/i18n/en.ts

label_registration_certificate_number: 'Registration Certificate Number',
label_registration_certificate_validity: 'Registration Certificate Validity',
label_vehicle_registration_document_number: 'Vehicle Registration Document Number',
placeholder_registration_certificate_number: 'e.g. AB-123456',
placeholder_vehicle_registration_document_number: 'e.g. 1234567890',
registration_documents_title: 'Registration Certificate & Vehicle Document',

7. Lépés: Backend i18n (opcionális)

Fájl: backend/static/locales/hu.json

"REGISTRATION_DOCUMENTS": {
  "CERTIFICATE_NUMBER": "Forgalmi engedély száma",
  "CERTIFICATE_VALIDITY": "Forgalmi engedély érvényessége",
  "DOCUMENT_NUMBER": "Törzskönyv száma"
}

Fájl: backend/static/locales/en.json

"REGISTRATION_DOCUMENTS": {
  "CERTIFICATE_NUMBER": "Registration Certificate Number",
  "CERTIFICATE_VALIDITY": "Registration Certificate Validity",
  "DOCUMENT_NUMBER": "Vehicle Registration Document Number"
}

Tesztelési terv

  1. Adatbázis: docker exec -it sf_api python -m app.scripts.sync_engine futtatása után ellenőrizni, hogy a 3 új oszlop létrejött a vehicle.assets táblában
  2. API: POST /vehicles hívás új mezőkkel → 201 Created + az új mezők visszaküldése
  3. API: PUT /vehicles/{id} hívás új mezőkkel → 200 OK + az új mezők frissítése
  4. API: GET /vehicles/{id} → az új mezők megjelennek a válaszban
  5. Frontend: VehicleFormModal → Admin tabon megjelennek az új mezők, mentéskor elküldődnek, szerkesztéskor visszatöltődnek