import os import shutil from fastapi import APIRouter, Depends, HTTPException, status, UploadFile, File, BackgroundTasks from sqlalchemy.orm import Session from typing import List, Optional import uuid from app.db.database import get_db from app.models.models import Activity, Evidence, User from app.security import get_current_active_user from app.services.activities import ActivityService from app import schemas from app.schemas import ActivityCreate, ActivityUpdate router = APIRouter( prefix="/activities", tags=["Activities"] ) def get_activity_service( db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user) ) -> ActivityService: return ActivityService(db, current_user) UPLOAD_DIR = "uploads" if not os.path.exists(UPLOAD_DIR): os.makedirs(UPLOAD_DIR) @router.post("/", response_model=schemas.Activity) def create_activity( activity: ActivityCreate, service: ActivityService = Depends(get_activity_service) ): return service.create_activity(activity) @router.get("/", response_model=List[schemas.Activity]) def read_activities( project_id: Optional[int] = None, specialty_id: Optional[int] = None, skip: int = 0, limit: int = 100, service: ActivityService = Depends(get_activity_service) ): db_activities = service.get_activities(project_id, specialty_id, skip, limit) return db_activities @router.get("/{activity_id}", response_model=schemas.Activity) def read_activity( activity_id: int, service: ActivityService = Depends(get_activity_service) ): return service.get_activity(activity_id) @router.put("/{activity_id}", response_model=schemas.Activity) def update_activity( activity_id: int, activity: schemas.ActivityUpdate, service: ActivityService = Depends(get_activity_service) ): db_activity = service.update_activity(activity_id, activity) return db_activity @router.post("/{activity_id}/upload", response_model=schemas.Evidence) async def upload_evidence( activity_id: int, background_tasks: BackgroundTasks, file: UploadFile = File(...), description: Optional[str] = None, captured_at: Optional[str] = None, service: ActivityService = Depends(get_activity_service) ): db_evidence = service.upload_evidence( activity_id, background_tasks, file, description, captured_at ) return db_evidence @router.post("/evidence/{evidence_id}/retry-transcription", response_model=schemas.Evidence) async def retry_transcription( evidence_id: int, background_tasks: BackgroundTasks, db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user) ): db_evidence = db.query(Evidence).filter(Evidence.id == evidence_id).first() if not db_evidence: raise HTTPException(status_code=404, detail="Evidence not found") if not db_evidence.media_type or "audio" not in db_evidence.media_type: raise HTTPException(status_code=400, detail="Only audio evidence can be transcribed") # Update status to pending db_evidence.transcription_status = "pending" db_evidence.transcription = None db.commit() db.refresh(db_evidence) # Queue transcription task from app.services.transcription_worker import process_transcription background_tasks.add_task(process_transcription, db_evidence.id) return db_evidence @router.put("/evidence/{evidence_id}", response_model=schemas.Evidence) def update_evidence( evidence_id: int, evidence: schemas.EvidenceUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user) ): db_evidence = db.query(Evidence).filter(Evidence.id == evidence_id).first() if not db_evidence: raise HTTPException(status_code=404, detail="Evidence not found") update_data = evidence.dict(exclude_unset=True) for key, value in update_data.items(): setattr(db_evidence, key, value) db.commit() db.refresh(db_evidence) return db_evidence @router.delete("/evidence/{evidence_id}") def delete_evidence( evidence_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_active_user) ): db_evidence = db.query(Evidence).filter(Evidence.id == evidence_id).first() if not db_evidence: raise HTTPException(status_code=404, detail="Evidence not found") # Optional: Delete file from disk if db_evidence.file_path and os.path.exists(db_evidence.file_path): try: os.remove(db_evidence.file_path) except: pass db.delete(db_evidence) db.commit() return {"detail": "Evidence deleted"}