import os import shutil import uuid import datetime from fastapi import APIRouter, Depends, HTTPException, status, UploadFile, File from sqlalchemy.orm import Session from typing import List, Optional from app.db.database import get_db from app.models.models import NonConformity, Evidence import app.schemas router = APIRouter( prefix="/guest", tags=["Guest Access"] ) UPLOAD_DIR = "uploads" if not os.path.exists(UPLOAD_DIR): os.makedirs(UPLOAD_DIR) @router.get("/nc/{access_hash}", response_model=app.schemas.NonConformity) def read_guest_nc( access_hash: str, db: Session = Depends(get_db) ): db_nc = db.query(NonConformity).filter(NonConformity.access_hash == access_hash).first() if not db_nc: raise HTTPException(status_code=404, detail="Non-Conformity not found or invalid link") return db_nc @router.patch("/nc/{access_hash}", response_model=app.schemas.NonConformity) def update_guest_nc( access_hash: str, nc_update: app.schemas.NonConformityUpdate, db: Session = Depends(get_db) ): db_nc = db.query(NonConformity).filter(NonConformity.access_hash == access_hash).first() if not db_nc: raise HTTPException(status_code=404, detail="Non-Conformity not found or invalid link") # Only allow updating specific fields for guest # guest_actions, closure_description? description? # The requirement says: "Describing actions taken." -> guest_actions # "Upload evidence" -> handled by upload endpoint # We will trust the validation in schema but we might want to restrict what guests can change. # For now, let's allow updating guest_actions and maybe status if they can close it? # User said: "Add PATCH endpoint to update NC activities/closure by guest." if nc_update.guest_actions is not None: db_nc.guest_actions = nc_update.guest_actions if nc_update.closure_description is not None: db_nc.closure_description = nc_update.closure_description if nc_update.status is not None: # Maybe allow them to mark as "resolved" or something? db_nc.status = nc_update.status db.commit() db.refresh(db_nc) return db_nc @router.post("/nc/{access_hash}/upload", response_model=app.schemas.Evidence) async def upload_guest_evidence( access_hash: str, file: UploadFile = File(...), description: Optional[str] = None, db: Session = Depends(get_db) ): db_nc = db.query(NonConformity).filter(NonConformity.access_hash == access_hash).first() if not db_nc: raise HTTPException(status_code=404, detail="Non-Conformity not found or invalid link") # Generate unique filename file_ext = os.path.splitext(file.filename)[1] unique_filename = f"guest_nc_{uuid.uuid4()}{file_ext}" file_path = os.path.join(UPLOAD_DIR, unique_filename) # Save file with open(file_path, "wb") as buffer: shutil.copyfileobj(file.file, buffer) # Save to database db_evidence = Evidence( non_conformity_id=db_nc.id, file_path=file_path, media_type=file.content_type, description=description, captured_at=datetime.datetime.utcnow() ) db.add(db_evidence) db.commit() db.refresh(db_evidence) return db_evidence