from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from typing import List, Optional from datetime import datetime from database.database import get_db from database.models import Issue, IssueStatus, User, UserRole from database import schemas from routers.auth import get_current_user from services.file_service import save_base64_image, delete_file router = APIRouter(prefix="/api/issues", tags=["issues"]) @router.post("/", response_model=schemas.Issue) async def create_issue( issue: schemas.IssueCreate, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): # 이미지 저장 photo_path = None if issue.photo: photo_path = save_base64_image(issue.photo) # Issue 생성 db_issue = Issue( category=issue.category, description=issue.description, photo_path=photo_path, reporter_id=current_user.id, status=IssueStatus.NEW ) db.add(db_issue) db.commit() db.refresh(db_issue) return db_issue @router.get("/", response_model=List[schemas.Issue]) async def read_issues( skip: int = 0, limit: int = 100, status: Optional[IssueStatus] = None, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): query = db.query(Issue) # 일반 사용자는 자신의 이슈만 조회 if current_user.role == UserRole.USER: query = query.filter(Issue.reporter_id == current_user.id) if status: query = query.filter(Issue.status == status) issues = query.offset(skip).limit(limit).all() return issues @router.get("/{issue_id}", response_model=schemas.Issue) async def read_issue( issue_id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): issue = db.query(Issue).filter(Issue.id == issue_id).first() if not issue: raise HTTPException(status_code=404, detail="Issue not found") # 권한 확인 if current_user.role == UserRole.USER and issue.reporter_id != current_user.id: raise HTTPException(status_code=403, detail="Not authorized to view this issue") return issue @router.put("/{issue_id}", response_model=schemas.Issue) async def update_issue( issue_id: int, issue_update: schemas.IssueUpdate, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): issue = db.query(Issue).filter(Issue.id == issue_id).first() if not issue: raise HTTPException(status_code=404, detail="Issue not found") # 권한 확인 if current_user.role == UserRole.USER and issue.reporter_id != current_user.id: raise HTTPException(status_code=403, detail="Not authorized to update this issue") # 업데이트 update_data = issue_update.dict(exclude_unset=True) # 사진이 업데이트되는 경우 처리 if "photo" in update_data: # 기존 사진 삭제 if issue.photo_path: delete_file(issue.photo_path) # 새 사진 저장 if update_data["photo"]: photo_path = save_base64_image(update_data["photo"]) update_data["photo_path"] = photo_path else: update_data["photo_path"] = None # photo 필드는 제거 (DB에는 photo_path만 저장) del update_data["photo"] # work_hours가 입력되면 자동으로 상태를 complete로 변경 if "work_hours" in update_data and update_data["work_hours"] > 0: if issue.status == IssueStatus.NEW: update_data["status"] = IssueStatus.COMPLETE for field, value in update_data.items(): setattr(issue, field, value) db.commit() db.refresh(issue) return issue @router.delete("/{issue_id}") async def delete_issue( issue_id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): issue = db.query(Issue).filter(Issue.id == issue_id).first() if not issue: raise HTTPException(status_code=404, detail="Issue not found") # 권한 확인 (관리자만 삭제 가능) if current_user.role != UserRole.ADMIN: raise HTTPException(status_code=403, detail="Only admin can delete issues") # 이미지 파일 삭제 if issue.photo_path: delete_file(issue.photo_path) db.delete(issue) db.commit() return {"detail": "Issue deleted successfully"} @router.get("/stats/summary") async def get_issue_stats( current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """이슈 통계 조회""" query = db.query(Issue) # 일반 사용자는 자신의 이슈만 if current_user.role == UserRole.USER: query = query.filter(Issue.reporter_id == current_user.id) total = query.count() new = query.filter(Issue.status == IssueStatus.NEW).count() progress = query.filter(Issue.status == IssueStatus.PROGRESS).count() complete = query.filter(Issue.status == IssueStatus.COMPLETE).count() return { "total": total, "new": new, "progress": progress, "complete": complete }