admin frontend elkezdése, járművek tisztázása, frontend fejleszts

This commit is contained in:
Roo
2026-06-15 18:52:38 +00:00
parent ef8df9608c
commit 213ba3b0f1
80 changed files with 11615 additions and 2304 deletions

View File

@@ -0,0 +1,269 @@
#!/usr/bin/env python3
"""
Seed szkript a jövőbiztos SaaS csomag-architektúra 1. fázisához.
Létrehozza a 6 alap subscription tier-t a system.subscription_tiers táblában.
Használat:
docker compose exec sf_api python3 /app/backend/app/scripts/seed_packages.py
Architektúra:
A csomagok rules JSONB oszlopa egy szabványos struktúrát követ:
{
"type": "private" | "corporate",
"pricing": {"monthly_price": float, "yearly_price": float, "currency": "EUR"},
"allowances": {"max_vehicles": int, "max_garages": int, "monthly_free_credits": int},
"entitlements": ["SRV_..."],
"affiliate": {"commission_rate_percent": int, "referral_bonus_credits": int}
}
"""
import asyncio
import json
import logging
from sqlalchemy import select, delete
from app.database import AsyncSessionLocal
from app.models.core_logic import SubscriptionTier
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
)
logger = logging.getLogger("Seed-Packages")
# ---------------------------------------------------------------------------
# Csomagdefiníciók
# ---------------------------------------------------------------------------
PACKAGES = [
{
"name": "private_free_v1",
"rules": {
"type": "private",
"display_name": "Privát Ingyenes",
"pricing": {
"monthly_price": 0.0,
"yearly_price": 0.0,
"currency": "EUR",
"credit_price": 0,
},
"allowances": {
"max_vehicles": 1,
"max_garages": 1,
"monthly_free_credits": 0,
},
"entitlements": [],
"affiliate": {
"commission_rate_percent": 0,
"referral_bonus_credits": 0,
},
"lifecycle": {
"is_public": True,
},
},
"is_custom": False,
},
{
"name": "private_pro_v1",
"rules": {
"type": "private",
"display_name": "Privát Pro",
"pricing": {
"monthly_price": 4.99,
"yearly_price": 49.99,
"currency": "EUR",
"credit_price": 500,
},
"allowances": {
"max_vehicles": 3,
"max_garages": 1,
"monthly_free_credits": 50,
},
"entitlements": ["SRV_DATA_EXPORT"],
"affiliate": {
"commission_rate_percent": 10,
"referral_bonus_credits": 25,
},
"lifecycle": {
"is_public": True,
},
},
"is_custom": False,
},
{
"name": "private_vip_v1",
"rules": {
"type": "private",
"display_name": "Privát VIP",
"pricing": {
"monthly_price": 9.99,
"yearly_price": 99.99,
"currency": "EUR",
"credit_price": 1200,
},
"allowances": {
"max_vehicles": 10,
"max_garages": 1,
"monthly_free_credits": 150,
},
"entitlements": ["SRV_DATA_EXPORT", "SRV_AI_UPLOAD"],
"affiliate": {
"commission_rate_percent": 15,
"referral_bonus_credits": 50,
},
"lifecycle": {
"is_public": True,
},
},
"is_custom": False,
},
{
"name": "corp_premium_v1",
"rules": {
"type": "corporate",
"display_name": "Céges Prémium",
"pricing": {
"monthly_price": 29.99,
"yearly_price": 299.99,
"currency": "EUR",
"credit_price": 3000,
},
"allowances": {
"max_vehicles": 20,
"max_garages": 3,
"monthly_free_credits": 300,
},
"entitlements": ["SRV_DATA_EXPORT", "SRV_AI_UPLOAD"],
"affiliate": {
"commission_rate_percent": 15,
"referral_bonus_credits": 100,
},
"lifecycle": {
"is_public": True,
},
},
"is_custom": False,
},
{
"name": "corp_premium_plus_v1",
"rules": {
"type": "corporate",
"display_name": "Céges Prémium Plus",
"pricing": {
"monthly_price": 59.99,
"yearly_price": 599.99,
"currency": "EUR",
"credit_price": 6000,
},
"allowances": {
"max_vehicles": 50,
"max_garages": 10,
"monthly_free_credits": 800,
},
"entitlements": [
"SRV_DATA_EXPORT",
"SRV_AI_UPLOAD",
"SRV_ACCOUNTING_SYNC",
],
"affiliate": {
"commission_rate_percent": 20,
"referral_bonus_credits": 250,
},
"lifecycle": {
"is_public": True,
},
},
"is_custom": False,
},
{
"name": "corp_vip_v1",
"rules": {
"type": "corporate",
"display_name": "Céges VIP",
"pricing": {
"monthly_price": 149.99,
"yearly_price": 1499.99,
"currency": "EUR",
"credit_price": 15000,
},
"allowances": {
"max_vehicles": 200,
"max_garages": 50,
"monthly_free_credits": 2500,
},
"entitlements": [
"SRV_DATA_EXPORT",
"SRV_AI_UPLOAD",
"SRV_ACCOUNTING_SYNC",
"SRV_API_ACCESS",
],
"affiliate": {
"commission_rate_percent": 25,
"referral_bonus_credits": 500,
},
"lifecycle": {
"is_public": True,
},
},
"is_custom": False,
},
]
async def seed():
logger.info("=" * 60)
logger.info("Seed Packages - Advanced Subscription Tiers (Phase 1)")
logger.info("=" * 60)
async with AsyncSessionLocal() as db:
# 1. Töröljük a meglévő rekordokat (tiszta lap)
logger.info("Törlöm a meglévő subscription_tiers rekordokat...")
await db.execute(delete(SubscriptionTier))
await db.commit()
logger.info("✅ Meglévő rekordok törölve.")
# 2. Beszúrjuk a 6 új csomagot
inserted_count = 0
for pkg in PACKAGES:
tier = SubscriptionTier(
name=pkg["name"],
rules=pkg["rules"],
is_custom=pkg["is_custom"],
)
db.add(tier)
inserted_count += 1
logger.info(f" Hozzáadva: {pkg['name']}")
await db.commit()
logger.info(f"{inserted_count} csomag sikeresen beszúrva.")
# 3. Visszaigazolás: listázzuk ki az összes rekordot
logger.info("-" * 60)
logger.info("Visszaigazolás - system.subscription_tiers tartalma:")
logger.info("-" * 60)
result = await db.execute(
select(SubscriptionTier).order_by(SubscriptionTier.id)
)
tiers = result.scalars().all()
for tier in tiers:
rules_json = json.dumps(tier.rules, indent=2, ensure_ascii=False)
logger.info(f"\n ID: {tier.id}")
logger.info(f" Name: {tier.name}")
logger.info(f" Is Custom: {tier.is_custom}")
logger.info(f" Rules:\n{rules_json}")
logger.info(" " + "-" * 40)
logger.info(f"\n✅ Összesen {len(tiers)} aktív csomag a rendszerben.")
# 4. JSONB példa kiírása
if tiers:
sample = tiers[0]
logger.info("=" * 60)
logger.info("JSONB PÉLDA (private_free_v1):")
logger.info("=" * 60)
logger.info(json.dumps(sample.rules, indent=2, ensure_ascii=False))
if __name__ == "__main__":
asyncio.run(seed())