from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from app import models, schemas from app.database import get_db from app.services.standard_qa_service import add_audit_log, approve_raw_qa, refresh_session_counts, set_raw_status router = APIRouter(prefix="/raw-qa", tags=["raw_qa"]) def _get_raw(db: Session, raw_id: int) -> models.RawQAItem: raw = db.get(models.RawQAItem, raw_id) if not raw: raise HTTPException(status_code=404, detail="原始问答不存在") return raw @router.get("", response_model=list[schemas.RawQAItemRead]) def list_raw_qa( review_status: str | None = None, risk_level: str | None = None, session_id: int | None = None, primary_topic: str | None = None, course_stage: str | None = None, db: Session = Depends(get_db), ) -> list[models.RawQAItem]: query = db.query(models.RawQAItem) if review_status: query = query.filter(models.RawQAItem.review_status == review_status) if risk_level: query = query.filter(models.RawQAItem.risk_level == risk_level) if session_id: query = query.filter(models.RawQAItem.session_id == session_id) if primary_topic: query = query.filter(models.RawQAItem.primary_topic == primary_topic) if course_stage: query = query.filter(models.RawQAItem.course_stage == course_stage) return query.order_by(models.RawQAItem.created_at.desc()).all() @router.get("/{raw_id}", response_model=schemas.RawQAItemRead) def get_raw_qa(raw_id: int, db: Session = Depends(get_db)) -> models.RawQAItem: return _get_raw(db, raw_id) @router.patch("/{raw_id}", response_model=schemas.RawQAItemRead) def update_raw_qa(raw_id: int, payload: schemas.RawQAItemUpdate, db: Session = Depends(get_db)) -> models.RawQAItem: raw = _get_raw(db, raw_id) for key, value in payload.model_dump(exclude_unset=True).items(): setattr(raw, key, value) db.commit() db.refresh(raw) return raw @router.post("/{raw_id}/approve", response_model=schemas.RawQAItemRead) def approve(raw_id: int, payload: schemas.ReviewActionRequest | None = None, db: Session = Depends(get_db)) -> models.RawQAItem: payload = payload or schemas.ReviewActionRequest() return approve_raw_qa(db, _get_raw(db, raw_id), payload.reviewer_id, payload.comment) @router.post("/{raw_id}/revise", response_model=schemas.RawQAItemRead) def revise(raw_id: int, payload: schemas.ReviewActionRequest | None = None, db: Session = Depends(get_db)) -> models.RawQAItem: payload = payload or schemas.ReviewActionRequest() return set_raw_status( db, _get_raw(db, raw_id), models.ReviewStatus.needs_revision, models.AuditAction.revise, payload.reviewer_id, payload.comment, ) @router.post("/{raw_id}/reject", response_model=schemas.RawQAItemRead) def reject(raw_id: int, payload: schemas.ReviewActionRequest | None = None, db: Session = Depends(get_db)) -> models.RawQAItem: payload = payload or schemas.ReviewActionRequest() return set_raw_status( db, _get_raw(db, raw_id), models.ReviewStatus.rejected, models.AuditAction.reject, payload.reviewer_id, payload.comment, ) @router.post("/{raw_id}/forbid", response_model=schemas.RawQAItemRead) def forbid(raw_id: int, payload: schemas.ReviewActionRequest | None = None, db: Session = Depends(get_db)) -> models.RawQAItem: payload = payload or schemas.ReviewActionRequest() raw = _get_raw(db, raw_id) raw.suggested_to_standard_qa = False return set_raw_status( db, raw, models.ReviewStatus.forbidden, models.AuditAction.forbid, payload.reviewer_id, payload.comment, ) @router.post("/{raw_id}/mark-high-risk", response_model=schemas.RawQAItemRead) def mark_high_risk( raw_id: int, payload: schemas.ReviewActionRequest | None = None, db: Session = Depends(get_db) ) -> models.RawQAItem: payload = payload or schemas.ReviewActionRequest() raw = _get_raw(db, raw_id) before = raw.risk_level.value raw.risk_level = models.RiskLevel.high raw.suggested_to_standard_qa = False add_audit_log( db, user_id=payload.reviewer_id, target_type=models.TargetType.raw_qa, target_id=raw.id, action=models.AuditAction.mark_high_risk, before_status=before, after_status=raw.risk_level.value, comment=payload.comment, ) refresh_session_counts(db, raw.session_id) db.commit() db.refresh(raw) return raw @router.post("/{raw_id}/mark-desensitization", response_model=schemas.RawQAItemRead) def mark_desensitization( raw_id: int, payload: schemas.ReviewActionRequest | None = None, db: Session = Depends(get_db) ) -> models.RawQAItem: payload = payload or schemas.ReviewActionRequest() raw = _get_raw(db, raw_id) before = raw.desensitization_status.value raw.need_desensitization = True raw.desensitization_status = models.DesensitizationStatus.needed add_audit_log( db, user_id=payload.reviewer_id, target_type=models.TargetType.raw_qa, target_id=raw.id, action=models.AuditAction.mark_desensitization, before_status=before, after_status=raw.desensitization_status.value, comment=payload.comment, ) db.commit() db.refresh(raw) return raw