refaktor címtár

This commit is contained in:
Roo
2026-07-01 19:49:58 +00:00
parent 6e627d0ebe
commit 7654913d21
198 changed files with 3485 additions and 1609 deletions

View File

@@ -0,0 +1,60 @@
"""
Unified Address Pydantic Schemas (P0 Refactoring).
AddressIn: For creation/updates — matches system.addresses columns.
AddressOut: For responses — returns the full Address object including id,
zip/city resolved via the postal_code relationship.
Usage:
from app.schemas.address import AddressIn, AddressOut
"""
from pydantic import BaseModel, Field, ConfigDict
from typing import Optional
from datetime import datetime
class AddressIn(BaseModel):
"""Unified address input schema for creation and updates.
Maps to system.addresses table columns.
The `zip` and `city` fields are used to look up / create a
system.geo_postal_codes record; the resulting FK is stored as
postal_code_id on the Address record.
"""
zip: Optional[str] = Field(None, max_length=10, description="Irányítószám (postal code)")
city: Optional[str] = Field(None, max_length=100, description="Város")
street_name: Optional[str] = Field(None, max_length=200, description="Utca neve")
street_type: Optional[str] = Field(None, max_length=50, description="Közterület jellege (utca, út, tér, stb.)")
house_number: Optional[str] = Field(None, max_length=50, description="Házszám")
stairwell: Optional[str] = Field(None, max_length=20, description="Lépcsőház")
floor: Optional[str] = Field(None, max_length=20, description="Emelet")
door: Optional[str] = Field(None, max_length=20, description="Ajtó")
parcel_id: Optional[str] = Field(None, max_length=50, description="Helyrajzi szám / parcella ID")
full_address_text: Optional[str] = Field(None, description="Teljes cím szövegesen")
latitude: Optional[float] = Field(None, description="GPS szélesség")
longitude: Optional[float] = Field(None, description="GPS hosszúság")
class AddressOut(BaseModel):
"""Unified address output schema for API responses.
Includes the full Address object data, with zip/city resolved
via the postal_code relationship.
"""
id: str # UUID as string for JSON serialization
zip: Optional[str] = None
city: Optional[str] = None
street_name: Optional[str] = None
street_type: Optional[str] = None
house_number: Optional[str] = None
stairwell: Optional[str] = None
floor: Optional[str] = None
door: Optional[str] = None
parcel_id: Optional[str] = None
full_address_text: Optional[str] = None
latitude: Optional[float] = None
longitude: Optional[float] = None
created_at: Optional[datetime] = None
model_config = ConfigDict(from_attributes=True)

View File

@@ -2,6 +2,8 @@ from pydantic import BaseModel, Field, ConfigDict, model_validator
from typing import Optional, List, Any
from datetime import datetime
from app.schemas.address import AddressIn, AddressOut
# =============================================================================
# Organization Member Schemas (P0: Full CRUD for Garage Employees)
@@ -101,16 +103,8 @@ class CorpOnboardIn(BaseModel):
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
# --- P0 REFACTORED: Unified address via AddressIn ---
address: AddressIn = Field(..., description="Székhely címe (AddressIn struktúrában)")
contacts: List[ContactCreate] = []
@@ -132,13 +126,8 @@ class OrganizationUpdate(BaseModel):
name: Optional[str] = None
full_name: Optional[str] = None
tax_number: Optional[str] = None
# ── Cím adatok (Address fields) ──
address_zip: Optional[str] = None
address_city: Optional[str] = None
address_street_name: Optional[str] = None
address_street_type: Optional[str] = None
address_house_number: Optional[str] = None
address_hrsz: Optional[str] = None
# ── P0 REFACTORED: Unified address via AddressIn ──
address: Optional[AddressIn] = None
# ── Crowdsourced search fields ──
aliases: Optional[List[str]] = None
tags: Optional[List[str]] = None
@@ -170,12 +159,7 @@ class OrganizationResponse(BaseModel):
external_integration_config: Optional[Any] = None
aliases: List[str] = Field(default_factory=list)
tags: List[str] = Field(default_factory=list)
# ── Cím adatok (Address fields) ──
address_zip: Optional[str] = None
address_city: Optional[str] = None
address_street_name: Optional[str] = None
address_street_type: Optional[str] = None
address_house_number: Optional[str] = None
address_hrsz: Optional[str] = None
# ── P0 REFACTORED: Unified address via AddressOut ──
address: Optional[AddressOut] = None
model_config = ConfigDict(from_attributes=True)

View File

