RABAC felépítése megtörtént ill hirdetési portál alapok lerakva

This commit is contained in:
Roo
2026-06-19 06:06:34 +00:00
parent fe3c32597d
commit 9ba2d9180d
30 changed files with 4336 additions and 76 deletions

View File

@@ -951,3 +951,153 @@ A PATCH `/api/v1/organizations/{id}` végpont 200 OK-val tért vissza, és az ad
- `GET /api/v1/organizations/my` → **200 OK**, tartalmazza a cím mezőket ✅
- `PATCH /api/v1/organizations/{id}` → **200 OK**, a válasz tartalmazza a cím mezőket ✅
- A cím adatok elérhetők a frontend `OrganizationSettingsModal` form-jában ✅
## 2026-06-18 - P0: Subscription Stacking & Ad Engine Implementation
### 🎯 Cél
Subscription időhalmozás (stacking) implementálása `duration_days` segítségével a JSONB `rules`-ban, valamint a Native Ad Engine adatbázis séma (`marketing` schema) létrehozása.
### 🔧 Változtatások
**1. Pydantic Schema Bővítés - [`subscription.py`](backend/app/schemas/subscription.py:43):**
- `DurationModel`: `days` (default=30) és `allow_stacking` (default=True) mezők
- `AdPolicyModel`: `show_ads`, `ad_free_grace_days`, `max_daily_impressions` mezők
- `SubscriptionRulesModel`: `duration: Optional[DurationModel]` és `ad_policy: Optional[AdPolicyModel]` opcionális mezők
**2. Stacking Logika - [`billing_engine.py`](backend/app/services/billing_engine.py:722):**
- `upgrade_org_subscription()`: `duration_days` kiolvasása `tier.rules`-ból, `valid_until` számítás stackinggel
- `upgrade_subscription()`: `UserSubscription` kezelés stacking logikával
- Képlet: `IF existing.valid_until > NOW → stacked = existing + duration_days ELSE fresh = NOW + duration_days`
**3. Ad Engine Modellek - [`marketing.py`](backend/app/models/marketing.py:1):**
- 7 tábla a `marketing` sémában: `campaigns`, `creatives`, `placements`, `campaign_creatives`, `campaign_placements`, `ad_impressions`, `ad_clicks`
- String-based enumok (`CampaignStatus`, `CreativeType`, `PlacementType`) `CheckConstraint`-tel a `sync_engine` kompatibilitásért
- Priority + weighted random selection logika a hirdetés kiválasztáshoz
**4. Seed Adatok - [`seed_packages.py`](backend/app/scripts/seed_packages.py:266):**
- Mind a 6 csomag frissítve `duration` (30 nap, `allow_stacking=true`) és `ad_policy` mezőkkel
- Free: `show_ads=true`, `max_daily_impressions=50`
- Pro: `show_ads=true`, `grace_days=3`, `max_impressions=100`
- VIP/Corporate: `show_ads=false`
- UPSERT (`INSERT ... ON CONFLICT DO UPDATE`) használata DELETE helyett FK referenciák megőrzéséért
**5. Modell Regisztráció - [`__init__.py`](backend/app/models/__init__.py:54):**
- Marketing modellek importálva és `__all__`-hoz adva
### ✅ Verifikáció
- `sync_engine`: 1152 elem szinkronban, 7 marketing tábla létrehozva ✅
- `seed_packages`: 6 csomag sikeresen frissítve duration/ad_policy mezőkkel ✅
- Pydantic validáció: `DurationModel`, `AdPolicyModel`, `SubscriptionRulesModel` hibátlan ✅
- Stacking logika szimuláció: Fresh (30 nap), Stacked (40 nap = 10 + 30), Expired reset (30 nap) ✅
- Gitea kártya #271 létrehozva és elindítva ✅
## 2026-06-18 - P0 Debug: GET /api/v1/subscriptions/public 404 Fix
### 🎯 Cél
A frontend SubscriptionPlansView által hívott `GET /api/v1/subscriptions/public` végpont 404-es hibájának kivizsgálása és javítása.
### 🔧 Változtatások
**1. ROOT CAUSE - Stale container cache:**
- A [`subscriptions.py`](backend/app/api/v1/endpoints/subscriptions.py) fájl új volt (untracked `??` git statusban)
- A futó uvicorn konténer a régi modulgráfot cache-elte, nem tudott az új router-ről
- **Fix:** `docker compose restart sf_api` — a konténer újratöltése után a végpont 200 OK-val válaszolt ✅
**2. i18n - Missing `common.retry` key:**
- A [`hu.ts`](frontend/src/i18n/hu.ts:9) `common` szekciójába hozzáadva: `retry: 'Újrapróbálkozás'`
- A [`en.ts`](frontend/src/i18n/en.ts:9) `common` szekciójába hozzáadva: `retry: 'Retry'`
**3. `is_public` filtering:**
- A [`get_public_subscriptions`](backend/app/api/v1/endpoints/subscriptions.py:47) végpont most már szűri a csomagokat a `rules.lifecycle.is_public` JSONB mező alapján
- Csak azok a tier-ek kerülnek visszaadásra, ahol `is_public=True` (alapértelmezett: True)
### ✅ Verifikáció
- `GET /api/v1/subscriptions/public` → **200 OK**, 10 tier visszaadva
- Minden tier `is_public=True` értékkel rendelkezik
- A frontend i18n kulcsok (`common.retry`) mindkét nyelven elérhetők
## 2026-06-18 - P0 Booster Architecture & Minimalist Subscription UI
### 🎯 Cél
P0 architektúra frissítés: Booster kvóta rendszer, marketing adatok a subscription tier-ekhez, minimalista előfizetési kártyák és részletes modal.
### 🔧 Változtatások
**1. `extra_allowances` JSONB oszlop**
- [`OrganizationSubscription`](backend/app/models/core_logic.py:42) modellhez hozzáadva: `extra_allowances: Mapped[dict] = mapped_column(JSONB, server_default=text("'{}'::jsonb"), default=dict)`
- A `sync_engine` sikeresen létrehozta a `finance.org_subscriptions.extra_allowances` oszlopot
**2. Kvóta motor frissítés**
- [`get_user_vehicle_limit()`](backend/app/services/asset_service.py:610) most beolvassa az `extra_allowances.extra_vehicles` értéket és hozzáadja a végső limithez
- [`scan_registration_document`](backend/app/api/v1/endpoints/evidence.py:43) evidence végpont is figyelembe veszi az `extra_allowances`-t a kvóta ellenőrzésnél
**3. Marketing adatok**
- [`MarketingModel`](backend/app/schemas/subscription.py:68) Pydantic séma létrehozva `subtitle`, `badge`, `highlight_color` mezőkkel
- [`SubscriptionRulesModel`](backend/app/schemas/subscription.py:121) `marketing` mezővel bővítve
- Mind a 6 fő csomag [`seed_packages.py`](backend/app/scripts/seed_packages.py) marketing adatokkal frissítve (magyar subtitle, badge, highlight_color)
**4. Minimalista előfizetési kártyák**
- [`SubscriptionPlansView.vue`](frontend/src/views/SubscriptionPlansView.vue) teljes átírása: csak név, badge, subtitle, ár, 3 kulcs statisztika (max_vehicles, max_garages, monthly_free_credits) megjelenítése
- Gomb szöveg: "Részletek & Vásárlás"
- `h-full` + `flex flex-col` az egyenlő kártyamagasságokért
**5. PlanDetailsModal komponens**
- [`PlanDetailsModal.vue`](frontend/src/components/subscription/PlanDetailsModal.vue) létrehozva: Teleport modal, fejléc highlight színnel, havi/éves váltó, megtakarítás % kijelzés, 3 kulcs statisztika, szolgáltatás lista, rendelés szimuláció gomb
- i18n kulcsok hozzáadva (`hu.ts`, `en.ts`)
### ✅ Verifikáció
- `extra_allowances` oszlop létezik: `finance.org_subscriptions.extra_allowances` JSONB, default `'{}'::jsonb`
- 6 subscription tier rendelkezik marketing adatokkal (private_free, private_pro, private_vip, corp_premium, corp_premium_plus, corp_vip)
- Minden Python fájl szintaktikailag helyes
- `seed_packages.py` sikeresen lefutott, az adatok perzisztálva
## 2026-06-18 - P0: Multi-Region Pricing & Admin Marketing UI
### 🎯 Cél
Multi-region pricing (pricing_zones) bevezetése a subscription rendszerbe: a backend dinamikusan feloldja a megfelelő árat a felhasználó országkódja alapján, a frontend pedig megjeleníti a feloldott árat. Admin UI-ban marketing mezők és pricing zones szerkesztő hozzáadása.
### 🔧 Változtatások
**1. BACKEND - Schema [`subscription.py`](backend/app/schemas/subscription.py):**
- `PricingZoneModel` osztály hozzáadva: `monthly_price`, `yearly_price`, `currency`, `credit_price`
- `pricing_zones: Optional[Dict[str, PricingZoneModel]]` mező a `SubscriptionRulesModel`-ben
- `MarketingModel` osztály hozzáadva: `subtitle`, `badge`, `highlight_color`
- `marketing: Optional[MarketingModel]` mező a `SubscriptionRulesModel`-ben
- `PublicSubscriptionTierResponse` séma: `resolved_pricing: Optional[PricingZoneModel]` mezővel
**2. BACKEND - Seed [`seed_packages.py`](backend/app/scripts/seed_packages.py):**
- `pricing_zones()` helper függvény: DEFAULT (EUR), HU (HUF), US (USD) zónákkal
- Mind a 6 fő csomag (`private_free`, `private_pro`, `private_vip`, `corp_premium`, `corp_premium_plus`, `corp_vip`) `pricing_zones` adatokat kapott
**3. BACKEND - Endpoint [`subscriptions.py`](backend/app/api/v1/endpoints/subscriptions.py):**
- `resolve_pricing(rules, country_code)` függvény: országkód → pricing_zones → DEFAULT → legacy pricing → None
- `get_user_country_code(current_user, db)` aszinkron függvény: aktív org country_code → person address country → "DEFAULT"
- `GET /public` végpont frissítve: `List[PublicSubscriptionTierResponse]` visszatérés, `resolved_pricing` kitöltve
**4. FRONTEND - [`SubscriptionPlansView.vue`](frontend/src/views/SubscriptionPlansView.vue):**
- `resolved_pricing` mező a `SubscriptionPlan` interfészben
- `resolvedMonthlyPrice()`, `resolvedYearlyPrice()`, `resolvedCurrency()`, `yearlySavingsPercent()` helperek
- Dinamikus `Intl.NumberFormat` pénznem formázás (HUF=0 tizedes, más=2 tizedes)
- Havi + éves ár kijelzés megtakarítás %-kal
**5. FRONTEND - [`PlanDetailsModal.vue`](frontend/src/components/subscription/PlanDetailsModal.vue):**
- `resolved_pricing` alapján számított `resolvedMonthlyPrice`, `resolvedYearlyPrice`, `resolvedCurrency` computed property-k
- Dinamikus pénznem formázás
**6. FRONTEND - Admin Store [`adminPackages.ts`](frontend/src/stores/adminPackages.ts):**
- `PricingZoneModel` interfész hozzáadva
- `MarketingModel` interfész hozzáadva
- `pricing_zones` és `marketing` mezők a `SubscriptionRulesModel`-ben
**7. FRONTEND - Admin UI [`PackageEditModal.vue`](frontend/src/components/admin/PackageEditModal.vue):**
- Marketing szekció: Alcím (Subtitle), Jelvény (Badge), Kiemelő szín (Hex color picker)
- Pricing Zones szekció: dinamikus lista zónák hozzáadásával/törlésével/szerkesztésével (country code, havi/éves ár, pénznem, kredit ár)
- `buildRules()` frissítve: marketing és pricing_zones beszúrása a rules objektumba
- `watch` handler frissítve: meglévő marketing és pricing_zones adatok betöltése szerkesztéskor
### ✅ Verifikáció
- `sync_engine` sikeresen lefutott, a séma konzisztens
- `seed_packages.py` sikeresen lefutott, mind a 6 fő csomag rendelkezik `pricing_zones` adatokkal (HU, US, DEFAULT)
- API végpont (`GET /api/v1/subscriptions/public`) helyesen adja vissza a `resolved_pricing` mezőt
- Frontend TypeScript ellenőrzés: nincs új hiba a módosított fájlokban
- Admin UI: marketing mezők és pricing zones szerkesztő működik