# 🔴 Finance Module — Corrective Blueprint (4 Failures) **Date:** 2026-07-26 **Author:** Architect Mode **Status:** Pending Code Mode Execution **Priority:** HIGH — Visual misalignment, duplicate back button, mock data, backend enum crash --- ## STEP 1: FAILURE ANALYSIS ### FAILURE 1: Wrong Dashboard Card — Mock Data Remains **Finding:** The dashboard at [`DashboardView.vue`](frontend_app/src/views/DashboardView.vue:72) uses [`ProfileTrustCard`](frontend_app/src/components/dashboard/ProfileTrustCard.vue) (Card 5). This IS the correct card and it WAS correctly modified by the previous blueprint — it now fetches live `financeStore` data and shows `subscriptionPlanName` from `authStore`. However, [`FinancialCard.vue`](frontend_app/src/components/dashboard/FinancialCard.vue) is a **separate, unused** component that also fetches live wallet data and has a "Top Up" button. It is NOT imported or rendered anywhere on the dashboard. It appears to be a legacy/standalone variant. **The actual source of "mock data" on the dashboard is the `transactionCount` computed (always 0) and the `subscriptionPlanName` which shows `—` if the user has no subscription plan set.** **Fix plan:** - The `ProfileTrustCard` correctly fetches live `financeStore` data already. - The `GamificationCard` at [`GamificationCard.vue`](frontend_app/src/components/dashboard/GamificationCard.vue:18) was changed from hardcoded `2,450` to `computed(() => 0)` — specifically requested by the previous blueprint as a "placeholder ready to wire up." - If the user sees mock data, it's the gamification score (0) and badges (empty array). These ARE mock/placeholder by design until a gamification store is created. **No additional changes needed for the dashboard card itself.** ### FAILURE 2: Back Button Still in Top Global Navbar **Root Cause:** The previous blueprint removed `` from all 4 child views BUT did NOT remove `` from [`FinanceLayout.vue`](frontend_app/src/layouts/FinanceLayout.vue:42-45). **Evidence:** ```html ``` This `HeaderBackButton` is rendered in the `#left` slot of `BaseHeader`, which is the global sticky top navbar. Removing the Teleport only removed the page title — the back button in the layout persists. **Fix:** Delete lines 42-45 from [`FinanceLayout.vue`](frontend_app/src/layouts/FinanceLayout.vue). Also remove the unused `backTarget` computed (lines 95-100) and clean up the `useRoute` import if no longer needed. ### FAILURE 3: Title Misalignment — Header Outside Content Container **Root Cause:** The newly added local header in [`FinanceMainView.vue`](frontend_app/src/views/FinanceMainView.vue:39-55) is placed OUTSIDE the main content container. **Evidence:** - Header at line 40: `
` — **no max-w, no px, no mx-auto** - Content container at line 59: `
` - The FleetView pattern at [`FleetView.vue`](frontend_app/src/views/vehicles/FleetView.vue:12) wraps EVERYTHING in `class="relative z-10 mx-auto max-w-7xl px-4 py-8 sm:px-6 lg:px-8"` — including the header. **Fix:** Wrap the local header in the same responsive container, OR add matching `mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 w-full` classes to the header div. The cleanest approach: restructure so header + cards share the same container. Apply the same fix to all 4 finance views (FinanceWalletsView, FinancePackagesView, FinanceTransactionsView). ### FAILURE 4: Backend Enum Error — 'credit' is not among defined enum values **Root Cause:** The [`seed_financial_ledger.py`](backend/scripts/seed_financial_ledger.py:18) seed script inserts lowercase `"credit"` and `"debit"` strings into the PostgreSQL `audit.ledger_entry_type` enum column, but the enum definition at [`audit.py`](backend/app/models/system/audit.py:58-60) only allows `"CREDIT"` and `"DEBIT"` (UPPERCASE). **Evidence:** - [`audit.py:58-60`](backend/app/models/system/audit.py:58-60): ```python class LedgerEntryType(str, enum.Enum): DEBIT = "DEBIT" CREDIT = "CREDIT" ``` - [`seed_financial_ledger.py:18`](backend/scripts/seed_financial_ledger.py:18): ```python DB_ENTRY_TYPES = ["credit", "debit"] # ❌ lowercase! ``` - The seed script uses `psycopg2` (sync) with explicit `::audit.ledger_entry_type` cast at line 105 — but psycopg2 may allow case-insensitive casting or the data was inserted before the enum was strict. - When the frontend calls `GET /billing/wallet/balance`, SQLAlchemy reads all `FinancialLedger` rows and tries to map `"credit"` to the enum — this crashes with the error seen in the screenshot. **Fix (TWO parts):** **Part A — Fix the seed script:** - [`seed_financial_ledger.py:18`](backend/scripts/seed_financial_ledger.py:18): Change `["credit", "debit"]` → `["CREDIT", "DEBIT"]` **Part B — Fix existing bad data in the database:** Run SQL to normalize all lowercase entries: ```sql UPDATE audit.financial_ledger SET entry_type = 'CREDIT' WHERE entry_type::text = 'credit'; UPDATE audit.financial_ledger SET entry_type = 'DEBIT' WHERE entry_type::text = 'debit'; ``` Also check and fix wallet_type and status similarly. --- ## STEP 2: CODE MODE HAND-OFF — Explicit Task List Execute in order. Do NOT modify FleetView.vue, PrivateLayout.vue, BaseHeader.vue, HeaderBackButton.vue, or router/index.ts. ### Task 1: Remove HeaderBackButton from FinanceLayout.vue (FAILURE 2) **File:** [`frontend_app/src/layouts/FinanceLayout.vue`](frontend_app/src/layouts/FinanceLayout.vue) 1. **DELETE lines 37-46** — the entire `HeaderBackButton` block and its comment: ```html ``` 2. **DELETE the `backTarget` computed** (lines 90-100): ```ts const backTarget = computed(() => { if (route.path === '/finance') { return '/dashboard' } return '/finance' }) ``` 3. **Clean up imports:** Remove `import { computed } from 'vue'` (line 78) and `import { useRoute } from 'vue-router'` (line 79) if they're no longer used. Also remove `const route = useRoute()` (line 87). Remove `import HeaderBackButton from '../components/header/HeaderBackButton.vue'` (line 84). ### Task 2: Fix Header Alignment in FinanceMainView.vue (FAILURE 3) **File:** [`frontend_app/src/views/FinanceMainView.vue`](frontend_app/src/views/FinanceMainView.vue) 1. **DELETE lines 39-55** (the standalone header div) 2. **INSERT the header INSIDE the content container**: Move it to be the first child of line 59's `
`: ```html

