Skip to content

workflow: approval prediction — expose in query detail + review queue + WS event #653

Description

@babltiga

Part of #645 (approval-outcome prediction epic — read it first for the big picture).

Goal

Expose the prediction on the read side: the query detail endpoint, the review queue list, and a realtime WebSocket event so open pages refresh when a prediction lands. Backend only — the UI is the next sub-issue.

Depends on the core.api sub-issue.

Steps

Copy the AF-624 cost-estimate exposure pattern throughout — it walked exactly this path.

  1. core/api/QueryDetailView.java — add a nested record ApprovalPredictionDetail(UUID id, Double probability, boolean skipped, String skippedReason, boolean failed, Instant createdAt) and a new field. Add a backward-compatible constructor delegating with null, exactly like the existing cost-estimate constructor chain — don't break existing callers.
  2. core/internal/DefaultQueryRequestLookupService.java — populate it via ApprovalPredictionLookupService (see how toCostEstimateDetail joins the estimate).
  3. workflow/internal/web/QueryDetailResponse.java — add an approval_prediction sub-record (snake_case JSON) with a from(...) mapper; null when no row yet (frontend shows "pending").
  4. Review queue: add nullable approvalProbability to workflow.api.ReviewService.PendingReview and workflow/internal/web/PendingReviewItem. Populate in workflow/internal/DefaultReviewService with one batch call findByQueryRequestIds(...) over the page of queue items — never a per-row lookup (N+1).
  5. Realtime: in realtime/internal/RealtimeEventDispatcher, consume core/events/ApprovalPredictionCompletedEvent → emit query.prediction_complete to the relevant users (mirror the existing query.estimate_complete handler).
  6. Docs: docs/04-api-spec.md — add the approval_prediction block to the query-detail response example, the approval_probability field to the review-queue item, and the query.prediction_complete WS event to the events table.

Acceptance criteria

  • Updated mapper/unit tests: QueryDetailResponse mapping (present / null / skipped / failed variants), PendingReviewItem mapping, DefaultReviewService batch-lookup test (verify a single findByQueryRequestIds call), RealtimeEventDispatcher test for the new event.
  • Springdoc @Operation/@ApiResponse annotations remain accurate on touched controllers.
  • mvn test -Dtest=ApplicationModulesTest and -Dtest=ApiPackageDependencyTest pass.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions