-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extend API to save and load cohort and dataselection #374
Comments
DisclaimerSince we decided to overhaul the query endpoint after the q4 release, here are some of my thoughts (not yet in a structured way) as a basis for discussion. I am quite sure that there are things I missed (or just do not know for now). GeneralQueries will always be saved with the criteria and at least a label. There is no longer a distinction between "query" "saved query" and the dreaded "template". CohortsCohorts are similar to our current "query", but they can not have results at any time. They must however have a label and may or may not have a description. In my opinion, we do not need to impose any limits on cohorts. Let users save as many as they want. Maybe we can offer an option to archive them or mark as favorites? Needed endpoints
Data Extractionl (DEQ part of CRTDL)Needed endpoints
QueriesQueries are a combination of CCDL query, DEQ query + label + description + results Feasibility queriesEither a CRTDL with an empty DEQ part or some other format? Needed endpoints
Data Extraction-QueriesCRTDL with filled DEQ part + label + description + results Needed endpoints
Questions
|
it was decided to drop the prvious saving mechanism and from now on only save a CRTDL, which may or may not be filled out fully. therefore the following changes will be required:
|
@kleinertp, @mgebhardttmf: should there still be a restriction on how many queries a user can save with a result ? |
Following todays discussion, the suggestion in the earlier comment will be changed to: DisclaimerThe requirements have now become clear(er), but this is still just a proposal as a foundation for further discussion/specification. GeneralQueries will always be saved with the criteria and at least a label. There is no longer a distinction between "saved query" and the dreaded "template". As for the backend (basically not important here, but just for the sake of clarification), this will lead to the following changes:
NamingCohortsCohorts are simply CRTDL entities without a dataExtraction part. Query annotationsA label, description and results Data QueriesData Queries are CRTDL queries with both CCDL and dataExtraction parts Saved QueriesSaved queries are Data Queries + Query Annotations Needed endpointsBasically the same api but all query objects are now CRTDL objects.
|
@michael-82 |
@michael-82
|
@juliangruendner I changed the entry above accordingly. Please check if it is now the way it should be |
@michael-82 some changes are still necessary:
|
@juliangruendner I changed the post accordingly. However, I do not yet have a good idea for naming the results endpoints, but I agree that we should probably do that. |
Update after discussion from 2025-02-05After further consideration, the following was "decided" (still preliminary if anything comes up) GeneralIn the backend we distinguish between "data query" and "feasibiliy query" (maybe a better wording could be found). Feasibility queries are (right now) the only kind of query that will be sent somewhere. User side of the storyThe user can (without knowing what's under the hood) create / read / update / delete CRTDLs (called "Data Query"). Basically this is like the template idea from earlier. There will be no necessary validation of anything. The only additional thing that is needed is a name for the query when stored. Query "states"So basically we have 3 different types of "saved query" (like we had earlier...but it will hopefully be clearer to the user what is up)
Question: It was made clear by @kleinertp that the appsfactory app must be able to retrieve queries with or without result (so state 2+3). Should the limit of N queries be imposed on both types? Or just on the one with results? Feasibility onlyIt must also still be possible to execute a feasibility query without creating a CRTDL query first. This will simply use the same endpoint as spawning a feasibility query from a CRTDL does. In this case, the old behaviour from the well known dataportal occurs. The user can still save this as a CRTDL afterwards, but it is not necessary. In this case the create endpoint from earlier can be used. In this case, the feasibility query will instantly be linked. If the result shall be saved alongside, this should be 2 calls from the frontend to the backend (up for discussion however...maybe we could put something up to do it all in one call) RESTAs for the REST endpoints this would lead to the following (a swagger file will follow to better illustrate it) Note: In order to include links to (or information from) the feasibility query and/or result we must either provide multiple resources to read all that or wrap the CRTDL in one more layer that holds that information. Paths 1POST ../dataquery (accepts json...does not validate) save a data query GET ../dataquery/{id} load one data query. if a feasibility query is linked to that, include this information (if we go for an additional wrapper around the crtdl) PUT ../dataquery/{id} - (accepts json...does not validate) update a data query. Only possible if no feasibility query is linked to it. GET ../dataquery/saved-query-slots - basically as is POST ../query/feasibility - the "old" execute query endpoint. accepts VALID ccdl GET ../query/feasibilty/{id}/summary-result - basically as is Another option would be to change the paths to /query Paths 2I guess it comes down to preference what to do here. For the sake of completeness I'll fully list it again here. The functionality behind it would be exactly the same. POST ../query/data (accepts json...does not validate) save a data query GET ../query/data/{id} load one data query. if a feasibility query is linked to that, include this information (if we go for an additional wrapper around the crtdl) PUT ../query/data/{id} - (accepts json...does not validate) update a data query. Only possible if no feasibility query is linked to it. GET ../query/data/saved-query-slots - basically as is POST ../query/feasibility - the "old" execute query endpoint. accepts VALID ccdl GET ../query/feasibilty/{id}/summary-result - basically as is |
Some more minor endpoints are needed - e.g. to delete the connection between a dataquery and a feasibility query. The following two open api examples already contain this. There are some open questions in it that need to be addressed. There are no differences between the two openapi files besides the different paths. Note: There might still be some inconsistencies (especially considering wording/spelling) but I wanted to put this up for discussion anyways. As always...easiest to copy the following examples to https://editor-next.swagger.io/ Option 1openapi: 3.1.0
info:
title: Dataportal Backend REST API - Query Parts only
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
version: 6.0.0
externalDocs:
description: Check out the github repository
url: https://github.com/medizininformatik-initiative/feasibility-backend
servers:
- url: https://to.be.defined
variables:
basePath:
default: /api/v5
paths:
/dataquery:
post:
tags:
- dataquery
summary: Store a dataquery in the backend.
description: The query will only be stored, nothing will be dispatched. Does not have to pass any validation and may be incomplete
operationId: storeDataQuery
requestBody:
description: CRTDL
content:
application/json:
schema:
$ref: "#/components/schemas/CRTDL"
required: true
responses:
201:
description: Dataquery successfully stored
headers:
Location:
description: Path to the result of your newly created dataquery
schema:
type: string
examples:
- https://my-dataportal-backend/api/v5/dataquery/42
content: {}
401:
description: Unauthorized - please login first
422:
description: Invalid input
security:
- dataportal_auth:
- user
get:
tags:
- dataquery
summary: Get the list of the calling users dataqueries
description: This returns a list with basic information about the queries. Id, label (if present) and creation date. Basically for all parameters I'm not sure if we need them (at least right away)
operationId: getDataQueryList
parameters:
- name: filter
in: query
description: filters query...either for those with linked feasibility and or results? Or by name?
required: false
schema:
type: string
enum:
- feasibility
- name: skip-validation
in: query
description: If true, do not validate the query and do not include a list of invalid terms. TODO - maybe invert this?
required: false
schema:
type: boolean
default: false
- name: limit
in: query
description: How many queries to retrieve
required: false
schema:
type: integer
default: 20
- name: offset
in: query
description: Where to start the list of queries
required: false
schema:
type: integer
default: 0
responses:
200:
description: successful operation
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/DataQueryListEntry"
401:
description: Unauthorized - please login first
security:
- dataportal_auth:
- user
/dataquery/by-user/{userId}:
get:
tags:
- dataquery
summary: Finds query summary (id, label, lastModified) of all queries of one user
operationId: findDataQueriesByUser
parameters:
- name: userId
in: path
description: User to filter by (keycloak id)
required: true
schema:
type: string
- name: filter
in: query
description: filters query...either for those with linked feasibility and or results? Or by name?
required: false
schema:
type: string
enum:
- feasibility
- name: skip-validation
in: query
description: If true, do not validate the query and do not include a list of invalid terms. TODO - maybe invert this?
required: false
schema:
type: boolean
default: false
- name: limit
in: query
description: How many queries to retrieve
required: false
schema:
type: integer
default: 20
- name: offset
in: query
description: Where to start the list of queries
required: false
schema:
type: integer
default: 0
responses:
200:
description: successful operation
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/DataQueryListEntry"
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: User not found
security:
- dataportal_auth:
- admin
/dataquery/{queryId}:
get:
tags:
- dataquery
summary: (Option A - only this one) Read dataquery by ID
description: Returns a single dataquery. Contains everything known about the query, including results and structured query
operationId: getDataQueryById
parameters:
- name: queryId
in: path
description: ID of query to return
required: true
schema:
type: integer
format: int64
- name: skip-validation
in: query
description: If true, do not validate the query and do not include a list of invalid terms
required: false
schema:
type: boolean
default: false
responses:
200:
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/CRTDLplus"
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: Query not found
security:
- dataportal_auth:
- user
- admin
put:
tags:
- dataquery
summary: Update a dataquery in the backend.
description: The query will be updated, but only if no feasibility query is linked to it. It must be provided completely, there are no partial updates.
operationId: updateDataQuery
requestBody:
description: CRTDL
content:
application/json:
schema:
$ref: "#/components/schemas/CRTDL"
required: true
responses:
200:
description: Dataquery successfully updated
content: {}
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: The dataquery could not be found
409:
description: The dataquery is linked to a feasibility query and can not be updated (or should this maybe be 400)
security:
- dataportal_auth:
- user
delete:
tags:
- dataquery
summary: Delete a dataquery (only possible if no feasibility query is linked)
operationId: deleteDataQuery
parameters:
- name: queryId
in: path
required: true
schema:
type: integer
format: int64
responses:
204:
description: No content
content:
{}
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: The dataquery could not be found
409:
description: The dataquery is linked to a feasibility query and can not be deleted (or should this maybe be 400)
/dataquery/{queryId}/crtdl:
get:
tags:
- dataquery
summary: (Option B+C - 1/3) Read dataquery CRTDL by ID
description: Returns a single dataquery. Contains only the CRTDL
operationId: getDataQueryCRTDLById
parameters:
- name: queryId
in: path
description: ID of query to return
required: true
schema:
type: integer
format: int64
- name: skip-validation
in: query
description: If true, do not validate the query and do not include a list of invalid terms
required: false
schema:
type: boolean
default: false
responses:
200:
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/CRTDL"
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: Query not found
security:
- dataportal_auth:
- user
- admin
/dataquery/{queryId}/feasibility-query:
get:
tags:
- dataquery
summary: (Option B - 2/3) Read information about feasibility query linked to dataquery by dataquery ID
description: Returns a single dataquery. Contains only the info about feasibility query
operationId: getDataQueryFeasibilityQueryById
parameters:
- name: queryId
in: path
description: ID of query to return
required: true
schema:
type: integer
format: int64
responses:
200:
description: OK
content:
application/json:
schema:
type: object
properties:
dispatchedAt:
type: string
format: date-time
example: "2025-02-06T12:34:56Z"
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: Query not found or no feasibility part available for this query
security:
- dataportal_auth:
- user
- admin
delete:
tags:
- dataquery
summary: Delete the link between the dataquery and the feasibility query. The feasibility query itself can never be deleted, only the link between the two is deleted. This also deletes a possibly saved result.
operationId: deleteFeasibilityQueryConnection
parameters:
- name: queryId
in: path
required: true
schema:
type: integer
format: int64
responses:
204:
description: Link to feasibility query was deleted (or there was none linked)
content:
{ }
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: The dataquery could not be found
/dataquery/{queryId}/feasibility-result:
get:
tags:
- dataquery
summary: (Option B - 3/3) Read information about feasibility result linked to dataquery by dataquery ID
description: Returns a single dataquery. Contains only the info about feasibility result
operationId: getDataQueryFeasibilityResultById
parameters:
- name: queryId
in: path
description: ID of query to return
required: true
schema:
type: integer
format: int64
responses:
200:
description: OK
content:
application/json:
schema:
type: object
properties:
receivedAt:
type: string
format: date-time
examples:
- "2025-02-06T12:34:56Z"
totalNumberOfResults:
type: integer
examples:
- 42
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: Query not found or no feasibility part available for this query
security:
- dataportal_auth:
- user
- admin
delete:
tags:
- dataquery
summary: Delete the link between the dataquery and the feasibility result
operationId: deleteFeasibilityQueryResult
parameters:
- name: queryId
in: path
required: true
schema:
type: integer
format: int64
responses:
204:
description: Link to feasibility result was deleted (or there was none linked)
content:
{ }
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: The dataquery could not be found
/dataquery/{queryId}/feasibility-info:
get:
tags:
- dataquery
summary: (Option C - 2/2) Read information about feasibility query and result linked to dataquery by dataquery ID
description: Returns a single dataquery. Contains only the info about feasibility query and possibly result
operationId: getDataQueryFeasibilityInfoById
parameters:
- name: queryId
in: path
description: ID of query to return
required: true
schema:
type: integer
format: int64
responses:
200:
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/FeasibilityAndResult"
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: Query not found or no feasibility part available for this query
security:
- dataportal_auth:
- user
- admin
delete:
tags:
- dataquery
summary: Delete the link between the dataquery and the feasibility query AND result.
operationId: deleteFeasibilityQueryConnectionAndResult
parameters:
- name: queryId
in: path
required: true
schema:
type: integer
format: int64
responses:
204:
description: Link to feasibility query was deleted (or there was none linked)
content:
{ }
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: The dataquery could not be found
/dataquery/saved-query-slots:
get:
tags:
- dataquery
summary: Show how many saved query slots a user already used and how many he has left.
operationId: getSavedDataQuerySlots
responses:
200:
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/SavedQuerySlots"
security:
- dataportal_auth:
- user
/query/validate:
post:
tags:
- query
- validation
summary: Validates a submitted CRTDL or just CCDL? to check for schema violations or invalid termCodes
description: It could be useful to split this in ccdl and dataquery or at least offer a parameter to determine which should be checked.
operationId: validateQuery
requestBody:
description: Query to validate
content:
application/json:
schema:
$ref: "#/components/schemas/CRTDL"
required: true
responses:
200:
description: Query adheres to json schema. If invalid termCodes are present, they will be in the response.
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/CRTDL"
400:
description: Query does not adhere to json schema
401:
description: Unauthorized - please login first
/query/feasibility/{queryId}/summary-result:
get:
tags:
- query
summary: Read query result summary by query ID
description: Returns the aggregated results to a query. There is no breakdown by site. So, the resultLines parameter of the response is de facto an array of QueryResultLines, but it will always be empty in this case.
operationId: getQueryResultSummary
parameters:
- name: queryId
in: path
description: ID of query for which the results are requested
required: true
schema:
type: integer
format: int64
responses:
200:
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/QueryResultSummary"
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: Query not found
429:
description: Too many requests
security:
- dataportal_auth:
- admin
- user
/query/feasibility/{queryId}/detailed-result:
get:
tags:
- query
summary: Read query result by ID
description: Returns results to query with the real site names - admin rights required
operationId: getQueryResultDetailed
parameters:
- name: queryId
in: path
description: ID of query for which the results are requested
required: true
schema:
type: integer
format: int64
responses:
200:
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/QueryResult"
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: Query not found
security:
- dataportal_auth:
- admin
/query/feasibility/{queryId}/detailed-obfuscated-result:
get:
tags:
- query
summary: Read obfuscated query result by ID
description: Returns all results to query with the site names obfuscated.
operationId: getQueryResultDetailedObfuscated
parameters:
- name: queryId
in: path
description: ID of query for which the results are requested
required: true
schema:
type: integer
format: int64
responses:
200:
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/QueryResultObfuscated"
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: Query not found
429:
description: Too many requests
security:
- dataportal_auth:
- admin
- user
/query/feasibility/detailed-obfuscated-result-rate-limit:
get:
summary: get the rate limit for detailed obfuscated results
operationId: getDetailedObfuscatedResultRateLimit
responses:
200:
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/QueryResultRateLimit"
/query/feasibility:
post:
tags:
- query
summary: Create a feasibility query in the broker
description: The query will be spawned in the broker and directly be dispatched. It CAN be linked to a dataquery
operationId: runQuery
parameters:
- name: dataquery-id
in: query
description: If this is a feasibility query that is spawned from a saved dataquery, provide the id of said dataquery
required: false
schema:
type: integer
examples:
- 42
requestBody:
description: Structured query to create and dispatch
content:
application/json:
schema:
$ref: "#/components/schemas/StructuredQuery"
required: true
responses:
201:
description: Query successfully dispatched
headers:
Location:
description: Path to the result of your newly created query
schema:
type: string
examples:
- https://to.be.defined/api/v5/query/42
content: {}
400:
description: If a dataquery-id was supplied but this could not be saved (either because it does not exist or already has a linked feasibility query)
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
422:
description: Invalid input
429:
description: Too many requests in a given amount of time (configurable)
500:
description: Dispatch error
security:
- dataportal_auth:
- user
x-codegen-request-body-name: body
components:
schemas:
CRTDLplus:
type: object
properties:
feasibility:
type: object
$ref: "#/components/schemas/FeasibilityAndResult"
dataQuery:
type: object
$ref: "#/components/schemas/CRTDL"
CRTDL:
type: object
properties:
display:
type: string
examples:
- Example CRTDL
cohortDefinition:
type: object
$ref: "#/components/schemas/StructuredQuery"
dataExtraction:
type: object
$ref: "#/components/schemas/DataExtractionQuery"
DataExtractionQuery:
type: object
properties:
id:
type: string
examples:
- 123
attributeGroups:
type: array
items:
type: string
examples:
- to be done correctly...for now just a placeholder because it doesn't matter for this conversation
FeasibilityAndResult:
type: object
properties:
dispatchDate:
type: string
format: date-time
resultDate:
type: string
format: date-time
totalNumberOfResults:
type: integer
DataQueryListEntry:
type: object
required:
- id
- label
properties:
id:
type: integer
format: int64
label:
type: string
comment:
type: string
createdAt:
type: string
format: date-time
totalNumberOfPatients:
type: integer
isValid:
type: boolean
Query:
type: object
required:
- id
- content
properties:
id:
type: integer
format: int64
content:
$ref: "#/components/schemas/StructuredQuery"
label:
type: string
results:
$ref: "#/components/schemas/QueryResult"
QueryResultSummary:
type: object
properties:
totalNumberOfPatients:
type: integer
format: int64
queryId:
type: string
resultLines:
type: array
items:
$ref: "#/components/schemas/QueryResultLine"
QueryResultObfuscated:
type: object
properties:
totalNumberOfPatients:
type: integer
format: int64
queryId:
type: string
resultLines:
type: array
items:
$ref: "#/components/schemas/QueryResultLineObfuscated"
QueryResult:
type: object
properties:
totalNumberOfPatients:
type: integer
format: int64
queryId:
type: string
resultLines:
type: array
items:
$ref: "#/components/schemas/QueryResultLine"
QueryResultLine:
type: object
required:
- siteName
- numberOfPatients
properties:
siteName:
type: string
numberOfPatients:
type: integer
format: int64
QueryResultLineObfuscated:
type: object
required:
- siteName
- numberOfPatients
properties:
siteName:
type: string
description: obfuscated site name
numberOfPatients:
type: integer
format: int64
QueryResultRateLimit:
type: object
properties:
limit:
type: number
format: int64
remaining:
type: number
format: int64
QueryTemplateListItem:
type: object
required:
- label
properties:
id:
type: integer
format: int64
label:
type: string
description: The 'name' of the query. Is assigned by the user via GUI.
examples:
- my-query-1
comment:
type: string
description: A more detailed information about the query. Is also assigned by the user via GUI.
examples:
- I wanted to see how many patients I could find for my study XYZ
lastModified:
type: string
format: date-time
createdBy:
type: string
description: Keycloak id of the user who created the query
isValid:
type: boolean
description: is the query valid?
QueryTemplate:
type: object
required:
- label
properties:
id:
type: integer
format: int64
label:
type: string
description: The 'name' of the query. Is assigned by the user via GUI.
examples:
- my-query-1
comment:
type: string
description: A more detailed information about the query. Is also assigned by the user via GUI.
examples:
- I wanted to see how many patients I could find for my study XYZ
content:
$ref: "#/components/schemas/StructuredQuery"
lastModified:
type: string
format: date-time
createdBy:
type: string
description: Keycloak id of the user who created the query
StructuredQuery:
type: object
required:
- version
- inclusionCriteria
properties:
version:
type: string
format: uri
description: The json schema version
examples:
- http://to_be_decided.com/draft-1/schema#
display:
type: string
examples:
- foobar
inclusionCriteria:
type: array
items:
$ref: "#/components/schemas/CriterionList"
exclusionCriteria:
type: array
items:
$ref: "#/components/schemas/CriterionList"
SavedQuery:
type: object
required:
- label
properties:
label:
type: string
description: The 'name' of the query. Is assigned by the user via GUI.
examples:
- my-query-1
comment:
type: string
description: A more detailed information about the query. Is also assigned by the user via GUI.
examples:
- I wanted to see how many patients I could find for my study XYZ
totalNumberOfPatients:
type: integer
format: int64
description: The number of results that were found for this query.
examples:
- 12345
SavedQuerySlots:
type: object
required:
- used
- total
properties:
used:
type: integer
description: The amount of used saved query slots for a user.
examples:
- 2
total:
type: integer
description: The total amount of saved query slots per user.
examples:
- 10
TermCode:
description: The termCode defines a concept based on a coding system (i.e. LOINC). The triplet of code, system and version identify the concept.
type: object
required:
- code
- system
- display
properties:
code:
type: string
examples:
- 119373006
system:
type: string
examples:
- http://snomed.info/sct
version:
type: string
examples:
- http://snomed.info/sct/900000000000207008/version/20210731
display:
type: string
examples:
- Amniotic fluid specimen (specimen)
beforeDate:
type: string
format: date-time
afterDate:
type: string
format: date-time
TimeRestriction:
anyOf:
- $ref: "#/components/schemas/beforeDate"
- $ref: "#/components/schemas/afterDate"
Unit:
type: object
required:
- code
- display
properties:
code:
type: string
display:
type: string
AttributeFilter:
type: object
description: An AttributeFilter requires different properties, depending on the type. Please refer to the JSON Schema for this.
required:
- type
properties:
attributeCode:
$ref: "#/components/schemas/TermCode"
ValueFilter:
type: object
description: A ValueFilter requires different properties, depending on the type. Please refer to the JSON Schema for this.
required:
- type
properties:
type:
type: string
enum:
- concept
- quantity-comparator
- quantity-range
selectedConcepts:
type: array
items:
$ref: "#/components/schemas/TermCode"
comparator:
type: string
enum:
- eq
- ue
- le
- lt
- ge
- gt
unit:
$ref: "#/components/schemas/Unit"
value:
type: number
format: double
minValue:
type: number
format: double
maxValue:
type: number
format: double
Criterion:
type: object
required:
- termCodes
properties:
termCodes:
type: array
items:
$ref: "#/components/schemas/TermCode"
attributeFilters:
type: array
items:
$ref: "#/components/schemas/AttributeFilter"
valueFilter:
$ref: "#/components/schemas/ValueFilter"
timeRestriction:
$ref: "#/components/schemas/TimeRestriction"
issues:
type: array
items:
$ref: "#/components/schemas/ValidationIssue"
CriterionList:
type: array
items:
$ref: "#/components/schemas/Criterion"
ContextualizedTermCodeList:
type: object
properties:
contextualizedTermCodes:
type: array
items:
$ref: "#/components/schemas/ContextualizedTermCode"
ContextualizedTermCode:
type: object
properties:
termcode:
$ref: "#/components/schemas/TermCode"
context:
$ref: "#/components/schemas/TermCode"
ValidationIssue:
type: object
required:
- code
- detail
properties:
code:
type: string
examples:
- VAL-20001
detail:
type: string
examples:
- The combination of context and termcode(s) is not found.
securitySchemes:
dataportal_auth:
type: oauth2
flows:
implicit:
authorizationUrl: http://to.be.defined/auth
scopes:
user: Dataportal user role
admin: Dataportal admin role
Option 2openapi: 3.1.0
info:
title: Dataportal Backend REST API - Query Parts only
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
version: 6.0.0
externalDocs:
description: Check out the github repository
url: https://github.com/medizininformatik-initiative/feasibility-backend
servers:
- url: https://to.be.defined
variables:
basePath:
default: /api/v5
paths:
/query/data:
post:
tags:
- dataquery
summary: Store a dataquery in the backend.
description: The query will only be stored, nothing will be dispatched. Does not have to pass any validation and may be incomplete
operationId: storeDataQuery
requestBody:
description: CRTDL
content:
application/json:
schema:
$ref: "#/components/schemas/CRTDL"
required: true
responses:
201:
description: Dataquery successfully stored
headers:
Location:
description: Path to the result of your newly created dataquery
schema:
type: string
examples:
- https://my-dataportal-backend/api/v5/dataquery/42
content: {}
401:
description: Unauthorized - please login first
422:
description: Invalid input
security:
- dataportal_auth:
- user
get:
tags:
- dataquery
summary: Get the list of the calling users dataqueries
description: This returns a list with basic information about the queries. Id, label (if present) and creation date. Basically for all parameters I'm not sure if we need them (at least right away)
operationId: getDataQueryList
parameters:
- name: filter
in: query
description: filters query...either for those with linked feasibility and or results? Or by name?
required: false
schema:
type: string
enum:
- feasibility
- name: skip-validation
in: query
description: If true, do not validate the query and do not include a list of invalid terms. TODO - maybe invert this?
required: false
schema:
type: boolean
default: false
- name: limit
in: query
description: How many queries to retrieve
required: false
schema:
type: integer
default: 20
- name: offset
in: query
description: Where to start the list of queries
required: false
schema:
type: integer
default: 0
responses:
200:
description: successful operation
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/DataQueryListEntry"
401:
description: Unauthorized - please login first
security:
- dataportal_auth:
- user
/query/data/by-user/{userId}:
get:
tags:
- dataquery
summary: Finds query summary (id, label, lastModified) of all queries of one user
operationId: findDataQueriesByUser
parameters:
- name: userId
in: path
description: User to filter by (keycloak id)
required: true
schema:
type: string
- name: filter
in: query
description: filters query...either for those with linked feasibility and or results? Or by name?
required: false
schema:
type: string
enum:
- feasibility
- name: skip-validation
in: query
description: If true, do not validate the query and do not include a list of invalid terms. TODO - maybe invert this?
required: false
schema:
type: boolean
default: false
- name: limit
in: query
description: How many queries to retrieve
required: false
schema:
type: integer
default: 20
- name: offset
in: query
description: Where to start the list of queries
required: false
schema:
type: integer
default: 0
responses:
200:
description: successful operation
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/DataQueryListEntry"
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: User not found
security:
- dataportal_auth:
- admin
/query/data/{queryId}:
get:
tags:
- dataquery
summary: (Option A - only this one) Read dataquery by ID
description: Returns a single dataquery. Contains everything known about the query, including results and structured query
operationId: getDataQueryById
parameters:
- name: queryId
in: path
description: ID of query to return
required: true
schema:
type: integer
format: int64
- name: skip-validation
in: query
description: If true, do not validate the query and do not include a list of invalid terms
required: false
schema:
type: boolean
default: false
responses:
200:
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/CRTDLplus"
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: Query not found
security:
- dataportal_auth:
- user
- admin
put:
tags:
- dataquery
summary: Update a dataquery in the backend.
description: The query will be updated, but only if no feasibility query is linked to it. It must be provided completely, there are no partial updates.
operationId: updateDataQuery
requestBody:
description: CRTDL
content:
application/json:
schema:
$ref: "#/components/schemas/CRTDL"
required: true
responses:
200:
description: Dataquery successfully updated
content: {}
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: The dataquery could not be found
409:
description: The dataquery is linked to a feasibility query and can not be updated (or should this maybe be 400)
security:
- dataportal_auth:
- user
delete:
tags:
- dataquery
summary: Delete a dataquery (only possible if no feasibility query is linked)
operationId: deleteDataQuery
parameters:
- name: queryId
in: path
required: true
schema:
type: integer
format: int64
responses:
204:
description: No content
content:
{}
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: The dataquery could not be found
409:
description: The dataquery is linked to a feasibility query and can not be deleted (or should this maybe be 400)
/query/data/{queryId}/crtdl:
get:
tags:
- dataquery
summary: (Option B+C - 1/3) Read dataquery CRTDL by ID
description: Returns a single dataquery. Contains only the CRTDL
operationId: getDataQueryCRTDLById
parameters:
- name: queryId
in: path
description: ID of query to return
required: true
schema:
type: integer
format: int64
- name: skip-validation
in: query
description: If true, do not validate the query and do not include a list of invalid terms
required: false
schema:
type: boolean
default: false
responses:
200:
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/CRTDL"
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: Query not found
security:
- dataportal_auth:
- user
- admin
/query/data/{queryId}/feasibility-query:
get:
tags:
- dataquery
summary: (Option B - 2/3) Read information about feasibility query linked to dataquery by dataquery ID
description: Returns a single dataquery. Contains only the info about feasibility query
operationId: getDataQueryFeasibilityQueryById
parameters:
- name: queryId
in: path
description: ID of query to return
required: true
schema:
type: integer
format: int64
responses:
200:
description: OK
content:
application/json:
schema:
type: object
properties:
dispatchedAt:
type: string
format: date-time
example: "2025-02-06T12:34:56Z"
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: Query not found or no feasibility part available for this query
security:
- dataportal_auth:
- user
- admin
delete:
tags:
- dataquery
summary: Delete the link between the dataquery and the feasibility query. The feasibility query itself can never be deleted, only the link between the two is deleted. This also deletes a possibly saved result.
operationId: deleteFeasibilityQueryConnection
parameters:
- name: queryId
in: path
required: true
schema:
type: integer
format: int64
responses:
204:
description: Link to feasibility query was deleted (or there was none linked)
content:
{ }
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: The dataquery could not be found
/query/data/{queryId}/feasibility-result:
get:
tags:
- dataquery
summary: (Option B - 3/3) Read information about feasibility result linked to dataquery by dataquery ID
description: Returns a single dataquery. Contains only the info about feasibility result
operationId: getDataQueryFeasibilityResultById
parameters:
- name: queryId
in: path
description: ID of query to return
required: true
schema:
type: integer
format: int64
responses:
200:
description: OK
content:
application/json:
schema:
type: object
properties:
receivedAt:
type: string
format: date-time
examples:
- "2025-02-06T12:34:56Z"
totalNumberOfResults:
type: integer
examples:
- 42
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: Query not found or no feasibility part available for this query
security:
- dataportal_auth:
- user
- admin
delete:
tags:
- dataquery
summary: Delete the link between the dataquery and the feasibility result
operationId: deleteFeasibilityQueryResult
parameters:
- name: queryId
in: path
required: true
schema:
type: integer
format: int64
responses:
204:
description: Link to feasibility result was deleted (or there was none linked)
content:
{ }
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: The dataquery could not be found
/query/data/{queryId}/feasibility-info:
get:
tags:
- dataquery
summary: (Option C - 2/2) Read information about feasibility query and result linked to dataquery by dataquery ID
description: Returns a single dataquery. Contains only the info about feasibility query and possibly result
operationId: getDataQueryFeasibilityInfoById
parameters:
- name: queryId
in: path
description: ID of query to return
required: true
schema:
type: integer
format: int64
responses:
200:
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/FeasibilityAndResult"
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: Query not found or no feasibility part available for this query
security:
- dataportal_auth:
- user
- admin
delete:
tags:
- dataquery
summary: Delete the link between the dataquery and the feasibility query AND result.
operationId: deleteFeasibilityQueryConnectionAndResult
parameters:
- name: queryId
in: path
required: true
schema:
type: integer
format: int64
responses:
204:
description: Link to feasibility query was deleted (or there was none linked)
content:
{ }
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: The dataquery could not be found
/query/data/saved-query-slots:
get:
tags:
- dataquery
summary: Show how many saved query slots a user already used and how many he has left.
operationId: getSavedDataQuerySlots
responses:
200:
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/SavedQuerySlots"
security:
- dataportal_auth:
- user
/query/validate:
post:
tags:
- query
- validation
summary: Validates a submitted CRTDL or just CCDL? to check for schema violations or invalid termCodes
description: It could be useful to split this in ccdl and dataquery or at least offer a parameter to determine which should be checked.
operationId: validateQuery
requestBody:
description: Query to validate
content:
application/json:
schema:
$ref: "#/components/schemas/CRTDL"
required: true
responses:
200:
description: Query adheres to json schema. If invalid termCodes are present, they will be in the response.
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/CRTDL"
400:
description: Query does not adhere to json schema
401:
description: Unauthorized - please login first
/query/feasibility/{queryId}/summary-result:
get:
tags:
- query
summary: Read query result summary by query ID
description: Returns the aggregated results to a query. There is no breakdown by site. So, the resultLines parameter of the response is de facto an array of QueryResultLines, but it will always be empty in this case.
operationId: getQueryResultSummary
parameters:
- name: queryId
in: path
description: ID of query for which the results are requested
required: true
schema:
type: integer
format: int64
responses:
200:
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/QueryResultSummary"
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: Query not found
429:
description: Too many requests
security:
- dataportal_auth:
- admin
- user
/query/feasibility/{queryId}/detailed-result:
get:
tags:
- query
summary: Read query result by ID
description: Returns results to query with the real site names - admin rights required
operationId: getQueryResultDetailed
parameters:
- name: queryId
in: path
description: ID of query for which the results are requested
required: true
schema:
type: integer
format: int64
responses:
200:
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/QueryResult"
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: Query not found
security:
- dataportal_auth:
- admin
/query/feasibility/{queryId}/detailed-obfuscated-result:
get:
tags:
- query
summary: Read obfuscated query result by ID
description: Returns all results to query with the site names obfuscated.
operationId: getQueryResultDetailedObfuscated
parameters:
- name: queryId
in: path
description: ID of query for which the results are requested
required: true
schema:
type: integer
format: int64
responses:
200:
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/QueryResultObfuscated"
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
404:
description: Query not found
429:
description: Too many requests
security:
- dataportal_auth:
- admin
- user
/query/feasibility/detailed-obfuscated-result-rate-limit:
get:
summary: get the rate limit for detailed obfuscated results
operationId: getDetailedObfuscatedResultRateLimit
responses:
200:
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/QueryResultRateLimit"
/query/feasibility:
post:
tags:
- query
summary: Create a feasibility query in the broker
description: The query will be spawned in the broker and directly be dispatched. It CAN be linked to a dataquery
operationId: runQuery
parameters:
- name: dataquery-id
in: query
description: If this is a feasibility query that is spawned from a saved dataquery, provide the id of said dataquery
required: false
schema:
type: integer
examples:
- 42
requestBody:
description: Structured query to create and dispatch
content:
application/json:
schema:
$ref: "#/components/schemas/StructuredQuery"
required: true
responses:
201:
description: Query successfully dispatched
headers:
Location:
description: Path to the result of your newly created query
schema:
type: string
examples:
- https://to.be.defined/api/v5/query/42
content: {}
400:
description: If a dataquery-id was supplied but this could not be saved (either because it does not exist or already has a linked feasibility query)
401:
description: Unauthorized - please login first
403:
description: Forbidden - insufficient access rights
422:
description: Invalid input
429:
description: Too many requests in a given amount of time (configurable)
500:
description: Dispatch error
security:
- dataportal_auth:
- user
x-codegen-request-body-name: body
components:
schemas:
CRTDLplus:
type: object
properties:
feasibility:
type: object
$ref: "#/components/schemas/FeasibilityAndResult"
dataQuery:
type: object
$ref: "#/components/schemas/CRTDL"
CRTDL:
type: object
properties:
display:
type: string
examples:
- Example CRTDL
cohortDefinition:
type: object
$ref: "#/components/schemas/StructuredQuery"
dataExtraction:
type: object
$ref: "#/components/schemas/DataExtractionQuery"
DataExtractionQuery:
type: object
properties:
id:
type: string
examples:
- 123
attributeGroups:
type: array
items:
type: string
examples:
- to be done correctly...for now just a placeholder because it doesn't matter for this conversation
FeasibilityAndResult:
type: object
properties:
dispatchDate:
type: string
format: date-time
resultDate:
type: string
format: date-time
totalNumberOfResults:
type: integer
DataQueryListEntry:
type: object
required:
- id
- label
properties:
id:
type: integer
format: int64
label:
type: string
comment:
type: string
createdAt:
type: string
format: date-time
totalNumberOfPatients:
type: integer
isValid:
type: boolean
Query:
type: object
required:
- id
- content
properties:
id:
type: integer
format: int64
content:
$ref: "#/components/schemas/StructuredQuery"
label:
type: string
results:
$ref: "#/components/schemas/QueryResult"
QueryResultSummary:
type: object
properties:
totalNumberOfPatients:
type: integer
format: int64
queryId:
type: string
resultLines:
type: array
items:
$ref: "#/components/schemas/QueryResultLine"
QueryResultObfuscated:
type: object
properties:
totalNumberOfPatients:
type: integer
format: int64
queryId:
type: string
resultLines:
type: array
items:
$ref: "#/components/schemas/QueryResultLineObfuscated"
QueryResult:
type: object
properties:
totalNumberOfPatients:
type: integer
format: int64
queryId:
type: string
resultLines:
type: array
items:
$ref: "#/components/schemas/QueryResultLine"
QueryResultLine:
type: object
required:
- siteName
- numberOfPatients
properties:
siteName:
type: string
numberOfPatients:
type: integer
format: int64
QueryResultLineObfuscated:
type: object
required:
- siteName
- numberOfPatients
properties:
siteName:
type: string
description: obfuscated site name
numberOfPatients:
type: integer
format: int64
QueryResultRateLimit:
type: object
properties:
limit:
type: number
format: int64
remaining:
type: number
format: int64
QueryTemplateListItem:
type: object
required:
- label
properties:
id:
type: integer
format: int64
label:
type: string
description: The 'name' of the query. Is assigned by the user via GUI.
examples:
- my-query-1
comment:
type: string
description: A more detailed information about the query. Is also assigned by the user via GUI.
examples:
- I wanted to see how many patients I could find for my study XYZ
lastModified:
type: string
format: date-time
createdBy:
type: string
description: Keycloak id of the user who created the query
isValid:
type: boolean
description: is the query valid?
QueryTemplate:
type: object
required:
- label
properties:
id:
type: integer
format: int64
label:
type: string
description: The 'name' of the query. Is assigned by the user via GUI.
examples:
- my-query-1
comment:
type: string
description: A more detailed information about the query. Is also assigned by the user via GUI.
examples:
- I wanted to see how many patients I could find for my study XYZ
content:
$ref: "#/components/schemas/StructuredQuery"
lastModified:
type: string
format: date-time
createdBy:
type: string
description: Keycloak id of the user who created the query
StructuredQuery:
type: object
required:
- version
- inclusionCriteria
properties:
version:
type: string
format: uri
description: The json schema version
examples:
- http://to_be_decided.com/draft-1/schema#
display:
type: string
examples:
- foobar
inclusionCriteria:
type: array
items:
$ref: "#/components/schemas/CriterionList"
exclusionCriteria:
type: array
items:
$ref: "#/components/schemas/CriterionList"
SavedQuery:
type: object
required:
- label
properties:
label:
type: string
description: The 'name' of the query. Is assigned by the user via GUI.
examples:
- my-query-1
comment:
type: string
description: A more detailed information about the query. Is also assigned by the user via GUI.
examples:
- I wanted to see how many patients I could find for my study XYZ
totalNumberOfPatients:
type: integer
format: int64
description: The number of results that were found for this query.
examples:
- 12345
SavedQuerySlots:
type: object
required:
- used
- total
properties:
used:
type: integer
description: The amount of used saved query slots for a user.
examples:
- 2
total:
type: integer
description: The total amount of saved query slots per user.
examples:
- 10
TermCode:
description: The termCode defines a concept based on a coding system (i.e. LOINC). The triplet of code, system and version identify the concept.
type: object
required:
- code
- system
- display
properties:
code:
type: string
examples:
- 119373006
system:
type: string
examples:
- http://snomed.info/sct
version:
type: string
examples:
- http://snomed.info/sct/900000000000207008/version/20210731
display:
type: string
examples:
- Amniotic fluid specimen (specimen)
beforeDate:
type: string
format: date-time
afterDate:
type: string
format: date-time
TimeRestriction:
anyOf:
- $ref: "#/components/schemas/beforeDate"
- $ref: "#/components/schemas/afterDate"
Unit:
type: object
required:
- code
- display
properties:
code:
type: string
display:
type: string
AttributeFilter:
type: object
description: An AttributeFilter requires different properties, depending on the type. Please refer to the JSON Schema for this.
required:
- type
properties:
attributeCode:
$ref: "#/components/schemas/TermCode"
ValueFilter:
type: object
description: A ValueFilter requires different properties, depending on the type. Please refer to the JSON Schema for this.
required:
- type
properties:
type:
type: string
enum:
- concept
- quantity-comparator
- quantity-range
selectedConcepts:
type: array
items:
$ref: "#/components/schemas/TermCode"
comparator:
type: string
enum:
- eq
- ue
- le
- lt
- ge
- gt
unit:
$ref: "#/components/schemas/Unit"
value:
type: number
format: double
minValue:
type: number
format: double
maxValue:
type: number
format: double
Criterion:
type: object
required:
- termCodes
properties:
termCodes:
type: array
items:
$ref: "#/components/schemas/TermCode"
attributeFilters:
type: array
items:
$ref: "#/components/schemas/AttributeFilter"
valueFilter:
$ref: "#/components/schemas/ValueFilter"
timeRestriction:
$ref: "#/components/schemas/TimeRestriction"
issues:
type: array
items:
$ref: "#/components/schemas/ValidationIssue"
CriterionList:
type: array
items:
$ref: "#/components/schemas/Criterion"
ContextualizedTermCodeList:
type: object
properties:
contextualizedTermCodes:
type: array
items:
$ref: "#/components/schemas/ContextualizedTermCode"
ContextualizedTermCode:
type: object
properties:
termcode:
$ref: "#/components/schemas/TermCode"
context:
$ref: "#/components/schemas/TermCode"
ValidationIssue:
type: object
required:
- code
- detail
properties:
code:
type: string
examples:
- VAL-20001
detail:
type: string
examples:
- The combination of context and termcode(s) is not found.
securitySchemes:
dataportal_auth:
type: oauth2
flows:
implicit:
authorizationUrl: http://to.be.defined/auth
scopes:
user: Dataportal user role
admin: Dataportal admin role
|
@michael-82 i would prefer Option 2 |
Update after discussion from 2025-02-13GeneralIn the backend we distinguish between "data query" and "feasibility query" (maybe a better wording could be found). Feasibility queries are (right now) the only kind of query that will be sent somewhere. The user can create / read / update / delete dataqueries. Basically this is like the template idea from earlier. There will be no necessary validation of anything. The only additional thing that is needed is a name for the query when stored. PathsCRUD
List queries
Feasibility
Please let me know your thoughts on this @juliangruendner @Shayan1375 @thkoehler11 |
CRUD- GET ../query/data/{id} load one data query. if a feasibility query is linked to that, include this information (if we go for an additional wrapper around the crtdl)
List queries- GET ../query/data lists id, name and timestamp of all of the current users stored data queries
ValidationFor the initial version, a validation endpoint for the CRTDL should be implemented to verify CCDL criteria and DSE profiles. Future iterations should include deeper validation, such as attributeFilter, valueFilter, and more. |
- update swaggerfile - bump version to next major snapshot
- update swaggerfile - bump version to next major snapshot
- WIP - move api to v5 - add Dataquery - remove query template - add database migration script - implement CRUD functions for dataquery - tests must be adapted
- convert saved queries and templates to dataqueries in db migration
- update swaggerfile - bump version to next major snapshot
- remove some unused methods and variables
- modify script to copy saved queries and templates to not include a "null" dataExtraction object
- re-enable websecurity requestmatchers - remove querytemplate validators - move get saved query slots (not sure if needed tho)
- implement tests for DataqueryHandler
- add check if user has stored too many dataqueries with result - fix missing result size in get dataquery - start working on more tests (lot of code commented out)
- add max queries per user variable to DataquerySpringConfig - don't throw storage full exception on dataquery without result - fix wrong path on CodeableConceptRestController and TerminologyRestController - add more tests to check for handling of full storage
- update swaggerfile - bump version to next major snapshot
- WIP - move api to v5 - add Dataquery - remove query template - add database migration script - implement CRUD functions for dataquery - tests must be adapted
- convert saved queries and templates to dataqueries in db migration
- remove some unused methods and variables
- modify script to copy saved queries and templates to not include a "null" dataExtraction object
- re-enable websecurity requestmatchers - remove querytemplate validators - move get saved query slots (not sure if needed tho)
- implement tests for DataqueryHandler
- add check if user has stored too many dataqueries with result - fix missing result size in get dataquery - start working on more tests (lot of code commented out)
- add max queries per user variable to DataquerySpringConfig - don't throw storage full exception on dataquery without result - fix wrong path on CodeableConceptRestController and TerminologyRestController - add more tests to check for handling of full storage
- fix feasibility query url in github integration test
- update ontology tag in github integration test - add debug output to check which curl cmd fails - add check for data storage limits on updates in DataqueryHandlerTest
- fix missing path fragment in returned location header when creating a feasibility query - add missing tests in DataqueryHandlerRestControllerIT
- fix wrong method in test for retrieving query slots - revert verbosity in github action integration test
- enable FeasibilityQueryHandlerRestControllerIT - remove unused tests from FeasibilityQueryHandlerRestControllerIT
- enable QueryHandlerServiceIT - remove unused tests from QueryHandlerServiceIT - todo: add those tests in a DataqueryHandlerIT
- remove unused exception classes - add DataqueryHandlerIT
- remove unused exception classes - add DataqueryHandlerIT
- move api to v5 - add Dataquery - remove query template and saved query - add database migration script - remove unused methods, exceptions and tests - update ontology tag in github integration test - modify swagger file - convert saved queries and templates to dataqueries in db migration
- remove some unused imports - fix some minor potential errors
Update: 2025-02-14: Please see this comment for the current state of discussion.
Extend API to save and load cohort and dataselection.
The API should be extended to allow the saving and loading of a cohort selection (CCDL) and a dataselection (dataExtraction part CRTDL).
Further it should be possible to save a CRTDL, which combines the cohort seleection and dataselection parts.
For this the endpoint
POST /query/{queryId}/saved
should be changed to
POST /query/saved and accept the following body:
Response: analogous to current saved Reponse, but with additional Id of saved query
IMPORTANT: It should also be possible to POST a query with a query ID from a query not in /cohort-selection, but in /query (as in a query that has been sent)
Further the endpoint /query/by-user/{userId} should still return the totalNumberOfPatients if a query has been previously saved with a query from query instead of cohort-selection
This future post from the UI will then require a ccdlID and a dataExtractionId to be supplied.
For this two new endpoints should be created, one to post each part to the backend.
POST /cohort-selection
Body: = CCDL (equivalent to what is currently send to query)
Response: analogous to current template endpoint, if successfull 201OK with Location Header and link to successfully stored cohort-selection
POST /data-selection
Body: the dataExtraction part of the CRTDL = https://github.com/medizininformatik-initiative/clinical-resource-transfer-definition-language
example:
Response: analogous to current template endpoint, if successfull 201OK with Location Header and link to successfully stored data-selection
Update 2025-02-17
Following the discussion in this comment ff.
Modified 2025-02-26: Changed Dataquery json slightly (don't put label/comment/nrofresults in another object) and move saved query slots endpoint (not sure if this is still needed anyways...)
The preliminary OpenAPI description
The text was updated successfully, but these errors were encountered: