Platform bundle: marketing publish, IT ops, packaging, agents mesh.

Volledige Foodlinkk Command Center uitbreiding met social automatisering,
reclamefolder filters, Proxmox monitoring en documentatie.
This commit is contained in:
Aissa
2026-06-09 00:41:27 +00:00
commit 5d60d33db1
212 changed files with 30044 additions and 0 deletions
+80
View File
@@ -0,0 +1,80 @@
"""Packaging generation API routes."""
from __future__ import annotations
from datetime import datetime
from typing import Any, Literal
from uuid import uuid4
from fastapi import APIRouter, HTTPException, Query
from fastapi.responses import Response
from pydantic import BaseModel, Field
from app.packaging.export import svg_to_pdf_bytes, svg_to_png_bytes
from app.packaging.generator import FOODLINKK_BRAND, generate_packaging
router = APIRouter(prefix="/packaging", tags=["packaging"])
_PROJECTS: dict[str, dict[str, Any]] = {}
class PackagingSpec(BaseModel):
type: Literal["folding_box", "wrap", "round_label"]
width_mm: float = Field(default=120, gt=0, le=4000)
height_mm: float = Field(default=80, gt=0, le=4000)
depth_mm: float = Field(default=40, ge=0, le=4000)
elements: dict[str, bool] = Field(default_factory=dict)
brand: dict[str, str] = Field(default_factory=dict)
barcode_value: str | None = Field(default=None, max_length=64)
@router.post("/generate")
def packaging_generate(spec: PackagingSpec) -> dict[str, Any]:
spec_data = spec.model_dump()
if not spec_data["brand"]:
spec_data["brand"] = dict(FOODLINKK_BRAND)
svg = generate_packaging(spec_data)
project_id = uuid4().hex
now = datetime.utcnow().isoformat() + "Z"
_PROJECTS[project_id] = {
"id": project_id,
"created_at": now,
"spec": spec_data,
"svg": svg,
}
return {"id": project_id, "created_at": now, "svg": svg, "spec": spec_data}
@router.get("/projects")
def packaging_projects(limit: int = Query(default=30, ge=1, le=200)) -> dict[str, Any]:
items = sorted(_PROJECTS.values(), key=lambda x: x["created_at"], reverse=True)[:limit]
return {
"items": [{"id": p["id"], "created_at": p["created_at"], "spec": p["spec"]} for p in items],
"count": len(items),
}
@router.get("/download/{project_id}")
def packaging_download(project_id: str, format: str = Query(default="svg", pattern="^(svg|png|pdf)$")):
project = _PROJECTS.get(project_id)
if not project:
raise HTTPException(status_code=404, detail="Packaging project not found")
svg = project["svg"]
filename = f"foodlinkk-packaging-{project_id[:8]}.{format}"
if format == "svg":
return Response(
content=svg.encode("utf-8"),
media_type="image/svg+xml",
headers={"Content-Disposition": f'attachment; filename="{filename}"'},
)
if format == "png":
return Response(
content=svg_to_png_bytes(svg),
media_type="image/png",
headers={"Content-Disposition": f'attachment; filename="{filename}"'},
)
return Response(
content=svg_to_pdf_bytes(svg),
media_type="application/pdf",
headers={"Content-Disposition": f'attachment; filename="{filename}"'},
)