from uuid import UUID from fastapi import APIRouter, Depends from sqlalchemy.orm import Session from app.api.schemas import AttributeIn, AttributeOut, ProductIn, ProductOut, VariantIn, VariantOut from app.errors import AppError from app.persistence.db import get_session from app.persistence.repositories import CatalogRepository from app.services.ingestion_service import IngestionService router = APIRouter(prefix="/api/v1") @router.post("/products", status_code=201) def create_product(payload: ProductIn, session: Session = Depends(get_session)) -> ProductOut: product = IngestionService(session).create_product(payload.model_dump()) return ProductOut.model_validate(product.__dict__) @router.get("/products/{product_id}") def get_product(product_id: UUID, session: Session = Depends(get_session)) -> ProductOut: product = CatalogRepository(session).get_product(product_id) if product is None: raise AppError(404, "NOT_FOUND", "product not found", {"id": str(product_id)}) return ProductOut.model_validate(product.__dict__) @router.post("/products/{product_id}/variants", status_code=201) def create_variant(product_id: UUID, payload: VariantIn, session: Session = Depends(get_session)): variant = IngestionService(session).create_variant(product_id, payload.model_dump()) return { "id": variant.id, "product_id": variant.product_id, "name": variant.name, "manufacturer_sku": variant.manufacturer_sku, "identifiers": variant.identifiers, "created_at": variant.created_at, } @router.get("/variants/{variant_id}") def get_variant(variant_id: UUID, session: Session = Depends(get_session)) -> VariantOut: repo = CatalogRepository(session) variant = repo.get_variant(variant_id) if variant is None: raise AppError(404, "NOT_FOUND", "variant not found", {"id": str(variant_id)}) attributes = [AttributeOut.model_validate(item.__dict__) for item in repo.list_attributes(variant_id)] return VariantOut( id=variant.id, product_id=variant.product_id, name=variant.name, manufacturer_sku=variant.manufacturer_sku, identifiers=variant.identifiers, created_at=variant.created_at, attributes=attributes, ) @router.post("/variants/{variant_id}/attributes", status_code=201) def add_attribute(variant_id: UUID, payload: AttributeIn, session: Session = Depends(get_session)) -> AttributeOut: statement = IngestionService(session).add_attribute(variant_id, payload.model_dump()) return AttributeOut.model_validate(statement.__dict__)