""" API Routes para gestión de Servicios. """ from datetime import datetime from typing import List, Optional from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.orm import Session from pydantic import BaseModel from app.core.database import get_db from app.models.service import Service router = APIRouter() # =========================================== # SCHEMAS # =========================================== class ServiceCreate(BaseModel): name: str description: str short_description: Optional[str] = None category: str target_sectors: Optional[List[str]] = None benefits: Optional[List[str]] = None features: Optional[List[str]] = None case_studies: Optional[List[dict]] = None icon: Optional[str] = None images: Optional[List[str]] = None main_image: Optional[str] = None price_range: Optional[str] = None has_free_demo: bool = False tags: Optional[List[str]] = None call_to_action: Optional[str] = None is_featured: bool = False class Config: from_attributes = True class ServiceUpdate(BaseModel): name: Optional[str] = None description: Optional[str] = None short_description: Optional[str] = None category: Optional[str] = None target_sectors: Optional[List[str]] = None benefits: Optional[List[str]] = None features: Optional[List[str]] = None case_studies: Optional[List[dict]] = None icon: Optional[str] = None images: Optional[List[str]] = None main_image: Optional[str] = None price_range: Optional[str] = None has_free_demo: Optional[bool] = None tags: Optional[List[str]] = None call_to_action: Optional[str] = None is_active: Optional[bool] = None is_featured: Optional[bool] = None class Config: from_attributes = True # =========================================== # ENDPOINTS # =========================================== @router.get("/") async def list_services( category: Optional[str] = Query(None), target_sector: Optional[str] = Query(None), is_active: Optional[bool] = Query(True), is_featured: Optional[bool] = Query(None), limit: int = Query(50, le=100), offset: int = Query(0), db: Session = Depends(get_db) ): """Listar servicios con filtros.""" query = db.query(Service) if category: query = query.filter(Service.category == category) if is_active is not None: query = query.filter(Service.is_active == is_active) if is_featured is not None: query = query.filter(Service.is_featured == is_featured) if target_sector: query = query.filter(Service.target_sectors.contains([target_sector])) services = query.order_by(Service.created_at.desc()).offset(offset).limit(limit).all() return [s.to_dict() for s in services] @router.get("/categories") async def list_categories(db: Session = Depends(get_db)): """Listar categorías únicas de servicios.""" categories = db.query(Service.category).distinct().all() return [c[0] for c in categories if c[0]] @router.get("/featured") async def list_featured_services(db: Session = Depends(get_db)): """Listar servicios destacados.""" services = db.query(Service).filter( Service.is_featured == True, Service.is_active == True ).all() return [s.to_dict() for s in services] @router.get("/{service_id}") async def get_service(service_id: int, db: Session = Depends(get_db)): """Obtener un servicio por ID.""" service = db.query(Service).filter(Service.id == service_id).first() if not service: raise HTTPException(status_code=404, detail="Servicio no encontrado") return service.to_dict() @router.post("/") async def create_service(service_data: ServiceCreate, db: Session = Depends(get_db)): """Crear un nuevo servicio.""" service = Service(**service_data.dict()) db.add(service) db.commit() db.refresh(service) return service.to_dict() @router.put("/{service_id}") async def update_service(service_id: int, service_data: ServiceUpdate, db: Session = Depends(get_db)): """Actualizar un servicio.""" service = db.query(Service).filter(Service.id == service_id).first() if not service: raise HTTPException(status_code=404, detail="Servicio no encontrado") update_data = service_data.dict(exclude_unset=True) for field, value in update_data.items(): setattr(service, field, value) service.updated_at = datetime.utcnow() db.commit() db.refresh(service) return service.to_dict() @router.delete("/{service_id}") async def delete_service(service_id: int, db: Session = Depends(get_db)): """Eliminar un servicio.""" service = db.query(Service).filter(Service.id == service_id).first() if not service: raise HTTPException(status_code=404, detail="Servicio no encontrado") db.delete(service) db.commit() return {"message": "Servicio eliminado", "service_id": service_id} @router.post("/{service_id}/toggle-featured") async def toggle_featured(service_id: int, db: Session = Depends(get_db)): """Alternar estado de servicio destacado.""" service = db.query(Service).filter(Service.id == service_id).first() if not service: raise HTTPException(status_code=404, detail="Servicio no encontrado") service.is_featured = not service.is_featured db.commit() return { "message": f"Servicio {'destacado' if service.is_featured else 'no destacado'}", "is_featured": service.is_featured }