RENCI / pds

PDS application (tx-router plugin)
MIT License
1 stars 0 forks source link

[BUG] (pds) plugin does not yet exist for Deliverable 5.1 #130

Closed krobasky closed 4 years ago

krobasky commented 4 years ago

Which repo (e.g., tx-logging)? pds, deliverable 5.1

Expected Behavior provides simple /config and /gudance endpoints to dashboard developer, abstracting away all the calls to FHIR, maper, and guidance plugins; also abstracts away calls between mapper and FHIR plugin from the mapper plugin provider.

Actual Behavior currently this functionality exists in part, manifested in the /aggregator and the /profile endpoints.

Information Check-in code to the existing pds repo; we will continue to use pds for ticketing across all the repos, and the CHANGES, AUTHOR, LICENSE, etc. files will remain unchanged. The PDS release cycle will be maintained from this repo.

Don't close this ticket until:

  1. the spec below has been fully implemented (talk to me if changes are required)
  2. test cases for calling the endpoints are deployed and configured for autotest/autobuild on dockerhub for v0.2.0 (stable release) and 'unstable' (master branch), using the file 'env.TAG' in the ./pds (see tx-router/env.TAG and tx-router/test/test.sh for example code)
  3. the new plugin is deployed on pds.renci.org and both endpoints are fully working with the deployed containers for pdspi-fhir-example, pdspi-mapping-example and pdspi-guidance-example.
  4. all the environmental variable values in all the dockercompose files are set using variables (not hard-coded) and those variables are documented and explained in the pds repo (see tx-router/test/test.sh and tx-router/test/docker-compose.yml for examples)
  5. the pds repo docker-compose.yml files are pointing to the :unstable version of dependent containers.
  6. the pds repo has no submodules, but does have the configured plugin yml files, including its own, using environmental variable names instead of hard-coded values
  7. there is documentation on the pds repo README on how to install/configue/deploy (can be pointing to other repos), especially HOW to set the environmental variables that are required by the plugins
  8. Somebody on the team has done a code-review and an acceptance test of the solution

FYI - Items that might trigger a new version include:

The specific, API design for this new plugin is at: https://app.swaggerhub.com/apis/krobasky/pds

the Yaml (no longer current, see swaggerhub link above):

openapi: 3.0.0
# Added by API Auto Mocking Plugin
servers:
  - description: pds service plugin
    url: https://virtserver.swaggerhub.com/krobasky/pds/1.0.0
info:
  description: Simple PDS plugin
  version: "1.0.0"
  title: Simple PDS API
  contact:
    email: txscience@lists.renci.org
paths:
  /guidance:
    post:
      summary: given a patient ID and a plugin id, return the guidance
      operationId: api.get_guidance
      responses:
        '200':
          description: guidance matching query
          content: 
            application/json:
              schema:
                  $ref: '#/components/schemas/Guidance'
        '400':
          description: bad input parameter
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GuidanceInputs'
  /config:
    get:
      summary: gets list of plugins with their selectors and required variables
      operationId: api.get_config
      parameters:
        - name: piid
          example: "pdspi-guidance-example"
          in: query
          required: false
          schema:
            type: string
          description: if present, return PluginConfig tailored to include only information about the indicated plugin
      responses:
        '200':
          description: config matching query
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PluginConfig'
        '400':
          description: bad input parameter
