182 lines
7.8 KiB
Markdown
182 lines
7.8 KiB
Markdown
# 📦 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
|