Skip to content
This repository has been archived by the owner on Feb 27, 2024. It is now read-only.

Add jvm target and assessment endpoints for admin app #244

Merged
merged 5 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions bridge-client/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ sqldelight {
val iosFrameworkName = "BridgeClient"

kotlin {
targetHierarchy.default()
androidTarget {
publishAllLibraryVariants()
compilations.all {
Expand All @@ -48,6 +49,14 @@ kotlin {
}
}

jvm() {
compilations.all {
kotlinOptions {
jvmTarget = "1.8"
}
}
}

val xcframework = XCFramework(iosFrameworkName)

// ios() includes x86 sim & arm64 device
Expand Down Expand Up @@ -140,6 +149,12 @@ kotlin {
val iosSimulatorArm64Test by sourceSets.getting
iosSimulatorArm64Main.dependsOn(iosMain)
iosSimulatorArm64Test.dependsOn(iosTest)

sourceSets["jvmMain"].dependencies {
implementation(libs.sqlDelight.jvm)
implementation(libs.ktor.client.android)
}

}
}
android {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*

internal abstract class AbstractApi(protected val basePath: String, protected val httpClient: HttpClient) {
abstract class AbstractApi(val basePath: String, val httpClient: HttpClient) {

companion object {
const val BASE_PATH = "https://webservices.sagebridge.org"
Expand All @@ -17,7 +17,7 @@ internal abstract class AbstractApi(protected val basePath: String, protected va
return postDataResponse(model, path).body()
}

internal suspend inline fun <reified T> postDataResponse(model: T, path: String) : HttpResponse {
suspend inline fun <reified T> postDataResponse(model: T, path: String) : HttpResponse {
val builder = HttpRequestBuilder()

builder.method = HttpMethod.Post
Expand Down Expand Up @@ -51,7 +51,7 @@ internal abstract class AbstractApi(protected val basePath: String, protected va
return getDataResponse(path, modifiedDateTimeString, queryParams).body()
}

internal suspend fun getDataResponse(
suspend fun getDataResponse(
path: String,
modifiedDateTimeString: String? = null,
queryParams: Map<String, String>? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ package org.sagebionetworks.bridge.kmm.shared.apis


import io.ktor.client.*
import org.sagebionetworks.bridge.kmm.shared.models.Assessment
import org.sagebionetworks.bridge.kmm.shared.models.AssessmentConfig
import org.sagebionetworks.bridge.kmm.shared.models.AssessmentInfo
import org.sagebionetworks.bridge.kmm.shared.models.AssessmentList

internal class AssessmentsApi(basePath: String = BASE_PATH, httpClient: HttpClient) : AbstractApi(basePath, httpClient) {
class AssessmentsApi(basePath: String = BASE_PATH, httpClient: HttpClient) : AbstractApi(basePath, httpClient) {

/**
* Get the JSON config for this assessment
Expand All @@ -30,4 +32,45 @@ internal class AssessmentsApi(basePath: String = BASE_PATH, httpClient: HttpClie
return getData(assessmentInfo.configPath)
}

/**
* Get a specific assessment revision.
* A GUID uniquely identifies a specific assessment revision.
* @param guid A guid
* @return Assessment
*/
suspend fun getAssessmentByGUID(guid: String) : Assessment {
return getData("v1/assessments/$guid")
}

/**
* Get assessments in the app context.
* This is a paged API that can be filtered by the categories and tags assigned to assessments. The most recent (highest) revision of each assessment is returned in the API.
* @param offsetBy next page start offset for pagination (optional, default to 0)
* @param pageSize maximum number of records in each returned page (optional, default to 50)
* @param tag One or more tags. Every resource that has at least one of the tags will be returned (resources do not need to match all tags). (optional)
* @param includeDeleted Should deleted items be returned in results? (optional, default to false)
* @return AssessmentListComposed
*/
suspend fun getAssessments(offsetBy: Int? = 0, pageSize: Int? = 100, tag:String? = null, includeDeleted: Boolean? = false) : AssessmentList {
val parameters = mutableMapOf<String, String>()
with(parameters) {
offsetBy?.let { put("offsetBy", it.toString()) }
pageSize?.let { put("pageSize", it.toString()) }
tag?.let { put("tag", it) }
includeDeleted?.let { put("includeDeleted", it.toString()) }
}
return getData("v1/assessments", queryParams = parameters)
}

/**
* Update an assessment revision.
* A GUID uniquely identifies a specific assessment revision. Only members of the organization that own this assessment can update it. This operation returns the updated assessment revision.
* @param guid A guid
* @param assessment Updated assessment
* @return Assessment
*/
suspend fun updateAssessment(guid: String, assessment: Assessment) : Assessment {
return postData(assessment, "v1/assessments/$guid" )
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
/**
* Bridge Server API
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* OpenAPI spec version: 0.25.33
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
package org.sagebionetworks.bridge.kmm.shared.models


import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable


/**
* The assessment object contains the general cataloguing information we have on an assessment, and includes both a set of links to documents that describe the assessment and its use, as well as a configuration object for client applications. An assessment can be defined in an app context, or it can be shared in our shared assessment libary. Assessments are globally visible to all study authors in an app context, but are owned by a specific organization, and only members of that organization can edit the assessment. When shared, the configuration for an assessment is immutable and there are no APIs to update it.
* @param identifier A human-readable identifier for an assessment, which can have one or more revisions.
* @param revision
* @param ownerId The ID of the organization that owns this assessment. Only members of that organization will be able to edit the assessment, either in an app context or in the shared assessment library.
* @param title A name for the assessment that is shown to study designers, but not to study participants if there are labels that can be shown instead.
* @param osName The name of the operating system (conventional names are \"Android,\" \"iPhone OS,\" and \"Both\").
* @param phase One of an enumerated list of states an assessment can be in.
* @param guid Each assessment revision is assigned a unique GUID which can be used to retrieve it through the API. Assessments will also have a unique combination of an identifier and a revision, and can be retrieved as a set of revisions under a given identifier.
* @param labels A collection of labels for this assessment. Only one label can be included for each language, and if the user’s language cannot be selected, English will be selected as a default. If an English label does not exist, then the assessment title can be used instead.
* @param colorScheme
* @param summary
* @param originGuid If this assessment was copied from a shared assessment, this will be the GUID of the shared assessment revision that was used to make this copy. Certain aspects of the assessment (notably, the assessment's configuration) are guaranteed to be identical to this origin assessment.
* @param validationStatus
* @param normingStatus
* @param minutesToComplete The number of minutes it takes for a participant to complete this assessment.
* @param tags A set of tags that apply to this assessment. Tags should be namespaced with a prefix followed by a period (e.g. \"category.neurodegenerative\"), as the tag API will give you these tags in a map keyed from the prefix to a list of the values under that prefix.
* @param customizationFields A map of AssessmentNode GUIDs to a set of field identifiers in that node that can be customized by developers without invalidating an assessment (the assessment will maintain its link to the shared assessment it was derived from, if any, and the authors of the assessment are confident that these changes to the configuration will not invalidate the scientific validity of the assessment). This specification guides validation of submissions to update an AssessmentNode through a specific customization API.
* @param createdOn The date and time the assessment was created.
* @param modifiedOn The date and time the assessment was last modified.
* @param deleted Has this assessment been logically deleted (an admin can restore it)?
* @param version The optimistic locking version of the assessment. This value must be submitted as part of the next update of the model. If it does not match the value on the server, a 409 error (Conflict) will prevent the update from occurring. It can also serve as a key to determine if a local cache of `Assessment` needs to be updated.
* @param imageResource
* @param frameworkIdentifier The framework this assessment belongs to.
* @param jsonSchemaUrl A URL for a resource specifying a JSON schema for the archived results.
* @param category The category of assessment.
* @param minAge The minimum age for which this assessment has been validated.
* @param maxAge The maximum age for which this assessment has been validated.
* @param additionalMetadata Additional metadata fields, expressed as a key-value map.
* @param type Assessment
*/
@Serializable
data class Assessment (
/* A human-readable identifier for an assessment, which can have one or more revisions. */
@SerialName("identifier")
val identifier: kotlin.String,

@SerialName("revision")
val revision: kotlin.Long,

/* The ID of the organization that owns this assessment. Only members of that organization will be able to edit the assessment, either in an app context or in the shared assessment library. */
@SerialName("ownerId")
val ownerId: kotlin.String,

/* A name for the assessment that is shown to study designers, but not to study participants if there are labels that can be shown instead. */
@SerialName("title")
val title: kotlin.String,

/* The name of the operating system (conventional names are \"Android,\" \"iPhone OS,\" and \"Both\"). */
@SerialName("osName")
val osName: kotlin.String,

/* One of an enumerated list of states an assessment can be in. */
@SerialName("phase")
val phase: Assessment.Phase,

/* Each assessment revision is assigned a unique GUID which can be used to retrieve it through the API. Assessments will also have a unique combination of an identifier and a revision, and can be retrieved as a set of revisions under a given identifier. */
@SerialName("guid")
val guid: kotlin.String? = null,

/* A collection of labels for this assessment. Only one label can be included for each language, and if the user’s language cannot be selected, English will be selected as a default. If an English label does not exist, then the assessment title can be used instead. */
@SerialName("labels")
val labels: kotlin.collections.List<Label>? = null,

@SerialName("colorScheme")
val colorScheme: ColorScheme? = null,

@SerialName("summary")
val summary: kotlin.String? = null,

/* If this assessment was copied from a shared assessment, this will be the GUID of the shared assessment revision that was used to make this copy. Certain aspects of the assessment (notably, the assessment's configuration) are guaranteed to be identical to this origin assessment. */
@SerialName("originGuid")
val originGuid: kotlin.String? = null,

@SerialName("validationStatus")
val validationStatus: kotlin.String? = null,

@SerialName("normingStatus")
val normingStatus: kotlin.String? = null,

/* The number of minutes it takes for a participant to complete this assessment. */
@SerialName("minutesToComplete")
val minutesToComplete: kotlin.Int? = null,

/* A set of tags that apply to this assessment. Tags should be namespaced with a prefix followed by a period (e.g. \"category.neurodegenerative\"), as the tag API will give you these tags in a map keyed from the prefix to a list of the values under that prefix. */
@SerialName("tags")
val tags: kotlin.collections.List<kotlin.String>? = null,

/* A map of AssessmentNode GUIDs to a set of field identifiers in that node that can be customized by developers without invalidating an assessment (the assessment will maintain its link to the shared assessment it was derived from, if any, and the authors of the assessment are confident that these changes to the configuration will not invalidate the scientific validity of the assessment). This specification guides validation of submissions to update an AssessmentNode through a specific customization API. */
@SerialName("customizationFields")
val customizationFields: kotlin.collections.Map<kotlin.String, kotlin.collections.List<PropertyInfo>>? = null,

/* The date and time the assessment was created. */
@SerialName("createdOn")
val createdOn: kotlin.String? = null,

/* The date and time the assessment was last modified. */
@SerialName("modifiedOn")
val modifiedOn: kotlin.String? = null,

/* Has this assessment been logically deleted (an admin can restore it)? */
@SerialName("deleted")
val deleted: kotlin.Boolean? = null,

/* The optimistic locking version of the assessment. This value must be submitted as part of the next update of the model. If it does not match the value on the server, a 409 error (Conflict) will prevent the update from occurring. It can also serve as a key to determine if a local cache of `Assessment` needs to be updated. */
@SerialName("version")
val version: kotlin.Long? = null,

@SerialName("imageResource")
val imageResource: ImageResource? = null,

/* The framework this assessment belongs to. */
@SerialName("frameworkIdentifier")
val frameworkIdentifier: kotlin.String? = null,

/* A URL for a resource specifying a JSON schema for the archived results. */
@SerialName("jsonSchemaUrl")
val jsonSchemaUrl: kotlin.String? = null,

/* The category of assessment. */
@SerialName("category")
val category: kotlin.String? = null,

/* The minimum age for which this assessment has been validated. */
@SerialName("minAge")
val minAge: kotlin.Int? = null,
/* The maximum age for which this assessment has been validated. */

@SerialName("maxAge")
val maxAge: kotlin.Int? = null,

/* Additional metadata fields, expressed as a key-value map. */
@SerialName("additionalMetadata")
val additionalMetadata: kotlinx.serialization.json.JsonObject? = null,

/* Assessment */
@SerialName("type")
val type: kotlin.String? = null

) {

/**
* One of an enumerated list of states an assessment can be in.
* Values: "draft","review","published"
*/
@Serializable
enum class Phase {

@SerialName("draft")
DRAFT,

@SerialName("review")
REVIEW,

@SerialName("published")
PUBLISHED;

}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Bridge Server API
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* OpenAPI spec version: 0.21.29
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
package org.sagebionetworks.bridge.kmm.shared.models

import kotlinx.serialization.Serializable
import kotlinx.serialization.SerialName

/**
*
* @param requestParams
* @param type ResourceList
* @param total The total number of records in the items list
* @param items
*/
@Serializable
data class AssessmentList (
@SerialName("requestParams")
val requestParams: RequestParams? = null,
/* ResourceList */
@SerialName("type")
val type: String,
/* The total number of records in the items list */
@SerialName("total")
val total: Int,
@SerialName("items")
val items: List<Assessment>
)

Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* Bridge Server API
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* OpenAPI spec version: 0.25.33
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
package org.sagebionetworks.bridge.kmm.shared.models

import kotlinx.serialization.Serializable






import kotlinx.serialization.SerialName


/**
*
* @param propName The property name of the property on the JSON object that can be edited.
* @param label A short label for the property.
* @param description A longer description of the property and the allowable values that it can take.
* @param propType A type hint to a UI editor for this property. The value is not constrained to support complex types, but we suggest 'string', 'number', or 'boolean' as basic values to support with editing tools.
* @param type PropertyInfo
*/
@Serializable
public data class PropertyInfo (
/* The property name of the property on the JSON object that can be edited. */

@SerialName("propName")
val propName: kotlin.String,
/* A short label for the property. */

@SerialName("label")
val label: kotlin.String,
/* A longer description of the property and the allowable values that it can take. */

@SerialName("description")
val description: kotlin.String? = null,
/* A type hint to a UI editor for this property. The value is not constrained to support complex types, but we suggest 'string', 'number', or 'boolean' as basic values to support with editing tools. */

@SerialName("propType")
val propType: kotlin.String? = null,
/* PropertyInfo */

@SerialName("type")
val type: kotlin.String? = null

) {

}

Loading
Loading