Wire up Errors tab in Auditing: auto-create ErrorItem on Analysis Error
- Create ErrorItem record when proof analysis results in "Analysis Error" status - Add submitter_name/submitter_agency fields to ErrorItemResponse schema - Eager-load proof creator and agency in error items query to avoid N+1 - Populate submitter fields from proof creator in the API route - Update frontend ErrorItemResponse type and conversion to map submitter fields - Fix ErrorsTable proof name styling to blue link (text-active-blue) matching Flags tab Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
9ec892b46b
commit
220a97ab57
6 changed files with 24 additions and 5 deletions
|
|
@ -475,6 +475,8 @@ async def list_error_items(
|
|||
id=item.id,
|
||||
proof_version_id=item.proof_version_id,
|
||||
error_summary=item.error_summary,
|
||||
submitter_name=item.proof_version.proof.created_by_user.name if item.proof_version and item.proof_version.proof and item.proof_version.proof.created_by_user else None,
|
||||
submitter_agency=item.proof_version.proof.created_by_user.agency.name if item.proof_version and item.proof_version.proof and item.proof_version.proof.created_by_user and item.proof_version.proof.created_by_user.agency else None,
|
||||
campaign_name=item.proof_version.proof.campaign.name if item.proof_version and item.proof_version.proof and item.proof_version.proof.campaign else None,
|
||||
proof_name=item.proof_version.proof.proof_name if item.proof_version and item.proof_version.proof else None,
|
||||
version=item.proof_version.version if item.proof_version else None,
|
||||
|
|
|
|||
|
|
@ -129,6 +129,8 @@ class ErrorItemResponse(BaseModel):
|
|||
id: uuid.UUID
|
||||
proof_version_id: uuid.UUID
|
||||
error_summary: Optional[str]
|
||||
submitter_name: Optional[str]
|
||||
submitter_agency: Optional[str]
|
||||
campaign_name: Optional[str]
|
||||
proof_name: Optional[str]
|
||||
version: Optional[int]
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from sqlalchemy import select
|
|||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import selectinload
|
||||
|
||||
from app.models.models import FlaggedItem, ResolvedItem, ErrorItem, ProofVersion, Proof, Campaign
|
||||
from app.models.models import FlaggedItem, ResolvedItem, ErrorItem, ProofVersion, Proof, Campaign, User
|
||||
|
||||
|
||||
class AuditRepository:
|
||||
|
|
@ -134,6 +134,10 @@ class AuditRepository:
|
|||
selectinload(ErrorItem.proof_version)
|
||||
.selectinload(ProofVersion.proof)
|
||||
.selectinload(Proof.campaign),
|
||||
selectinload(ErrorItem.proof_version)
|
||||
.selectinload(ProofVersion.proof)
|
||||
.selectinload(Proof.created_by_user)
|
||||
.selectinload(User.agency),
|
||||
)
|
||||
.join(ProofVersion)
|
||||
.join(Proof)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from app.websocket.manager import ConnectionManager
|
|||
from app.services.analysis_service import AnalysisService
|
||||
from app.models.schemas import SubReview
|
||||
from app.models.database import async_session_factory
|
||||
from app.repositories import ProofRepository, CampaignRepository, UserRepository
|
||||
from app.repositories import ProofRepository, CampaignRepository, UserRepository, AuditRepository
|
||||
from app.services.storage_service import storage_service
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
|
@ -231,6 +231,15 @@ async def handle_analyze_message(
|
|||
is_identical_file=is_identical_file,
|
||||
)
|
||||
|
||||
# Auto-create ErrorItem when analysis results in an error
|
||||
if result.overallStatus == "Analysis Error":
|
||||
audit_repo = AuditRepository(session)
|
||||
await audit_repo.create_error_item(
|
||||
proof_version_id=version.id,
|
||||
error_summary=result.leadAgentSummary,
|
||||
)
|
||||
logger.info(f"[WEBSOCKET] Created ErrorItem for analysis error on version {version.id}")
|
||||
|
||||
await session.commit()
|
||||
proof_id = str(proof.id)
|
||||
version_id = str(version.id)
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ const ErrorsTable: React.FC<{ items: ErrorItem[], onNavigate: AuditingProps['onN
|
|||
onClick={() => onNavigate(item)}
|
||||
title={`Click to view Version ${item.version} of ${item.proofName}`}
|
||||
>
|
||||
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-black-title">{item.proofName}</td>
|
||||
<td className="px-6 py-4 whitespace-nowrap text-sm font-semibold text-active-blue">{item.proofName}</td>
|
||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-black-title">Version {item.version}</td>
|
||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-black-title">{item.submitter}</td>
|
||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-black-title">{item.submitAgency}</td>
|
||||
|
|
|
|||
|
|
@ -81,6 +81,8 @@ export interface ErrorItemResponse {
|
|||
id: string;
|
||||
proof_version_id: string;
|
||||
error_summary: string | null;
|
||||
submitter_name: string | null;
|
||||
submitter_agency: string | null;
|
||||
campaign_name: string | null;
|
||||
proof_name: string | null;
|
||||
version: number | null;
|
||||
|
|
@ -333,8 +335,8 @@ class ApiService {
|
|||
campaignName: item.campaign_name || '',
|
||||
proofName: item.proof_name || '',
|
||||
version: item.version || 1,
|
||||
submitter: '',
|
||||
submitAgency: '',
|
||||
submitter: item.submitter_name || '',
|
||||
submitAgency: item.submitter_agency || '',
|
||||
errorSummary: item.error_summary || '',
|
||||
timestamp: item.created_at,
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue