Spaces:
Running
Running
| from fastapi import APIRouter, Depends, HTTPException, status | |
| from sqlalchemy.orm import Session | |
| from typing import List, Optional | |
| from pydantic import BaseModel, Field | |
| from app.services.database import get_db | |
| from app.services.context_manager import ContextManager | |
| from app.models.schemas import CaseContext, CaseStatus | |
| from app.workers.celery_worker import run_case_manager_task | |
| from app.api.auth import get_current_user | |
| from app.models.database_models import UserModel | |
| router = APIRouter(prefix="/api/cases", tags=["Cases"]) | |
| class CreateCaseRequest(BaseModel): | |
| problem_statement: str = Field(..., example="Why are my Instagram views dropping?") | |
| constraints: Optional[List[str]] = Field(default_factory=list, example=["creator niche = tech"]) | |
| def create_case( | |
| payload: CreateCaseRequest, | |
| db: Session = Depends(get_db), | |
| current_user: UserModel = Depends(get_current_user) | |
| ): | |
| """ | |
| Initializes a new investigation case in the shared context database and links it to the current user. | |
| """ | |
| try: | |
| context = ContextManager.create_context( | |
| db=db, | |
| problem_statement=payload.problem_statement, | |
| constraints=payload.constraints, | |
| user_id=current_user.id | |
| ) | |
| return context | |
| except Exception as e: | |
| raise HTTPException( | |
| status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, | |
| detail=f"Failed to create case: {str(e)}" | |
| ) | |
| def get_case( | |
| case_id: str, | |
| db: Session = Depends(get_db), | |
| current_user: UserModel = Depends(get_current_user) | |
| ): | |
| """ | |
| Retrieves the complete shared context for a case, validating user authorization. | |
| """ | |
| context = ContextManager.get_context(db=db, case_id=case_id) | |
| if not context: | |
| raise HTTPException( | |
| status_code=status.HTTP_404_NOT_FOUND, | |
| detail=f"Case with ID {case_id} not found." | |
| ) | |
| from app.models.database_models import CaseContextModel | |
| case_db = db.query(CaseContextModel).filter(CaseContextModel.case_id == case_id).first() | |
| if case_db and case_db.user_id and case_db.user_id != current_user.id: | |
| raise HTTPException( | |
| status_code=status.HTTP_403_FORBIDDEN, | |
| detail="Access denied to this case." | |
| ) | |
| return context | |
| def decompose_case( | |
| case_id: str, | |
| db: Session = Depends(get_db), | |
| current_user: UserModel = Depends(get_current_user) | |
| ): | |
| """ | |
| Triggers the Case Manager Agent task asynchronously via Celery, validating user authorization. | |
| """ | |
| from app.models.database_models import CaseContextModel | |
| case_db = db.query(CaseContextModel).filter(CaseContextModel.case_id == case_id).first() | |
| if not case_db: | |
| raise HTTPException( | |
| status_code=status.HTTP_404_NOT_FOUND, | |
| detail=f"Case with ID {case_id} not found." | |
| ) | |
| if case_db.user_id and case_db.user_id != current_user.id: | |
| raise HTTPException( | |
| status_code=status.HTTP_403_FORBIDDEN, | |
| detail="Access denied to this case." | |
| ) | |
| context = ContextManager.get_context(db=db, case_id=case_id) | |
| if context.hypotheses: | |
| raise HTTPException( | |
| status_code=status.HTTP_400_BAD_REQUEST, | |
| detail="This case has already been decomposed into hypotheses." | |
| ) | |
| # 2. Update status to investigating | |
| updated_context = ContextManager.update_status(db=db, case_id=case_id, status=CaseStatus.INVESTIGATING) | |
| try: | |
| # 3. Dispatch Celery task to the Redis broker | |
| run_case_manager_task.delay(case_id) | |
| # Return the updated context showing the new 'investigating' status immediately | |
| return updated_context | |
| except Exception as e: | |
| # Rollback status to failed if task dispatch fails | |
| ContextManager.update_status(db=db, case_id=case_id, status=CaseStatus.FAILED) | |
| raise HTTPException( | |
| status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, | |
| detail=f"Failed to queue agent task: {str(e)}" | |
| ) | |
| def get_cases( | |
| limit: int = 20, | |
| db: Session = Depends(get_db), | |
| current_user: UserModel = Depends(get_current_user) | |
| ): | |
| """ | |
| Retrieves all investigation cases in the database belonging to the current user. | |
| """ | |
| try: | |
| return ContextManager.get_all_contexts(db=db, limit=limit, user_id=current_user.id) | |
| except Exception as e: | |
| raise HTTPException( | |
| status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, | |
| detail=f"Failed to fetch cases: {str(e)}" | |
| ) |