components:
  schemas:
    GuidanceInputs:
      type: object
      required:
        - piid
        - ptid
      properties:
        piid:
          type: string
          example: "pdspi-guidance-example"
          description: uniquely identifies the enabled and installed plugin to use for retrieving guidance
        ptid:
          type: string
          example: "38"
          description: the ID of the patient for which guidance is required
        pluginParameterValues:
          type: array
          items:
            $ref: '#/components/schemas/PluginParameter'
        userSuppliedPatientVariables:
          type: array
          items:
            $ref: '#/components/schemas/PatientVariable'
    Guidance:
      type: object
      properties:
        title:
          type: string
        id:
          type: string
        justification:
          type: array
          items:
            $ref: '#/components/schemas/PatientVariable'
          description: "a list of patient variables that were used and how they were computed and why they were needed "
        cards:
          type: array
          items:
            $ref: '#/components/schemas/Card'
    Card:
      type: object
      required:
        - id
        - summary
        - indicator
        - source
      properties:
        id: 
          type: string
        title:
          type: string
        summary:
          type: string
          description: "cds-hooks: <140-character summary sentence for display to the user inside of this card"
          example: "some <140 char Summary Message"
        detail:
          type: string
          description: "cds-hooks: - optional detailed information to display (GitHub Flavored Markdown)"
          example: "some sort of optional GitHub Markdown details"
        indicator:
          type: string
          description: " urgency/importance of what this card conveys (info/warning/critical)"
          example: "info"
        source:
          $ref: "#/components/schemas/Source"
        suggestions:
          type: array
          items:
            $ref: '#/components/schemas/Suggestion'
        selectionBehavior:
          type: string
          description: " intended behavior of the suggestions. If suggestions present, value must be at-most-one"
        links: 
          type: array
          items:
            $ref: '#/components/schemas/Link'
    Source:
      type: object
      required:
        - label
      properties:
        label:
          type: string
          description: "short, human-readable label to display source of the card’s information"
          example: Human-readable source label
        url:
          type: string
          description: "optional absolute URL to load to learn more about the organization or data set"
          example: "https://example.com"
        icon:
          type: string
          description: " absolute url for an icon for the source of this card (100x100 pixel PNG without any transparent regions)"
          example: "https://example.com/img/icon-100px.png"
    Suggestion:
      type: object
      required:
        - label
      properties:
        uuid:
          type: string
          description: "unique identifier for auditing and logging suggestions"
          example: e1187895-ad57-4ff7-a1f1-ccf954b2fe46
        label:
          type: string
          description: "human-readable label to display for this suggestion"
          example: "Human-readable suggestion label"
        actions:
          type: array
          items:
            $ref: '#/components/schemas/Action'
    Action:
      type: object
      required:
        - type
        - description
      properties:
        title:
          type: string
        id:
          type: string
        type:
          type: string
          description: "type of action being performed (create/update/delete)"
          example: "create"
        description:
          type: string
          description: "human-readable description of the suggested action"
          example: "Create a prescription for Acetaminophen 250 MG"
        resource:
          type: string
          description: "FHIR resource to create/update or id of resource to delete"
          example: "MedicationRequest"
    Link:
      type: object
      required:
        - label
        - url
        - type
      properties:
        label:
          type: string
          description: "human-readable label to display"
          example: "SMART Example App"
        url:
          type: string
          description: "URL to GET when link is clicked"
        type:
          type: string
          description: "type of the given URL (absolute/smart) "
        appContext:
          type: string
          description: "additional context to share with a linked SMART app"
    PluginConfig:
      type: object
      properties:
        title:
          type: string
          description: "Meaningful name for this plugin"
          example: "Aminogycoside dosing guidance"
        piid:
          type: string
          description: "A string, unique to this deployment, used to identify this plugin in realtime"
          example: "pdspi-aminogycoside-nomogram"
        pluginSelectors:
          type: array
          items:
            $ref: '#/components/schemas/PluginSelector'
        pluginParameterDefaults:
          type: array
          items:
            $ref: '#/components/schemas/PluginParameter'
        requiredPatientVariables:
          type: array
          items:
            $ref: '#/components/schemas/PatientVariableType'
    PluginSelector:
      description: The combination of selector values map to a unique plugin. That is, no two plugins can install with the identical vectors of selector values.  
      type: object
      properties:
        title:
          type: string
          example: "Gentamicin"
        code:
          type: string
          example: "1596450"
        selectorType:
          $ref: '#/components/schemas/PluginSelectorType'
    PluginSelectorType:
      description: Plugins providing Drug selector types will always use RxCUI when naming the drug. Diagnosis types will use ICD10, and genetics will use SNP for variants and NCBI for gene and transcript names.  
      type: object
      properties:
        title:
          type: string
          example: "Drug"
        system:
          type: string
          example: "RxCUI"
    PluginParameter:
      type: object
      properties:
        value:
          type: string
          description: the actual value of the model parameter
          example: "Hartford"
        units:
          type: string
          description: "The unit is standard throughout the pds system. It's up to the guidance plugin to make unit conversions as needed by the guidance model, just as it is up to the dashboard to make unit conversions as needed by the end user."
          example: "none"
        parameterType:
          $ref: '#/components/schemas/PluginParameterType'
    PluginParameterType:
      type: object
      properties:
        title:
          type: string
          example: "Extended interval nomogram"
        code:  
          type: string
          example: "PDS:01"
        system: 
          type: string
          example: "PDS.plugin.parameters"
        legalValues:
          type: string
          example: 'enum: ["Hartford", "Urban-Craig", "Conventional A", "Conventional B"]'
        description:
          type: string
          example: "This calculator uses one of four extended-interval nomograms. Please choose one nomogram."
    PatientVariable:
      type: object
      properties:
        value:
          type: string
          description: the actual value of the patient variable. If 'pds-retrieve-datum' then retrieve from patient data warehouse, otherwise use the value as-is
          example: "0.5"
        units:
          type: string
          description: "The unit is standard throughout the pds system. It's up to the guidance plugin to make unit conversions as needed by the guidance model, just as it is up to the dashboard to make unit conversions as needed by the end user."
          example: "years"
        how:
          type: string
          description: "If the variable is 'pds-retrieve-datum', then 'how' will read 'The value was specified by the end user.'"
          example: "The value was specified by the end user."
        variableType:
          $ref: '#/components/schemas/PatientVariableType'
    PatientVariableType:
      type: object
      properties:
        title:
          type: string
          example: "Age"
        clinicalFeatureVariable:
          type: string
          example: "LOINC:30525-0"
        description: 
          type: string
          example: "Age is a floating point number; e.g., a 6 month old child is 0.5 years."
        why:
          type: string
          example: "Age is used to calculate the creatinine clearance. Dosing is lower for geriatric patient and contraindicated for pediatric patients"
