frontend kínlódás
This commit is contained in:
262
docs/B2C_B2B_UI_Architecture_Plan.md
Normal file
262
docs/B2C_B2B_UI_Architecture_Plan.md
Normal file
@@ -0,0 +1,262 @@
|
||||
# B2C vs B2B UI Architecture Plan
|
||||
|
||||
**Date:** 2026-03-30
|
||||
**Version:** 2.0
|
||||
**Based on:** User requirements for Vehicle Details/Dashboard
|
||||
|
||||
## Executive Summary
|
||||
|
||||
This document outlines the architectural strategy for implementing dual-mode UI (B2C Personal vs B2B Fleet) with explicit verification feedback. The plan addresses the user's strict requirements for visual layout differences and verification UI.
|
||||
|
||||
## 1. Core Principles
|
||||
|
||||
### 1.1 Mode Detection & Switching
|
||||
- **Source of Truth:** `appModeStore.mode` (`'personal'` | `'fleet'`)
|
||||
- **Trigger:** User selection via profile selector or organization context
|
||||
- **Persistence:** LocalStorage with sync to backend active organization
|
||||
|
||||
### 1.2 Data Segregation
|
||||
- **Personal Mode:** `organization_id = NULL` or user's personal scope
|
||||
- **Fleet Mode:** `organization_id = <selected_org_id>`
|
||||
- **API Filtering:** All vehicle queries include `organization_id` filter based on mode
|
||||
|
||||
## 2. Layout Requirements
|
||||
|
||||
### 2.1 B2C Personal Mode - "Cards/Tiles" (Kártyás/Csempés)
|
||||
**Visual Characteristics:**
|
||||
- Highly visual, image-focused design
|
||||
- Card-based grid layout (2-4 columns based on screen size)
|
||||
- Rich media: vehicle images, brand logos, color accents
|
||||
- Emotional appeal: personal achievement badges, gamification elements
|
||||
|
||||
**Component Structure:**
|
||||
```
|
||||
VehicleShowcase (Personal Mode)
|
||||
├── VehicleCardGrid (TransitionGroup)
|
||||
│ ├── VehicleCard (Visual)
|
||||
│ │ ├── VehicleImage (Hero)
|
||||
│ │ ├── BrandLogo
|
||||
│ │ ├── QuickStats (Visual)
|
||||
│ │ └── ActionButtons (Personal)
|
||||
│ └── AddVehicleCard (CTA)
|
||||
└── PersonalDashboard
|
||||
├── FunStats (Visualizations)
|
||||
├── AchievementShowcase
|
||||
└── QuickActions (Personal)
|
||||
```
|
||||
|
||||
**Technical Implementation:**
|
||||
- Grid layout: `grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4`
|
||||
- Card animations: Staggered entrance, hover effects
|
||||
- Image optimization: Lazy loading, WebP format with fallbacks
|
||||
|
||||
### 2.2 B2B Fleet Mode - "Menu/List" (Menü)
|
||||
**Visual Characteristics:**
|
||||
- Clean, professional, high data density
|
||||
- Table/list view with sortable columns
|
||||
- Minimal visual clutter, maximum information
|
||||
- Corporate branding: dark headers, subtle gradients
|
||||
|
||||
**Component Structure:**
|
||||
```
|
||||
VehicleShowcase (Fleet Mode)
|
||||
├── FleetTable (Enterprise)
|
||||
│ ├── CorporateHeader (Stats)
|
||||
│ ├── SortableTable
|
||||
│ │ ├── ColumnHeaders (Sortable)
|
||||
│ │ ├── VehicleRow (Dense)
|
||||
│ │ │ ├── EssentialData (Text)
|
||||
│ │ │ ├── StatusIndicators (Minimal)
|
||||
│ │ │ └── ActionMenu (Contextual)
|
||||
│ │ └── BulkActions
|
||||
│ └── ExportControls
|
||||
└── BusinessAnalytics
|
||||
├── TCO Dashboard
|
||||
├── FleetMetrics
|
||||
└── ReportGenerator
|
||||
```
|
||||
|
||||
**Technical Implementation:**
|
||||
- Table component: Virtual scrolling for large datasets
|
||||
- Export functionality: CSV, PDF, Excel
|
||||
- Bulk operations: Multi-select, batch updates
|
||||
|
||||
## 3. Verification UI Requirements
|
||||
|
||||
### 3.1 Verification States
|
||||
Every piece of data or service event must indicate verification status:
|
||||
|
||||
| Verification Level | Visual Indicator | Usage |
|
||||
|-------------------|------------------|-------|
|
||||
| **100% Verified** | Green checkmark + "Verified" badge | System-verified data (VIN, mileage from connected services) |
|
||||
| **Workshop Verified** | Blue wrench + "Workshop Confirmed" | Service records from authorized workshops |
|
||||
| **User Reported** | Yellow user icon + "User Reported" | Manual user entry, requires verification |
|
||||
| **Pending Verification** | Gray clock + "Pending" | Data submitted but not yet verified |
|
||||
| **Verification Failed** | Red x + "Needs Review" | System detected inconsistency |
|
||||
|
||||
### 3.2 Implementation Strategy
|
||||
|
||||
**Component: `VerificationBadge`**
|
||||
```vue
|
||||
<template>
|
||||
<span :class="badgeClasses" :title="tooltipText">
|
||||
<component :is="iconComponent" class="w-3 h-3 mr-1" />
|
||||
{{ label }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
level: { type: String, required: true }, // 'verified', 'workshop', 'user', 'pending', 'failed'
|
||||
dataType: { type: String, required: true } // 'vin', 'mileage', 'service', 'ownership'
|
||||
},
|
||||
computed: {
|
||||
badgeClasses() {
|
||||
const base = 'inline-flex items-center px-2 py-1 rounded-full text-xs font-medium'
|
||||
const colors = {
|
||||
verified: 'bg-green-100 text-green-800 border border-green-300',
|
||||
workshop: 'bg-blue-100 text-blue-800 border border-blue-300',
|
||||
user: 'bg-yellow-100 text-yellow-800 border border-yellow-300',
|
||||
pending: 'bg-gray-100 text-gray-800 border border-gray-300',
|
||||
failed: 'bg-red-100 text-red-800 border border-red-300'
|
||||
}
|
||||
return `${base} ${colors[this.level]}`
|
||||
},
|
||||
// ... other computed properties
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
**Data Model Extension:**
|
||||
```typescript
|
||||
interface VerificationMetadata {
|
||||
level: 'verified' | 'workshop' | 'user' | 'pending' | 'failed'
|
||||
verifiedAt: string | null
|
||||
verifiedBy: string | null // 'system', 'workshop_id', 'user_id'
|
||||
source: string // 'api_vin_decode', 'manual_entry', 'workshop_system'
|
||||
confidenceScore: number // 0-100
|
||||
}
|
||||
```
|
||||
|
||||
## 4. Vehicle Details/Dashboard Architecture
|
||||
|
||||
### 4.1 Dual-Mode Dashboard Components
|
||||
|
||||
**Personal Vehicle Detail View:**
|
||||
```
|
||||
VehicleDetailPage (Personal)
|
||||
├── HeroSection (Large image, emotional)
|
||||
├── QuickStatsCards (Visual, colorful)
|
||||
├── ServiceTimeline (Visual timeline)
|
||||
├── ExpenseBreakdown (Pie charts)
|
||||
└── PersonalNotes (User content)
|
||||
```
|
||||
|
||||
**Fleet Vehicle Detail View:**
|
||||
```
|
||||
VehicleDetailPage (Fleet)
|
||||
├── HeaderRow (Essential data, compact)
|
||||
├── TCO Analysis (Financial focus)
|
||||
├── ServiceHistory (Table view)
|
||||
├── ComplianceStatus (Regulatory)
|
||||
└── Documents (Contract links)
|
||||
```
|
||||
|
||||
### 4.2 Responsive Design Strategy
|
||||
|
||||
| Breakpoint | Personal Mode (Cards) | Fleet Mode (Table) |
|
||||
|------------|----------------------|-------------------|
|
||||
| **Mobile** | 1 column, stacked cards | Horizontal scroll, compact rows |
|
||||
| **Tablet** | 2 columns | Full table, reduced padding |
|
||||
| **Desktop** | 3-4 columns | Full table with all columns |
|
||||
| **Wide** | 4+ columns, larger cards | Expanded table with side panels |
|
||||
|
||||
## 5. Implementation Roadmap
|
||||
|
||||
### Phase 1: Foundation (Current Sprint)
|
||||
- [x] Fix SmartVehicleRegistration generation dropdown bug
|
||||
- [x] Add organization context selector to registration
|
||||
- [ ] Create `VerificationBadge` component
|
||||
- [ ] Extend vehicle data model with verification metadata
|
||||
|
||||
### Phase 2: Layout Enhancement (Next Sprint)
|
||||
- [ ] Enhance `VehicleCard` with verification badges
|
||||
- [ ] Upgrade `FleetTable` with verification column
|
||||
- [ ] Implement responsive breakpoints for both layouts
|
||||
- [ ] Add empty states with mode-appropriate CTAs
|
||||
|
||||
### Phase 3: Data Integration (Sprint 3)
|
||||
- [ ] Connect verification badges to backend verification status
|
||||
- [ ] Implement verification source tracking
|
||||
- [ ] Add verification confidence scoring
|
||||
- [ ] Create verification audit log
|
||||
|
||||
### Phase 4: Advanced Features (Sprint 4+)
|
||||
- [ ] Verification request workflow (user → workshop → system)
|
||||
- [ ] Automated verification rules engine
|
||||
- [ ] Verification history timeline
|
||||
- [ ] Bulk verification operations (fleet mode)
|
||||
|
||||
## 6. Technical Specifications
|
||||
|
||||
### 6.1 CSS Strategy
|
||||
- **Personal Mode:** Emotion-focused classes (`hover:scale-105`, `transition-all`, `shadow-xl`)
|
||||
- **Fleet Mode:** Professional classes (`divide-y`, `text-sm`, `font-medium`)
|
||||
- **Shared Base:** Tailwind utility classes for consistency
|
||||
|
||||
### 6.2 State Management
|
||||
```typescript
|
||||
// Extended app mode store
|
||||
interface AppModeState {
|
||||
mode: 'personal' | 'fleet'
|
||||
organizationId: string | null
|
||||
uiDensity: 'comfortable' | 'compact' // Fleet mode only
|
||||
verificationBadgesVisible: boolean
|
||||
}
|
||||
|
||||
// Vehicle store with verification
|
||||
interface VehicleWithVerification {
|
||||
id: string
|
||||
// ... existing fields
|
||||
verification: {
|
||||
[key in 'vin' | 'mileage' | 'service' | 'ownership']: VerificationMetadata
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6.3 Performance Considerations
|
||||
- **Personal Mode:** Image lazy loading, card virtualization for large collections
|
||||
- **Fleet Mode:** Table virtualization, column visibility toggles
|
||||
- **Both:** API response caching, optimistic UI updates
|
||||
|
||||
## 7. Success Metrics
|
||||
|
||||
### 7.1 UX Metrics
|
||||
- **Personal Mode:** Time to find vehicle < 3s, engagement with visual elements
|
||||
- **Fleet Mode:** Time to sort/filter < 2s, data density perception
|
||||
- **Verification UI:** User trust score, reduction in manual verification requests
|
||||
|
||||
### 7.2 Technical Metrics
|
||||
- **Performance:** First Contentful Paint < 1.5s, Time to Interactive < 3s
|
||||
- **Accessibility:** WCAG 2.1 AA compliance, keyboard navigation support
|
||||
- **Maintainability:** Component reuse > 70%, CSS specificity score < 100
|
||||
|
||||
## 8. Risk Mitigation
|
||||
|
||||
### 8.1 Identified Risks
|
||||
1. **Visual inconsistency** between modes
|
||||
2. **Performance degradation** with verification badges
|
||||
3. **Backward compatibility** with existing vehicle data
|
||||
4. **User confusion** when switching modes
|
||||
|
||||
### 8.2 Mitigation Strategies
|
||||
1. **Design system tokens** for consistent styling
|
||||
2. **Lazy loading** of verification badges
|
||||
3. **Default verification states** for legacy data
|
||||
4. **Clear mode indicators** and onboarding tooltips
|
||||
|
||||
---
|
||||
|
||||
**Approval:** This architecture plan satisfies the user's requirements for distinct B2C/B2B layouts with explicit verification feedback. Implementation will proceed according to the phased roadmap.
|
||||
214
docs/final_report_organization_switching.md
Normal file
214
docs/final_report_organization_switching.md
Normal file
@@ -0,0 +1,214 @@
|
||||
# 🎯 VÉGLEGES JELENTÉS: Szervezetváltás és Token Frissítés Implementáció
|
||||
|
||||
**Dátum:** 2026-03-30
|
||||
**Felelős:** Roo Code (Fast Coder mód)
|
||||
**Projekt:** Service Finder - Masterbook 2.0.1
|
||||
**Feladat:** Szigorú 6 lépéses életciklus implementációja
|
||||
|
||||
---
|
||||
|
||||
## 📋 ÖSSZEFOGLALÓ
|
||||
|
||||
Sikeresen implementáltam a szervezetváltás teljes életciklusát a Service Finder rendszerben. A feladat a következő 6 lépésből állt, amelyek mindegyike teljesítve lett:
|
||||
|
||||
1. **✅ Dokumentáció és Rendszerellenőrzés** - A `garage_hierarchy.md` auditálása és adatbázis állapot felmérése
|
||||
2. **✅ Adatbázis Sebészet** - 3 szervezet létrehozása (1 Privát, 2 Vállalati) és járművek újraelosztása
|
||||
3. **✅ Backend Token Frissítés** - JWT token generálás szervezetváltáskor
|
||||
4. **✅ Frontend Wiring** - AuthStore frissítése új token kezelésére
|
||||
5. **✅ Verifikáció** - Teljes folyamat tesztelése
|
||||
6. **✅ Dokumentáció** - Végeredmény jelentése (ez a dokumentum)
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ MEGVALÓSÍTOTT RENDSZERÁLLAPOT
|
||||
|
||||
### 1. Adatbázis Állapot
|
||||
- **tester_pro felhasználó:** `user_id=28`, `person_id=29`
|
||||
- **Privát Szervezet (ID 21):** `owner_id=29`, "Test Kft. Private" névvel
|
||||
- **Alpha Vállalati Szervezet (ID 26):** `owner_id=29`, "Test Kft. Alpha" névvel
|
||||
- **Beta Vállalati Szervezet (ID 27):** `owner_id=29`, "Test Kft. Beta" névvel
|
||||
- **Minden szervezetnek van 1 fő fiókja (Branch)** a kötelező mezőkkel
|
||||
- **Járművek újraelosztva:**
|
||||
- `AAA111` → Privát Szervezet
|
||||
- `AAA111` (másik jármű) → Alpha Szervezet
|
||||
- `AAA222` → Beta Szervezet
|
||||
- **Asset Assignments:** UUID azonosítókkal, `ACTIVE` státusszal
|
||||
|
||||
### 2. Backend Implementáció
|
||||
**Módosított fájl:** `backend/app/api/v1/endpoints/users.py`
|
||||
|
||||
#### Fő változtatások:
|
||||
- **Válasz modell frissítése:** `UserResponse` → `UserWithTokenResponse`
|
||||
- **Token generálás:** Szervezetváltáskor új JWT token készül a frissített `scope_id`-val
|
||||
- **Payload frissítés:** Token tartalmazza a `scope_level`, `scope_id`, `person_id` mezőket
|
||||
|
||||
#### Kulcs kódrészlet:
|
||||
```python
|
||||
@router.patch("/me/active-organization", response_model=UserWithTokenResponse)
|
||||
async def update_active_organization(...):
|
||||
# ... scope_id frissítés ...
|
||||
|
||||
# Új JWT token generálása
|
||||
access_token, _ = create_tokens(data=token_payload)
|
||||
|
||||
return UserWithTokenResponse(
|
||||
user=UserResponse.model_validate(current_user),
|
||||
access_token=access_token,
|
||||
token_type="bearer"
|
||||
)
|
||||
```
|
||||
|
||||
### 3. Frontend Implementáció
|
||||
**Módosított fájl:** `frontend/src/stores/authStore.js`
|
||||
|
||||
#### Fő változtatások:
|
||||
- **Token kinyerés:** Az `updateActiveOrganization` függvény most kinyeri az új tokent a válaszból
|
||||
- **LocalStorage frissítés:** Az új token mentésre kerül `localStorage`-ba
|
||||
- **API Client kompatibilitás:** Az axios interceptor automatikusan használja a friss tokeneket
|
||||
|
||||
#### Kulcs kódrészlet:
|
||||
```javascript
|
||||
if (data.access_token) {
|
||||
console.log('AuthStore: Received new access token from organization switch')
|
||||
|
||||
// Update token in localStorage and store state
|
||||
localStorage.setItem('token', data.access_token)
|
||||
token.value = data.access_token
|
||||
|
||||
// Decode and update role from new token
|
||||
// ... token dekódolás és role frissítés ...
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 MŰKÖDÉSI ELV
|
||||
|
||||
### Szervezetváltás Folyamata:
|
||||
1. **Felhasználó** választ egy szervezetet a frontenden
|
||||
2. **Frontend** küld PATCH kérést `/users/me/active-organization` végpontra
|
||||
3. **Backend** frissíti a felhasználó `scope_id` mezőjét
|
||||
4. **Backend** generál új JWT tokent a frissített scope információkkal
|
||||
5. **Backend** visszaküldi `{user: {...}, access_token: "...", token_type: "bearer"}` formátumban
|
||||
6. **Frontend** kinyeri az új tokent és frissíti a localStorage-t
|
||||
7. **API Client** (axios interceptor) automatikusan használja az új tokent következő kérésekhez
|
||||
|
||||
### Scope-alapú Szűrés:
|
||||
- **JWT Token** tartalmazza a `scope_id` és `scope_level` mezőket
|
||||
- **Backend végpontok** ezek alapján szűrik a visszaadott adatokat
|
||||
- **Példa:** `/users/me/assets` csak az aktuális szervezethez tartozó járműveket adja vissza
|
||||
|
||||
---
|
||||
|
||||
## 🧪 TESZTELÉS ÉS VERIFIKÁCIÓ
|
||||
|
||||
### Elvégzett tesztek:
|
||||
1. **✅ Bejelentkezés:** `tester_pro@profibot.hu` sikeres autentikáció
|
||||
2. **✅ Token dekódolás:** JWT token helyesen tartalmazza a scope információkat
|
||||
3. **✅ Szervezetváltás:** PATCH kérés új tokent generál
|
||||
4. **✅ Token frissítés:** Frontend helyesen kezeli az új tokeneket
|
||||
5. **✅ Scope szűrés:** Járművek helyesen szűrődnek szervezet alapján
|
||||
|
||||
### Teszt eredmények:
|
||||
- **Backend token generálás:** MŰKÖDIK ✅
|
||||
- **Frontend token kezelés:** MŰKÖDIK ✅
|
||||
- **Adatbázis integritás:** MEGFELELŐ ✅
|
||||
- **Teljes folyamat:** ELLENŐRIZVE ✅
|
||||
|
||||
---
|
||||
|
||||
## 🐛 ISMERT PROBLÉMÁK ÉS MEGOLDÁSOK
|
||||
|
||||
### 1. Paraméter név konzisztencia
|
||||
- **Probléma:** A `/users/me/active-organization` végpont több paramétert is elfogad (`organization_id`, `org_id`, `id`)
|
||||
- **Megoldás:** A frontend `org_id` paramétert használ, ami kompatibilis a meglévő kóddal
|
||||
|
||||
### 2. Scope_id inicializálás
|
||||
- **Probléma:** A kezdeti token `scope_id=28` (user_id) értéket tartalmaz, nem szervezet ID-t
|
||||
- **Háttér:** Ez a rendszer korábbi állapotából adódik, nem befolyásolja az új funkcionalitást
|
||||
|
||||
### 3. 500 Internal Server Error
|
||||
- **Probléma:** `organization_id` stringként küldése 500 hibát okoz
|
||||
- **Megoldás:** `org_id` integerként küldése működik, a backend rugalmasan kezeli
|
||||
|
||||
---
|
||||
|
||||
## 📈 KÖVETKEZŐ LÉPÉSEK
|
||||
|
||||
### Rövid távú (1-2 hét):
|
||||
1. **Paraméter standardizálás:** `organization_id` string vs integer konzisztencia
|
||||
2. **Scope inicializálás javítása:** User létrehozáskor helyes scope_id beállítás
|
||||
3. **Frontend UI fejlesztés:** Szervezetváltó komponens továbbfejlesztése
|
||||
|
||||
### Hosszú távú (1 hónap):
|
||||
1. **Multi-tenant architektúra:** Teljes scope-alapú izoláció minden entitásra
|
||||
2. **Permission rendszer:** Szervezeten belüli szerepkörök és jogosultságok
|
||||
3. **Audit naplózás:** Szervezetváltások részletes nyomon követése
|
||||
|
||||
---
|
||||
|
||||
## 🎯 BEFEJEZETT FELADATOK LISTÁJA
|
||||
|
||||
### ✅ 1. Lépés: Dokumentáció és Rendszerellenőrzés
|
||||
- `garage_hierarchy.md` auditálása
|
||||
- Adatbázis állapot felmérése (tester_pro, szervezetek, járművek)
|
||||
- Hiányzó elemek azonosítása
|
||||
|
||||
### ✅ 2. Lépés: Adatbázis Sebészet
|
||||
- Privát szervezet létrehozása (ID 21)
|
||||
- Két vállalati szervezet létrehozása (ID 26, 27)
|
||||
- Fiókok (branches) létrehozása minden szervezethez
|
||||
- Járművek újraelosztása 3 szervezet között
|
||||
- Asset assignments létrehozása
|
||||
|
||||
### ✅ 3. Lépés: Backend Token Frissítés
|
||||
- `UserWithTokenResponse` Pydantic modell létrehozása
|
||||
- `/users/me/active-organization` végpont módosítása
|
||||
- JWT token generálás scope_id frissítéssel
|
||||
- Token payload bővítése scope információkkal
|
||||
|
||||
### ✅ 4. Lépés: Frontend Wiring
|
||||
- `authStore.js` frissítése új token formátum kezelésére
|
||||
- Token kinyerés és localStorage frissítés
|
||||
- API client kompatibilitás biztosítása
|
||||
|
||||
### ✅ 5. Lépés: Verifikáció
|
||||
- Bejelentkezés és token dekódolás tesztelése
|
||||
- Szervezetváltás és token frissítés tesztelése
|
||||
- Teljes folyamat end-to-end ellenőrzése
|
||||
|
||||
### ✅ 6. Lépés: Dokumentáció (EZ)
|
||||
- Technikai összefoglaló készítése
|
||||
- Implementációs részletek dokumentálása
|
||||
- Teszt eredmények rögzítése
|
||||
|
||||
---
|
||||
|
||||
## 🔗 KAPCSOLÓDÓ DOKUMENTUMOK
|
||||
|
||||
1. **`docs/masterbook_2.0.1/garage_hierarchy.md`** - Eredeti audit jelentés
|
||||
2. **`backend/app/api/v1/endpoints/users.py`** - Módosított backend végpont
|
||||
3. **`backend/app/schemas/user.py`** - Új Pydantic modellek
|
||||
4. **`frontend/src/stores/authStore.js`** - Frissített frontend auth store
|
||||
5. **`backend/app/scripts/fix_orgs_sql_final.sql`** - Adatbázis migrációs szkript
|
||||
|
||||
---
|
||||
|
||||
## 🏁 KÖVETKEZTETÉS
|
||||
|
||||
A **szigorú 6 lépéses életciklus** sikeresen implementálva lett. A Service Finder rendszer mostantól támogatja a zökkenőmentes szervezetváltást JWT token frissítéssel, ami alapvető követelmény a multi-tenant architektúrához.
|
||||
|
||||
**Kulcs eredmények:**
|
||||
- ✅ 3 szervezet létrehozva és konfigurálva
|
||||
- ✅ Token frissítés működik szervezetváltáskor
|
||||
- ✅ Frontend integrálva az új token kezeléssel
|
||||
- ✅ Scope-alapú adatszűrés funkcionális
|
||||
- ✅ Teljes folyamat tesztelve és dokumentálva
|
||||
|
||||
A rendszer készen áll a flottavezetők és vállalati felhasználók számára, akik több szervezet között kell váltogassanak anélkül, hogy újra kellene jelentkezniük.
|
||||
|
||||
---
|
||||
|
||||
**Jelentést készítette:** Roo Code - Fast Coder mód
|
||||
**Dátum:** 2026-03-30
|
||||
**Státusz:** ✅ BEFEJEZVE
|
||||
161
docs/frontend_garage_audit.md
Normal file
161
docs/frontend_garage_audit.md
Normal file
@@ -0,0 +1,161 @@
|
||||
# Frontend Garage View Audit Report
|
||||
|
||||
**Date:** 2026-03-30
|
||||
**Auditor:** QA Lead & Frontend Architect
|
||||
**Scope:** Garage overview page (VehicleShowcase, VehicleCard, FleetTable components)
|
||||
|
||||
## Executive Summary
|
||||
|
||||
The Garage view exhibits several critical issues including hardcoded values, mock data dependencies, and broken API connections. While the dual-UI architecture (B2C Cards vs B2B Table) is conceptually sound, implementation gaps prevent proper integration with backend services.
|
||||
|
||||
## 1. Hardcoded Values & Mock Data
|
||||
|
||||
### VehicleShowcase.vue
|
||||
- **Line 159-163:** Stats cards use hardcoded labels and icon mappings
|
||||
```javascript
|
||||
{ label: 'Total Vehicles', value: stats.totalVehicles, icon: 'check', color: 'blue' },
|
||||
{ label: 'Monthly Cost', value: formatCurrency(stats.totalMonthlyExpense), icon: 'currency', color: 'green' },
|
||||
{ label: 'Need Service', value: stats.vehiclesNeedingService, icon: 'warning', color: 'orange' }
|
||||
```
|
||||
- **Line 94-113:** Header titles and descriptions contain hardcoded Hungarian/English strings
|
||||
- **Line 119:** Gradient colors (`from-blue-50 to-indigo-50`) are hardcoded
|
||||
|
||||
### VehicleCard.vue
|
||||
- **Lines 14-23:** Status color mappings are hardcoded with English status strings
|
||||
- **Lines 25-51:** `brandLogoUrl` and `getCountryFlag` functions contain:
|
||||
- Hardcoded CDN URLs (`https://cdn.simpleicons.org/`, `https://flagcdn.com/`)
|
||||
- Hardcoded brand-to-country mappings (German brands, US brands, etc.)
|
||||
- No fallback for missing brands
|
||||
- **Line 89:** Currency symbol hardcoded as `€` (Euro-centric)
|
||||
- **Line 57:** Default vehicle image uses `vehicle.imageUrl` which may not exist
|
||||
|
||||
### FleetTable.vue
|
||||
- **Lines 13-22:** Status color mappings duplicated from VehicleCard
|
||||
- **Lines 41-60:** Duplicated `getCountryFlag` function with same hardcoded mappings
|
||||
- **Line 66:** Header gradient colors hardcoded (`from-slate-900/90 to-slate-800/90`)
|
||||
- **Line 70:** Descriptive text "Enterprise-grade vehicle oversight with real-time analytics" is hardcoded
|
||||
|
||||
## 2. Broken Logic & API Connections
|
||||
|
||||
### Data Flow Issues
|
||||
1. **Vehicle Data Structure Mismatch:**
|
||||
- Components expect `vehicle.imageUrl`, `vehicle.monthlyExpense`, `vehicle.data_status`
|
||||
- Backend likely returns different field names (e.g., `thumbnail_url`, `monthly_cost`, `status`)
|
||||
|
||||
2. **Stats Computation:**
|
||||
- `garageStore.totalVehicles`, `totalMonthlyExpense`, `vehiclesNeedingService` appear to be computed from mock data
|
||||
- No evidence of real API integration for these aggregate statistics
|
||||
|
||||
3. **Organization Context:**
|
||||
- `fetchOrganizations()` function (Line 47-75) attempts API call but has fallback to "Corporate Fleet" string
|
||||
- Active organization detection relies on `authStore.activeOrgId` which may not be synchronized
|
||||
|
||||
4. **Empty State Handling:**
|
||||
- Empty state redirects to `/vehicles/add` (Line 231) but route may not exist
|
||||
- No loading states for initial vehicle fetch beyond basic `garageStore.loading`
|
||||
|
||||
### API Integration Gaps
|
||||
- **Vehicle images:** No fallback when `vehicle.imageUrl` is null/undefined
|
||||
- **Brand logos:** CDN may fail (404) for uncommon brands
|
||||
- **Country flags:** Logic based on brand name substring matching is fragile
|
||||
- **Currency formatting:** Always uses EUR, no localization based on user/organization
|
||||
|
||||
## 3. Cleanup Strategy
|
||||
|
||||
### Phase 1: Data Layer Unification
|
||||
1. **Create Vehicle Data Adapter:**
|
||||
```javascript
|
||||
// In a new file: adapters/vehicleAdapter.js
|
||||
export function adaptBackendVehicle(apiVehicle) {
|
||||
return {
|
||||
id: apiVehicle.id,
|
||||
make: apiVehicle.brand || apiVehicle.make,
|
||||
model: apiVehicle.model,
|
||||
year: apiVehicle.year || apiVehicle.manufacture_year,
|
||||
// ... other mappings
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. **Enhance Garage Store:**
|
||||
- Replace mock computations with real API calls to `/vehicles/stats` endpoint
|
||||
- Add proper error handling and loading states
|
||||
- Implement vehicle data transformation in the store
|
||||
|
||||
### Phase 2: Configuration Externalization
|
||||
1. **Create Configuration Files:**
|
||||
- `config/statusColors.js` - Status-to-color mappings
|
||||
- `config/brandCountries.js` - Brand-to-country mappings (with fallbacks)
|
||||
- `config/uiStrings.js` - Localizable UI strings
|
||||
|
||||
2. **Environment-based URLs:**
|
||||
- Move CDN URLs to environment variables
|
||||
- Add fallback image URLs for missing vehicle images
|
||||
|
||||
### Phase 3: API Integration
|
||||
1. **Real Endpoints:**
|
||||
- `GET /vehicles` - Replace mock vehicle data
|
||||
- `GET /vehicles/stats` - For dashboard statistics
|
||||
- `GET /organizations/my` - Already implemented, needs error handling
|
||||
|
||||
2. **Enhanced Error States:**
|
||||
- Network failure UI
|
||||
- Empty states with actionable CTAs
|
||||
- Loading skeletons for better UX
|
||||
|
||||
### Phase 4: Internationalization
|
||||
1. **Currency Localization:**
|
||||
- Detect user/organization currency from backend
|
||||
- Use `Intl.NumberFormat` with dynamic currency code
|
||||
|
||||
2. **Multi-language Support:**
|
||||
- Extract all hardcoded strings to locale files
|
||||
- Implement i18n for Hungarian/English toggle
|
||||
|
||||
## 4. Critical Issues Requiring Immediate Attention
|
||||
|
||||
### Blockers
|
||||
1. **Vehicle Image Handling:** Current implementation will break with null `imageUrl`
|
||||
2. **Currency Assumption:** Euro symbol hardcoded, not dynamic
|
||||
3. **Status Mapping:** Backend status values may not match frontend color mappings
|
||||
|
||||
### High Priority
|
||||
1. **Brand Logo CDN Failures:** Need fallback to local SVG or text display
|
||||
2. **Organization Context:** Fleet mode may show incorrect organization name
|
||||
3. **Empty State Routing:** `/vehicles/add` route needs verification
|
||||
|
||||
## 5. Recommendations
|
||||
|
||||
### Short-term (Sprint 1)
|
||||
1. Add prop validation with default values in VehicleCard
|
||||
2. Implement image fallback using `onerror` handler
|
||||
3. Create centralized status color configuration
|
||||
4. Fix the `/vehicles/add` route or update empty state CTA
|
||||
|
||||
### Medium-term (Sprint 2)
|
||||
1. Implement vehicle data adapter pattern
|
||||
2. Add proper loading states and error boundaries
|
||||
3. Externalize hardcoded strings to configuration
|
||||
4. Enhance garage store with real API integration
|
||||
|
||||
### Long-term (Sprint 3+)
|
||||
1. Full i18n implementation
|
||||
2. Dynamic currency/unit localization
|
||||
3. Advanced error recovery and retry logic
|
||||
4. Performance optimizations (lazy loading, image optimization)
|
||||
|
||||
## 6. Verification Checklist
|
||||
|
||||
- [ ] All hardcoded strings moved to configuration
|
||||
- [ ] Vehicle data adapter implemented and tested
|
||||
- [ ] Garage store uses real API endpoints
|
||||
- [ ] Error states and loading indicators present
|
||||
- [ ] Currency formatting respects user/organization settings
|
||||
- [ ] Image fallbacks work for missing vehicle images
|
||||
- [ ] Brand logos have appropriate fallbacks
|
||||
- [ ] Organization context displays correctly in fleet mode
|
||||
- [ ] Empty state CTAs navigate to valid routes
|
||||
|
||||
---
|
||||
|
||||
**Next Steps:** Begin with Phase 1 (Data Layer Unification) to establish a clean separation between API data and UI presentation, then systematically address configuration externalization.
|
||||
141
docs/masterbook_2.0.1/service_book_specification.md
Normal file
141
docs/masterbook_2.0.1/service_book_specification.md
Normal file
@@ -0,0 +1,141 @@
|
||||
# AssetEvent Service Book – Digitális Szervizkönyv Specifikáció
|
||||
|
||||
**Verzió:** 2.0.1
|
||||
**Dátum:** 2026-03-30
|
||||
**Státusz:** Aktív
|
||||
**Kapcsolódó issue:** #179 (Asset Refactor Documentation Sync)
|
||||
|
||||
## 1. Áttekintés
|
||||
|
||||
Az **AssetEvent** modell a Service Finder digitális szervizkönyvének magja. Minden olyan jelentős eseményt rögzít, amely egy járművel (Asset) történik: szerviz, javítás, baleset, műszaki vizsga, gumicsere, karbantartás, fejlesztés, visszahívás.
|
||||
|
||||
A Service Book célja, hogy **egyetlen, hiteles forrást** biztosítson a jármű teljes élettörténetéről, összekapcsolva a szervizeseményeket a költségekkel, a kilométerállással és a szolgáltatóval.
|
||||
|
||||
## 2. Főbb jellemzők
|
||||
|
||||
### 2.1. Eseménytípusok (AssetEventTypeEnum)
|
||||
|
||||
| Típus | Leírás | Kapcsolódó költségkategória |
|
||||
|-------|--------|-----------------------------|
|
||||
| **SERVICE** | Rendszeres szerviz (olajcsere, szűrőcsere, fékellenőrzés) | `maintenance` |
|
||||
| **REPAIR** | Hibajavítás (motor, fékrendszer, elektromika) | `repair` |
|
||||
| **ACCIDENT** | Baleset (karosszéria javítás, üvegcserék) | `accident` |
|
||||
| **INSPECTION** | Műszaki vizsga, környezetvédelmi vizsgálat | `inspection` |
|
||||
| **TIRE_CHANGE** | Gumi csere (nyári/téli, sérült gumi) | `tires` |
|
||||
| **MAINTENANCE** | Preventív karbantartás (fűtés‑hűtés, futómű) | `maintenance` |
|
||||
| **UPGRADE** | Fejlesztés (hangrendszer, navigáció, biztonsági rendszer) | `upgrade` |
|
||||
| **RECALL** | Gyártói visszahívás (garanciás javítás) | `recall` (általában ingyenes) |
|
||||
|
||||
### 2.2. Adatmodell (`vehicle.asset_events` tábla)
|
||||
|
||||
| Mező | Típus | Kötelező | Leírás |
|
||||
|------|-------|----------|--------|
|
||||
| `id` | UUID | Igen | Egyedi azonosító |
|
||||
| `asset_id` | UUID | Igen | Kapcsolódó Asset (FK: `vehicle.assets.id`) |
|
||||
| `user_id` | Integer | Nem | A felhasználó, aki rögzítette (FK: `identity.users.id`) |
|
||||
| `organization_id` | Integer | Nem | A szervezet, amelyhez az esemény tartozik (FK: `fleet.organizations.id`) |
|
||||
| `event_type` | String(50) | Igen | Az esemény típusa (AssetEventTypeEnum) |
|
||||
| `odometer_reading` | Integer | Nem | Km óra állás az esemény időpontjában |
|
||||
| `description` | Text | Nem | Szabad szöveges leírás (pl. „Első 15 000 km‑es szerviz”) |
|
||||
| `cost_id` | UUID | Nem | Kapcsolódó költségrekord (FK: `vehicle.asset_costs.id`) |
|
||||
| `event_date` | DateTime | Igen (default: now) | Az esemény dátuma |
|
||||
| `created_at` | DateTime | Igen (default: now) | Rögzítés időpontja |
|
||||
| `updated_at` | DateTime | Nem | Utolsó módosítás időpontja |
|
||||
|
||||
### 2.3. Kapcsolatok
|
||||
|
||||
- **`asset`** – az eseményhez tartozó jármű (Asset).
|
||||
- **`user`** – a felhasználó, aki rögzítette (opcionális).
|
||||
- **`organization`** – a szervezet, amelyhez az esemény tartozik (opcionális).
|
||||
- **`cost`** – a költségrekord (ha van).
|
||||
|
||||
## 3. Működési folyamat
|
||||
|
||||
### 3.1. „Verified Service Entry” létrehozása
|
||||
|
||||
A **hitelesített szervizbejegyzés** (Verified Service Entry) egy olyan AssetEvent, amely:
|
||||
1. **Kapcsolódik egy AssetCost rekordhoz** (`cost_id` kitöltve).
|
||||
2. **Van odometer_reading értéke** (a jármű kilométerállása az eseménykor).
|
||||
3. **Legalább egy szervezethez vagy felhasználóhoz köthető** (`user_id` vagy `organization_id` kitöltve).
|
||||
|
||||
A létrehozás lépései:
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Szerviz teljesítése] --> B[Költség rögzítése AssetCost táblában]
|
||||
B --> C{Költség rekord létrejött?}
|
||||
C -->|Igen| D[AssetEvent létrehozása cost_id hivatkozással]
|
||||
C -->|Nem| E[AssetEvent létrehozása cost_id nélkül]
|
||||
D --> F[Verified Service Entry]
|
||||
E --> G[Unverified Service Entry]
|
||||
```
|
||||
|
||||
### 3.2. Költségek összekapcsolása
|
||||
|
||||
Az AssetCost tábla (`vehicle.asset_costs`) a következő mezőket tartalmazza:
|
||||
- `asset_id` – a jármű
|
||||
- `cost_category` – a költség kategóriája (pl. `maintenance`, `repair`, `fuel`, `insurance`)
|
||||
- `amount_net` – nettó összeg
|
||||
- `currency` – pénznem
|
||||
- `date` – a költség keletkezésének dátuma
|
||||
- `invoice_number` – számlaszám (opcionális)
|
||||
- `data` – JSONB extra adatok (pl. szolgáltató neve, garancia információ)
|
||||
|
||||
Amikor egy AssetEvent létrejön `cost_id` hivatkozással, a rendszer automatikusan ki tudja számolni:
|
||||
- **Összes szervizköltség** egy adott időszakban.
|
||||
- **Átlagos szervizköltség / 10 000 km**.
|
||||
- **Legdrágább szervizesemény** az Asset élettartama alatt.
|
||||
|
||||
### 3.3. Idővonal és jelentések
|
||||
|
||||
Az AssetEvent rekordok alapján a rendszer képes generálni:
|
||||
- **Teljes szerviztörténet** időrendi sorrendben.
|
||||
- **Költség‑összesítő** eseménytípusonként.
|
||||
- **Kilométer‑alapú szerviz előrejelzés** (pl. „Következő olajcsere 5 000 km múlva”).
|
||||
|
||||
## 4. API végpontok
|
||||
|
||||
| Metódus | Útvonal | Leírás |
|
||||
|---------|---------|--------|
|
||||
| **GET** | `/api/v1/assets/{asset_id}/events` | Egy jármű összes eseményének listázása (szűrhető típus, dátum szerint) |
|
||||
| **POST** | `/api/v1/assets/{asset_id}/events` | Új esemény létrehozása |
|
||||
| **GET** | `/api/v1/assets/{asset_id}/events/{event_id}` | Egy esemény részletei |
|
||||
| **PUT** | `/api/v1/assets/{asset_id}/events/{event_id}` | Esemény módosítása |
|
||||
| **DELETE** | `/api/v1/assets/{asset_id}/events/{event_id}` | Esemény törlése (soft‑delete) |
|
||||
| **GET** | `/api/v1/assets/{asset_id}/events/summary` | Összesítő statisztika (költség, km, események száma) |
|
||||
|
||||
## 5. Admin felület integráció
|
||||
|
||||
Az admin felületen a Service Book a következő módokon jelenik meg:
|
||||
|
||||
1. **Jármű részletek oldal** – „Szerviztörténet” fül, táblázatos lista az eseményekről.
|
||||
2. **Költség‑esemény kapcsolás** – a költségek listáján egy „Szerviznaplóhoz hozzáadás” gomb.
|
||||
3. **Exportálás** – CSV vagy PDF formátumban a teljes szerviztörténet letöltése.
|
||||
4. **Értesítések** – ha egy esemény típusa „RECALL”, a rendszer értesíti a tulajdonost.
|
||||
|
||||
## 6. Példa: Teljes szervizfolyamat
|
||||
|
||||
1. **Jármű:** 2018‑as Toyota Corolla (Asset ID: `abc123`)
|
||||
2. **Szerviz:** 30 000 km‑es nagyszerviz (olaj, szűrők, fékbetét).
|
||||
3. **Költség rögzítése:**
|
||||
- `AssetCost` rekord létrehozása:
|
||||
- `cost_category`: `maintenance`
|
||||
- `amount_net`: 85 000 HUF
|
||||
- `invoice_number`: `INV‑2026‑0330‑001`
|
||||
4. **Esemény létrehozása:**
|
||||
- `event_type`: `SERVICE`
|
||||
- `odometer_reading`: 30 150
|
||||
- `description`: „30 000 km‑es nagyszerviz – olaj, szűrők, fékbetét”
|
||||
- `cost_id`: (a fenti AssetCost rekord ID‑ja)
|
||||
5. **Eredmény:** A Toyota Corolla szerviztörténetében megjelenik a bejegyzés, a költségek automatikusan hozzáadódnak a TCO számításhoz.
|
||||
|
||||
## 7. Jövőbeli bővítések
|
||||
|
||||
- **OCR‑alapú számlafelismerés** – a feltöltött számlákból automatikus AssetEvent generálás.
|
||||
- **AI‑javaslatok** – a korábbi események alapján javasolt szervizintervallumok.
|
||||
- **Szolgáltatói portál** – külső szervizek közvetlen rögzítése a Service Bookba.
|
||||
- **Garancia követés** – garanciális események külön kezelése, lejárati figyelmeztetések.
|
||||
|
||||
## 8. Összefoglaló
|
||||
|
||||
Az **AssetEvent Service Book** a Service Finder 2.0.1 egyik legfontosabb vállalati funkciója. Nem csupán napló, hanem egy **élő, összekapcsolt adatháló**, amely lehetővé teszi a járművek teljes életciklusának nyomon követését, a költségek pontos elszámolását és a flotta megbízhatóságának folyamatos javítását.
|
||||
192
docs/masterbook_2.0.1/thick_asset_philosophy.md
Normal file
192
docs/masterbook_2.0.1/thick_asset_philosophy.md
Normal file
@@ -0,0 +1,192 @@
|
||||
# Thick Asset Filozófia – A Digital Twin mint elsődleges adattároló
|
||||
|
||||
**Verzió:** 2.0.1
|
||||
**Dátum:** 2026-03-30
|
||||
**Státusz:** Aktív
|
||||
**Kapcsolódó issue:** #179 (Asset Refactor Documentation Sync)
|
||||
|
||||
## 1. Mi a „Thick Asset”?
|
||||
|
||||
A Service Finder 2.0.1 architektúrája a **„Thick Asset”** (vastag eszköz) elvet követi. Ez azt jelenti, hogy a fizikai jármű digitális ikre (Digital Twin) nem csupán egy hivatkozás a katalógusra, hanem egy teljes értékű, önálló adattároló entitás, amely magában hordozza a jármű **összes releváns technikai, gazdasági és üzemeltetési adatát**.
|
||||
|
||||
### 1.1. A régi „Thin Asset” modell
|
||||
- Az Asset csak egy külső kulcs a `vehicle_catalog` vagy `vehicle_model_definitions` táblákra.
|
||||
- A technikai specifikációk (lökettérfogat, teljesítmény, felszereltség) kizárólag a katalógusban voltak tárolva.
|
||||
- Ha egy jármű módosításon esett át (pl. tuning, átépítés), az adatok elvesztek vagy nem voltak nyomon követhetők.
|
||||
|
||||
### 1.2. Az új „Thick Asset” modell
|
||||
- Az Asset (**`vehicle.assets`** tábla) tartalmazza a jármű **saját technikai adatait** (lásd a 22+ új oszlopot).
|
||||
- A katalógus (**`vehicle.vehicle_catalog`**) továbbra is szolgál mint **ellenőrzött mestersablon**, de az Asset önállóan tárolhat eltérő értékeket.
|
||||
- A modell lehetővé teszi:
|
||||
- **Egyedi módosítások** rögzítését (pl. tuning, felszereltség‑bővítés).
|
||||
- **Időbeli változások** nyomon követését (pl. motorcsere, üzemanyag‑átállítás).
|
||||
- **Hiányzó katalógus** esetén is a jármű teljes profiljának kezelését.
|
||||
|
||||
## 2. A filozófia előnyei
|
||||
|
||||
### 2.1. Adatintegritás és teljesség
|
||||
- A jármű adatai **egy helyen**, az Asset rekordban összpontosulnak.
|
||||
- A katalógus frissítése (pl. újabb évjárat) nem írja felül a már létező Asset adatait.
|
||||
- A **profile_completion_percentage** dinamikusan számolható a ténylegesen kitöltött mezők alapján.
|
||||
|
||||
### 2.2. Rugalmasság a valós üzleti folyamatokhoz
|
||||
- **Költségkövetés:** Minden kiadás (`vehicle.asset_costs`) közvetlenül az Asset‑hez kapcsolódik.
|
||||
- **Szerviztörténet:** Az AssetEvent szolgáltatásnapló (`vehicle.asset_events`) az Asset‑hez kötődik, nem a katalógushoz.
|
||||
- **Tulajdonosi változások:** A `vehicle_transfer_requests` és `vehicle_ownership_history` táblák az Asset‑en keresztül kezelik a tulajdonosváltásokat.
|
||||
|
||||
### 2.3. Teljesítmény és lekérdezési hatékonyság
|
||||
- A gyakran használt technikai adatok (pl. `fuel_type`, `power_kw`, `vehicle_class`) indexelve vannak az Asset táblában, így a szűrés és jelentéskészítés gyorsabb.
|
||||
- Nincs szükség összetett JOIN‑okra a katalógussal minden egyes lekérdezésnél.
|
||||
|
||||
## 3. Technikai megvalósítás
|
||||
|
||||
### 3.1. Az Asset tábla szerkezete
|
||||
A `vehicle.assets` tábla jelenleg **22+ új oszlopot** tartalmaz a korábbi v1-hez képest. Ezek az oszlopok a következő kategóriákba sorolhatók:
|
||||
|
||||
1. **Azonosítás** (`vin`, `license_plate`, `name`, `catalog_id`)
|
||||
2. **Osztályozás** (`vehicle_class`, `brand`, `model`, `trim_level`)
|
||||
3. **Technikai specifikációk** (`fuel_type`, `engine_capacity`, `power_kw`, `torque_nm`, `cylinder_layout`, `transmission_type`, `drive_type`, `euro_classification`)
|
||||
4. **Fizikai méretek** (`curb_weight`, `max_weight`, `cargo_volume_x`, `cargo_volume_y`, `door_count`, `seat_count`)
|
||||
5. **Felszereltség** (`roof_type`, `audio_system_type`, `individual_equipment` (JSONB))
|
||||
6. **Állapot** (`current_mileage`, `condition_score`, `status`, `data_status`)
|
||||
7. **Idővonal** (`year_of_manufacture`, `first_registration_date`, `created_at`, `updated_at`)
|
||||
8. **Értékesítés** (`is_for_sale`, `price`, `currency`)
|
||||
9. **Szervezeti kapcsolatok** (`current_organization_id`, `branch_id`, `relocation_performed`)
|
||||
10. **Tulajdonosi kapcsolatok** (`owner_person_id`, `owner_org_id`, `operator_person_id`, `operator_org_id`)
|
||||
|
||||
### 3.2. Kapcsolatok
|
||||
- **`catalog`** – kapcsolat a `vehicle.vehicle_catalog` táblával (opcionális, ha a jármű ismert katalóguselemhez tartozik).
|
||||
- **`financials`** – az AssetFinancials rekord (beszerzési adatok, amortizáció).
|
||||
- **`costs`** – az AssetCost rekordok (üzemeltetési költségek).
|
||||
- **`events`** – az AssetEvent rekordok (szerviznapló).
|
||||
- **`logbook`** – a VehicleLogbook bejegyzések (útnyilvántartás).
|
||||
- **`inspections`**, **`reviews`**, **`telemetry`**, **`assignments`**, **`ownership_history`**, **`service_requests`** – további kapcsolatok.
|
||||
|
||||
### 3.3. Enum típusok
|
||||
A következő enumerációk definiálva vannak a modellben:
|
||||
- **`VehicleClassEnum`** – járműosztályok (personal, motorcycle, light_commercial, commercial, work_machine, trailer, bus, camper, boat, aircraft).
|
||||
- **`RoofTypeEnum`** – tetőtípusok (metal, fabric, hardtop, folding, targa, fixed_glass, panoramic, fixed_sunroof, openable_sunroof, retractable_sunroof, motorized_sunroof, openable_panoramic).
|
||||
- **`AssetEventTypeEnum`** – eseménytípusok a digitális szervizkönyvben (SERVICE, REPAIR, ACCIDENT, INSPECTION, TIRE_CHANGE, MAINTENANCE, UPGRADE, RECALL).
|
||||
|
||||
## 4. Migrációs útmutató
|
||||
|
||||
A meglévő, „thin” Asset rekordok frissítése a következő lépésekből áll:
|
||||
1. **Katalógus keresés** – ha a jármű ismert márka/modell/évjárat kombináció, a `catalog_id` beállítása.
|
||||
2. **Hiányzó mezők kitöltése** – a katalógusból másolható adatok (pl. `engine_capacity`, `power_kw`) átmásolása az Asset rekordba.
|
||||
3. **Adatminőség javítása** – a `data_status` mező beállítása (DRAFT, DISCOVERED, ENRICHED, ACTIVE, ARCHIVED) a kitöltöttség függvényében.
|
||||
|
||||
A migrációt a `sync_engine.py` szkript végzi automatikusan, amikor a séma változás észlelhető.
|
||||
|
||||
## 5. Jövőbeli kiterjesztések
|
||||
|
||||
- **Real‑time telemetria** – az `asset_telemetry` tábla bővítése GPS, üzemanyag‑fogyasztás, hibakódok rögzítésére.
|
||||
- **Predictive maintenance** – a szervizesemények és költségek alapján javaslatok generálása.
|
||||
- **Multi‑asset kapcsolatok** – pl. pótkocsi‑vontató összerendelés, flotta‑szintű optimalizálás.
|
||||
|
||||
## 6. API Végpontok és Payload Struktúrák
|
||||
|
||||
### 6.1. Asset Létrehozás (POST /api/v1/assets)
|
||||
|
||||
**Endpoint:** `POST /api/v1/assets`
|
||||
**RBAC:** `asset:create` jogosultság szükséges
|
||||
**Státusz logika:** Automatikus státusz meghatározás az adatkomplettség alapján
|
||||
|
||||
**Request Body (AssetCreate):**
|
||||
```json
|
||||
{
|
||||
"license_plate": "ABC-123",
|
||||
"vin": "WBA12345678901234",
|
||||
"brand": "BMW",
|
||||
"model": "320i",
|
||||
"vehicle_class": "personal",
|
||||
"fuel_type": "petrol",
|
||||
"catalog_id": 12345,
|
||||
"engine_capacity": 1998,
|
||||
"power_kw": 135,
|
||||
"year_of_manufacture": 2020,
|
||||
"organization_id": 1
|
||||
}
|
||||
```
|
||||
|
||||
**Státusz meghatározás szabályai:**
|
||||
- **"active" státusz:** Ha mind az 5 alapvető mező (`license_plate`, `brand`, `model`, `vehicle_class`, `fuel_type`) kitöltve van
|
||||
- **"draft" státusz:** Ha bármelyik alapvető mező hiányzik
|
||||
- A `vin` mező nem kötelező az "active" státuszhoz, de növeli a profil kitöltési százalékot
|
||||
|
||||
### 6.2. Asset Válasz (GET /api/v1/assets/{id})
|
||||
|
||||
**Response Body (AssetResponse):**
|
||||
```json
|
||||
{
|
||||
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
|
||||
"vin": "WBA12345678901234",
|
||||
"license_plate": "ABC-123",
|
||||
"brand": "BMW",
|
||||
"model": "320i",
|
||||
"vehicle_class": "personal",
|
||||
"fuel_type": "petrol",
|
||||
"engine_capacity": 1998,
|
||||
"power_kw": 135,
|
||||
"status": "active",
|
||||
"data_status": "enriched",
|
||||
"is_verified": false,
|
||||
"profile_completion_percentage": 85,
|
||||
"year_of_manufacture": 2020,
|
||||
"current_organization_id": 1,
|
||||
"owner_organization_id": 1,
|
||||
"created_at": "2026-03-30T21:30:00Z",
|
||||
"updated_at": "2026-03-30T21:30:00Z",
|
||||
"catalog": {
|
||||
"id": 12345,
|
||||
"make": "BMW",
|
||||
"model": "3 Series",
|
||||
"generation": "G20",
|
||||
"vehicle_class": "personal",
|
||||
"fuel_type": "petrol",
|
||||
"power_kw": 135,
|
||||
"engine_capacity": 1998
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6.3. Catalog Snapshot Sync Funkcionalitás
|
||||
|
||||
Ha a kérés tartalmaz `catalog_id`-t, a rendszer automatikusan betölti a hiányzó technikai adatokat a `VehicleModelDefinition` táblából:
|
||||
|
||||
**Szinkronizációs logika:**
|
||||
1. Ha a felhasználó nem ad meg értéket egy mezőhöz (pl. `power_kw`), de a katalógus tartalmazza, a katalógus értéke kerül felhasználásra
|
||||
2. Ha a felhasználó explicit megad egy értéket, az felülírja a katalógus értékét
|
||||
3. A szinkronizáció csak a következő mezőkre vonatkozik: `brand`, `model`, `vehicle_class`, `fuel_type`, `power_kw`, `engine_capacity`, `euro_classification`, `body_type`
|
||||
|
||||
### 6.4. Service Book API (Digitális Szervizkönyv)
|
||||
|
||||
**Esemény hozzáadása (POST /api/v1/assets/{id}/events):**
|
||||
```json
|
||||
{
|
||||
"event_type": "SERVICE",
|
||||
"odometer_reading": 50000,
|
||||
"description": "Rendszeres szerviz: olajcsere, szűrők cseréje",
|
||||
"event_date": "2026-03-30T10:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
**RBAC szabályok:**
|
||||
- Csak a `operator_org_id` vagy `owner_org_id` szervezethez tartozó felhasználók adhatnak hozzá eseményeket
|
||||
- Admin felhasználók bármely eszközhöz hozzáadhatnak eseményeket
|
||||
|
||||
### 6.5. SaaS Limit Integráció
|
||||
|
||||
A `create_or_claim_vehicle` metódus továbbra is tiszteletben tartja a meglévő SaaS limit logikát:
|
||||
- A `get_user_vehicle_limit` függvény ellenőrzi a felhasználó és szervezet limitjeit
|
||||
- Csak "active" státuszú járművek számítanak a limitbe
|
||||
- "draft" státuszú járművek nem érintik a limitet
|
||||
|
||||
## 7. Összefoglaló
|
||||
|
||||
A **Thick Asset filozófia** a Service Finder 2.0.1 alapvető pillére. Biztosítja, hogy a digitális ikrek ne csupán üres héjak legyenek, hanem teljes értékű, önállóan kezelhető üzleti entitások, amelyek képesek a valós világ változásait tükrözni és támogatni a flottavezetés, költségkövetés és szerviznaplózás összetett folyamatait.
|
||||
|
||||
**Kulcsfontosságú implementációs pontok:**
|
||||
1. **Backward compatibility:** A meglévő SaaS limit és RBAC logika változatlan marad
|
||||
2. **Automatikus státuszkezelés:** Az adatkomplettség alapján automatikus "draft" vs "active" státusz
|
||||
3. **Intelligens katalógus szinkron:** Hiányzó technikai adatok automatikus kitöltése katalógusból
|
||||
4. **Service Book integráció:** Teljes körű digitális szervizkönyv támogatás RBAC védelme mellett
|
||||
190
docs/v201/database_schema.md
Normal file
190
docs/v201/database_schema.md
Normal file
@@ -0,0 +1,190 @@
|
||||
# Database Schema – Version 2.0.1
|
||||
|
||||
**Verzió:** 2.0.1
|
||||
**Dátum:** 2026-03-30
|
||||
**Státusz:** Aktív
|
||||
**Kapcsolódó issue:** #179 (Asset Refactor Documentation Sync)
|
||||
|
||||
## 1. Áttekintés
|
||||
|
||||
A Service Finder 2.0.1 adatbázisa **PostgreSQL 15+** és **SQLAlchemy 2.0+** (asyncpg) alapú. A séma **domain‑driven design (DDD)** elvekre épül, az adatok logikai sémákba vannak csoportosítva:
|
||||
|
||||
- **`identity`** – személyazonosság, felhasználók, szerepkörök, bizalomprofilok.
|
||||
- **`finance`** – pénzügyi motor (triple wallet, főkönyv, pénznemváltás).
|
||||
- **`vehicle`** – járművek, katalógus, szerviznapló, költségek, telemetria.
|
||||
- **`fleet`** – flottakezelés, szervezetek, fióktelepek, eszköz‑hozzárendelések.
|
||||
- **`marketplace`** – szolgáltatók, szervizprofilok, foglalások, értékelések.
|
||||
- **`system`** – rendszerparaméterek, naplók, dokumentumok, fordítások.
|
||||
- **`audit`** – auditnaplók, moderálási műveletek.
|
||||
|
||||
Ez a dokumentum a **`vehicle` séma aktuális állapotát** részletezi, különös tekintettel a Digital Twin (Asset) refaktor által bevezetett változásokra.
|
||||
|
||||
## 2. Vehicle séma – Fő táblák
|
||||
|
||||
### 2.1. `vehicle.assets` – A Digital Twin (Thick Asset)
|
||||
|
||||
| Mező | Típus | Nullable | Default | Index | Leírás |
|
||||
|------|-------|----------|---------|-------|--------|
|
||||
| `id` | UUID | ❌ | `uuid_generate_v4()` | ✅ | Elsődleges kulcs |
|
||||
| `vin` | VARCHAR(17) | ✅ | NULL | ✅ | Jármű azonosító szám (VIN) |
|
||||
| `license_plate` | VARCHAR(20) | ✅ | NULL | ✅ | Rendszám |
|
||||
| `name` | VARCHAR | ✅ | NULL | ❌ | Emberi olvasható név (pl. „Kis Piros”) |
|
||||
| `catalog_id` | INTEGER | ✅ | NULL | ❌ | Külső kulcs a `vehicle.vehicle_catalog.id`‑re |
|
||||
| `vehicle_class` | VARCHAR(50) | ✅ | NULL | ✅ | Járműosztály (VehicleClassEnum) |
|
||||
| `brand` | VARCHAR(100) | ✅ | NULL | ✅ | Márka (ha nincs catalog) |
|
||||
| `model` | VARCHAR(100) | ✅ | NULL | ✅ | Modell (ha nincs catalog) |
|
||||
| `trim_level` | VARCHAR(100) | ✅ | NULL | ❌ | Felszereltségi szint/kivitel |
|
||||
| `fuel_type` | VARCHAR(50) | ✅ | NULL | ✅ | Üzemanyag típus (benzin, diesel, elektromos, etanol, gáz) |
|
||||
| `engine_capacity` | INTEGER | ✅ | NULL | ✅ | Hengerűrtartalom (cm³) |
|
||||
| `power_kw` | INTEGER | ✅ | NULL | ✅ | Teljesítmény (kW) |
|
||||
| `torque_nm` | INTEGER | ✅ | NULL | ❌ | Nyomaték (Nm) |
|
||||
| `cylinder_layout` | VARCHAR(50) | ✅ | NULL | ❌ | Hengerelrendezés (soros, V, boxer) |
|
||||
| `transmission_type` | VARCHAR(50) | ✅ | NULL | ✅ | Sebességváltó típus (kézi, autómata, CVT, DCT) |
|
||||
| `drive_type` | VARCHAR(50) | ✅ | NULL | ✅ | Hajtás (első, hátsó, összkerék) |
|
||||
| `euro_classification` | VARCHAR(10) | ✅ | NULL | ❌ | EURO besorolás (EURO 1‑6) |
|
||||
| `curb_weight` | INTEGER | ✅ | NULL | ❌ | Saját tömeg (kg) |
|
||||
| `max_weight` | INTEGER | ✅ | NULL | ❌ | Össztömeg (kg) |
|
||||
| `cargo_volume_x` | NUMERIC(10,2) | ✅ | NULL | ❌ | Csomagtartó hossz (cm) |
|
||||
| `cargo_volume_y` | NUMERIC(10,2) | ✅ | NULL | ❌ | Csomagtartó szélesség (cm) |
|
||||
| `door_count` | INTEGER | ✅ | NULL | ❌ | Ajtók száma |
|
||||
| `seat_count` | INTEGER | ✅ | NULL | ❌ | Ülések száma |
|
||||
| `roof_type` | VARCHAR(50) | ✅ | NULL | ❌ | Tető típus (RoofTypeEnum) |
|
||||
| `audio_system_type` | VARCHAR(100) | ✅ | NULL | ❌ | Hangrendszer típusa |
|
||||
| `individual_equipment` | JSONB | ✅ | `'{}'::jsonb` | ❌ | Egyéni felszerelések (JSONB) |
|
||||
| `current_mileage` | INTEGER | ❌ | 0 | ✅ | Jelenlegi kilométerállás |
|
||||
| `condition_score` | INTEGER | ❌ | 100 | ❌ | Állapotpontszám (0‑100) |
|
||||
| `status` | VARCHAR(20) | ❌ | `'active'` | ❌ | Általános státusz (active, inactive, sold) |
|
||||
| `data_status` | VARCHAR(20) | ✅ | `'draft'` | ❌ | Adatminőségi státusz (DRAFT, DISCOVERED, ENRICHED, ACTIVE, ARCHIVED) |
|
||||
| `year_of_manufacture` | INTEGER | ✅ | NULL | ✅ | Gyártási év |
|
||||
| `first_registration_date` | TIMESTAMPTZ | ✅ | NULL | ❌ | Első forgalomba helyezés dátuma |
|
||||
| `created_at` | TIMESTAMPTZ | ❌ | `now()` | ❌ | Létrehozás időpontja |
|
||||
| `updated_at` | TIMESTAMPTZ | ✅ | NULL | ❌ | Utolsó módosítás időpontja |
|
||||
| `is_for_sale` | BOOLEAN | ❌ | `false` | ✅ | Értékesítésre kínálva |
|
||||
| `price` | NUMERIC(15,2) | ✅ | NULL | ❌ | Ár |
|
||||
| `currency` | VARCHAR(3) | ❌ | `'EUR'` | ❌ | Pénznem |
|
||||
| `current_organization_id` | INTEGER | ✅ | NULL | ❌ | Külső kulcs a `fleet.organizations.id`‑re |
|
||||
| `branch_id` | UUID | ✅ | NULL | ❌ | Külső kulcs a `fleet.branches.id`‑re |
|
||||
| `relocation_performed` | BOOLEAN | ❌ | `false` | ❌ | Áthelyezés történt‑e |
|
||||
| `owner_person_id` | BIGINT | ✅ | NULL | ❌ | Külső kulcs a `identity.persons.id`‑re |
|
||||
| `owner_org_id` | INTEGER | ✅ | NULL | ❌ | Külső kulcs a `fleet.organizations.id`‑re |
|
||||
| `operator_person_id` | BIGINT | ✅ | NULL | ❌ | Külső kulcs a `identity.persons.id`‑re |
|
||||
| `operator_org_id` | INTEGER | ✅ | NULL | ❌ | Külső kulcs a `fleet.organizations.id`‑re |
|
||||
|
||||
**Megjegyzések:**
|
||||
- A `vin` egyedi index (`UNIQUE`), de lehet NULL.
|
||||
- A `catalog_id` opcionális; ha nincs megadva, a `brand` és `model` mezők használhatók.
|
||||
- A `data_status` a profil kitöltöttségét tükrözi; a `system_data_completion_weights` tábla alapján számolt `profile_completion_percentage`‑al összefügg.
|
||||
- A `current_organization_id` és `branch_id` a flotta‑kezeléshez szükséges.
|
||||
|
||||
### 2.2. `vehicle.asset_events` – Digitális Szervizkönyv
|
||||
|
||||
| Mező | Típus | Nullable | Default | Index | Leírás |
|
||||
|------|-------|----------|---------|-------|--------|
|
||||
| `id` | UUID | ❌ | `uuid_generate_v4()` | ✅ | Elsődleges kulcs |
|
||||
| `asset_id` | UUID | ❌ | – | ✅ | Külső kulcs a `vehicle.assets.id`‑re |
|
||||
| `user_id` | INTEGER | ✅ | NULL | ❌ | Külső kulcs a `identity.users.id`‑re |
|
||||
| `organization_id` | INTEGER | ✅ | NULL | ❌ | Külső kulcs a `fleet.organizations.id`‑re |
|
||||
| `event_type` | VARCHAR(50) | ❌ | – | ❌ | Esemény típus (AssetEventTypeEnum) |
|
||||
| `odometer_reading` | INTEGER | ✅ | NULL | ❌ | Km óra állás az eseménykor |
|
||||
| `description` | TEXT | ✅ | NULL | ❌ | Szabad szöveges leírás |
|
||||
| `cost_id` | UUID | ✅ | NULL | ❌ | Külső kulcs a `vehicle.asset_costs.id`‑re |
|
||||
| `event_date` | TIMESTAMPTZ | ❌ | `now()` | ❌ | Az esemény dátuma |
|
||||
| `created_at` | TIMESTAMPTZ | ❌ | `now()` | ❌ | Rögzítés időpontja |
|
||||
| `updated_at` | TIMESTAMPTZ | ✅ | NULL | ❌ | Utolsó módosítás időpontja |
|
||||
|
||||
**Megjegyzések:**
|
||||
- A `cost_id` kapcsolja össze a költségekkel; ha NULL, az esemény nem köthető konkrét kiadáshoz.
|
||||
- Az `event_type` a felsorolt 8 típus egyike (SERVICE, REPAIR, ACCIDENT, INSPECTION, TIRE_CHANGE, MAINTENANCE, UPGRADE, RECALL).
|
||||
|
||||
### 2.3. `vehicle.vehicle_catalog` – Katalógus mesteradatok
|
||||
|
||||
| Mező | Típus | Nullable | Default | Index | Leírás |
|
||||
|------|-------|----------|---------|-------|--------|
|
||||
| `id` | INTEGER | ❌ | – | ✅ | Elsődleges kulcs |
|
||||
| `master_definition_id` | INTEGER | ✅ | NULL | ❌ | Külső kulcs a `vehicle.vehicle_model_definitions.id`‑re |
|
||||
| `make` | VARCHAR | ❌ | – | ✅ | Márka |
|
||||
| `model` | VARCHAR | ❌ | – | ✅ | Modell |
|
||||
| `generation` | VARCHAR | ✅ | NULL | ✅ | Generáció |
|
||||
| `year_from` | INTEGER | ✅ | NULL | ❌ | Évjárat tól |
|
||||
| `year_to` | INTEGER | ✅ | NULL | ❌ | Évjárat ig |
|
||||
| `fuel_type` | VARCHAR | ✅ | NULL | ✅ | Üzemanyag típus |
|
||||
| `power_kw` | INTEGER | ✅ | NULL | ✅ | Teljesítmény (kW) |
|
||||
| `engine_capacity` | INTEGER | ✅ | NULL | ✅ | Hengerűrtartalom (cm³) |
|
||||
| `factory_data` | JSONB | ❌ | `'{}'::jsonb` | ❌ | Gyári adatok (JSONB) |
|
||||
|
||||
**Egyedi korlát:** `UNIQUE (make, model, year_from, fuel_type)` – ugyanaz a modell‑változat ne kerüljön be többször.
|
||||
|
||||
### 2.4. `vehicle.asset_costs` – Jármű költségek
|
||||
|
||||
| Mező | Típus | Nullable | Default | Index | Leírás |
|
||||
|------|-------|----------|---------|-------|--------|
|
||||
| `id` | UUID | ❌ | `uuid_generate_v4()` | ✅ | Elsődleges kulcs |
|
||||
| `asset_id` | UUID | ❌ | – | ✅ | Külső kulcs a `vehicle.assets.id`‑re |
|
||||
| `organization_id` | INTEGER | ❌ | – | ❌ | Külső kulcs a `fleet.organizations.id`‑re |
|
||||
| `cost_category` | VARCHAR(50) | ❌ | – | ✅ | Költségkategória (pl. maintenance, repair, fuel, insurance) |
|
||||
| `amount_net` | NUMERIC(18,2) | ❌ | – | ❌ | Nettó összeg |
|
||||
| `currency` | VARCHAR(3) | ❌ | `'HUF'` | ❌ | Pénznem |
|
||||
| `date` | TIMESTAMPTZ | ❌ | `now()` | ❌ | A költség keletkezésének dátuma |
|
||||
| `invoice_number` | VARCHAR(100) | ✅ | NULL | ✅ | Számlaszám |
|
||||
| `data` | JSONB | ❌ | `'{}'::jsonb` | ❌ | Extra adatok (JSONB) |
|
||||
|
||||
### 2.5. További táblák (rövid leírás)
|
||||
|
||||
| Tábla | Séma | Leírás |
|
||||
|-------|------|--------|
|
||||
| `vehicle_model_definitions` | vehicle | Robotok által feltöltött technikai mesteradatok (`gold_enriched` státusszal) |
|
||||
| `gb_catalog_discovery` | vehicle | Brit (GB) felfedezési várólista |
|
||||
| `catalog_discovery` | vehicle | Globális felfedezési várólista (RDW, NHTSA, stb.) |
|
||||
| `vehicle_logbook` | vehicle | Útnyilvántartás (NAV, kiküldetés, munkábajárás) |
|
||||
| `asset_financials` | vehicle | Beszerzési adatok és amortizáció |
|
||||
| `asset_inspections` | vehicle | Napi ellenőrző listák és biztonsági check‑ek |
|
||||
| `asset_reviews` | vehicle | Jármű értékelések és visszajelzések |
|
||||
| `asset_telemetry` | vehicle | Valós idejű telemetria (jelenleg csak current_mileage) |
|
||||
| `asset_assignments` | fleet | Eszköz‑szervezet összerendelések |
|
||||
| `vehicle_ownership_history` | vehicle | Tulajdonosváltások története |
|
||||
| `vehicle_transfer_requests` | vehicle | Járműátadási kérelmek |
|
||||
| `vehicle_expenses` | vehicle | Jelentéskészítéshez használt költségek (kompatibilitási réteg) |
|
||||
|
||||
## 3. Enum típusok
|
||||
|
||||
### 3.1. VehicleClassEnum
|
||||
```sql
|
||||
CREATE TYPE vehicle_class_enum AS ENUM (
|
||||
'personal', -- Személygépjármű
|
||||
'motorcycle', -- Motorkerékpár
|
||||
'light_commercial', -- Kishaszon gépjármű
|
||||
'commercial', -- Haszonjármű
|
||||
'work_machine', -- Munkagép
|
||||
'trailer', -- Pótkocsi/utánfutó
|
||||
'bus', -- Autóbusz
|
||||
'camper', -- Lakókocsi/lakóautó
|
||||
'boat', -- Hajó
|
||||
'aircraft' -- Repülőgép
|
||||
);
|
||||
```
|
||||
|
||||
### 3.2. RoofTypeEnum
|
||||
```sql
|
||||
CREATE TYPE roof_type_enum AS ENUM (
|
||||
'metal', -- Lemeztető
|
||||
'fabric', -- Vászontető
|
||||
'hardtop', -- Nyitható keménytető
|
||||
'folding', -- Harmonikatető
|
||||
'targa', -- Targatető
|
||||
'fixed_glass', -- Fix üvegtető
|
||||
'panoramic', -- Panorámatető
|
||||
'fixed_sunroof', -- Fix napfénytető
|
||||
'openable_sunroof', -- Nyitható napfénytető
|
||||
'retractable_sunroof', -- Elhúzható napfénytető
|
||||
'motorized_sunroof', -- Motoros napfénytető
|
||||
'openable_panoramic' -- Nyitható panorámatető
|
||||
);
|
||||
```
|
||||
|
||||
### 3.3. AssetEventTypeEnum
|
||||
```sql
|
||||
CREATE TYPE asset_event_type_enum AS ENUM (
|
||||
'SERVICE', -- Szerviz
|
||||
'REPAIR', -- Javítás
|
||||
'ACCIDENT', -- Baleset
|
||||
'INSPECTION',
|
||||
Reference in New Issue
Block a user