Files
resolutionflow/backend/app/api/endpoints/session_resolutions.py
chihlasm a928901a2f feat: add resolution output API endpoints
Adds GET /outputs, PATCH /outputs/{id}, and POST /outputs/{id}/push
endpoints under /ai-sessions/{session_id}/, plus integration tests.
Router registered before ai_sessions to avoid path conflict.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 08:47:09 +00:00

81 lines
2.8 KiB
Python

"""Resolution output endpoints."""
import logging
from typing import Annotated
from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.api.deps import get_current_active_user, get_db
from app.models.user import User
from app.models.session_resolution_output import SessionResolutionOutput
from app.services.resolution_output_generator import ResolutionOutputGenerator
from app.schemas.session_resolution import (
ResolutionOutputResponse,
ResolutionOutputEditRequest,
ResolutionOutputPushRequest,
ResolutionOutputPushResponse,
AllResolutionOutputsResponse,
)
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/ai-sessions/{session_id}", tags=["session-resolutions"])
@router.get("/outputs", response_model=AllResolutionOutputsResponse)
async def get_outputs(
session_id: UUID,
current_user: Annotated[User, Depends(get_current_active_user)],
db: Annotated[AsyncSession, Depends(get_db)],
) -> AllResolutionOutputsResponse:
result = await db.execute(
select(SessionResolutionOutput)
.where(SessionResolutionOutput.session_id == session_id)
.order_by(SessionResolutionOutput.output_type)
)
outputs = result.scalars().all()
return AllResolutionOutputsResponse(
outputs=[ResolutionOutputResponse.model_validate(o) for o in outputs]
)
@router.patch("/outputs/{output_id}", response_model=ResolutionOutputResponse)
async def edit_output(
session_id: UUID,
output_id: UUID,
body: ResolutionOutputEditRequest,
current_user: Annotated[User, Depends(get_current_active_user)],
db: Annotated[AsyncSession, Depends(get_db)],
) -> ResolutionOutputResponse:
gen = ResolutionOutputGenerator(db)
try:
output = await gen.edit_output(output_id, body.edited_content)
except ValueError as e:
raise HTTPException(status_code=404, detail=str(e))
await db.commit()
return ResolutionOutputResponse.model_validate(output)
@router.post("/outputs/{output_id}/push", response_model=ResolutionOutputPushResponse)
async def push_output(
session_id: UUID,
output_id: UUID,
body: ResolutionOutputPushRequest,
current_user: Annotated[User, Depends(get_current_active_user)],
db: Annotated[AsyncSession, Depends(get_db)],
) -> ResolutionOutputPushResponse:
gen = ResolutionOutputGenerator(db)
try:
output = await gen.push_output(output_id, body.destination)
except ValueError as e:
raise HTTPException(status_code=404, detail=str(e))
await db.commit()
return ResolutionOutputPushResponse(
output_id=output.id,
status=output.status,
pushed_to=output.pushed_to or body.destination,
pushed_reference=output.pushed_reference,
)