krobasky commented 4 years ago

pds will also need the following admin endpoint:

krobasky commented 4 years ago

Here are a couple of figures to help inform the implementation: image image

xu-hao commented 4 years ago

Work in progress merge profile and aggregator into one plugin

xu-hao commented 4 years ago

You may already know this:

the ‘pds’ plugin you’re working on can call tx-router to get all the plugin info, no need to call a new endpoint in pdspi-config
you’ll want to check for appropriate plugin responses since the pds will be version-controlled on those acceptable responses. It would be really great if these were all in one, computer-readable file (JSON) that can be easily updated.
In that regard, look at the example  response in the GET ‘/config’ for pdspi-guidance-example. Together with that JSON, here are allowable values:
    selectors – each can have more than one occurrence in the ‘selectors’ array

                                                           i.      pluginType: codes: g | c | m | f , titles => “Guidance”, “Convenience”, “Mapping”, “FHIR”, respectively

                                                         ii.      fhirPlugin: any | <valid-URL>, titles => “Compatible with any FHIR server” | “HAPI FHIR Server” | “SmartHealthIT”, respectively

                                                       iii.      drug: any | 1596450 |  1114195 | 1546356 | 1364430 | 1599538 | 1927851, titles => “Provides guidance regardless of drug” | “Gentamicin” | “Rivaroxiban” | “Dabigatran” | “Apixaban” | “Edoxaban” | “Betrixaban”

                                                       iv.      indication: any | LP30576-0 | LP185693-1 | LP19605-2, titles => “Provides guidance for any indication” | “Positive for Pseudomonas” | “Positive for Proteus, any species” | “Positive for e coli infection”  (there will be more)

    clinical variables (see ticket 75 for possible values), there will be more:

LOINC:2160-0: serum creatinine

LOINC:82810-3: pregnancy

HP:0001892: bleeding

HP:0000077: kidney dysfunction

LOINC:30525-0: Age

LOINC:54134-2: Race

LOINC:54120-1: Ethnicity

LOINC:21840-4: Sex

LOINC:8302-2: height

LOINC:29463-7: weight

LOINC:39156-5: bmi

    units:  none | years | m | kg | mg/dL | kg/m^2
    graphs: none | sawtooth – talk to David and Ryan to see if there will be more

Once you’ve made any necessary changes to fit your detailed designs for pds, can you please paste this info into a new ticket?

All this also changes the workflow slide to the following (see red arrows):

image

krobasky commented 4 years ago

the yaml in the description is no loger current, see swaggerhub