RABC fejlesztése és beélesítése hibák kijavításával
This commit is contained in:
@@ -22,16 +22,17 @@ if TYPE_CHECKING:
|
||||
from ..marketplace.service_request import ServiceRequest
|
||||
|
||||
class UserRole(str, enum.Enum):
|
||||
superadmin = "superadmin"
|
||||
admin = "admin"
|
||||
region_admin = "region_admin"
|
||||
country_admin = "country_admin"
|
||||
moderator = "moderator"
|
||||
sales_agent = "sales_agent"
|
||||
user = "user"
|
||||
service_owner = "service_owner"
|
||||
fleet_manager = "fleet_manager"
|
||||
driver = "driver"
|
||||
"""Rendszerszintű (System-level) szerepkörök.
|
||||
|
||||
Csak a globális platform szerepkörök maradnak itt.
|
||||
Szervezeti szerepkörök: lásd OrgUserRole a marketplace/organization.py-ban.
|
||||
"""
|
||||
SUPERADMIN = "SUPERADMIN"
|
||||
ADMIN = "ADMIN"
|
||||
MODERATOR = "MODERATOR"
|
||||
SALES_REP = "SALES_REP"
|
||||
SERVICE_MGR = "SERVICE_MGR"
|
||||
USER = "USER"
|
||||
|
||||
class Person(Base):
|
||||
"""
|
||||
@@ -133,7 +134,7 @@ class User(Base):
|
||||
|
||||
role: Mapped[UserRole] = mapped_column(
|
||||
PG_ENUM(UserRole, name="userrole", schema="identity"),
|
||||
default=UserRole.user
|
||||
default=UserRole.USER
|
||||
)
|
||||
|
||||
person_id: Mapped[Optional[int]] = mapped_column(BigInteger, ForeignKey("identity.persons.id"))
|
||||
|
||||
@@ -25,17 +25,25 @@ class OrgType(str, enum.Enum):
|
||||
business = "business"
|
||||
|
||||
class OrgUserRole(str, enum.Enum):
|
||||
"""Szervezeti (Organization-level) szerepkörök.
|
||||
|
||||
Ezek a szerepkörök a szervezeten/flottán belüli jogosultságokat határozzák meg.
|
||||
Minden szerepkörhöz egyedi JSON permissions objektum tartozik a fleet.org_roles táblában.
|
||||
"""
|
||||
OWNER = "OWNER"
|
||||
ADMIN = "ADMIN"
|
||||
MANAGER = "MANAGER"
|
||||
MEMBER = "MEMBER"
|
||||
AGENT = "AGENT"
|
||||
ACCOUNTANT = "ACCOUNTANT"
|
||||
DRIVER = "DRIVER"
|
||||
VIEWER = "VIEWER"
|
||||
|
||||
class OrgRole(Base):
|
||||
"""
|
||||
Dinamikus szerepkör modell (RBAC).
|
||||
Dinamikus szerepkör modell (RBAC Phase 2).
|
||||
A szervezeti szerepkörök adatbázis-vezéreltek, nem hardkódolt Enum-ok.
|
||||
Alapértelmezett szerepkörök: OWNER, ADMIN, MANAGER, MEMBER, AGENT.
|
||||
Alapértelmezett szerepkörök: OWNER, ADMIN, ACCOUNTANT, DRIVER, VIEWER.
|
||||
|
||||
permissions: JSONB oszlop a capability-alapú jogosultságok tárolására.
|
||||
Példa: {"can_add_expense": True, "can_approve_expense": False}
|
||||
"""
|
||||
__tablename__ = "org_roles"
|
||||
__table_args__ = {"schema": "fleet"}
|
||||
@@ -48,6 +56,16 @@ class OrgRole(Base):
|
||||
priority: Mapped[int] = mapped_column(Integer, default=0)
|
||||
is_active: Mapped[bool] = mapped_column(Boolean, default=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
|
||||
# ── RBAC Phase 2: JSONB permissions column ──
|
||||
# Stores capability flags for this role, e.g.:
|
||||
# {"can_add_expense": True, "can_approve_expense": True, "can_view_financials": True}
|
||||
permissions: Mapped[dict] = mapped_column(
|
||||
JSONB,
|
||||
nullable=False,
|
||||
default=dict,
|
||||
server_default=text("'{}'::jsonb")
|
||||
)
|
||||
|
||||
class Organization(Base):
|
||||
"""
|
||||
@@ -119,9 +137,18 @@ class Organization(Base):
|
||||
is_deleted: Mapped[bool] = mapped_column(Boolean, default=False)
|
||||
is_active: Mapped[bool] = mapped_column(Boolean, default=True)
|
||||
|
||||
# ── 📦 ELŐFIZETÉS / SUBSCRIPTION ──
|
||||
subscription_plan: Mapped[str] = mapped_column(String(30), server_default=text("'FREE'"), index=True)
|
||||
base_asset_limit: Mapped[int] = mapped_column(Integer, server_default=text("1"))
|
||||
purchased_extra_slots: Mapped[int] = mapped_column(Integer, server_default=text("0"))
|
||||
|
||||
# P0 FEATURE: Subscription Tier FK — connects this org to a system.subscription_tiers record
|
||||
subscription_tier_id: Mapped[Optional[int]] = mapped_column(
|
||||
Integer,
|
||||
ForeignKey("system.subscription_tiers.id"),
|
||||
nullable=True,
|
||||
index=True
|
||||
)
|
||||
|
||||
notification_settings: Mapped[Any] = mapped_column(JSON, server_default=text("'{\"notify_owner\": true, \"alert_days_before\": [30, 15, 7, 1]}'::jsonb"))
|
||||
external_integration_config: Mapped[Any] = mapped_column(JSON, server_default=text("'{}'::jsonb"))
|
||||
@@ -215,9 +242,12 @@ class OrganizationMember(Base):
|
||||
# Meghívó lejárati ideje
|
||||
expires_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True))
|
||||
|
||||
# Dinamikus szerepkör (String, nem Enum) - az OrgRole táblából validáljuk
|
||||
# Dinamikus szerepkör - PostgreSQL ENUM típus (fleet.orguserrole)
|
||||
# A PG_ENUM használata biztosítja, hogy az SQLAlchemy megfelelő típuskényszerítést
|
||||
# (type cast) alkalmazzon a lekérdezéseknél, elkerülve az
|
||||
# "operator does not exist: fleet.orguserrole = character varying" hibát.
|
||||
role: Mapped[str] = mapped_column(
|
||||
String(50),
|
||||
PG_ENUM(OrgUserRole, name="orguserrole", schema="fleet", create_type=False),
|
||||
default="MEMBER",
|
||||
server_default=text("'MEMBER'")
|
||||
)
|
||||
|
||||
@@ -247,6 +247,13 @@ class AssetFinancials(Base):
|
||||
asset: Mapped["Asset"] = relationship("Asset", back_populates="financials")
|
||||
|
||||
|
||||
class AssetCostStatusEnum(str, enum.Enum):
|
||||
"""Költség státuszok a jóváhagyási munkafolyamathoz."""
|
||||
DRAFT = "DRAFT"
|
||||
PENDING_APPROVAL = "PENDING_APPROVAL"
|
||||
APPROVED = "APPROVED"
|
||||
|
||||
|
||||
class AssetCost(Base):
|
||||
""" II. Üzemeltetés és TCO kimutatás. """
|
||||
__tablename__ = "asset_costs"
|
||||
@@ -257,15 +264,35 @@ class AssetCost(Base):
|
||||
|
||||
category_id: Mapped[int] = mapped_column(Integer, ForeignKey("vehicle.cost_categories.id"), index=True, nullable=False)
|
||||
amount_net: Mapped[float] = mapped_column(Numeric(18, 2), nullable=False)
|
||||
amount_gross: Mapped[Optional[float]] = mapped_column(Numeric(18, 2), nullable=True)
|
||||
vat_rate: Mapped[Optional[float]] = mapped_column(Numeric(5, 2), nullable=True)
|
||||
currency: Mapped[str] = mapped_column(String(3), default="HUF")
|
||||
date: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
invoice_number: Mapped[Optional[str]] = mapped_column(String(100), index=True)
|
||||
document_id: Mapped[Optional[uuid.UUID]] = mapped_column(PG_UUID(as_uuid=True), ForeignKey("system.documents.id"), nullable=True)
|
||||
|
||||
# Státusz a jóváhagyási munkafolyamathoz
|
||||
status: Mapped[str] = mapped_column(String(30), default="DRAFT", server_default=text("'DRAFT'"), index=True)
|
||||
|
||||
# Kétirányú hivatkozás az AssetEvent felé (kettős könyvelés elkerülése)
|
||||
linked_asset_event_id: Mapped[Optional[uuid.UUID]] = mapped_column(
|
||||
PG_UUID(as_uuid=True),
|
||||
ForeignKey("vehicle.asset_events.id"),
|
||||
nullable=True,
|
||||
index=True
|
||||
)
|
||||
|
||||
data: Mapped[dict] = mapped_column(JSONB, server_default=text("'{}'::jsonb"))
|
||||
asset: Mapped["Asset"] = relationship("Asset", back_populates="costs")
|
||||
organization: Mapped["Organization"] = relationship("Organization")
|
||||
category: Mapped["CostCategory"] = relationship("CostCategory")
|
||||
|
||||
# Kapcsolat a hivatkozott eseményhez
|
||||
linked_event: Mapped[Optional["AssetEvent"]] = relationship(
|
||||
"AssetEvent",
|
||||
foreign_keys=[linked_asset_event_id],
|
||||
post_update=True
|
||||
)
|
||||
|
||||
|
||||
class VehicleLogbook(Base):
|
||||
@@ -396,6 +423,13 @@ class AssetEventTypeEnum(str, enum.Enum):
|
||||
RECALL = "RECALL" # Visszahívás
|
||||
|
||||
|
||||
class AssetEventStatusEnum(str, enum.Enum):
|
||||
"""Esemény státuszok a feldolgozási munkafolyamathoz."""
|
||||
DRAFT = "DRAFT"
|
||||
MISSING_TECH_DATA = "MISSING_TECH_DATA"
|
||||
COMPLETED = "COMPLETED"
|
||||
|
||||
|
||||
class AssetEvent(Base):
|
||||
""" Digitális Szervizkönyv - Szerviz, baleset és egyéb jelentős események. """
|
||||
__tablename__ = "asset_events"
|
||||
@@ -411,6 +445,17 @@ class AssetEvent(Base):
|
||||
description: Mapped[Optional[str]] = mapped_column(Text)
|
||||
cost_id: Mapped[Optional[uuid.UUID]] = mapped_column(PG_UUID(as_uuid=True), ForeignKey("vehicle.asset_costs.id"), nullable=True)
|
||||
|
||||
# Státusz a feldolgozási munkafolyamathoz
|
||||
status: Mapped[str] = mapped_column(String(30), default="DRAFT", server_default=text("'DRAFT'"), index=True)
|
||||
|
||||
# Kétirányú hivatkozás az AssetCost felé (kettős könyvelés elkerülése)
|
||||
linked_expense_id: Mapped[Optional[uuid.UUID]] = mapped_column(
|
||||
PG_UUID(as_uuid=True),
|
||||
ForeignKey("vehicle.asset_costs.id"),
|
||||
nullable=True,
|
||||
index=True
|
||||
)
|
||||
|
||||
event_date: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
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())
|
||||
@@ -419,7 +464,15 @@ class AssetEvent(Base):
|
||||
asset: Mapped["Asset"] = relationship("Asset", back_populates="events")
|
||||
user: Mapped[Optional["User"]] = relationship("User")
|
||||
organization: Mapped[Optional["Organization"]] = relationship("Organization")
|
||||
cost: Mapped[Optional["AssetCost"]] = relationship("AssetCost")
|
||||
cost: Mapped[Optional["AssetCost"]] = relationship("AssetCost", foreign_keys=[cost_id])
|
||||
|
||||
# Kapcsolat a hivatkozott költséghez
|
||||
linked_expense: Mapped[Optional["AssetCost"]] = relationship(
|
||||
"AssetCost",
|
||||
foreign_keys=[linked_expense_id],
|
||||
post_update=True,
|
||||
primaryjoin="AssetEvent.linked_expense_id == AssetCost.id"
|
||||
)
|
||||
|
||||
|
||||
class ExchangeRate(Base):
|
||||
|
||||
Reference in New Issue
Block a user