# Service Finder Fejlesztési Történet ## 2026-06-21 - P0 Deep Audit: Database Consistency & Zombie API Hunt ### 🎯 Cél Teljes körű adatbázis konzisztencia ellenőrzés és zombie API végpontok felderítése a `vehicle`, `finance`, `fleet_finance` sémákban, mielőtt a frontend fejlesztés elkezdődik. ### 🔧 Eredmények **1. ADATBÁZIS TISZTASÁG:** ✅ PASS - API modul import: ✅ Sikeres (2 route: GET, POST) - Sync Engine: ✅ 1210 OK, 0 Fixed, 0 Extra - E2E test: ⚠️ Pre-existing conftest hiba (verification token timeout - nem kapcsolódó) ## 2026-06-23 - Cost Entry Wizard (CostEntryWizard.vue) - 4-lépéses Számla Űrlap ### 🎯 Cél 4-lépéses stepper wizard építése részletes számla/invoice költségek rögzítésére a CostsActionsCard-ból indíthatóan. ### 🔧 Módosított fájlok - **`frontend/src/components/cost/CostEntryWizard.vue`** (ÚJ) - 4-step stepper wizard komponens - **`frontend/src/components/dashboard/CostsActionsCard.vue`** - "🧾 Részletes Számla" gomb hozzáadva, CostEntryWizard import és modal state - **`frontend/src/i18n/en.ts`** - costWizard i18n szekció hozzáadva - **`frontend/src/i18n/hu.ts`** - costWizard i18n szekció hozzáadva ### 🧩 CostEntryWizard lépések 1. **Alapadatok**: Jármű (read-only), kategória cascade (fő+alkategória), dátum 2. **Pénzügyek**: Nettó összeg, ÁFA kulcs (0/5/10/20/27%), Bruttó összeg (GROSS-FIRST), Pénznem 3. **Admin & Szállító**: Dinamikus vendor autocomplete (GET /organizations?org_type=SERVICE_PROVIDER) szabad szöveges fallbackkel, számlaszám, számla dátuma, fizetési határidő 4. **Fájlok**: Drag & drop fájl feltöltő UI (csak UI szintű file picker) ### 🔌 API Integráció - POST `/expenses/` a `costStore.addExpense()`-on keresztül AssetCostBase payload-dal - Payload tartalmazza: amount_gross (GROSS-FIRST), category_id, currency, date, data JSONB (net_amount, vat_rate, invoice_number, invoice_date, payment_deadline, vendor_id, vendor_name, file_names) ### ✅ Verifikáció - Vite build: ✅ Sikeres (253 modules, 6.94s) - Gitea kártya: #277 ## 2026-06-23 - Dashboard Cost Card Navigation Fix & Dedicated Costs Page ### 🎯 Cél A dashboard költség kártya üres területére kattintva és a "További költségek" gombbal is a költségek oldalra navigálás. Dedikált CostsView oldal létrehozása vissza gombbal és garázs háttérrel. ### 🔧 Módosított fájlok - **`frontend/src/views/costs/CostsView.vue`** (ÚJ) - Teljes költség oldal garázs háttérrel, vissza gombbal, költség táblázattal és paginációval - **`frontend/src/router/index.ts`** - `/dashboard/costs` route hozzáadva a CostsView-hoz - **`frontend/src/components/dashboard/CostsActionsCard.vue`** - Header bar kattinthatóvá téve + "További költségek" gomb átirányítva a `/dashboard/costs` oldalra - **`frontend/src/layouts/PrivateLayout.vue`** - Hamburger menü "Költségek" navigáció `/dashboard/costs`-ra módosítva - **`frontend/src/i18n/hu.ts`** - `costs.backToDashboard` kulcs hozzáadva - **`frontend/src/i18n/en.ts`** - `costs.backToDashboard` kulcs hozzáadva ### ✅ Verifikáció - Vite build: ✅ Sikeres (CostsView-DaFsqPnD.js chunk generálva) ## 2026-06-23 - Hotfix: Backend Expenses GET / endpoint & AssetCost.organization FK fix ### 🎯 Cél Két kritikus backend hiba javítása: 1. A `GET /api/v1/expenses/` hívás 404-et adott (nem létezett `GET /` végpont), amit a reverse proxy 307-es HTTPS→HTTP átirányítással válaszolt, ami Mixed Content blokkolást okozott a böngészőben. 2. A backend indításkor `InvalidRequestError`-ral összeomlott az `AssetCost.organization` relationship hibás konfigurációja miatt (két FK ugyanarra a táblára, de a `foreign_keys` paraméter hiányzott). ### 🔧 Módosított fájlok - **`backend/app/api/v1/endpoints/expenses.py`** - `GET /` végpont hozzáadva: list_all_expenses() - szervezet összes költségének listázása paginációval, Asset, CostCategory, Organization JOIN-okkal - **`backend/app/models/fleet_finance/models.py`** - `AssetCost.organization` relationship javítva: `foreign_keys=[organization_id]` paraméter hozzáadva a kétértelmű FK kapcsolat feloldásához ### 🔧 Eredmények - Backend konténer: ✅ Tisztán indul, nincs SQLAlchemy hiba - Login: ✅ Működik (nem omlik össze) - `GET /api/v1/expenses/`: ✅ Végpont elérhető, paginált költség listát ad vissza ## 2026-06-23 - Hotfix #2: Expenses API 307 redirect / Mixed Content - trailing slash fix ### 🎯 Cél A `GET /api/v1/expenses` hívás 307-es HTTPS→HTTP átirányítást kapott, mert a backend route `@router.get("/")` (perjellel) volt definiálva, de a frontend `/expenses` (perjel nélkül) hívta. A Starlette automatikus 307 redirect-je a külső openresty proxy miatt `http://` címmé alakult → Mixed Content blokk. ### 🔧 Módosított fájlok - **`backend/app/api/v1/endpoints/expenses.py`** - `@router.get("/")` → `@router.get("")` (perjel eltávolítva a route-ból) ### 🔧 Eredmények - Backend konténer: ✅ Tisztán indul - `GET /api/v1/expenses` most direkt egyezik a route-tal → nincs 307 redirect → nincs Mixed Content ## 2026-06-23 - Hotfix #3: Expenses API 500 Internal Server Error - AssetCost.cost_date → AssetCost.date ### 🎯 Cél A `GET /api/v1/expenses` végpont 500-as hibát dobott: `AttributeError: type object 'AssetCost' has no attribute 'cost_date'`. Az `AssetCost` modellben a mező neve `date` (110. sor), de a kód `cost_date`-t használt. ### 🔧 Módosított fájlok - **`backend/app/api/v1/endpoints/expenses.py`** - 2 helyen javítva: - 157. sor: `AssetCost.cost_date` → `AssetCost.date` - 193. sor: `cost.cost_date.isoformat()` → `cost.date.isoformat()` ### 🔧 Eredmények - Backend konténer: ✅ Tisztán indul - `GET /api/v1/expenses`: ✅ Várhatóan 200 OK (nem 500) --- ## 2026-06-23: Dashboard üres AdPlacementWidget elrejtése ### 🎯 Cél A felhasználó kérésére: a dashboardon a "PRO" feliratú `SubscriptionStatusWidget` mellett egy üres csempe volt látható (`AdPlacementWidget`), mert nincs hirdetés beállítva a rendszerben. A kérés az volt, hogy rejtsük el ezt az üres csempét. ### 🔧 Módosított fájlok - **`frontend/src/components/dashboard/AdPlacementWidget.vue`** - `defineEmits` hozzáadva: `ads-loaded` esemény, amely jelzi a szülőnek, hogy van-e hirdetés (`hasAds: boolean`). Az esemény a `fetchAds` siker és hiba ágában is meghívásra kerül. - **`frontend/src/views/DashboardView.vue`** - `adWidgetHasAds` ref hozzáadva (alapértelmezett: `false`). A hirdetési csempe wrapper `