amazon-transcreation/backend/app/api/v1/output.py
DJP 98fa16bfc3 feat: complete Phase 1-2 scaffold — backend, frontend, pipeline skeleton
Full-stack Amazon AI Transcreation Platform with:
- FastAPI backend (async, PostgreSQL, Redis, Celery) with 11 DB tables
- JWT auth (SSO-ready abstract provider pattern)
- 6-agent pipeline orchestrator with deterministic modules
- Next.js 14 frontend with Amazon branding (Ember fonts, orange/dark theme)
- Job wizard, monitoring HUD, output review, admin screens
- 154 TM/reference files imported, 12 locales configured
- Docker Compose for all services

Agents 2-5 (TM retrieval, ranker, transcreator, compliance) are stubs
pending Phase 3 LLM integration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 12:31:43 -04:00

84 lines
2.8 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.feedback_service import FeedbackService
from app.services.output_service import OutputService
router = APIRouter(prefix="/output", tags=["output"])
output_service = OutputService()
feedback_service = FeedbackService()
@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"]
)
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",
)