from typing import List, Optional from sqlalchemy.orm import Session from app.db.crud import CRUDBase from app.models.tomato import TomatoImage, AnalysisResult, SeverityDetail from app.schemas.tomato import TomatoImageCreate, AnalysisResultCreate, SeverityDetailCreate class CRUDTomatoImage(CRUDBase[TomatoImage, TomatoImageCreate, TomatoImageCreate]): def get_by_path(self, db: Session, *, file_path: str) -> Optional[TomatoImage]: return db.query(TomatoImage).filter(TomatoImage.file_path == file_path).first() class CRUDAnalysisResult(CRUDBase[AnalysisResult, AnalysisResultCreate, AnalysisResultCreate]): def get_for_image(self, db: Session, *, image_id: str) -> List[AnalysisResult]: return db.query(AnalysisResult).filter(AnalysisResult.image_id == image_id).all() def create_with_details( self, db: Session, *, analysis_in: AnalysisResultCreate, details_in: List[SeverityDetailCreate] ) -> AnalysisResult: # Create the analysis result analysis_obj = self.create(db=db, obj_in=analysis_in) # Create severity details linked to this analysis for detail in details_in: severity_obj = SeverityDetail( analysis_id=analysis_obj.id, severity_class=detail.severity_class, confidence=detail.confidence, affected_area_percentage=detail.affected_area_percentage ) db.add(severity_obj) db.commit() db.refresh(analysis_obj) return analysis_obj class CRUDSeverityDetail(CRUDBase[SeverityDetail, SeverityDetailCreate, SeverityDetailCreate]): def get_for_analysis(self, db: Session, *, analysis_id: str) -> List[SeverityDetail]: return db.query(SeverityDetail).filter(SeverityDetail.analysis_id == analysis_id).all() tomato_image = CRUDTomatoImage(TomatoImage) analysis_result = CRUDAnalysisResult(AnalysisResult) severity_detail = CRUDSeverityDetail(SeverityDetail)