Fix: Throughput API v1 available - Details posted to Irving. POWERBI_KEY was missing from the .ENV file, so was not live.
Add: Editor now supports editing a mix's resolved formula directly, with % and kg dual entry on ingredient rows
Fix: Mix Editor should bring through correct ingredients. New resolved formula (same logic we use in Mix Calculator).
Fix: Security headers on all API responses (hardening)
Add: New mix button available on the Mix Editor.
Add: New ingredient button available on the Ingredient Editor
This commit is contained in:
2026-06-16 14:43:17 +12:00
parent 8f9a7b8193
commit 7db95e2027
46 changed files with 3805 additions and 1049 deletions
+57
View File
@@ -32,6 +32,14 @@ class EditorProductUpdate(BaseModel):
notes: str | None = Field(default=None, max_length=2000)
class EditorMixCreate(BaseModel):
model_config = ConfigDict(extra="forbid")
client_name: str = Field(min_length=1, max_length=255)
name: str = Field(min_length=1, max_length=255)
notes: str | None = Field(default=None, max_length=2000)
class EditorMixUpdate(BaseModel):
model_config = ConfigDict(extra="forbid")
@@ -71,6 +79,55 @@ class EditorMixFormulaRead(BaseModel):
total_kg: float
class EditorResolvedMixIngredient(BaseModel):
raw_material_id: int
raw_material_name: str
quantity_kg: float
# This row's share of the mix total, matching the Mix Calculator.
mix_percentage: float
unit: str
notes: str | None
class EditorResolvedMixFormula(BaseModel):
"""A mix formula resolved the way the Mix Calculator reads it.
`source` is `product` when the numbers come from a representative product's
own formula, or `mix` when they come from the shared mix master fallback.
The PUT endpoint writes back to whichever source produced these rows.
"""
id: int
tenant_id: str
client_name: str
name: str
source: str
product_id: int | None
ingredients: list[EditorResolvedMixIngredient]
total_kg: float
class EditorMixFormulaRowInput(BaseModel):
model_config = ConfigDict(extra="forbid")
raw_material_id: int
quantity_kg: float = Field(gt=0)
notes: str | None = Field(default=None, max_length=1000)
class EditorMixFormulaReplace(BaseModel):
"""Full replacement of a mix's formula in one save.
The frontend keeps kilograms as the canonical value (percentages are an
entry aid that resolve back to kg against the total), so the API only needs
the resolved kg per row.
"""
model_config = ConfigDict(extra="forbid")
rows: list[EditorMixFormulaRowInput] = Field(min_length=1)
class EditorMixIngredientCreate(BaseModel):
model_config = ConfigDict(extra="forbid")