Class AnnotationSetsWebService
java.lang.Object
ubic.gemma.rest.AnnotationSetsWebService
REST surface for the unified
AnnotationSet entity.
Two URL families:
- Per-dataset —
POST /datasets/{id}/annotation-sets,GET /datasets/{id}/annotation-sets,GET /datasets/{id}/annotation-sets/draft,PUT /datasets/{id}/annotation-sets/draft. JAX-RS annotations are declared onDatasetsWebServicebecause Jersey resolves/datasets/*against the class-level@Path("/datasets")and never falls through to this resource's class-level@Path("/"). The handler bodies live here; the DatasetsWebService methods delegate. - Cross-dataset —
GET /annotation-sets,GET /annotation-sets/{id},POST /annotation-sets/{id}/finalize,POST /annotation-sets/{id}/reopen,DELETE /annotation-sets/{id}. Declared here directly.
Idempotency on create is (investigation, role, runId). The
service-level attach carries the audit-conditional aspect so
an event row is emitted only on actual insert, not on retry.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classstatic classFull-payload response shape.static classThin metadata response shape (no payloadJson).static classBody ofclearDispositions(Long).static classstatic classWire shape of one per-finding ruling.static classBody forfinalizeAnnotationSet(Long, String, AnnotationSetsWebService.FinalizeRequest); optional, and one field.static classstatic classstatic classstatic classWire shape of one triage ruling.static class -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionjakarta.ws.rs.core.ResponseErase every per-finding ruling on an annotation set so it can be dispositioned again from scratch.jakarta.ws.rs.core.ResponseDelete an annotation set by id.jakarta.ws.rs.core.ResponsefinalizeAnnotationSet(Long id, String onBehalfOf, AnnotationSetsWebService.FinalizeRequest body) Mark an annotation set finalized.getAnnotationSet(Long id) Single annotation set (full payload).jakarta.ws.rs.core.ResponsegetCandidates(jakarta.ws.rs.core.UriInfo uriInfo) Screening queue: redirect to the existing/datasets?filter=curationDetails.needsAttention=truequery.jakarta.ws.rs.core.ResponsegetDispositions(Long id, boolean history) The rulings on an annotation set's findings — the standing one per finding, or the whole sequence.jakarta.ws.rs.core.ResponsegetDraftForDataset(DatasetArg<?> datasetArg, String onBehalfOf) Fetch a curator'sDRAFTfor the given dataset.jakarta.ws.rs.core.ResponseEvery ruling on an annotation set, most recent first.jakarta.ws.rs.core.ResponselistAnnotationSets(DatasetArg<?> datasetArg, String role, String source, String createdBy, String shape) List annotation sets attached to a dataset, newest first.listAnnotationSetsAcross(String role, String source, String createdBy, String kind, String status, String datasetIds, OffsetArg offsetArg, LimitArg limitArg, String sort) Cross-experiment list of annotation sets, paginated.jakarta.ws.rs.core.ResponseClear finalized status on an annotation set.jakarta.ws.rs.core.ResponseruleOnFinding(Long id, String onBehalfOf, AnnotationSetsWebService.DispositionRequest body) Record a curator's ruling on ONE finding inside an audit set.jakarta.ws.rs.core.ResponseSet where a proposal stands with its reviewer.jakarta.ws.rs.core.ResponsesubmitAnnotationSet(DatasetArg<?> datasetArg, AnnotationSetsWebService.AnnotationSetRequest body) Create or upsert an annotation set on a dataset.jakarta.ws.rs.core.ResponsetriageAnnotationSet(Long id, String onBehalfOf, AnnotationSetsWebService.TriageRequest body) Record or replace the caller's triage ruling on an annotation set.jakarta.ws.rs.core.Responsejakarta.ws.rs.core.ResponseupsertDraftForDataset(DatasetArg<?> datasetArg, String onBehalfOf, AnnotationSetsWebService.UpsertDraftRequest body) Upsert a curator'sDRAFTfor the given dataset.jakarta.ws.rs.core.ResponsewithdrawTriage(Long id, String onBehalfOf) Withdraw the caller's ruling, returning the set to un-triaged if it was the only one.
-
Constructor Details
-
AnnotationSetsWebService
public AnnotationSetsWebService()
-
-
Method Details
-
getCandidates
@GET @Path("/candidates") @PreAuthorize("hasAuthority('GROUP_CURATOR')") public jakarta.ws.rs.core.Response getCandidates(@Context jakarta.ws.rs.core.UriInfo uriInfo) Screening queue: redirect to the existing/datasets?filter=curationDetails.needsAttention=truequery. Implemented as a 302 so any query parameters the caller supplies (limit, offset, sort, etc.) pass through verbatim. -
submitAnnotationSet
public jakarta.ws.rs.core.Response submitAnnotationSet(DatasetArg<?> datasetArg, @Nullable AnnotationSetsWebService.AnnotationSetRequest body) Create or upsert an annotation set on a dataset. The body'sroledetermines the lifecycle shape:PROPOSALrequires arunId;DRAFTderives one from the current user (use the dedicated draft PUT instead for upsert semantics);SNAPSHOTgenerates a UUID whenrunIdis omitted. -
listAnnotationSets
public jakarta.ws.rs.core.Response listAnnotationSets(DatasetArg<?> datasetArg, @Nullable String role, @Nullable String source, @Nullable String createdBy, @Nullable String shape) List annotation sets attached to a dataset, newest first. Filter byrole,source,createdBy; choose response shape withshape=full|meta(defaultfull). -
getDraftForDataset
public jakarta.ws.rs.core.Response getDraftForDataset(DatasetArg<?> datasetArg, @Nullable String onBehalfOf) Fetch a curator'sDRAFTfor the given dataset. 404 if no draft exists. Convenience over the role-filtered list because the curation client hits this on every dataset open.- Parameters:
onBehalfOf- whose draft to read; seeresolveCurator(String). Reading is delegated for the same reason writing is — an agent fetching "the draft" without saying whose would get its own.
-
upsertDraftForDataset
public jakarta.ws.rs.core.Response upsertDraftForDataset(DatasetArg<?> datasetArg, @Nullable String onBehalfOf, @Nullable AnnotationSetsWebService.UpsertDraftRequest body) Upsert a curator'sDRAFTfor the given dataset. One DRAFT per (dataset, curator); body'spayloadJson+ optionalparkedElements+ optionalparentId(the PROPOSAL the draft was seeded from). Returns 201 on create, 200 on update.- Parameters:
onBehalfOf- which curator this draft belongs to; seeresolveCurator(String)
-
listAnnotationSetsAcross
@GET @Path("/annotation-sets") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_CURATOR') or hasAuthority('GROUP_ADMIN') or hasAuthority('GROUP_AGENT')") public PaginatedResponseDataObject<AnnotationSetsWebService.AnnotationSetSummaryResponse> listAnnotationSetsAcross(@QueryParam("role") @Nullable String role, @QueryParam("source") @Nullable String source, @QueryParam("createdBy") @Nullable String createdBy, @QueryParam("kind") @Nullable String kind, @QueryParam("status") @Nullable String status, @QueryParam("datasetIds") @Nullable String datasetIds, @QueryParam("offset") @DefaultValue("0") OffsetArg offsetArg, @QueryParam("limit") @DefaultValue("20") LimitArg limitArg, @QueryParam("sort") @DefaultValue("-createdAt") String sort) Cross-experiment list of annotation sets, paginated. Thin metadata projection (nopayloadJson). -
getAnnotationSet
@GET @Path("/annotation-sets/{id}") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_CURATOR') or hasAuthority('GROUP_ADMIN') or hasAuthority('GROUP_AGENT')") public ResponseDataObject<AnnotationSetsWebService.AnnotationSetResponse> getAnnotationSet(@PathParam("id") Long id) Single annotation set (full payload). -
finalizeAnnotationSet
@POST @Path("/annotation-sets/{id}/finalize") @Consumes("application/json") @Produces("application/json") @PreAuthorize("isAuthenticated()") public jakarta.ws.rs.core.Response finalizeAnnotationSet(@PathParam("id") Long id, @QueryParam("onBehalfOf") @Nullable String onBehalfOf, @Nullable AnnotationSetsWebService.FinalizeRequest body) Mark an annotation set finalized. For DRAFT this means "done editing"; for SNAPSHOT this is the curator's bless to mark the row as the polished canonical view. Idempotent: second call returns 200 with no state change. -
setAnnotationSetStatus
@PATCH @Path("/annotation-sets/{id}/status") @Consumes("application/json") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_CURATOR') or hasAuthority('GROUP_ADMIN') or hasAuthority('GROUP_AGENT')") public jakarta.ws.rs.core.Response setAnnotationSetStatus(@PathParam("id") Long id, @Nullable AnnotationSetsWebService.StatusRequest body) Set where a proposal stands with its reviewer. -
triageAnnotationSet
@PATCH @Path("/annotation-sets/{id}/triage") @Consumes("application/json") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_CURATOR') or hasAuthority('GROUP_ADMIN') or hasAuthority('GROUP_AGENT')") public jakarta.ws.rs.core.Response triageAnnotationSet(@PathParam("id") Long id, @QueryParam("onBehalfOf") @Nullable String onBehalfOf, @Nullable AnnotationSetsWebService.TriageRequest body) Record or replace the caller's triage ruling on an annotation set.Idempotent per judge: a second call from the same judge updates their standing ruling rather than adding one, so a curator changing their mind leaves one row and not a history.
-
withdrawTriage
@DELETE @Path("/annotation-sets/{id}/triage") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_CURATOR') or hasAuthority('GROUP_ADMIN') or hasAuthority('GROUP_AGENT')") public jakarta.ws.rs.core.Response withdrawTriage(@PathParam("id") Long id, @QueryParam("onBehalfOf") @Nullable String onBehalfOf) Withdraw the caller's ruling, returning the set to un-triaged if it was the only one. 204 whether or not a row was there -- a withdrawal that finds nothing has still achieved what it asked for. -
getTriage
@GET @Path("/annotation-sets/{id}/triage") @Produces("application/json") @PreAuthorize("isAuthenticated()") public jakarta.ws.rs.core.Response getTriage(@PathParam("id") Long id) Every ruling on an annotation set, most recent first. The head of the list is the effective verdict. -
ruleOnFinding
@POST @Path("/annotation-sets/{id}/dispositions") @Consumes("application/json") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_CURATOR') or hasAuthority('GROUP_ADMIN') or hasAuthority('GROUP_AGENT')") public jakarta.ws.rs.core.Response ruleOnFinding(@PathParam("id") Long id, @QueryParam("onBehalfOf") @Nullable String onBehalfOf, @Nullable AnnotationSetsWebService.DispositionRequest body) Record a curator's ruling on ONE finding inside an audit set.Append-only: a curator who changes their mind adds a row rather than replacing one, and the read folds to the newest per finding.
-
getDispositions
@GET @Path("/annotation-sets/{id}/dispositions") @Produces("application/json") @PreAuthorize("isAuthenticated()") public jakarta.ws.rs.core.Response getDispositions(@PathParam("id") Long id, @QueryParam("history") @DefaultValue("false") boolean history) The rulings on an annotation set's findings — the standing one per finding, or the whole sequence. -
clearDispositions
@DELETE @Path("/annotation-sets/{id}/dispositions") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_CURATOR')") public jakarta.ws.rs.core.Response clearDispositions(@PathParam("id") Long id) Erase every per-finding ruling on an annotation set so it can be dispositioned again from scratch. -
reopenAnnotationSet
@POST @Path("/annotation-sets/{id}/reopen") @Consumes("application/json") @Produces("application/json") @PreAuthorize("isAuthenticated()") public jakarta.ws.rs.core.Response reopenAnnotationSet(@PathParam("id") Long id) Clear finalized status on an annotation set. Idempotent. -
updateAnnotationSetProvenance
@PATCH @Path("/annotation-sets/{id}") @Consumes("application/json") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_CURATOR') or hasAuthority('GROUP_ADMIN') or hasAuthority('GROUP_AGENT')") public jakarta.ws.rs.core.Response updateAnnotationSetProvenance(@PathParam("id") Long id, @Nullable AnnotationSetsWebService.ProvenanceRequest body) -
deleteAnnotationSet
@DELETE @Path("/annotation-sets/{id}") @Produces("application/json") @PreAuthorize("hasAuthority('GROUP_CURATOR') or hasAuthority('GROUP_ADMIN')") public jakarta.ws.rs.core.Response deleteAnnotationSet(@PathParam("id") Long id) Delete an annotation set by id. Descendants survive with theirparentcleared via FKON DELETE SET NULL.
-