Initial commit: Robot ökoszisztéma v2.0 - Stabilizált jármű és szerviz robotok
This commit is contained in:
123
backend/app/schemas/admin.py
Executable file
123
backend/app/schemas/admin.py
Executable file
@@ -0,0 +1,123 @@
|
||||
# /opt/docker/dev/service_finder/backend/app/api/v1/endpoints/admin.py
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select, func, text, delete
|
||||
from typing import List, Any, Dict, Optional
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from app.api import deps
|
||||
from app.models.identity import User, UserRole
|
||||
from app.models.system import SystemParameter
|
||||
from app.models.audit import SecurityAuditLog, OperationalLog
|
||||
from app.models.security import PendingAction, ActionStatus
|
||||
from app.services.security_service import security_service
|
||||
from app.services.translation_service import TranslationService
|
||||
from app.schemas.admin import PointRuleResponse, LevelConfigResponse, ConfigUpdate
|
||||
from app.schemas.admin_security import PendingActionResponse, SecurityStatusResponse
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
# --- 🛡️ ADMIN JOGOSULTSÁG ELLENŐRZŐ ---
|
||||
async def check_admin_access(current_user: User = Depends(deps.get_current_active_user)):
|
||||
""" Csak Admin vagy Superadmin léphet be a Sentinel központba. """
|
||||
if current_user.role not in [UserRole.admin, UserRole.superadmin]:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Sentinel jogosultság szükséges a művelethez!"
|
||||
)
|
||||
return current_user
|
||||
|
||||
# --- 🛰️ 1. SENTINEL: RENDSZERÁLLAPOT ÉS MONITORING ---
|
||||
|
||||
@router.get("/health-monitor", response_model=Dict[str, Any], tags=["Sentinel Monitoring"])
|
||||
async def get_system_health(
|
||||
db: AsyncSession = Depends(deps.get_db),
|
||||
admin: User = Depends(check_admin_access)
|
||||
):
|
||||
""" Részletes rendszerstatisztikák (Felhasználók, Eszközök, Biztonság). """
|
||||
stats = {}
|
||||
|
||||
# Felhasználói eloszlás (Nyers SQL a sebességért)
|
||||
user_res = await db.execute(text("SELECT subscription_plan, count(*) FROM data.users GROUP BY subscription_plan"))
|
||||
stats["user_distribution"] = {row[0]: row[1] for row in user_res}
|
||||
|
||||
# Eszköz és Szervezet számlálók
|
||||
stats["total_assets"] = (await db.execute(text("SELECT count(*) FROM data.assets"))).scalar()
|
||||
stats["total_organizations"] = (await db.execute(text("SELECT count(*) FROM data.organizations"))).scalar()
|
||||
|
||||
# Biztonsági riasztások (Kritikus logok az elmúlt 24 órában)
|
||||
day_ago = datetime.now() - timedelta(days=1)
|
||||
crit_logs = await db.execute(
|
||||
select(func.count(SecurityAuditLog.id))
|
||||
.where(SecurityAuditLog.is_critical == True, SecurityAuditLog.created_at >= day_ago)
|
||||
)
|
||||
stats["critical_alerts_24h"] = crit_logs.scalar() or 0
|
||||
|
||||
return stats
|
||||
|
||||
# --- ⚖️ 2. SENTINEL: NÉGY SZEM ELV (Approval System) ---
|
||||
|
||||
@router.get("/pending-actions", response_model=List[PendingActionResponse], tags=["Sentinel Security"])
|
||||
async def list_pending_actions(
|
||||
db: AsyncSession = Depends(deps.get_db),
|
||||
admin: User = Depends(check_admin_access)
|
||||
):
|
||||
""" Jóváhagyásra váró kritikus műveletek listázása. """
|
||||
stmt = select(PendingAction).where(PendingAction.status == ActionStatus.pending)
|
||||
result = await db.execute(stmt)
|
||||
return result.scalars().all()
|
||||
|
||||
@router.post("/approve/{action_id}", tags=["Sentinel Security"])
|
||||
async def approve_action(
|
||||
action_id: int,
|
||||
db: AsyncSession = Depends(deps.get_db),
|
||||
admin: User = Depends(check_admin_access)
|
||||
):
|
||||
""" Művelet véglegesítése egy második admin által. """
|
||||
try:
|
||||
await security_service.approve_action(db, admin.id, action_id)
|
||||
return {"status": "success", "message": "Művelet végrehajtva."}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
|
||||
|
||||
# --- ⚙️ 3. DINAMIKUS KONFIGURÁCIÓ (System Parameters) ---
|
||||
|
||||
@router.get("/parameters", tags=["Dynamic Configuration"])
|
||||
async def list_all_parameters(
|
||||
db: AsyncSession = Depends(deps.get_db),
|
||||
admin: User = Depends(check_admin_access)
|
||||
):
|
||||
""" Globális és lokális paraméterek (Limitek, XP szorzók) lekérése. """
|
||||
result = await db.execute(select(SystemParameter))
|
||||
return result.scalars().all()
|
||||
|
||||
@router.post("/parameters", tags=["Dynamic Configuration"])
|
||||
async def set_parameter(
|
||||
config: ConfigUpdate,
|
||||
db: AsyncSession = Depends(deps.get_db),
|
||||
admin: User = Depends(check_admin_access)
|
||||
):
|
||||
""" Paraméter beállítása vagy frissítése hierarchikus scope-al. """
|
||||
query = text("""
|
||||
INSERT INTO data.system_parameters (key, value, scope_level, scope_id, category, last_modified_by)
|
||||
VALUES (:key, :val, :sl, :sid, :cat, :user)
|
||||
ON CONFLICT (key, scope_level, scope_id)
|
||||
DO UPDATE SET
|
||||
value = EXCLUDED.value,
|
||||
category = EXCLUDED.category,
|
||||
last_modified_by = EXCLUDED.last_modified_by,
|
||||
updated_at = now()
|
||||
""")
|
||||
|
||||
await db.execute(query, {
|
||||
"key": config.key, "val": config.value, "sl": config.scope_level,
|
||||
"sid": config.scope_id, "cat": config.category, "user": admin.email
|
||||
})
|
||||
await db.commit()
|
||||
return {"status": "success", "message": f"'{config.key}' frissítve."}
|
||||
|
||||
@router.post("/translations/sync", tags=["System Utilities"])
|
||||
async def sync_translations(db: AsyncSession = Depends(deps.get_db), admin: User = Depends(check_admin_access)):
|
||||
""" DB fordítások exportálása JSON fájlokba a frontendnek. """
|
||||
await TranslationService.export_to_json(db)
|
||||
return {"message": "Nyelvi fájlok frissítve."}
|
||||
23
backend/app/schemas/admin_security.py
Executable file
23
backend/app/schemas/admin_security.py
Executable file
@@ -0,0 +1,23 @@
|
||||
# /opt/docker/dev/service_finder/backend/app/schemas/admin_security.py
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
from datetime import datetime
|
||||
from typing import Optional, Any, Dict
|
||||
from app.models.security import ActionStatus
|
||||
|
||||
class PendingActionResponse(BaseModel):
|
||||
id: int
|
||||
requester_id: int
|
||||
action_type: str
|
||||
payload: Dict[str, Any]
|
||||
reason: str
|
||||
status: ActionStatus
|
||||
created_at: datetime
|
||||
expires_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
class SecurityStatusResponse(BaseModel):
|
||||
total_pending: int
|
||||
critical_logs_last_24h: int
|
||||
emergency_locks_active: int
|
||||
|
||||
56
backend/app/schemas/asset.py
Executable file
56
backend/app/schemas/asset.py
Executable file
@@ -0,0 +1,56 @@
|
||||
# /opt/docker/dev/service_finder/backend/app/schemas/asset.py
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
from typing import Optional, Dict, Any, List
|
||||
from uuid import UUID
|
||||
from datetime import datetime
|
||||
|
||||
class AssetCatalogResponse(BaseModel):
|
||||
""" A technikai katalógus (Master Data) teljes adattartalma. """
|
||||
id: int
|
||||
make: str
|
||||
model: str
|
||||
generation: Optional[str] = None
|
||||
engine_variant: Optional[str] = None
|
||||
year_from: Optional[int] = None
|
||||
year_to: Optional[int] = None
|
||||
vehicle_class: Optional[str] = None
|
||||
fuel_type: Optional[str] = None
|
||||
|
||||
# Technikai paraméterek az automatizáláshoz
|
||||
power_kw: Optional[int] = None
|
||||
engine_capacity: Optional[int] = None
|
||||
max_weight_kg: Optional[int] = None
|
||||
axle_count: Optional[int] = None
|
||||
euro_class: Optional[str] = None
|
||||
body_type: Optional[str] = None
|
||||
engine_code: Optional[str] = None
|
||||
|
||||
factory_data: Dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
class AssetResponse(BaseModel):
|
||||
""" A konkrét járműpéldány (Asset) teljes válaszmodellje. """
|
||||
id: UUID
|
||||
vin: str = Field(..., min_length=17, max_length=17)
|
||||
license_plate: Optional[str] = None
|
||||
name: Optional[str] = None
|
||||
year_of_manufacture: Optional[int] = None
|
||||
|
||||
# Státusz és ellenőrzés
|
||||
status: str
|
||||
is_verified: bool
|
||||
verification_method: Optional[str] = None
|
||||
catalog_match_score: Optional[float] = None
|
||||
|
||||
# Kapcsolt adatok
|
||||
catalog_id: Optional[int] = None
|
||||
catalog: Optional[AssetCatalogResponse] = None # Itt jön a dúsítás!
|
||||
|
||||
owner_organization_id: Optional[int] = None
|
||||
operator_person_id: Optional[int] = None
|
||||
|
||||
created_at: datetime
|
||||
updated_at: Optional[datetime] = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
35
backend/app/schemas/asset_cost.py
Executable file
35
backend/app/schemas/asset_cost.py
Executable file
@@ -0,0 +1,35 @@
|
||||
# /opt/docker/dev/service_finder/backend/app/schemas/asset_cost.py
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
from typing import Optional, Dict, Any
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
from uuid import UUID
|
||||
|
||||
class AssetCostBase(BaseModel):
|
||||
cost_type: str # fuel, service, tax, insurance
|
||||
amount_local: Decimal
|
||||
currency_local: str = "HUF"
|
||||
net_amount_local: Optional[Decimal] = None
|
||||
vat_rate: Optional[Decimal] = Field(default=27.0)
|
||||
|
||||
date: datetime = Field(default_factory=datetime.now)
|
||||
mileage_at_cost: Optional[int] = None
|
||||
description: Optional[str] = None
|
||||
data: Dict[str, Any] = Field(default_factory=dict) # nyugta adatai, GPS koordináták
|
||||
|
||||
class AssetCostCreate(AssetCostBase):
|
||||
asset_id: UUID
|
||||
organization_id: int
|
||||
|
||||
class AssetCostResponse(AssetCostBase):
|
||||
id: UUID
|
||||
asset_id: UUID
|
||||
organization_id: int
|
||||
driver_id: Optional[int] = None
|
||||
|
||||
# Pénzügyi dúsítás (Backend számolja)
|
||||
amount_eur: Optional[Decimal] = None
|
||||
exchange_rate_used: Optional[Decimal] = None
|
||||
created_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
54
backend/app/schemas/auth.py
Executable file
54
backend/app/schemas/auth.py
Executable file
@@ -0,0 +1,54 @@
|
||||
# /opt/docker/dev/service_finder/backend/app/schemas/auth.py
|
||||
from pydantic import BaseModel, EmailStr, Field, ConfigDict
|
||||
from typing import Optional, Dict, List
|
||||
from datetime import date, datetime
|
||||
|
||||
class DocumentDetail(BaseModel):
|
||||
number: str
|
||||
expiry_date: date
|
||||
|
||||
class ICEContact(BaseModel):
|
||||
name: str
|
||||
phone: str
|
||||
relationship: str
|
||||
|
||||
class UserLiteRegister(BaseModel):
|
||||
""" Step 1: Gyors regisztráció (Alap azonosítás). """
|
||||
email: EmailStr
|
||||
password: str = Field(..., min_length=8, description="Minimum 8 karakter hosszú jelszó")
|
||||
first_name: str
|
||||
last_name: str
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
class UserKYCComplete(BaseModel):
|
||||
""" Step 2: Teljes körű személyazonosítás és címadatok. """
|
||||
phone_number: str = Field(..., pattern=r"^\+?[0-9]{7,15}$")
|
||||
birth_place: str
|
||||
birth_date: date
|
||||
mothers_last_name: str
|
||||
mothers_first_name: str
|
||||
|
||||
# Atomizált címadatok a pontos GPS-hez és Robot-munkához
|
||||
address_zip: str
|
||||
address_city: str
|
||||
address_street_name: str
|
||||
address_street_type: str # utca, út, tér...
|
||||
address_house_number: str
|
||||
address_stairwell: Optional[str] = None
|
||||
address_floor: Optional[str] = None
|
||||
address_door: Optional[str] = None
|
||||
address_hrsz: Optional[str] = None # Külterület/Helyrajzi szám
|
||||
|
||||
# Okmányok és Vészhelyzet
|
||||
identity_docs: Dict[str, DocumentDetail] # pl: {"ID_CARD": {...}, "LICENSE": {...}}
|
||||
ice_contact: ICEContact
|
||||
|
||||
preferred_language: str = "hu"
|
||||
preferred_currency: str = "HUF"
|
||||
|
||||
class Token(BaseModel):
|
||||
access_token: str
|
||||
refresh_token: Optional[str] = None
|
||||
token_type: str = "bearer"
|
||||
is_active: bool
|
||||
47
backend/app/schemas/evidence.py
Executable file
47
backend/app/schemas/evidence.py
Executable file
@@ -0,0 +1,47 @@
|
||||
# app/schemas/evidence.py
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Optional
|
||||
|
||||
class RegistrationDocumentExtracted(BaseModel):
|
||||
"""A magyar forgalmi engedély teljes adattartalma."""
|
||||
# A - Okmány adatok
|
||||
license_plate: Optional[str] = Field(None, alias="A", description="Rendszám")
|
||||
first_registration_date: Optional[str] = Field(None, alias="B", description="Első nyilvántartásba vétel")
|
||||
doc_serial_number: Optional[str] = Field(None, description="Okmány sorszáma (jobb felső sarok)")
|
||||
|
||||
# C - Tulajdonos/Üzembentartó adatok
|
||||
owner_last_name: Optional[str] = Field(None, alias="C.1.1", description="Családi név vagy cégnév")
|
||||
owner_first_name: Optional[str] = Field(None, alias="C.1.2", description="Utónév")
|
||||
owner_address: Optional[str] = Field(None, alias="C.1.3", description="Lakcím/Székhely")
|
||||
owner_status: Optional[str] = Field(None, alias="C.4", description="Jogosultság státusza (a=tulaj, b=nem tulaj)")
|
||||
|
||||
# D - Jármű technikai adatai
|
||||
make: Optional[str] = Field(None, alias="D.1", description="Gyártmány")
|
||||
vehicle_type: Optional[str] = Field(None, alias="D.2", description="Típus")
|
||||
commercial_description: Optional[str] = Field(None, alias="D.3", description="Kereskedelmi leírás")
|
||||
vin: Optional[str] = Field(None, alias="E", description="Alvázszám (17 karakter)")
|
||||
|
||||
# G, F - Tömeg adatok
|
||||
weight_kg: Optional[int] = Field(None, alias="G", description="Saját tömeg")
|
||||
max_weight_kg: Optional[int] = Field(None, alias="F.1", description="Együttes tömeg")
|
||||
|
||||
# P, V - Motor és Környezetvédelem
|
||||
engine_capacity: Optional[int] = Field(None, alias="P.1", description="Hengerűrtartalom (cm3)")
|
||||
engine_power: Optional[float] = Field(None, alias="P.2", description="Teljesítmény (kW)")
|
||||
fuel_type: Optional[str] = Field(None, alias="P.3", description="Hajtóanyag")
|
||||
engine_code: Optional[str] = Field(None, alias="P.5", description="Motorkód")
|
||||
env_category: Optional[str] = Field(None, alias="V.9", description="Környezetvédelmi osztály")
|
||||
|
||||
# R, S, H - Egyéb
|
||||
color: Optional[str] = Field(None, alias="R", description="Szín")
|
||||
seats: Optional[int] = Field(None, alias="S.1", description="Ülések száma")
|
||||
expiry_date: Optional[str] = Field(None, alias="H", description="Műszaki érvényesség")
|
||||
transmission_type: Optional[str] = Field(None, description="Sebességváltó fajtája")
|
||||
|
||||
class Config:
|
||||
populate_by_name = True
|
||||
|
||||
class OcrResponse(BaseModel):
|
||||
success: bool
|
||||
message: str
|
||||
data: Optional[RegistrationDocumentExtracted] = None
|
||||
20
backend/app/schemas/fleet.py
Executable file
20
backend/app/schemas/fleet.py
Executable file
@@ -0,0 +1,20 @@
|
||||
# /opt/docker/dev/service_finder/backend/app/schemas/fleet.py
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
from typing import Optional, List
|
||||
from datetime import date
|
||||
from uuid import UUID
|
||||
|
||||
class EventCreate(BaseModel):
|
||||
asset_id: UUID
|
||||
event_type: str # 'SERVICE', 'FUEL', 'MOT'
|
||||
date: date
|
||||
odometer_value: int
|
||||
cost_amount: float
|
||||
description: Optional[str] = None
|
||||
provider_id: Optional[int] = None
|
||||
|
||||
class TCOStats(BaseModel):
|
||||
asset_id: UUID
|
||||
total_cost_huf: float
|
||||
cost_per_km: float
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
38
backend/app/schemas/organization.py
Executable file
38
backend/app/schemas/organization.py
Executable file
@@ -0,0 +1,38 @@
|
||||
from pydantic import BaseModel, Field, ConfigDict
|
||||
from typing import Optional, List
|
||||
|
||||
class ContactCreate(BaseModel):
|
||||
full_name: str
|
||||
email: str
|
||||
phone: Optional[str] = None
|
||||
contact_type: str = "primary"
|
||||
|
||||
class CorpOnboardIn(BaseModel):
|
||||
""" Teljes onboarding adatcsomag atomizált címekkel. """
|
||||
full_name: str = Field(..., description="Hivatalos cégnév")
|
||||
name: str = Field(..., description="Rövid név")
|
||||
display_name: str
|
||||
|
||||
tax_number: str
|
||||
reg_number: Optional[str] = None
|
||||
country_code: str = "HU"
|
||||
language: str = "hu"
|
||||
default_currency: str = "HUF"
|
||||
|
||||
# --- ATOMIZÁLT CÍM (Modell szinkron) ---
|
||||
address_zip: str
|
||||
address_city: str
|
||||
address_street_name: str
|
||||
address_street_type: str
|
||||
address_house_number: str
|
||||
address_stairwell: Optional[str] = None
|
||||
address_floor: Optional[str] = None
|
||||
address_door: Optional[str] = None
|
||||
address_hrsz: Optional[str] = None
|
||||
|
||||
contacts: List[ContactCreate] = []
|
||||
|
||||
class CorpOnboardResponse(BaseModel):
|
||||
organization_id: int
|
||||
status: str
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
38
backend/app/schemas/service.py
Executable file
38
backend/app/schemas/service.py
Executable file
@@ -0,0 +1,38 @@
|
||||
from pydantic import BaseModel, Field, ConfigDict
|
||||
from typing import Optional, List
|
||||
|
||||
class ContactCreate(BaseModel):
|
||||
full_name: str
|
||||
email: str
|
||||
phone: Optional[str] = None
|
||||
contact_type: str = "primary"
|
||||
|
||||
class CorpOnboardIn(BaseModel):
|
||||
""" Teljes onboarding adatcsomag atomizált címekkel. """
|
||||
full_name: str = Field(..., description="Hivatalos cégnév")
|
||||
name: str = Field(..., description="Rövid név")
|
||||
display_name: str
|
||||
|
||||
tax_number: str
|
||||
reg_number: Optional[str] = None
|
||||
country_code: str = "HU"
|
||||
language: str = "hu"
|
||||
default_currency: str = "HUF"
|
||||
|
||||
# --- ATOMIZÁLT CÍM (Modell szinkron) ---
|
||||
address_zip: str
|
||||
address_city: str
|
||||
address_street_name: str
|
||||
address_street_type: str
|
||||
address_house_number: str
|
||||
address_stairwell: Optional[str] = None
|
||||
address_floor: Optional[str] = None
|
||||
address_door: Optional[str] = None
|
||||
address_hrsz: Optional[str] = None
|
||||
|
||||
contacts: List[ContactCreate] = []
|
||||
|
||||
class CorpOnboardResponse(BaseModel):
|
||||
organization_id: int
|
||||
status: str
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
9
backend/app/schemas/service_hunt.py
Executable file
9
backend/app/schemas/service_hunt.py
Executable file
@@ -0,0 +1,9 @@
|
||||
# /opt/docker/dev/service_finder/backend/app/schemas/service_hunt.py
|
||||
class ServiceHuntRequest(BaseModel):
|
||||
name: str
|
||||
category_id: int
|
||||
address: str
|
||||
latitude: float
|
||||
longitude: float
|
||||
user_latitude: float
|
||||
user_longitude: float
|
||||
58
backend/app/schemas/social.py
Executable file
58
backend/app/schemas/social.py
Executable file
@@ -0,0 +1,58 @@
|
||||
# /opt/docker/dev/service_finder/backend/app/schemas/social.py
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
from typing import Optional, List
|
||||
from datetime import datetime
|
||||
from app.models.social import ModerationStatus, SourceType
|
||||
|
||||
# --- Alap Sémák (Szolgáltatók) ---
|
||||
|
||||
class ServiceProviderBase(BaseModel):
|
||||
name: str
|
||||
address: Optional[str] = None
|
||||
category: Optional[str] = None
|
||||
source: SourceType = SourceType.manual
|
||||
|
||||
class ServiceProviderCreate(BaseModel):
|
||||
name: str
|
||||
address: str
|
||||
category: Optional[str] = None
|
||||
|
||||
class ServiceProviderResponse(ServiceProviderBase):
|
||||
id: int
|
||||
status: ModerationStatus
|
||||
validation_score: int
|
||||
evidence_image_path: Optional[str] = None
|
||||
added_by_user_id: Optional[int] = None
|
||||
created_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
# --- Gamifikáció és Szavazás (Voting & Gamification) ---
|
||||
|
||||
class VoteCreate(BaseModel):
|
||||
vote_value: int
|
||||
|
||||
class LeaderboardEntry(BaseModel):
|
||||
username: str
|
||||
points: int
|
||||
rank: int
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
class BadgeSchema(BaseModel):
|
||||
id: int
|
||||
name: str
|
||||
description: str
|
||||
icon_url: Optional[str] = None # JAVÍTVA: icon_url a modell szerint
|
||||
|
||||
model_config = ConfigDict(from_attributes=True) # Pydantic V2 kompatibilis
|
||||
|
||||
class UserStatSchema(BaseModel):
|
||||
user_id: int
|
||||
total_xp: int # JAVÍTVA: total_xp a modell szerint
|
||||
current_level: int
|
||||
penalty_points: int # JAVÍTVA: új mező
|
||||
rank_title: Optional[str] = None
|
||||
badges: List[BadgeSchema] = []
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
10
backend/app/schemas/token.py
Executable file
10
backend/app/schemas/token.py
Executable file
@@ -0,0 +1,10 @@
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional
|
||||
|
||||
class Token(BaseModel):
|
||||
access_token: str
|
||||
token_type: str
|
||||
|
||||
class TokenData(BaseModel):
|
||||
username: Optional[str] = None
|
||||
role: Optional[str] = None
|
||||
25
backend/app/schemas/user.py
Executable file
25
backend/app/schemas/user.py
Executable file
@@ -0,0 +1,25 @@
|
||||
# /opt/docker/dev/service_finder/backend/app/schemas/user.py
|
||||
from pydantic import BaseModel, EmailStr, field_validator, ConfigDict
|
||||
from typing import Optional
|
||||
from datetime import date
|
||||
|
||||
class UserBase(BaseModel):
|
||||
email: EmailStr
|
||||
first_name: Optional[str] = None
|
||||
last_name: Optional[str] = None
|
||||
is_active: bool = True
|
||||
region_code: str = "HU"
|
||||
|
||||
class UserResponse(UserBase):
|
||||
id: int
|
||||
person_id: Optional[int] = None
|
||||
role: str
|
||||
subscription_plan: str
|
||||
scope_level: str
|
||||
scope_id: Optional[str] = None
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
class UserUpdate(BaseModel):
|
||||
first_name: Optional[str] = None
|
||||
last_name: Optional[str] = None
|
||||
preferred_language: Optional[str] = None
|
||||
30
backend/app/schemas/vehicle.py.old
Executable file
30
backend/app/schemas/vehicle.py.old
Executable file
@@ -0,0 +1,30 @@
|
||||
from pydantic import BaseModel, Field, validator
|
||||
from typing import Optional, List, Any
|
||||
from uuid import UUID
|
||||
from datetime import datetime
|
||||
|
||||
class EngineSpecBase(BaseModel):
|
||||
engine_code: str
|
||||
fuel_type: str
|
||||
power_kw: int
|
||||
default_service_interval_km: int = 15000
|
||||
|
||||
class VehicleBase(BaseModel):
|
||||
brand_id: int
|
||||
model_name: str
|
||||
identification_number: str
|
||||
license_plate: Optional[str] = None
|
||||
tracking_mode: str = "km"
|
||||
|
||||
class VehicleCreate(VehicleBase):
|
||||
current_company_id: int
|
||||
engine_spec_id: int
|
||||
|
||||
class VehicleRead(VehicleBase):
|
||||
id: UUID
|
||||
current_rating_pct: int
|
||||
total_real_usage: float
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
20
backend/app/schemas/vehicle_categories.py
Executable file
20
backend/app/schemas/vehicle_categories.py
Executable file
@@ -0,0 +1,20 @@
|
||||
# app/core/schemas/vehicle_categories.py
|
||||
|
||||
VEHICLE_SCHEMAS = {
|
||||
"motorcycle": {
|
||||
"features": ["ABS", "Markolatfűtés", "Szélvédő", "Bukócső/gomba", "Automata váltó", "Gyári dobozok", "Zárható doboz", "Veterán"],
|
||||
"service_items": ["motorolaj", "olajszűrő", "levegőszűrő", "lánc_szett", "fékfolyadék", "gyújtógyertya", "szelephézag_ellenőrzés"]
|
||||
},
|
||||
"car": {
|
||||
"features": ["Automata", "Tempomat", "Összkerékhajtás", "Alufelni", "Elektromos ablak", "Vonóhorog", "ISOFIX rendszer", "ESP", "Szervizkönyv", "Veterán"],
|
||||
"service_items": ["motorolaj", "olajszűrő", "levegőszűrő", "pollenszűrő", "vezérlés_szett", "hosszbordásszíj", "váltóolaj", "fagyálló"]
|
||||
},
|
||||
"truck": {
|
||||
"features": ["Légrugó", "Hálófülke", "Retarder/Intarder", "Emelőhátfal", "Tengelysúly-mérő", "AdBlue", "Állóhelyzeti klíma"],
|
||||
"service_items": ["motorolaj", "légfék_szárító_patron", "üzemanyagszűrő", "érintésvédelmi_vizsga", "tengely_zsírozás"]
|
||||
},
|
||||
"boat": {
|
||||
"features": ["Utánfutó", "Takaróponyva", "Orrsugárkormány", "Halradar", "Kormányállás", "Üzemanyagtartály", "Sólyakocsi", "Zárható tároló", "Elektromos horgonycsörlő"],
|
||||
"service_items": ["motorolaj", "hajómotor_anód", "vízpumpa_lapát", "téliesítés", "algagátlózás"]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user