Refactor: Auth & Identity System v1.4

- Fix: Resolved SQLAlchemy Mapper error for 'UserVehicle' using string-based relationships.
- Fix: Fixed Postgres Enum case sensitivity issue for 'userrole' (forcing lowercase 'user').
- Fix: Resolved ImportError for 'create_access_token' in security module.
- Feature: Implemented 2-step registration protocol (Lite Register -> KYC Step).
- Data: Added bank-level KYC fields (mother's name, ID/Driver/Boat/Pilot license expiry and categories).
- Business: Applied private fleet isolation (is_transferable=False for individual orgs).
- Docs: Updated Grand Master Book to v1.4 and added Developer Pitfalls guide.
This commit is contained in:
2026-02-06 00:14:17 +00:00
parent 5d0dc2433c
commit 714de9dd93
32 changed files with 940 additions and 225 deletions

View File

@@ -1,25 +1,21 @@
from app.db.base import Base
from .identity import User, Person, Wallet, UserRole # ÚJ központ
from .company import Company, CompanyMember, VehicleAssignment
from .identity import User, Person, Wallet, UserRole
from .organization import Organization, OrgType
from .vehicle import (
Vehicle,
VehicleOwnership,
VehicleBrand,
EngineSpec,
ServiceProvider,
ServiceRecord,
VehicleCategory,
VehicleModel,
VehicleVariant
OrganizationMember
)
# Aliasok a kompatibilitás kedvéért
UserVehicle = Vehicle
# Aliasok a kód többi részének
UserVehicle = Vehicle
__all__ = [
"Base", "User", "Person", "Wallet", "UserRole", "Vehicle", "VehicleOwnership",
"VehicleBrand", "EngineSpec", "ServiceProvider", "ServiceRecord", "Company",
"CompanyMember", "VehicleAssignment", "UserVehicle", "VehicleCategory",
"VehicleModel", "VehicleVariant", "Organization", "OrgType"
"Base", "User", "Person", "Wallet", "UserRole",
"Vehicle", "UserVehicle", "VehicleBrand", "EngineSpec",
"ServiceProvider", "ServiceRecord", "Organization",
"OrgType", "OrganizationMember"
]

BIN
backend/app/models/__pycache__/vehicle.cpython-312.pyc Executable file → Normal file

Binary file not shown.

View File

@@ -11,6 +11,7 @@ class UserRole(str, enum.Enum):
USER = "user"
SERVICE = "service"
FLEET_MANAGER = "fleet_manager"
DRIVER = "driver"
class Person(Base):
__tablename__ = "persons"
@@ -25,6 +26,7 @@ class Person(Base):
birth_place = Column(String, nullable=True)
birth_date = Column(DateTime, nullable=True)
# KYC Okmányok és Safety adatok
identity_docs = Column(JSON, server_default=text("'{}'::jsonb"))
medical_emergency = Column(JSON, server_default=text("'{}'::jsonb"))
ice_contact = Column(JSON, server_default=text("'{}'::jsonb"))
@@ -37,26 +39,26 @@ class User(Base):
id = Column(Integer, primary_key=True, index=True)
email = Column(String, unique=True, index=True, nullable=False)
hashed_password = Column(String, nullable=False)
hashed_password = Column(String, nullable=True) # Social Auth esetén null lehet!
# Social Auth mezők
social_provider = Column(String, nullable=True) # google, facebook
social_id = Column(String, nullable=True)
role = Column(Enum(UserRole), default=UserRole.USER)
is_active = Column(Boolean, default=True)
is_superuser = Column(Boolean, default=False)
is_company = Column(Boolean, default=False)
company_name = Column(String, nullable=True)
tax_number = Column(String, nullable=True)
region_code = Column(String, default="HU")
# Soft Delete
is_deleted = Column(Boolean, default=False)
deleted_at = Column(DateTime, nullable=True)
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
person_id = Column(Integer, ForeignKey("data.persons.id"), nullable=True)
person = relationship("Person", back_populates="users")
wallet = relationship("Wallet", back_populates="user", uselist=False)
owned_organizations = relationship("Organization", backref="owner")
owned_organizations = relationship("Organization", back_populates="owner")
created_at = Column(DateTime(timezone=True), server_default=func.now())
class Wallet(Base):
__tablename__ = "wallets"

View File

@@ -1,4 +1,3 @@
# /opt/docker/dev/service_finder/backend/app/models/organization.py
import enum
from sqlalchemy import Column, Integer, String, Boolean, Enum, DateTime, ForeignKey
from sqlalchemy.orm import relationship
@@ -19,22 +18,22 @@ class Organization(Base):
name = Column(String, nullable=False)
org_type = Column(Enum(OrgType), default=OrgType.INDIVIDUAL)
# A flotta technikai tulajdonosa (User)
owner_id = Column(Integer, ForeignKey("data.users.id"), nullable=True)
# MASTER BOOK v1.2 kiegészítések
# Üzleti szabályok
is_active = Column(Boolean, default=True)
# Csak cégek (nem INDIVIDUAL) esetén adható el a flotta
# Privát flotta (INDIVIDUAL) esetén False, cégeknél True
is_transferable = Column(Boolean, default=True)
# Hitelesítési adatok
# Verifikáció
is_verified = Column(Boolean, default=False)
# Türelmi idő vagy hitelesítés lejárata
verification_expires_at = Column(DateTime(timezone=True), nullable=True)
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# Kapcsolatok
vehicles = relationship("UserVehicle", back_populates="current_org")
members = relationship("OrganizationMember", back_populates="organization")
vehicles = relationship("Vehicle", back_populates="current_org")
members = relationship("OrganizationMember", back_populates="organization")
owner = relationship("User", back_populates="owned_organizations")

View File

@@ -44,7 +44,7 @@ class Vehicle(Base):
__tablename__ = "vehicles"
__table_args__ = {"schema": "data"}
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
current_company_id = Column(Integer, ForeignKey("data.companies.id"))
current_company_id = Column(Integer, ForeignKey("data.organizations.id"))
brand_id = Column(Integer, ForeignKey("data.vehicle_brands.id"))
model_name = Column(String(100))
engine_spec_id = Column(Integer, ForeignKey("data.engine_specs.id"))
@@ -54,14 +54,10 @@ class Vehicle(Base):
current_rating_pct = Column(Integer, default=100)
total_real_usage = Column(Numeric(15, 2), default=0)
created_at = Column(DateTime(timezone=True), server_default=func.now())
engine_spec = relationship("EngineSpec", back_populates="vehicles")
service_records = relationship("ServiceRecord", back_populates="vehicle", cascade="all, delete-orphan")
# --- KOMPATIBILITÁSI RÉTEG A RÉGI KÓDOKHOZ ---
VehicleOwnership = Vehicle
VehicleModel = Vehicle
VehicleVariant = Vehicle
VehicleCategory = VehicleBrand # JAVÍTVA: Nagy "B" betűvel
current_org = relationship("Organization", back_populates="vehicles")
class ServiceRecord(Base):
__tablename__ = "service_records"
@@ -74,4 +70,18 @@ class ServiceRecord(Base):
repair_quality_pct = Column(Integer, default=100)
vehicle = relationship("Vehicle", back_populates="service_records")
provider = relationship("ServiceProvider", back_populates="records") # JAVÍTVA
provider = relationship("ServiceProvider", back_populates="records")
class OrganizationMember(Base):
__tablename__ = "organization_members"
__table_args__ = {"schema": "data"}
id = Column(Integer, primary_key=True, index=True)
organization_id = Column(Integer, ForeignKey("data.organizations.id"), nullable=False)
user_id = Column(Integer, ForeignKey("data.users.id"), nullable=False)
role = Column(String, default="driver")
organization = relationship("Organization", back_populates="members")
# --- KOMPATIBILITÁSI RÉTEG ---
UserVehicle = Vehicle
VehicleOwnership = Vehicle