fix: resolve frontend/backend integration bugs

- Rename skincare route prefix /skin-snapshots → /skincare to match API client
- Add redirect_slashes=False to FastAPI app; change collection routes from "/" to ""
  to eliminate 307 redirects on POST/GET without trailing slash
- Fix redirect() inside try/catch in products/new and routines/new server actions
  (SvelteKit redirect() throws and was being caught as a 500 error)
- Eagerly load inventory and steps relationships via explicit SELECT + model_dump(mode="json"),
  working around SQLModel 0.0.37 not serializing Relationship fields in response_model
- Add field_validator for product_effect_profile to coerce DB-returned dict → ProductEffectProfile,
  eliminating Pydantic serializer warning
- Update all tests to use routes without trailing slash

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Piotr Oleszczyk 2026-02-26 21:53:17 +01:00
parent 8d4f9d1fc6
commit 9bf94a979c
11 changed files with 85 additions and 68 deletions

View file

@ -188,7 +188,7 @@ def get_or_404(session: Session, model, record_id) -> object:
# ---------------------------------------------------------------------------
@router.get("/", response_model=list[Product])
@router.get("", response_model=list[Product])
def list_products(
category: Optional[ProductCategory] = None,
brand: Optional[str] = None,
@ -224,7 +224,7 @@ def list_products(
return products
@router.post("/", response_model=Product, status_code=201)
@router.post("", response_model=Product, status_code=201)
def create_product(data: ProductCreate, session: Session = Depends(get_session)):
product = Product(
id=uuid4(),
@ -236,9 +236,13 @@ def create_product(data: ProductCreate, session: Session = Depends(get_session))
return product
@router.get("/{product_id}", response_model=Product)
@router.get("/{product_id}")
def get_product(product_id: UUID, session: Session = Depends(get_session)):
return get_or_404(session, Product, product_id)
product = get_or_404(session, Product, product_id)
inventory = session.exec(select(ProductInventory).where(ProductInventory.product_id == product_id)).all()
data = product.model_dump(mode="json")
data["inventory"] = [item.model_dump(mode="json") for item in inventory]
return data
@router.patch("/{product_id}", response_model=Product)