Create/list/resolve endpoints for tracking AI-applied changes to flows. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
80 lines
2.5 KiB
Python
80 lines
2.5 KiB
Python
"""AI Suggestion audit trail endpoints."""
|
|
from uuid import UUID
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
from sqlalchemy import select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from datetime import datetime, timezone
|
|
|
|
from app.api.deps import get_current_active_user, get_db
|
|
from app.models.user import User
|
|
from app.models.ai_suggestion import AISuggestion
|
|
from app.schemas.ai_suggestion import (
|
|
AISuggestionCreate,
|
|
AISuggestionResponse,
|
|
AISuggestionResolve,
|
|
)
|
|
|
|
router = APIRouter(prefix="/ai/suggestions", tags=["ai-suggestions"])
|
|
|
|
|
|
@router.get("/tree/{tree_id}", response_model=list[AISuggestionResponse])
|
|
async def list_suggestions(
|
|
tree_id: UUID,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: User = Depends(get_current_active_user),
|
|
):
|
|
"""List all suggestions for a flow, filtered to current user."""
|
|
result = await db.execute(
|
|
select(AISuggestion)
|
|
.where(AISuggestion.tree_id == tree_id, AISuggestion.user_id == current_user.id)
|
|
.order_by(AISuggestion.created_at.desc())
|
|
)
|
|
return result.scalars().all()
|
|
|
|
|
|
@router.post("", response_model=AISuggestionResponse, status_code=201)
|
|
async def create_suggestion(
|
|
data: AISuggestionCreate,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: User = Depends(get_current_active_user),
|
|
):
|
|
"""Record a new AI suggestion."""
|
|
suggestion = AISuggestion(
|
|
tree_id=data.tree_id,
|
|
user_id=current_user.id,
|
|
session_id=data.session_id,
|
|
action_type=data.action_type,
|
|
target_node_id=data.target_node_id,
|
|
changes_json=data.changes_json,
|
|
)
|
|
db.add(suggestion)
|
|
await db.commit()
|
|
await db.refresh(suggestion)
|
|
return suggestion
|
|
|
|
|
|
@router.patch("/{suggestion_id}", response_model=AISuggestionResponse)
|
|
async def resolve_suggestion(
|
|
suggestion_id: UUID,
|
|
data: AISuggestionResolve,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: User = Depends(get_current_active_user),
|
|
):
|
|
"""Accept or dismiss a suggestion."""
|
|
result = await db.execute(
|
|
select(AISuggestion).where(
|
|
AISuggestion.id == suggestion_id,
|
|
AISuggestion.user_id == current_user.id,
|
|
)
|
|
)
|
|
suggestion = result.scalar_one_or_none()
|
|
if not suggestion:
|
|
raise HTTPException(status_code=404, detail="Suggestion not found")
|
|
|
|
suggestion.status = data.status
|
|
suggestion.resolved_at = datetime.now(timezone.utc)
|
|
await db.commit()
|
|
await db.refresh(suggestion)
|
|
return suggestion
|