refactor(B1): migrate to domain-driven project structure

Move all models/schemas/services/routers into app/domains/.
Keep backward-compat shims in old locations for imports.
Preserves domains/rendering/tasks.py from Phase A.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-06 16:24:11 +01:00
parent 82bf46725b
commit b87df4a3e5
69 changed files with 1729 additions and 1831 deletions
+11 -92
View File
@@ -1,92 +1,11 @@
import uuid
from datetime import datetime
from typing import Any
from pydantic import BaseModel
from app.models.order import OrderStatus
from app.models.order_item import ItemStatus, AIValidationStatus
from app.schemas.order_line import OrderLineOut, OrderLineCreate # noqa: F401
class ComponentData(BaseModel):
part_name: str | None = None
material: str | None = None
component_type: str | None = None
column_index: int | None = None
class OrderItemCreate(BaseModel):
row_index: int
ebene1: str | None = None
ebene2: str | None = None
baureihe: str | None = None
pim_id: str | None = None
produkt_baureihe: str | None = None
gewaehltes_produkt: str | None = None
name_cad_modell: str | None = None
gewuenschte_bildnummer: str | None = None
lagertyp: str | None = None
medias_rendering: bool | None = None
components: list[ComponentData] = []
class OrderItemOut(BaseModel):
id: uuid.UUID
order_id: uuid.UUID
row_index: int
ebene1: str | None
ebene2: str | None
baureihe: str | None
pim_id: str | None
produkt_baureihe: str | None
gewaehltes_produkt: str | None
name_cad_modell: str | None
gewuenschte_bildnummer: str | None
lagertyp: str | None
medias_rendering: bool | None
components: list[dict]
cad_file_id: uuid.UUID | None
thumbnail_path: str | None
cad_parsed_objects: list[str] | None = None
cad_part_materials: list[dict] = []
ai_validation_status: AIValidationStatus
ai_validation_result: dict | None
item_status: ItemStatus
notes: str | None
created_at: datetime
model_config = {"from_attributes": True}
class OrderCreate(BaseModel):
template_id: uuid.UUID | None = None
source_excel: str | None = None
notes: str | None = None
items: list[OrderItemCreate] = []
lines: list[OrderLineCreate] = []
class OrderOut(BaseModel):
id: uuid.UUID
order_number: str
template_id: uuid.UUID | None
status: OrderStatus
created_by: uuid.UUID
source_excel: str | None
notes: str | None
created_at: datetime
updated_at: datetime
submitted_at: datetime | None = None
processing_started_at: datetime | None = None
completed_at: datetime | None = None
rejected_at: datetime | None = None
estimated_price: float | None = None
item_count: int = 0
line_count: int = 0
render_progress: dict | None = None
model_config = {"from_attributes": True}
class OrderDetailOut(OrderOut):
items: list[OrderItemOut] = []
lines: list[OrderLineOut] = []
# Compat shim — use app.domains.orders.schemas instead
from app.domains.orders.schemas import (
ComponentData, OrderItemCreate, OrderItemOut,
OrderLineCreate, OrderLineOut,
OrderCreate, OrderOut, OrderDetailOut,
)
__all__ = [
"ComponentData", "OrderItemCreate", "OrderItemOut",
"OrderLineCreate", "OrderLineOut",
"OrderCreate", "OrderOut", "OrderDetailOut",
]
+3 -39
View File
@@ -1,39 +1,3 @@
import uuid
from datetime import datetime
from pydantic import BaseModel
from app.schemas.product import ProductOut
from app.schemas.output_type import OutputTypeOut
class OrderLineCreate(BaseModel):
product_id: uuid.UUID
output_type_id: uuid.UUID | None = None
render_position_id: uuid.UUID | None = None
gewuenschte_bildnummer: str | None = None
notes: str | None = None
class OrderLineOut(BaseModel):
id: uuid.UUID
order_id: uuid.UUID
product_id: uuid.UUID
product: ProductOut
output_type_id: uuid.UUID | None
output_type: OutputTypeOut | None
gewuenschte_bildnummer: str | None
item_status: str
render_status: str
result_path: str | None
thumbnail_url: str | None = None
ai_validation_status: str
ai_validation_result: dict | None
render_backend_used: str | None = None
flamenco_job_id: str | None = None
unit_price: float | None = None
render_position_id: uuid.UUID | None = None
render_position_name: str | None = None
notes: str | None
created_at: datetime
updated_at: datetime
model_config = {"from_attributes": True}
# Compat shim — use app.domains.orders.schemas instead
from app.domains.orders.schemas import OrderLineCreate, OrderLineOut
__all__ = ["OrderLineCreate", "OrderLineOut"]
+3 -58
View File
@@ -1,58 +1,3 @@
import uuid
from datetime import datetime
from pydantic import BaseModel
class OutputTypeCreate(BaseModel):
name: str
description: str | None = None
renderer: str = "threejs"
render_settings: dict = {}
output_format: str = "png"
sort_order: int = 0
is_active: bool = True
compatible_categories: list[str] = []
render_backend: str = "auto"
is_animation: bool = False
transparent_bg: bool = False
pricing_tier_id: int | None = None
cycles_device: str | None = None
class OutputTypePatch(BaseModel):
name: str | None = None
description: str | None = None
renderer: str | None = None
render_settings: dict | None = None
output_format: str | None = None
sort_order: int | None = None
is_active: bool | None = None
compatible_categories: list[str] | None = None
render_backend: str | None = None
is_animation: bool | None = None
transparent_bg: bool | None = None
pricing_tier_id: int | None = None
cycles_device: str | None = None
class OutputTypeOut(BaseModel):
id: uuid.UUID
name: str
description: str | None
renderer: str
render_settings: dict
output_format: str
sort_order: int
compatible_categories: list[str]
render_backend: str
is_animation: bool
transparent_bg: bool
cycles_device: str | None = None
pricing_tier_id: int | None = None
pricing_tier_name: str | None = None
price_per_item: float | None = None
is_active: bool
created_at: datetime
updated_at: datetime
model_config = {"from_attributes": True}
# Compat shim — use app.domains.rendering.schemas instead
from app.domains.rendering.schemas import OutputTypeCreate, OutputTypePatch, OutputTypeOut
__all__ = ["OutputTypeCreate", "OutputTypePatch", "OutputTypeOut"]
+3 -72
View File
@@ -1,72 +1,3 @@
import uuid
from datetime import datetime
from pydantic import BaseModel
from app.schemas.render_position import RenderPositionOut
class ProductCreate(BaseModel):
pim_id: str
name: str | None = None
category_key: str | None = None
ebene1: str | None = None
ebene2: str | None = None
baureihe: str | None = None
produkt_baureihe: str | None = None
lagertyp: str | None = None
name_cad_modell: str | None = None
gewuenschte_bildnummer: str | None = None
medias_rendering: bool | None = None
components: list[dict] = []
cad_part_materials: list[dict] = []
notes: str | None = None
is_active: bool = True
source_excel: str | None = None
class ProductPatch(BaseModel):
name: str | None = None
category_key: str | None = None
ebene1: str | None = None
ebene2: str | None = None
baureihe: str | None = None
produkt_baureihe: str | None = None
lagertyp: str | None = None
name_cad_modell: str | None = None
gewuenschte_bildnummer: str | None = None
medias_rendering: bool | None = None
components: list[dict] | None = None
cad_part_materials: list[dict] | None = None
notes: str | None = None
is_active: bool | None = None
class ProductOut(BaseModel):
id: uuid.UUID
pim_id: str
name: str | None
category_key: str | None
ebene1: str | None
ebene2: str | None
baureihe: str | None
produkt_baureihe: str | None
lagertyp: str | None
name_cad_modell: str | None
gewuenschte_bildnummer: str | None
medias_rendering: bool | None
components: list[dict]
cad_part_materials: list[dict]
cad_file_id: uuid.UUID | None
thumbnail_url: str | None = None
render_image_url: str | None = None
processing_status: str | None = None
stl_cached: list[str] = []
cad_parsed_objects: list[str] | None = None
arbeitspaket: str | None = None
notes: str | None
is_active: bool
source_excel: str | None
render_positions: list[RenderPositionOut] = []
created_at: datetime
updated_at: datetime
model_config = {"from_attributes": True}
# Compat shim — use app.domains.products.schemas instead
from app.domains.products.schemas import ProductCreate, ProductPatch, ProductOut
__all__ = ["ProductCreate", "ProductPatch", "ProductOut"]
+3 -36
View File
@@ -1,36 +1,3 @@
import uuid
from datetime import datetime
from pydantic import BaseModel
class RenderPositionCreate(BaseModel):
name: str
rotation_x: float = 0.0
rotation_y: float = 0.0
rotation_z: float = 0.0
is_default: bool = False
sort_order: int = 0
class RenderPositionPatch(BaseModel):
name: str | None = None
rotation_x: float | None = None
rotation_y: float | None = None
rotation_z: float | None = None
is_default: bool | None = None
sort_order: int | None = None
class RenderPositionOut(BaseModel):
id: uuid.UUID
product_id: uuid.UUID
name: str
rotation_x: float
rotation_y: float
rotation_z: float
is_default: bool
sort_order: int
created_at: datetime
updated_at: datetime
model_config = {"from_attributes": True}
# Compat shim — use app.domains.rendering.schemas instead
from app.domains.rendering.schemas import RenderPositionCreate, RenderPositionPatch, RenderPositionOut
__all__ = ["RenderPositionCreate", "RenderPositionPatch", "RenderPositionOut"]
+3 -43
View File
@@ -1,43 +1,3 @@
from pydantic import BaseModel
from typing import Any
class ParsedComponent(BaseModel):
part_name: str | None = None
material: str | None = None
component_type: str | None = None
column_index: int
class ParsedRow(BaseModel):
row_index: int
ebene1: str | None = None
ebene2: str | None = None
baureihe: str | None = None
pim_id: str | None = None
produkt_baureihe: str | None = None
gewaehltes_produkt: str | None = None
name_cad_modell: str | None = None
gewuenschte_bildnummer: str | None = None
lagertyp: str | None = None
medias_rendering: bool | None = None
components: list[ParsedComponent] = []
class ParsedExcelResponse(BaseModel):
filename: str
excel_path: str | None = None # server-side path of the saved file
category_key: str | None = None
template_name: str | None = None
row_count: int
column_headers: list[str]
rows: list[ParsedRow]
warnings: list[str] = []
class StepUploadResponse(BaseModel):
cad_file_id: str
original_name: str
file_hash: str
status: str
matched_items: list[str] = []
# Compat shim — use app.domains.imports.schemas instead
from app.domains.imports.schemas import ParsedComponent, ParsedRow, ParsedExcelResponse, StepUploadResponse
__all__ = ["ParsedComponent", "ParsedRow", "ParsedExcelResponse", "StepUploadResponse"]
+3 -39
View File
@@ -1,39 +1,3 @@
import uuid
from datetime import datetime
from pydantic import BaseModel, EmailStr
from app.models.user import UserRole
class UserCreate(BaseModel):
email: EmailStr
password: str
full_name: str
role: UserRole = UserRole.client
class UserUpdate(BaseModel):
full_name: str | None = None
is_active: bool | None = None
role: UserRole | None = None
class UserOut(BaseModel):
id: uuid.UUID
email: str
full_name: str
role: UserRole
is_active: bool
created_at: datetime
model_config = {"from_attributes": True}
class TokenResponse(BaseModel):
access_token: str
token_type: str = "bearer"
user: UserOut
class LoginRequest(BaseModel):
email: EmailStr
password: str
# Compat shim — use app.domains.auth.schemas instead
from app.domains.auth.schemas import UserCreate, UserUpdate, UserOut, TokenResponse, LoginRequest
__all__ = ["UserCreate", "UserUpdate", "UserOut", "TokenResponse", "LoginRequest"]