admin felület fejlesztése garázs, előfizeztési csomagok
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# /opt/docker/dev/service_finder/backend/app/models/core_logic.py
|
||||
from typing import Optional, List, Any
|
||||
from datetime import datetime # Python saját típusa a típusjelöléshez
|
||||
from sqlalchemy import String, Integer, ForeignKey, Boolean, DateTime, Numeric, text
|
||||
from sqlalchemy import String, Integer, ForeignKey, Boolean, DateTime, Numeric, text, Float
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
from sqlalchemy.dialects.postgresql import JSONB
|
||||
from sqlalchemy.sql import func
|
||||
@@ -9,9 +9,65 @@ from sqlalchemy.sql import func
|
||||
# MB 2.0: A központi aszinkron adatbázis motorból húzzuk be a Base-t
|
||||
from app.database import Base
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# P0 SYSTEM ARCHITECTURE: Global Region Registry
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
class RegionConfig(Base):
|
||||
"""
|
||||
🌍 Global Region Configuration Registry.
|
||||
|
||||
Central table for L10n/i18n configuration. Drives all UI formatting
|
||||
(dates, numbers, currencies) and financial calculations (VAT, pricing).
|
||||
|
||||
Each row represents a country/region with its own locale, currency,
|
||||
VAT rate, and timezone settings.
|
||||
|
||||
Schema: system.region_config
|
||||
"""
|
||||
__tablename__ = "region_config"
|
||||
__table_args__ = {"schema": "system"}
|
||||
|
||||
country_code: Mapped[str] = mapped_column(
|
||||
String(10), primary_key=True, index=True,
|
||||
comment="ISO 3166-1 alpha-2 country code, e.g. 'HU', 'GB', or 'DEFAULT' for fallback"
|
||||
)
|
||||
name: Mapped[str] = mapped_column(
|
||||
String, nullable=False,
|
||||
comment="Human-readable region name, e.g. 'Hungary', 'United Kingdom'"
|
||||
)
|
||||
currency: Mapped[str] = mapped_column(
|
||||
String(3), nullable=False,
|
||||
comment="ISO 4217 currency code, e.g. 'HUF', 'GBP', 'EUR'"
|
||||
)
|
||||
default_vat_rate: Mapped[float] = mapped_column(
|
||||
Float, nullable=False, default=0.0,
|
||||
comment="Default VAT rate as decimal, e.g. 27.0 for 27%"
|
||||
)
|
||||
locale_code: Mapped[str] = mapped_column(
|
||||
String(10), nullable=False,
|
||||
comment="BCP 47 locale code, e.g. 'hu-HU', 'en-GB', 'de-DE'"
|
||||
)
|
||||
timezone: Mapped[str] = mapped_column(
|
||||
String(50), nullable=False,
|
||||
comment="IANA timezone, e.g. 'Europe/Budapest', 'Europe/London'"
|
||||
)
|
||||
is_active: Mapped[bool] = mapped_column(
|
||||
Boolean, nullable=False, default=True, server_default=text("true"),
|
||||
comment="Soft-toggle for region availability"
|
||||
)
|
||||
created_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), server_default=func.now()
|
||||
)
|
||||
updated_at: Mapped[Optional[datetime]] = mapped_column(
|
||||
DateTime(timezone=True), onupdate=func.now()
|
||||
)
|
||||
|
||||
|
||||
class SubscriptionTier(Base):
|
||||
"""
|
||||
Előfizetési csomagok definíciója (pl. Free, Premium, VIP).
|
||||
"""
|
||||
Előfizetési csomagok definíciója (pl. Free, Premium, VIP).
|
||||
A csomagok határozzák meg a korlátokat (pl. max járműszám).
|
||||
"""
|
||||
__tablename__ = "subscription_tiers"
|
||||
@@ -32,6 +88,42 @@ class SubscriptionTier(Base):
|
||||
server_default=text("'{}'::jsonb")
|
||||
)
|
||||
|
||||
# ── P0 AUDIT FIX: Database-driven tier level instead of hardcoded string mapping ──
|
||||
# Numeric level for the entitlement hierarchy: 0=free, 1=premium, 2=enterprise.
|
||||
# This replaces the hardcoded _map_tier_name() string-matching logic.
|
||||
# New tiers can be added with any name; the tier_level determines their position.
|
||||
tier_level: Mapped[int] = mapped_column(
|
||||
Integer,
|
||||
nullable=False,
|
||||
default=0,
|
||||
server_default=text("0"),
|
||||
comment="Entitlement hierarchy level: 0=free, 1=premium, 2=enterprise"
|
||||
)
|
||||
|
||||
# ── P0 SINGLETON PACKAGE RULES: is_default_fallback ──
|
||||
# Ha True, ez a csomag az alapértelmezett fallback csomag, amit a
|
||||
# subscription_service használ, ha a user előfizetése lejárt.
|
||||
# MAXIMUM EGY csomag lehet True értékkel (singleton).
|
||||
is_default_fallback: Mapped[bool] = mapped_column(
|
||||
Boolean,
|
||||
nullable=False,
|
||||
default=False,
|
||||
server_default=text("false"),
|
||||
comment="Singleton: maximum one tier can be the default fallback package"
|
||||
)
|
||||
|
||||
# ── P0 SINGLETON PACKAGE RULES: trial_days_on_signup ──
|
||||
# Ha > 0, ez a csomag a próbaidős csomag, amit új regisztrációnál
|
||||
# automatikusan hozzárendelünk a felhasználóhoz.
|
||||
# MAXIMUM EGY csomag lehet > 0 értékkel (singleton).
|
||||
trial_days_on_signup: Mapped[int] = mapped_column(
|
||||
Integer,
|
||||
nullable=False,
|
||||
default=0,
|
||||
server_default=text("0"),
|
||||
comment="Singleton: maximum one tier can have trial_days_on_signup > 0"
|
||||
)
|
||||
|
||||
class OrganizationSubscription(Base):
|
||||
"""
|
||||
Szervezetek aktuális előfizetései és azok érvényessége.
|
||||
@@ -56,6 +148,13 @@ class OrganizationSubscription(Base):
|
||||
# Példa: {"extra_vehicles": 1, "extra_garages": 1, "extra_credits": 100}
|
||||
extra_allowances: Mapped[dict] = mapped_column(JSONB, server_default=text("'{}'::jsonb"), default=dict)
|
||||
|
||||
# ── P0 FEATURE FLAG: relationship a SubscriptionTier-hez ──
|
||||
tier: Mapped[Optional["SubscriptionTier"]] = relationship(
|
||||
"SubscriptionTier",
|
||||
foreign_keys=[tier_id],
|
||||
lazy="selectin",
|
||||
)
|
||||
|
||||
class UserSubscription(Base):
|
||||
"""
|
||||
Felhasználók aktuális előfizetései és azok érvényessége.
|
||||
@@ -78,6 +177,13 @@ class UserSubscription(Base):
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
|
||||
# ── P0 FEATURE FLAG: relationship a SubscriptionTier-hez ──
|
||||
tier: Mapped[Optional["SubscriptionTier"]] = relationship(
|
||||
"SubscriptionTier",
|
||||
foreign_keys=[tier_id],
|
||||
lazy="selectin",
|
||||
)
|
||||
|
||||
|
||||
class CreditTransaction(Base):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user