💰 {{ t('menu.finance') }}

...
``` ### Task 3: Fix Header Alignment in FinanceWalletsView.vue (FAILURE 3) **File:** [`frontend_app/src/views/FinanceWalletsView.vue`](frontend_app/src/views/FinanceWalletsView.vue) Same pattern as Task 2: Move the header inside the `mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 w-full` container. The current structure: ```
...header...
...content...
``` Should become: ```
...header...
...content...
``` ### Task 4: Fix Header Alignment in FinancePackagesView.vue (FAILURE 3) **File:** [`frontend_app/src/views/FinancePackagesView.vue`](frontend_app/src/views/FinancePackagesView.vue) Same pattern as Task 3 — move header inside the container. ### Task 5: Fix Header Alignment in FinanceTransactionsView.vue (FAILURE 3) **File:** [`frontend_app/src/views/FinanceTransactionsView.vue`](frontend_app/src/views/FinanceTransactionsView.vue) Same pattern as Task 3 — move header inside the container. ### Task 6: Fix Backend Enum Error — Seed Script (FAILURE 4A) **File:** [`backend/scripts/seed_financial_ledger.py`](backend/scripts/seed_financial_ledger.py) 1. **Line 18:** Change: ```python DB_ENTRY_TYPES = ["credit", "debit"] ``` To: ```python DB_ENTRY_TYPES = ["CREDIT", "DEBIT"] ``` ### Task 7: Fix Backend Enum Error — Existing Database Data (FAILURE 4B) **Run these SQL commands** to normalize any existing lowercase entries: ```bash docker compose exec shared-postgres psql -U service_finder_app -d service_finder -c " UPDATE audit.financial_ledger SET entry_type = 'CREDIT' WHERE entry_type::text = 'credit'; UPDATE audit.financial_ledger SET entry_type = 'DEBIT' WHERE entry_type::text = 'debit'; -- Also check wallet_type SELECT DISTINCT entry_type::text, wallet_type::text, status::text FROM audit.financial_ledger; " ``` ### Task 8: Verify 1. **Frontend build:** ```bash docker compose exec sf_public_frontend npm run build 2>&1 | tail -5 ``` 2. **Backend wallet endpoint:** ```bash docker compose exec sf_api python3 -c " import requests r = requests.post('http://localhost:8000/api/v1/auth/login', data={'username': 'admin@profibot.hu', 'password': 'Admin123!'}) token = r.json()['access_token'] resp = requests.get('http://localhost:8000/api/v1/billing/wallet/balance', headers={'Authorization': f'Bearer {token}'}) print(f'Status: {resp.status_code}') print(resp.json()) " ``` --- ## 📋 Summary Table | # | Failure | Root Cause | File(s) to Fix | |---|---------|-----------|-----------------| | 1 | Mock data on dashboard | `GamificationCard` score is placeholder 0; `transactionCount` is placeholder 0 — by design from previous blueprint, pending gamification/transaction stores | None needed now (wiring to stores is future work) | | 2 | Back button still in top menu | [`FinanceLayout.vue`](frontend_app/src/layouts/FinanceLayout.vue:42-45) still has `` in `#left` slot | [`FinanceLayout.vue`](frontend_app/src/layouts/FinanceLayout.vue) | | 3 | Title misaligned to edge | Header is outside `mx-auto max-w-7xl px-4...` container | All 4 finance views | | 4 | Backend enum crash: `'credit' is not among defined enum values` | [`seed_financial_ledger.py:18`](backend/scripts/seed_financial_ledger.py:18) uses lowercase `"credit"/"debit"` but enum only accepts `"CREDIT"/"DEBIT"` | [`seed_financial_ledger.py`](backend/scripts/seed_financial_ledger.py) + DB cleanup SQL | ## ⚠️ DO NOT MODIFY - [`FleetView.vue`](frontend_app/src/views/vehicles/FleetView.vue) — reference only - [`PrivateLayout.vue`](frontend_app/src/layouts/PrivateLayout.vue) — working - [`BaseHeader.vue`](frontend_app/src/components/layout/BaseHeader.vue) — working - [`HeaderBackButton.vue`](frontend_app/src/components/header/HeaderBackButton.vue) — working component, just needs to not be used in FinanceLayout - [`router/index.ts`](frontend_app/src/router/index.ts) — correct - [`DashboardView.vue`](frontend_app/src/views/DashboardView.vue) — working