@@ -6,6 +6,12 @@ P1 CRITICAL ALIGN (2026-06-17): Atomizált címmezők bevezetése.
- street -> address_street_name, address_street_type, address_house_number
- A ProviderSearchResult is tartalmazza az atomizált címmezőket.
P3 UNIFIED ADDRESS REFACTOR (2026-07-01): Egységes AddressIn/AddressOut.
- ProviderSearchResult: address_detail: Optional[AddressOut] a meglévő flat mezők mellett
- ProviderQuickAddIn: address_detail: Optional[AddressIn] a meglévő flat mezők mellett
- ProviderUpdateIn: address_detail: Optional[AddressIn] a meglévő flat mezők mellett
- A flat mezők (address_zip, address_street_name, stb.) MEGMARADNAK a backward compatibility miatt
4-Level Category Architecture (2026-06-17):
===========================================
- CategoryTreeNode: Hierarchikus fa struktúra a frontend checkboxaihoz
@@ -15,6 +21,7 @@ P1 CRITICAL ALIGN (2026-06-17): Atomizált címmezők bevezetése.
from pydantic import BaseModel, Field, ConfigDict
from typing import Optional, List
from app.schemas.address import AddressIn, AddressOut
# ──────────────────────────────────────────────
@@ -97,6 +104,11 @@ class ProviderSearchResult(BaseModel):
- address_street_name, address_street_type, address_house_number
- A frontend ezeket intelligensen fűzi össze megjelenítéskor.
P3 UNIFIED ADDRESS REFACTOR (2026-07-01): address_detail mező.
- address_detail: Optional[AddressOut] — egységes cím objektum.
- A flat mezők (address_zip, address_street_name, stb.) MEGMARADNAK
a backward compatibility miatt.
FEATURE (2026-06-17): categories mező.
- A szolgáltatóhoz tartozó kategóriák (ExpertiseTag) listája.
- Tartalmazza az ID-t, nevet és szintet a frontend chip megjelenítéshez.
@@ -122,6 +134,8 @@ class ProviderSearchResult(BaseModel):
rating: Optional[float] = None
supported_vehicle_classes: Optional[List[str]] = None
specializations: Optional[dict] = None
# P3: Egységes cím objektum (a flat mezők mellett)
address_detail: Optional[AddressOut] = None
model_config = ConfigDict(from_attributes=True)
@@ -140,6 +154,11 @@ class ProviderQuickAddIn(BaseModel):
P1 CRITICAL ALIGN (2026-06-17): Atomizált címmezők.
- street ELTÁVOLÍTVA, helyette address_street_name, address_street_type, address_house_number
P3 UNIFIED ADDRESS REFACTOR (2026-07-01): address_detail mező.
- address_detail: Optional[AddressIn] — egységes cím objektum.
- A flat mezők (address_zip, address_street_name, stb.) MEGMARADNAK
a backward compatibility miatt.
P0 CRITICAL BUGFIX (2026-06-17): category_id most már opcionális.
- A 4-level kategória rendszer bevezetésével a frontend a category_ids
tömböt használja a kategóriák kiválasztására, nem a régi category_id-t.
@@ -167,6 +186,8 @@ class ProviderQuickAddIn(BaseModel):
specializations: Optional[dict] = Field(
None, description="Specializációk (pl. {'brands': ['Volvo'], 'propulsion': ['EV']})"
)
# P3: Egységes cím objektum (a flat mezők mellett)
address_detail: Optional[AddressIn] = None
class ProviderQuickAddResponse(BaseModel):
@@ -185,6 +206,11 @@ class ProviderUpdateIn(BaseModel):
- street ELTÁVOLÍTVA, helyette address_street_name, address_street_type, address_house_number
- Tartalmazza a contact_phone, contact_email, website és tags mezőket is.
P3 UNIFIED ADDRESS REFACTOR (2026-07-01): address_detail mező.
- address_detail: Optional[AddressIn] — egységes cím objektum.
- A flat mezők (address_zip, address_street_name, stb.) MEGMARADNAK
a backward compatibility miatt.
4-Level Category (2026-06-17):
- category_ids: A kiválasztott kategória ID-k listája (Szint 0-3)
- new_tags: A user által gépelt, új (még nem létező) címkék listája
@@ -212,6 +238,8 @@ class ProviderUpdateIn(BaseModel):
specializations: Optional[dict] = Field(
None, description="Specializációk (pl. {'brands': ['Volvo'], 'propulsion': ['EV']})"
)
# P3: Egységes cím objektum (a flat mezők mellett)
address_detail: Optional[AddressIn] = None
class ProviderUpdateResponse(BaseModel):

View File

@@ -4,24 +4,7 @@ from pydantic import BaseModel, EmailStr, field_validator, ConfigDict
from typing import Optional, Any, Dict
from datetime import date, datetime
class AddressResponse(BaseModel):
"""Beágyazott cím adatok a PersonResponse számára.
A mezőnevek address_ előtaggal egyeznek a frontend által várt PersonUpdate formátummal."""
address_zip: Optional[str] = None
address_city: Optional[str] = None
address_street_name: Optional[str] = None
address_street_type: Optional[str] = None
address_house_number: Optional[str] = None
address_stairwell: Optional[str] = None
address_floor: Optional[str] = None
address_door: Optional[str] = None
address_hrsz: Optional[str] = None
full_address_text: Optional[str] = None
latitude: Optional[float] = None
longitude: Optional[float] = None
model_config = ConfigDict(from_attributes=True)
from app.schemas.address import AddressIn, AddressOut
class PersonResponse(BaseModel):
@@ -38,7 +21,7 @@ class PersonResponse(BaseModel):
identity_docs: Optional[Any] = None
ice_contact: Optional[Any] = None
is_active: bool = True
address: Optional[AddressResponse] = None
address: Optional[AddressOut] = None
model_config = ConfigDict(from_attributes=True)
@@ -90,16 +73,8 @@ class PersonUpdate(BaseModel):
# Okmány adatok (identity_docs)
identity_docs: Optional[Any] = None
# Cím adatok
address_zip: Optional[str] = None
address_city: Optional[str] = None
address_street_name: Optional[str] = None
address_street_type: Optional[str] = None
address_house_number: Optional[str] = None
address_stairwell: Optional[str] = None
address_floor: Optional[str] = None
address_door: Optional[str] = None
address_hrsz: Optional[str] = None
# Cím adatok — egységes AddressIn séma
address: Optional[AddressIn] = None
class ChangePasswordRequest(BaseModel):