Interface AnnotationSetDispositionService

All Known Implementing Classes:
AnnotationSetDispositionServiceImpl

public interface AnnotationSetDispositionService
A curator's rulings on the individual findings inside an audit AnnotationSet.

🛑 decidedBy is the curator, not the caller. Curation writes reach Gemma through the curation agent rather than from the curator's browser, so the authenticated principal on these calls is normally the agent acting on someone's behalf. Every identity here is passed in explicitly and never read from the security context — the same rule, for the same reasons, as AnnotationSetTriageService. The REST layer decides who may claim to be whom.

Rulings are append-only; standingFor(AnnotationSet) applies the latest-wins fold.

  • Method Details

    • rule

      AnnotationSetDisposition rule(AnnotationSet annotationSet, String targetId, @Nullable String findingId, FindingDisposition disposition, String decidedBy, TriageJudgeKind judgeKind, @Nullable String reason)
      Record a ruling on one finding. Always a new row: a curator changing their mind adds to the history rather than overwriting it.
      Parameters:
      targetId - the target, in the producer's own numbering. Opaque — the payload is never parsed here, so an id naming no finding is accepted and only the producer can tell.
      findingId - which finding, when the producer supplies one. Opaque, like targetId. A target does NOT name a finding — one target routinely carries several, and two of them can be actionable — so a ruling keyed on the target alone cannot say what it ruled on. Null keeps the row target-keyed, which is what pre-existing rows and producers not emitting ids get.
      decidedBy - the ruling identity — a username for a person, a run id for an agent. Never the transport's principal.
      judgeKind - stored rather than inferred from decidedBy, so "has a person ruled on this" does not depend on knowing every agent run id.
      reason - why; what the agent needs in order to stop emitting a finding it got wrong. Optional on FindingDisposition.ACCEPTED and FindingDisposition.DISMISSED, REQUIRED on FindingDisposition.NEEDS_MORE_INFO — see below. Free text either way; there is no vocabulary.
      Throws:
      IllegalArgumentException - if disposition is FindingDisposition.NEEDS_MORE_INFO and no non-blank reason came with it. That value's entire content IS the reason: without the blocker, "a human looked and stopped" cannot be told apart from nobody having looked, which is the collapse that having no stored PENDING exists to prevent.
      IllegalStateException - if the set is already finalized. A review that has been closed out is not still taking rulings, and accepting one would leave a disposition dated after the finalization that produced the summary. Reopen the set first.
    • findBySet

      List<AnnotationSetDisposition> findBySet(AnnotationSet annotationSet)
      Every ruling on one set, most recent first — the full log, superseded rulings included.
    • historyFor

      List<AnnotationSetDisposition> historyFor(AnnotationSet annotationSet, String targetId)
      Every ruling on one finding, most recent first. The head is the standing ruling.
    • standingFor

      List<AnnotationSetDisposition> standingFor(AnnotationSet annotationSet)
      The standing ruling for each finding in one set — the most recent per finding id, or per target id for rows carrying no finding id. The two are separate buckets: a ruling on a finding never supersedes a ruling on a target, or the reverse.
    • standingForIds

      Map<Long, List<AnnotationSetDisposition>> standingForIds(Collection<Long> annotationSetIds)
      Batched standingFor(AnnotationSet), keyed by annotation set id. One round-trip for a whole page rather than one query per set.
    • clearDispositions

      int clearDispositions(AnnotationSet annotationSet)
      Erase every ruling on one set, so it can be dispositioned again from scratch. Returns how many rows went.

      🛑 A do-over after a FAULT, not a curator changing their mind. The rulings on a rebuilt calibration package, or ones taken through a wire-schema bug, record a mistake rather than a decision; superseding them one by one would preserve exactly the noise the caller is trying to be rid of. A curator who has reconsidered calls rule(AnnotationSet, String, String, FindingDisposition, String, TriageJudgeKind, String) again and the append-only history keeps both.

      This does NOT undo design edits a curator made in response to those rulings. Those live in the draft, and discarding the draft is a separate act.

      Returns:
      how many rulings were deleted; 0 when there were none