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>
This commit is contained in:
@@ -294,6 +294,93 @@ def set_material_override(order_id: str, material_name: str = "") -> str:
|
||||
return json.dumps(data, indent=2)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def create_order(
|
||||
product_ids: list[str],
|
||||
output_type_id: str = "",
|
||||
output_type_name: str = "",
|
||||
render_overrides: dict | None = None,
|
||||
material_override: str = "",
|
||||
notes: str = "",
|
||||
) -> str:
|
||||
"""Create a new order with the given products and output type.
|
||||
|
||||
Either output_type_id or output_type_name must be provided. If both are given,
|
||||
output_type_id takes priority. render_overrides allows overriding render settings
|
||||
like output_format, width, height, samples, engine per line.
|
||||
|
||||
Args:
|
||||
product_ids: List of product UUIDs to include in the order.
|
||||
output_type_id: UUID of the output type (takes priority over name).
|
||||
output_type_name: Name of the output type (used if output_type_id is empty).
|
||||
render_overrides: Optional dict of render setting overrides (e.g. {"output_format": "webp", "width": 2048, "height": 2048}).
|
||||
material_override: Optional SCHAEFFLER library material name to apply to all lines.
|
||||
notes: Optional notes for the order.
|
||||
"""
|
||||
# Resolve output_type_id from name if needed
|
||||
ot_id = output_type_id or None
|
||||
if not ot_id and output_type_name:
|
||||
rows = _db_query(
|
||||
"SELECT id FROM output_types WHERE name ILIKE %s AND is_active = true LIMIT 1",
|
||||
(output_type_name,),
|
||||
)
|
||||
if rows:
|
||||
ot_id = rows[0]["id"]
|
||||
else:
|
||||
return f"Error: No active output type found matching '{output_type_name}'."
|
||||
|
||||
lines = []
|
||||
for pid in product_ids:
|
||||
line: dict = {"product_id": pid}
|
||||
if ot_id:
|
||||
line["output_type_id"] = ot_id
|
||||
if render_overrides:
|
||||
line["render_overrides"] = render_overrides
|
||||
if material_override:
|
||||
line["material_override"] = material_override
|
||||
lines.append(line)
|
||||
|
||||
body: dict = {"lines": lines}
|
||||
if notes:
|
||||
body["notes"] = notes
|
||||
|
||||
try:
|
||||
data = _api_post("/api/orders", body)
|
||||
return json.dumps(
|
||||
{
|
||||
"order_id": data["id"],
|
||||
"order_number": data["order_number"],
|
||||
"status": data["status"],
|
||||
"line_count": data.get("line_count", len(lines)),
|
||||
"render_overrides": render_overrides,
|
||||
},
|
||||
indent=2,
|
||||
)
|
||||
except Exception as e:
|
||||
return f"Error creating order: {e}"
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def set_render_overrides(order_id: str, render_overrides: dict | None = None) -> str:
|
||||
"""Set render overrides on all lines of an order (batch).
|
||||
|
||||
Overrides any output type render settings at order time. Common overrides:
|
||||
output_format (png/jpg/webp), width, height, samples, engine (cycles/eevee),
|
||||
transparent_bg, bg_color, noise_threshold, denoiser.
|
||||
|
||||
Pass None/empty to clear all overrides.
|
||||
|
||||
Args:
|
||||
order_id: UUID of the order.
|
||||
render_overrides: Dict of render setting overrides, or None to clear.
|
||||
"""
|
||||
data = _api_post(
|
||||
f"/api/orders/{order_id}/batch-render-overrides",
|
||||
{"render_overrides": render_overrides},
|
||||
)
|
||||
return json.dumps(data, indent=2)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def get_queue_status() -> str:
|
||||
"""Get current render queue status — pending, active, completed/failed counts."""
|
||||
|
||||
Reference in New Issue
Block a user