Files
Hartmut b892f72f7e feat: per-line render overrides — override any output type setting at order time
Instead of duplicating output types for every variation (WebP vs PNG,
different resolution), keep one canonical output type and override
specific fields per order line via render_overrides JSONB.

Backend:
- render_overrides JSONB column on OrderLine (DB migration)
- Render task merges overrides with output type settings (format, width,
  height, samples, engine, denoiser, transparent_bg, cycles_device)
- POST /orders/{id}/batch-render-overrides endpoint for bulk override
- PatchLineBody accepts render_overrides for per-line patching

Frontend:
- Batch render overrides section on OrderDetail: output format dropdown
  (PNG/JPG/WebP) + resolution dropdown (512-4096)
- Clear button to remove overrides

MCP:
- create_order tool: accepts product_ids, output_type, render_overrides,
  material_override — enables "render all products as WebP" via Claude
- set_render_overrides tool: batch override on existing orders

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 12:26:38 +01:00

139 lines
3.9 KiB
Python

import uuid
from datetime import datetime
from typing import Any
from pydantic import BaseModel
from app.domains.orders.models import OrderStatus, ItemStatus, AIValidationStatus
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 RejectOrderRequest(BaseModel):
reason: str = ""
notify_client: bool = True
class OrderLineCreate(BaseModel):
product_id: uuid.UUID
output_type_id: uuid.UUID | None = None
render_position_id: uuid.UUID | None = None
global_render_position_id: uuid.UUID | None = None
gewuenschte_bildnummer: str | None = None
material_override: str | None = None
render_overrides: dict | None = None
notes: str | None = None
class OrderLineOut(BaseModel):
id: uuid.UUID
order_id: uuid.UUID
product_id: uuid.UUID
product: Any # ProductOut — forward ref to avoid circular imports
output_type_id: uuid.UUID | None
output_type: Any | None # OutputTypeOut
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
render_log: dict | None = None
render_started_at: datetime | None = None
render_completed_at: datetime | None = None
material_override: str | None = None
render_overrides: dict | None = None
notes: str | None
created_at: datetime
updated_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
rejection_reason: str | 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] = []