# 📩 Subscription Card Upgrade — RĂ©szletes ElemzĂ©s **Date:** 2026-07-27 **Author:** System Architect **Gitea Card:** #423 **Blueprint:** [`plans/logic_spec_subscription_card_upgrade.md`](../plans/logic_spec_subscription_card_upgrade.md) --- ## 1. Jelenlegi Állapot (As-Is) ### 1.1 A Card 2 a FinanceMainView-ban A [`FinanceMainView.vue`](../frontend_app/src/views/FinanceMainView.vue) nĂ©gy kĂĄrtyĂĄt jelenĂ­t meg a `/finance` oldalon. A mĂĄsodik kĂĄrtya ("📩 Csomagok") jelenleg Ă­gy nĂ©z ki: - **AdatforrĂĄs:** [`authStore.user?.subscription_plan`](../frontend_app/src/stores/auth.ts:62) — egy nyers string, pl. `"private_pro_v1"` - **MegjelenĂ­tĂ©s:** A nyers slug jelenik meg a kĂĄrtyĂĄn, minden formĂĄzĂĄs nĂ©lkĂŒl - **CTA:** Nincs dinamikus gomb, csak a teljes kĂĄrtya kattinthatĂł (ĂĄtnavigĂĄl `/finance/packages`-re) ```typescript // Jelenlegi adat forrĂĄsa (FinanceMainView.vue:249-252) const subscriptionPlanName = computed(() => { return authStore.user?.subscription_plan || '—' }) ``` ### 1.2 A Backend API (/auth/me) A [`read_users_me()`](../backend/app/api/v1/endpoints/users.py:147) vĂ©gpont **mĂĄr feloldja** a `SubscriptionTier` rekordot a `max_vehicles` Ă©s `max_garages` limit meghatĂĄrozĂĄsĂĄhoz (lines 206-253), de: - ❌ **Nem** adja vissza a `SubscriptionTier.rules["display_name"]` JSONB mezƑt - ❌ **Nem** adja vissza a `UserSubscription.valid_until` / `OrganizationSubscription.valid_until` lejĂĄrati dĂĄtumot - ❌ **Nem** adja vissza a `subscription_tier_id`-t ### 1.3 Mi MƱködik MĂĄr Most? A [`SubscriptionStatusWidget.vue`](../frontend_app/src/components/dashboard/SubscriptionStatusWidget.vue) Ă©s a [`SubscriptionInfoModal.vue`](../frontend_app/src/components/subscription/SubscriptionInfoModal.vue) mĂĄr rendelkezik a gazdagabb funkcionalitĂĄssal (jĂĄrmƱhasznĂĄlati progress bar, lejĂĄrati dĂĄtum), de ezek sötĂ©t tĂ©mĂĄjĂș komponensek, Ă©s a FinanceMainView vilĂĄgos tĂ©mĂĄjĂș Card 2-jĂ©ben nem hasznĂĄlhatĂłk közvetlenĂŒl. --- ## 2. AdatbĂĄzis Oldal (What Exists) ### 2.1 `system.subscription_tiers` A [`SubscriptionTier`](../backend/app/models/core_logic.py:68) modell JSONB `rules` mezƑje tartalmazza: ```json { "display_name": "PrivĂĄt Pro", "allowances": { "max_vehicles": 3, "max_garages": 1 }, "pricing": { "monthly_price": 9.99, "yearly_price": 99.99, "currency": "EUR" }, "duration": { "days": 30 }, "type": "private", "lifecycle": { "is_public": true }, "marketing": { "badge": "Pro", "subtitle": "..." } } ``` A `display_name` mezƑ lĂ©tezik a JSONB-ben, de jelenleg nem jut el a frontendig a `/auth/me`-n keresztĂŒl. ### 2.2 `finance.user_subscriptions` Ă©s `finance.org_subscriptions` MindkĂ©t tĂĄbla tartalmazza: - `tier_id` → FK a `system.subscription_tiers`-re - `valid_from` → ÉrvĂ©nyessĂ©g kezdete - `valid_until` → LejĂĄrat dĂĄtuma (None = nincs lejĂĄrat) - `is_active` → AktĂ­v-e a subscription A `SubscriptionService.get_user_subscription_details()` Ă©s `get_org_subscription_details()` metĂłdusok mĂĄr visszaadjĂĄk ezeket az adatokat, de ezek a `GET /subscriptions/my` vĂ©gpontokon keresztĂŒl Ă©rhetƑk el, nem a `/auth/me`-n. --- ## 3. A Terv (To-Be) ### 3.1 Adatfolyam ``` /auth/me ├─ subscription_plan: "private_pro_v1" (mĂĄr most is) ├─ subscription_display_name: "PrivĂĄt Pro" (ÚJ) ├─ subscription_expires_at: "2026-12-31T..." (ÚJ) ├─ subscription_tier_id: 14 (ÚJ) ├─ max_vehicles: 3 (mĂĄr most is) └─ max_garages: 1 (mĂĄr most is) │ â–Œ authStore.user │ â–Œ FinanceMainView Card 2 ┌─────────────────────────────────┐ │ 📩 ElƑfizetĂ©si Csomagok [AktĂ­v] │ │ │ │ ┌─────────────────────────┐ │ │ │ AktĂ­v │ │ │ │ PrivĂĄt Pro │ │ │ └─────────────────────────┘ │ │ │ │ LejĂĄrat: 2026.12.31 │ │ │ │ 🚗 jĂĄrmƱ: ████████░░ 3 / 5 │ │ │ │ [ Csomag KezelĂ©se ] │ └─────────────────────────────────┘ ``` ### 3.2 Backend VĂĄltozĂĄsok (1 fĂĄjl) **FĂĄjl:** [`users.py`](../backend/app/api/v1/endpoints/users.py) — `read_users_me()` fĂŒggvĂ©ny A mĂĄr meglĂ©vƑ `SubscriptionTier` feloldĂĄsi logika UTÁN (lines 206-253) hozzĂĄadunk egy Ășj blokkot, amely: 1. LekĂ©rdezi a `OrganizationSubscription` vagy `UserSubscription` rekordot (attĂłl fĂŒggƑen, hogy Corporate vagy Personal mĂłdban van a user) 2. Kiolvassa a `valid_until` Ă©rtĂ©ket 3. Kiolvassa a mĂĄr korĂĄbban feloldott `tier.rules["display_name"]` Ă©rtĂ©ket 4. HozzĂĄadja ezeket a `response_data` dict-hez ### 3.3 Frontend VĂĄltozĂĄsok (4 fĂĄjl) | FĂĄjl | VĂĄltozĂĄs | |------|----------| | [`auth.ts`](../frontend_app/src/stores/auth.ts) | `UserProfile` interface bƑvĂ­tĂ©se `subscription_display_name` Ă©s `subscription_tier_id` mezƑkkel | | [`FinanceMainView.vue`](../frontend_app/src/views/FinanceMainView.vue) | Card 2 template Ă©s computed property-k teljes cserĂ©je | | [`hu.ts`](../frontend_app/src/i18n/hu.ts) | `renewNow`, `upgradePlan` i18n kulcsok | | [`en.ts`](../frontend_app/src/i18n/en.ts) | `renewNow`, `upgradePlan` i18n kulcsok | --- ## 4. KockĂĄzatok Ă©s Fallback-ek | KockĂĄzat | KezelĂ©s | |----------|---------| | A `display_name` null lehet rĂ©gi tier rekordoknĂĄl | Fallback lĂĄnc: display_name → slug→human map → "Ingyenes" / "—" | | A `valid_until` None lehet (Ă©lettartam elƑfizetĂ©s) | A lejĂĄrati blokk csak `v-if="formattedExpiry"` esetĂ©n jelenik meg | | A `vehicleStore.vehicles` nincs betöltve | `onMounted`-ban fetch-eljĂŒk, ha szĂŒksĂ©ges | | Corporate vs. Personal mĂłd routing | A `ctaRoute` computed kezeli mindkĂ©t esetet | --- ## 5. KapcsolĂłdĂł FĂĄjlok TĂ©rkĂ©pe ``` backend/ app/ models/ core_logic.py ← SubscriptionTier, UserSubscription, OrganizationSubscription api/v1/endpoints/ users.py ← /auth/me — IDE KELL az Ășj mezƑket hozzĂĄadni services/ subscription_service.py ← SubscriptionService (mĂĄr van get_user_subscription_details) frontend_app/src/ views/ FinanceMainView.vue ← Card 2 — EZT ÍRJUK ÁT FinancePackagesView.vue ← /finance/packages (SubscriptionStatusWidget-et hasznĂĄl) components/ dashboard/ SubscriptionStatusWidget.vue ← SötĂ©t tĂ©mĂĄjĂș, gazdag widget (referencia) subscription/ SubscriptionInfoModal.vue ← Modal rĂ©szletes infĂłval (referencia) stores/ auth.ts ← UserProfile interface bƑvĂ­tĂ©se vehicle.ts ← vehicleStore (mĂĄr importĂĄlva mĂĄs komponensekben) i18n/ hu.ts ← Magyar fordĂ­tĂĄsok en.ts ← Angol fordĂ­tĂĄsok ``` --- ## 6. EllenƑrzƑ Lista a Code Mode szĂĄmĂĄra - [ ] `users.py`: `subscription_display_name`, `subscription_expires_at`, `subscription_tier_id` feloldĂĄsa - [ ] `auth.ts`: `UserProfile` interface bƑvĂ­tĂ©se - [ ] `FinanceMainView.vue`: Card 2 template csere (display_name, expiry, vehicle bar, CTA) - [ ] `FinanceMainView.vue`: Computed property-k hozzĂĄadĂĄsa - [ ] `FinanceMainView.vue`: `useVehicleStore` import Ă©s inicializĂĄlĂĄs - [ ] `hu.ts`: `renewNow`, `upgradePlan` kulcsok - [ ] `en.ts`: `renewNow`, `upgradePlan` kulcsok - [ ] `sync_engine.py` futtatĂĄsa (nincs sĂ©ma vĂĄltozĂĄs, de ellenƑrzĂ©s) - [ ] VizuĂĄlis teszt: Card 2 helyes megjelenĂ©s ellenƑrzĂ©se - [ ] FunkcionĂĄlis teszt: CTA gomb navigĂĄciĂł ellenƑrzĂ©se