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