Replace mock chart data on reports page with real backend queries (jobs over time, locale stats, usage stats, quality metrics). Add audit logging to auth (login/login_failed), file management (upload/delete TM and reference files), and feedback submission so the system logs page shows complete activity. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
92 lines
3.1 KiB
Python
92 lines
3.1 KiB
Python
from uuid import UUID
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from fastapi.responses import FileResponse
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.dependencies import get_current_user, get_db
|
|
from app.schemas.feedback import FeedbackCreate, FeedbackResponse
|
|
from app.schemas.output import OutputPreviewResponse
|
|
from app.services.audit_service import AuditService
|
|
from app.services.feedback_service import FeedbackService
|
|
from app.services.output_service import OutputService
|
|
|
|
router = APIRouter(prefix="/output", tags=["output"])
|
|
output_service = OutputService()
|
|
feedback_service = FeedbackService()
|
|
audit_service = AuditService()
|
|
|
|
|
|
@router.get(
|
|
"/jobs/{job_id}/locales/{locale_code}/preview",
|
|
response_model=OutputPreviewResponse,
|
|
)
|
|
async def get_output_preview(
|
|
job_id: UUID,
|
|
locale_code: str,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: dict = Depends(get_current_user),
|
|
) -> OutputPreviewResponse:
|
|
"""Get preview data for a locale instance output."""
|
|
preview = await output_service.get_preview(db, job_id, locale_code)
|
|
if preview is None:
|
|
raise HTTPException(
|
|
status_code=404,
|
|
detail="No output found for this job/locale combination",
|
|
)
|
|
return preview
|
|
|
|
|
|
@router.post(
|
|
"/feedback",
|
|
response_model=FeedbackResponse,
|
|
status_code=status.HTTP_201_CREATED,
|
|
)
|
|
async def create_feedback(
|
|
body: FeedbackCreate,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: dict = Depends(get_current_user),
|
|
) -> FeedbackResponse:
|
|
"""Submit feedback on an output row."""
|
|
feedback = await feedback_service.create_feedback(
|
|
db, body, current_user["user_id"]
|
|
)
|
|
await audit_service.log(
|
|
db, action="feedback", entity_type="output_row", entity_id=str(body.output_row_id),
|
|
user_id=current_user["user_id"],
|
|
details={"flag_type": body.flag_type.value, "comment": body.comment},
|
|
)
|
|
await db.commit()
|
|
return FeedbackResponse.model_validate(feedback)
|
|
|
|
|
|
@router.get("/feedback/{output_id}", response_model=list[FeedbackResponse])
|
|
async def list_feedback_for_output(
|
|
output_id: UUID,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: dict = Depends(get_current_user),
|
|
) -> list[FeedbackResponse]:
|
|
"""List all feedback for a specific output row."""
|
|
items = await feedback_service.list_feedback(db, output_id=output_id)
|
|
return [FeedbackResponse.model_validate(f) for f in items]
|
|
|
|
|
|
@router.get("/jobs/{job_id}/locales/{locale_code}/export")
|
|
async def export_output(
|
|
job_id: UUID,
|
|
locale_code: str,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: dict = Depends(get_current_user),
|
|
) -> FileResponse:
|
|
"""Export output as xlsx for a locale instance."""
|
|
file_path = await output_service.trigger_export(db, job_id, locale_code)
|
|
if file_path is None:
|
|
raise HTTPException(
|
|
status_code=404,
|
|
detail="No export available for this job/locale combination",
|
|
)
|
|
return FileResponse(
|
|
path=file_path,
|
|
filename=f"{job_id}_{locale_code}_output.xlsx",
|
|
media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
)
|