Skip to content

feat: Update workflows subgraph to graph-proxy@v0.1.18#156

Open
dls-graph-schema-federator[bot] wants to merge 1 commit into
mainfrom
workflows-graph-proxy@v0.1.18
Open

feat: Update workflows subgraph to graph-proxy@v0.1.18#156
dls-graph-schema-federator[bot] wants to merge 1 commit into
mainfrom
workflows-graph-proxy@v0.1.18

Conversation

@dls-graph-schema-federator
Copy link
Copy Markdown
Contributor

@github-actions
Copy link
Copy Markdown

diff --git a/tmp/old_sorted.json b/tmp/new_sorted.json
index 8855d63..057806a 100644
--- a/tmp/old_sorted.json
+++ b/tmp/new_sorted.json
@@ -2,222 +2,6 @@
   "compatibilityVersion": "1:0.57.0",
   "engineConfig": {
     "datasourceConfigurations": [
-      {
-        "childNodes": [
-          {
-            "fieldNames": [
-              "name",
-              "url",
-              "mimeType"
-            ],
-            "typeName": "Artifact"
-          },
-          {
-            "fieldNames": [
-              "content",
-              "podName"
-            ],
-            "typeName": "LogEntry"
-          },
-          {
-            "fieldNames": [
-              "hasPreviousPage",
-              "hasNextPage",
-              "startCursor",
-              "endCursor"
-            ],
-            "typeName": "PageInfo"
-          },
-          {
-            "fieldNames": [
-              "id",
-              "name",
-              "status",
-              "depends",
-              "dependencies",
-              "artifacts",
-              "stepType",
-              "startTime",
-              "endTime",
-              "message"
-            ],
-            "typeName": "Task"
-          },
-          {
-            "fieldNames": [
-              "repositoryUrl",
-              "path",
-              "targetRevision"
-            ],
-            "typeName": "TemplateSource"
-          },
-          {
-            "fieldNames": [
-              "proposalCode",
-              "proposalNumber",
-              "number"
-            ],
-            "typeName": "Visit"
-          },
-          {
-            "fieldNames": [
-              "id",
-              "name",
-              "visit",
-              "status",
-              "parameters",
-              "templateRef",
-              "creator"
-            ],
-            "typeName": "Workflow"
-          },
-          {
-            "fieldNames": [
-              "pageInfo",
-              "edges",
-              "nodes"
-            ],
-            "typeName": "WorkflowConnection"
-          },
-          {
-            "fieldNames": [
-              "creatorId"
-            ],
-            "typeName": "WorkflowCreator"
-          },
-          {
-            "fieldNames": [
-              "node",
-              "cursor"
-            ],
-            "typeName": "WorkflowEdge"
-          },
-          {
-            "fieldNames": [
-              "startTime",
-              "endTime",
-              "message",
-              "tasks"
-            ],
-            "typeName": "WorkflowErroredStatus"
-          },
-          {
-            "fieldNames": [
-              "startTime",
-              "endTime",
-              "message",
-              "tasks"
-            ],
-            "typeName": "WorkflowFailedStatus"
-          },
-          {
-            "fieldNames": [
-              "message"
-            ],
-            "typeName": "WorkflowPendingStatus"
-          },
-          {
-            "fieldNames": [
-              "startTime",
-              "message",
-              "tasks"
-            ],
-            "typeName": "WorkflowRunningStatus"
-          },
-          {
-            "fieldNames": [
-              "startTime",
-              "endTime",
-              "message",
-              "tasks"
-            ],
-            "typeName": "WorkflowSucceededStatus"
-          },
-          {
-            "fieldNames": [
-              "name",
-              "maintainer",
-              "title",
-              "description",
-              "repository",
-              "arguments",
-              "uiSchema",
-              "templateSource"
-            ],
-            "typeName": "WorkflowTemplate"
-          },
-          {
-            "fieldNames": [
-              "pageInfo",
-              "edges",
-              "nodes"
-            ],
-            "typeName": "WorkflowTemplateConnection"
-          },
-          {
-            "fieldNames": [
-              "node",
-              "cursor"
-            ],
-            "typeName": "WorkflowTemplateEdge"
-          }
-        ],
-        "customGraphql": {
-          "federation": {
-            "enabled": true,
-            "serviceSdl": "type Artifact {\n\t\"\"\"\n\tThe file name of the artifact\n\t\"\"\"\n\tname: String!\n\t\"\"\"\n\tThe download URL for the artifact\n\t\"\"\"\n\turl: Url!\n\t\"\"\"\n\tThe MIME type of the artifact data\n\t\"\"\"\n\tmimeType: String!\n}\n\nscalar Creator\n\n\"\"\"\nImplement the DateTime<Utc> scalar\n\nThe input/output is a string in RFC3339 format.\n\"\"\"\nscalar DateTime\n\n\"\"\"\nA scalar that can represent any JSON value.\n\"\"\"\nscalar JSON\n\n\"\"\"\nA scalar that can represent any JSON Object value.\n\"\"\"\nscalar JSONObject\n\n\"\"\"\nA single log line streamed from a pod\n\"\"\"\ntype LogEntry {\n\t\"\"\"\n\tThe log line content\n\t\"\"\"\n\tcontent: String!\n\t\"\"\"\n\tThe name of the pod producing the log\n\t\"\"\"\n\tpodName: String!\n}\n\n\"\"\"\nThe root mutation of the service\n\"\"\"\ntype Mutation {\n\tsubmitWorkflowTemplate(name: String!, visit: VisitInput!, parameters: JSON!): Workflow!\n}\n\n\"\"\"\nRepresents Relay Node types\n\"\"\"\nunion NodeValue = Workflow\n\n\"\"\"\nInformation about pagination in a connection\n\"\"\"\ntype PageInfo @shareable {\n\t\"\"\"\n\tWhen paginating backwards, are there more items?\n\t\"\"\"\n\thasPreviousPage: Boolean!\n\t\"\"\"\n\tWhen paginating forwards, are there more items?\n\t\"\"\"\n\thasNextPage: Boolean!\n\t\"\"\"\n\tWhen paginating backwards, the cursor to continue.\n\t\"\"\"\n\tstartCursor: String\n\t\"\"\"\n\tWhen paginating forwards, the cursor to continue.\n\t\"\"\"\n\tendCursor: String\n}\n\n\"\"\"\nThe root query of the service\n\"\"\"\ntype Query {\n\tnode(id: ID!): NodeValue\n\t\"\"\"\n\tGet a single [`Workflow`] by proposal, visit, and name\n\t\"\"\"\n\tworkflow(visit: VisitInput!, name: String!): Workflow!\n\tworkflows(visit: VisitInput!, cursor: String, limit: Int, filter: WorkflowFilter): WorkflowConnection!\n\tworkflowTemplate(name: String!): WorkflowTemplate!\n\tworkflowTemplates(cursor: String, limit: Int, filter: WorkflowTemplatesFilter): WorkflowTemplateConnection!\n}\n\n\"\"\"\nSupported DLS science groups\n\"\"\"\nenum ScienceGroup {\n\t\"\"\"\n\tMacromolecular Crystallography\n\t\"\"\"\n\tMX\n\t\"\"\"\n\tWorkflows Examples\n\t\"\"\"\n\tEXAMPLES\n\t\"\"\"\n\tMagnetic Materials\n\t\"\"\"\n\tMAGNETIC_MATERIALS\n\t\"\"\"\n\tSoft Condensed Matter\n\t\"\"\"\n\tCONDENSED_MATTER\n\t\"\"\"\n\tImaging and Microscopy\n\t\"\"\"\n\tIMAGING\n\t\"\"\"\n\tBiological Cryo-Imaging\n\t\"\"\"\n\tBIO_CRYO_IMAGING\n\t\"\"\"\n\tStructures and Surfaces\n\t\"\"\"\n\tSURFACES\n\t\"\"\"\n\tCrystallography\n\t\"\"\"\n\tCRYSTALLOGRAPHY\n\t\"\"\"\n\tSpectroscopy\n\t\"\"\"\n\tSPECTROSCOPY\n}\n\n\"\"\"\nThe root mutation of the service\n\"\"\"\ntype Subscription {\n\t\"\"\"\n\tProcessing to subscribe to logs for a single pod of a workflow\n\t\"\"\"\n\tlogs(visit: VisitInput!, workflowName: String!, taskId: String!): LogEntry!\n\t\"\"\"\n\tProcessing to subscribe to data for all workflows in a session\n\t\"\"\"\n\tworkflow(visit: VisitInput!, name: String!): Workflow!\n}\n\ntype Task {\n\t\"\"\"\n\tUnique name of the task\n\t\"\"\"\n\tid: String!\n\t\"\"\"\n\tDisplay name of the task\n\t\"\"\"\n\tname: String!\n\t\"\"\"\n\tCurrent status of a task\n\t\"\"\"\n\tstatus: TaskStatus!\n\t\"\"\"\n\tParent of a task\n\t\"\"\"\n\tdepends: [String!]!\n\t\"\"\"\n\tChildren of a task\n\t\"\"\"\n\tdependencies: [String!]!\n\t\"\"\"\n\tArtifacts produced by a task\n\t\"\"\"\n\tartifacts: [Artifact!]!\n\t\"\"\"\n\tNode type - Pod, DAG, etc\n\t\"\"\"\n\tstepType: String!\n\t\"\"\"\n\tStart time for a task on a workflow\n\t\"\"\"\n\tstartTime: DateTime\n\t\"\"\"\n\tEnd time for a task on a workflow\n\t\"\"\"\n\tendTime: DateTime\n\t\"\"\"\n\tA human readable message indicating details about why this step is in this condition\n\t\"\"\"\n\tmessage: String\n}\n\nenum TaskStatus {\n\tPENDING\n\tRUNNING\n\tSUCCEEDED\n\tSKIPPED\n\tFAILED\n\tERROR\n\tOMITTED\n}\n\nscalar Template\n\n\"\"\"\nInformation about where the template is stored\n\"\"\"\ntype TemplateSource {\n\t\"\"\"\n\tThe URL of the GitHub repository\n\t\"\"\"\n\trepositoryUrl: String!\n\t\"\"\"\n\tThe path to the template within the repository\n\t\"\"\"\n\tpath: String!\n\t\"\"\"\n\tThe current tracked branch of the repository\n\t\"\"\"\n\ttargetRevision: String!\n}\n\n\"\"\"\nURL is a String implementing the [URL Standard](http://url.spec.whatwg.org/)\n\"\"\"\nscalar Url\n\n\"\"\"\nA visit to an instrument as part of a session\n\"\"\"\ntype Visit {\n\t\"\"\"\n\tProject Proposal Code\n\t\"\"\"\n\tproposalCode: String!\n\t\"\"\"\n\tProject Proposal Number\n\t\"\"\"\n\tproposalNumber: Int!\n\t\"\"\"\n\tSession visit Number\n\t\"\"\"\n\tnumber: Int!\n}\n\n\"\"\"\nA visit to an instrument as part of a session\n\"\"\"\ninput VisitInput {\n\t\"\"\"\n\tProject Proposal Code\n\t\"\"\"\n\tproposalCode: String!\n\t\"\"\"\n\tProject Proposal Number\n\t\"\"\"\n\tproposalNumber: Int!\n\t\"\"\"\n\tSession visit Number\n\t\"\"\"\n\tnumber: Int!\n}\n\ntype Workflow {\n\t\"\"\"\n\tThe unique ID derived from the visit and name\n\t\"\"\"\n\tid: ID!\n\t\"\"\"\n\tThe name given to the workflow, unique within a given visit\n\t\"\"\"\n\tname: String!\n\t\"\"\"\n\tThe visit the Workflow was run against\n\t\"\"\"\n\tvisit: Visit!\n\t\"\"\"\n\tThe current status of the workflow\n\t\"\"\"\n\tstatus: WorkflowStatus\n\t\"\"\"\n\tThe top-level workflow parameters\n\t\"\"\"\n\tparameters: JSONObject\n\t\"\"\"\n\tThe name of the template used to run the workflow\n\t\"\"\"\n\ttemplateRef: String\n\t\"\"\"\n\tThe workflow creator\n\t\"\"\"\n\tcreator: WorkflowCreator!\n}\n\ntype WorkflowConnection @shareable {\n\t\"\"\"\n\tInformation to aid in pagination.\n\t\"\"\"\n\tpageInfo: PageInfo!\n\t\"\"\"\n\tA list of edges.\n\t\"\"\"\n\tedges: [WorkflowEdge!]!\n\t\"\"\"\n\tA list of nodes.\n\t\"\"\"\n\tnodes: [Workflow!]!\n}\n\n\"\"\"\nInformation about the creator of a workflow.\n\"\"\"\ntype WorkflowCreator {\n\t\"\"\"\n\tAn identifier unique to the creator of the workflow.\n\tTypically this is the creator's Fed-ID.\n\t\"\"\"\n\tcreatorId: String!\n}\n\n\"\"\"\nAn edge in a connection.\n\"\"\"\ntype WorkflowEdge @shareable {\n\t\"\"\"\n\tThe item at the end of the edge\n\t\"\"\"\n\tnode: Workflow!\n\t\"\"\"\n\tA cursor for use in pagination\n\t\"\"\"\n\tcursor: String!\n}\n\n\"\"\"\nAll tasks in the workflow have errored\n\"\"\"\ntype WorkflowErroredStatus {\n\t\"\"\"\n\tTime at which this workflow started\n\t\"\"\"\n\tstartTime: DateTime!\n\t\"\"\"\n\tTime at which this workflow completed\n\t\"\"\"\n\tendTime: DateTime!\n\t\"\"\"\n\tA human readable message indicating details about why the workflow is in this condition\n\t\"\"\"\n\tmessage: String\n\t\"\"\"\n\tTasks created by the workflow\n\t\"\"\"\n\ttasks: [Task!]!\n}\n\n\"\"\"\nAll tasks in the workflow have failed\n\"\"\"\ntype WorkflowFailedStatus {\n\t\"\"\"\n\tTime at which this workflow started\n\t\"\"\"\n\tstartTime: DateTime!\n\t\"\"\"\n\tTime at which this workflow completed\n\t\"\"\"\n\tendTime: DateTime!\n\t\"\"\"\n\tA human readable message indicating details about why the workflow is in this condition\n\t\"\"\"\n\tmessage: String\n\t\"\"\"\n\tTasks created by the workflow\n\t\"\"\"\n\ttasks: [Task!]!\n}\n\n\"\"\"\nAll the supported Workflows filters\n\"\"\"\ninput WorkflowFilter {\n\t\"\"\"\n\tThe status field for a workflow\n\t\"\"\"\n\tworkflowStatusFilter: WorkflowStatusFilter\n\t\"\"\"\n\tThe fedid of the user who created the workflow\n\t\"\"\"\n\tcreator: Creator\n\t\"\"\"\n\tThe name of the workflow template\n\t\"\"\"\n\ttemplate: Template\n}\n\ntype WorkflowPendingStatus {\n\t\"\"\"\n\tA human readable message indicating details about why the workflow is in this condition\n\t\"\"\"\n\tmessage: String\n}\n\ntype WorkflowRunningStatus {\n\t\"\"\"\n\tTime at which this workflow started\n\t\"\"\"\n\tstartTime: DateTime!\n\t\"\"\"\n\tA human readable message indicating details about why the workflow is in this condition\n\t\"\"\"\n\tmessage: String\n\t\"\"\"\n\tTasks created by the workflow\n\t\"\"\"\n\ttasks: [Task!]!\n}\n\n\"\"\"\nThe status of a workflow\n\"\"\"\nunion WorkflowStatus = WorkflowPendingStatus | WorkflowRunningStatus | WorkflowSucceededStatus | WorkflowFailedStatus | WorkflowErroredStatus\n\n\"\"\"\nRepresents workflow status filters\n\"\"\"\ninput WorkflowStatusFilter {\n\tpending: Boolean! = false\n\trunning: Boolean! = false\n\tsucceeded: Boolean! = false\n\tfailed: Boolean! = false\n\terror: Boolean! = false\n}\n\n\"\"\"\nAll tasks in the workflow have succeded\n\"\"\"\ntype WorkflowSucceededStatus {\n\t\"\"\"\n\tTime at which this workflow started\n\t\"\"\"\n\tstartTime: DateTime!\n\t\"\"\"\n\tTime at which this workflow completed\n\t\"\"\"\n\tendTime: DateTime!\n\t\"\"\"\n\tA human readable message indicating details about why the workflow is in this condition\n\t\"\"\"\n\tmessage: String\n\t\"\"\"\n\tTasks created by the workflow\n\t\"\"\"\n\ttasks: [Task!]!\n}\n\ntype WorkflowTemplate {\n\t\"\"\"\n\tThe name given to the workflow template, globally unique\n\t\"\"\"\n\tname: String!\n\t\"\"\"\n\tThe group who maintains the workflow template\n\t\"\"\"\n\tmaintainer: String!\n\t\"\"\"\n\tA human readable title for the workflow template\n\t\"\"\"\n\ttitle: String\n\t\"\"\"\n\tA human readable description of the workflow which is created\n\t\"\"\"\n\tdescription: String\n\t\"\"\"\n\tThe repository storing the code associated with this template.\n\t\"\"\"\n\trepository: String\n\t\"\"\"\n\tA JSON Schema describing the arguments of a Workflow Template\n\t\"\"\"\n\targuments: JSON!\n\t\"\"\"\n\tA JSON Forms UI Schema describing how to render the arguments of the Workflow Template\n\t\"\"\"\n\tuiSchema: JSON\n\t\"\"\"\n\tInformation about where the template is obtained from\n\t\"\"\"\n\ttemplateSource: TemplateSource\n}\n\ntype WorkflowTemplateConnection @shareable {\n\t\"\"\"\n\tInformation to aid in pagination.\n\t\"\"\"\n\tpageInfo: PageInfo!\n\t\"\"\"\n\tA list of edges.\n\t\"\"\"\n\tedges: [WorkflowTemplateEdge!]!\n\t\"\"\"\n\tA list of nodes.\n\t\"\"\"\n\tnodes: [WorkflowTemplate!]!\n}\n\n\"\"\"\nAn edge in a connection.\n\"\"\"\ntype WorkflowTemplateEdge @shareable {\n\t\"\"\"\n\tThe item at the end of the edge\n\t\"\"\"\n\tnode: WorkflowTemplate!\n\t\"\"\"\n\tA cursor for use in pagination\n\t\"\"\"\n\tcursor: String!\n}\n\n\"\"\"\nSupported label filters for ClusterWorkflowTemplates\n\"\"\"\ninput WorkflowTemplatesFilter {\n\t\"\"\"\n\tThe science group owning the template eg imaging\n\t\"\"\"\n\tscienceGroup: [ScienceGroup!]\n}\n\n\"\"\"\nDirects the executor to include this field or fragment only when the `if` argument is true.\n\"\"\"\ndirective @include(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT\n\"\"\"\nDirects the executor to skip this field or fragment when the `if` argument is true.\n\"\"\"\ndirective @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT\n\"\"\"\nProvides a scalar specification URL for specifying the behavior of custom scalar types.\n\"\"\"\ndirective @specifiedBy(url: String!) on SCALAR\nextend schema @link(\n\turl: \"https://specs.apollo.dev/federation/v2.5\",\n\timport: [\"@key\", \"@tag\", \"@shareable\", \"@inaccessible\", \"@override\", \"@external\", \"@provides\", \"@requires\", \"@composeDirective\", \"@interfaceObject\", \"@requiresScopes\"]\n)\n"
-          },
-          "fetch": {
-            "baseUrl": {},
-            "body": {},
-            "method": "POST",
-            "path": {},
-            "url": {
-              "staticVariableContent": "https://workflows.diamond.ac.uk/graphql"
-            }
-          },
-          "subscription": {
-            "enabled": true,
-            "protocol": "GRAPHQL_SUBSCRIPTION_PROTOCOL_WS",
-            "url": {
-              "staticVariableContent": "wss://workflows.diamond.ac.uk/graphql/ws"
-            },
-            "websocketSubprotocol": "GRAPHQL_WEBSOCKET_SUBPROTOCOL_AUTO"
-          },
-          "upstreamSchema": {
-            "key": "9a94e595184badd514b2996e26945dd3a01edbf4"
-          }
-        },
-        "id": "0",
-        "kind": "GRAPHQL",
-        "overrideFieldPathFromAlias": true,
-        "requestTimeoutSeconds": "10",
-        "rootNodes": [
-          {
-            "fieldNames": [
-              "submitWorkflowTemplate"
-            ],
-            "typeName": "Mutation"
-          },
-          {
-            "fieldNames": [
-              "node",
-              "workflow",
-              "workflows",
-              "workflowTemplate",
-              "workflowTemplates"
-            ],
-            "typeName": "Query"
-          },
-          {
-            "fieldNames": [
-              "logs",
-              "workflow"
-            ],
-            "typeName": "Subscription"
-          }
-        ]
-      },
       {
         "childNodes": [
           {
@@ -312,7 +96,7 @@
             "key": "636412ec8e6e8e278df46ce7da59047a6182733c"
           }
         },
-        "id": "1",
+        "id": "0",
         "keys": [
           {
             "selectionSet": "instrumentSessionNumber proposal { proposalNumber }",
@@ -530,7 +314,7 @@
             "key": "6f02287e3cbb3840d5136c3ef6f75c1e24560b94"
           }
         },
-        "id": "2",
+        "id": "1",
         "keys": [
           {
             "selectionSet": "instrumentSessionNumber proposal { proposalNumber }",
@@ -640,7 +424,7 @@
             "key": "ab9040c814f11559b1e7d93f67b38b284f1bf0d3"
           }
         },
-        "id": "3",
+        "id": "2",
         "kind": "GRAPHQL",
         "overrideFieldPathFromAlias": true,
         "requestTimeoutSeconds": "10",
@@ -653,6 +437,222 @@
             "typeName": "Query"
           }
         ]
+      },
+      {
+        "childNodes": [
+          {
+            "fieldNames": [
+              "name",
+              "url",
+              "mimeType"
+            ],
+            "typeName": "Artifact"
+          },
+          {
+            "fieldNames": [
+              "content",
+              "podName"
+            ],
+            "typeName": "LogEntry"
+          },
+          {
+            "fieldNames": [
+              "hasPreviousPage",
+              "hasNextPage",
+              "startCursor",
+              "endCursor"
+            ],
+            "typeName": "PageInfo"
+          },
+          {
+            "fieldNames": [
+              "id",
+              "name",
+              "status",
+              "depends",
+              "dependencies",
+              "artifacts",
+              "stepType",
+              "startTime",
+              "endTime",
+              "message"
+            ],
+            "typeName": "Task"
+          },
+          {
+            "fieldNames": [
+              "repositoryUrl",
+              "path",
+              "targetRevision"
+            ],
+            "typeName": "TemplateSource"
+          },
+          {
+            "fieldNames": [
+              "proposalCode",
+              "proposalNumber",
+              "number"
+            ],
+            "typeName": "Visit"
+          },
+          {
+            "fieldNames": [
+              "id",
+              "name",
+              "visit",
+              "status",
+              "parameters",
+              "templateRef",
+              "creator"
+            ],
+            "typeName": "Workflow"
+          },
+          {
+            "fieldNames": [
+              "pageInfo",
+              "edges",
+              "nodes"
+            ],
+            "typeName": "WorkflowConnection"
+          },
+          {
+            "fieldNames": [
+              "creatorId"
+            ],
+            "typeName": "WorkflowCreator"
+          },
+          {
+            "fieldNames": [
+              "node",
+              "cursor"
+            ],
+            "typeName": "WorkflowEdge"
+          },
+          {
+            "fieldNames": [
+              "startTime",
+              "endTime",
+              "message",
+              "tasks"
+            ],
+            "typeName": "WorkflowErroredStatus"
+          },
+          {
+            "fieldNames": [
+              "startTime",
+              "endTime",
+              "message",
+              "tasks"
+            ],
+            "typeName": "WorkflowFailedStatus"
+          },
+          {
+            "fieldNames": [
+              "message"
+            ],
+            "typeName": "WorkflowPendingStatus"
+          },
+          {
+            "fieldNames": [
+              "startTime",
+              "message",
+              "tasks"
+            ],
+            "typeName": "WorkflowRunningStatus"
+          },
+          {
+            "fieldNames": [
+              "startTime",
+              "endTime",
+              "message",
+              "tasks"
+            ],
+            "typeName": "WorkflowSucceededStatus"
+          },
+          {
+            "fieldNames": [
+              "name",
+              "maintainer",
+              "title",
+              "description",
+              "repository",
+              "arguments",
+              "uiSchema",
+              "templateSource"
+            ],
+            "typeName": "WorkflowTemplate"
+          },
+          {
+            "fieldNames": [
+              "pageInfo",
+              "edges",
+              "nodes"
+            ],
+            "typeName": "WorkflowTemplateConnection"
+          },
+          {
+            "fieldNames": [
+              "node",
+              "cursor"
+            ],
+            "typeName": "WorkflowTemplateEdge"
+          }
+        ],
+        "customGraphql": {
+          "federation": {
+            "enabled": true,
+            "serviceSdl": "type Artifact {\n\t\"\"\"\n\tThe file name of the artifact\n\t\"\"\"\n\tname: String!\n\t\"\"\"\n\tThe download URL for the artifact\n\t\"\"\"\n\turl: Url!\n\t\"\"\"\n\tThe MIME type of the artifact data\n\t\"\"\"\n\tmimeType: String!\n}\n\nscalar Creator\n\n\"\"\"\nImplement the DateTime<Utc> scalar\n\nThe input/output is a string in RFC3339 format.\n\"\"\"\nscalar DateTime\n\n\"\"\"\nA scalar that can represent any JSON value.\n\"\"\"\nscalar JSON\n\n\"\"\"\nA scalar that can represent any JSON Object value.\n\"\"\"\nscalar JSONObject\n\n\"\"\"\nA single log line streamed from a pod\n\"\"\"\ntype LogEntry {\n\t\"\"\"\n\tThe log line content\n\t\"\"\"\n\tcontent: String!\n\t\"\"\"\n\tThe name of the pod producing the log\n\t\"\"\"\n\tpodName: String!\n}\n\n\"\"\"\nThe root mutation of the service\n\"\"\"\ntype Mutation {\n\tsubmitWorkflowTemplate(name: String!, visit: VisitInput!, parameters: JSON!): Workflow!\n}\n\n\"\"\"\nRepresents Relay Node types\n\"\"\"\nunion NodeValue = Workflow\n\n\"\"\"\nInformation about pagination in a connection\n\"\"\"\ntype PageInfo @shareable {\n\t\"\"\"\n\tWhen paginating backwards, are there more items?\n\t\"\"\"\n\thasPreviousPage: Boolean!\n\t\"\"\"\n\tWhen paginating forwards, are there more items?\n\t\"\"\"\n\thasNextPage: Boolean!\n\t\"\"\"\n\tWhen paginating backwards, the cursor to continue.\n\t\"\"\"\n\tstartCursor: String\n\t\"\"\"\n\tWhen paginating forwards, the cursor to continue.\n\t\"\"\"\n\tendCursor: String\n}\n\n\"\"\"\nThe root query of the service\n\"\"\"\ntype Query {\n\tnode(id: ID!): NodeValue\n\t\"\"\"\n\tGet a single [`Workflow`] by proposal, visit, and name\n\t\"\"\"\n\tworkflow(visit: VisitInput!, name: String!): Workflow!\n\tworkflows(visit: VisitInput!, cursor: String, limit: Int, filter: WorkflowFilter): WorkflowConnection!\n\tworkflowTemplate(name: String!): WorkflowTemplate!\n\tworkflowTemplates(cursor: String, limit: Int, filter: WorkflowTemplatesFilter): WorkflowTemplateConnection!\n}\n\n\"\"\"\nSupported DLS science groups\n\"\"\"\nenum ScienceGroup {\n\t\"\"\"\n\tMacromolecular Crystallography\n\t\"\"\"\n\tMX\n\t\"\"\"\n\tWorkflows Examples\n\t\"\"\"\n\tEXAMPLES\n\t\"\"\"\n\tMagnetic Materials\n\t\"\"\"\n\tMAGNETIC_MATERIALS\n\t\"\"\"\n\tSoft Condensed Matter\n\t\"\"\"\n\tCONDENSED_MATTER\n\t\"\"\"\n\tImaging and Microscopy\n\t\"\"\"\n\tIMAGING\n\t\"\"\"\n\tBiological Cryo-Imaging\n\t\"\"\"\n\tBIO_CRYO_IMAGING\n\t\"\"\"\n\tStructures and Surfaces\n\t\"\"\"\n\tSURFACES\n\t\"\"\"\n\tCrystallography\n\t\"\"\"\n\tCRYSTALLOGRAPHY\n\t\"\"\"\n\tSpectroscopy\n\t\"\"\"\n\tSPECTROSCOPY\n}\n\n\"\"\"\nThe root mutation of the service\n\"\"\"\ntype Subscription {\n\t\"\"\"\n\tProcessing to subscribe to logs for a single pod of a workflow\n\t\"\"\"\n\tlogs(visit: VisitInput!, workflowName: String!, taskId: String!): LogEntry!\n\t\"\"\"\n\tProcessing to subscribe to data for all workflows in a session\n\t\"\"\"\n\tworkflow(visit: VisitInput!, name: String!): Workflow!\n}\n\ntype Task {\n\t\"\"\"\n\tUnique name of the task\n\t\"\"\"\n\tid: String!\n\t\"\"\"\n\tDisplay name of the task\n\t\"\"\"\n\tname: String!\n\t\"\"\"\n\tCurrent status of a task\n\t\"\"\"\n\tstatus: TaskStatus!\n\t\"\"\"\n\tParent of a task\n\t\"\"\"\n\tdepends: [String!]!\n\t\"\"\"\n\tChildren of a task\n\t\"\"\"\n\tdependencies: [String!]!\n\t\"\"\"\n\tArtifacts produced by a task\n\t\"\"\"\n\tartifacts: [Artifact!]!\n\t\"\"\"\n\tNode type - Pod, DAG, etc\n\t\"\"\"\n\tstepType: String!\n\t\"\"\"\n\tStart time for a task on a workflow\n\t\"\"\"\n\tstartTime: DateTime\n\t\"\"\"\n\tEnd time for a task on a workflow\n\t\"\"\"\n\tendTime: DateTime\n\t\"\"\"\n\tA human readable message indicating details about why this step is in this condition\n\t\"\"\"\n\tmessage: String\n}\n\nenum TaskStatus {\n\tPENDING\n\tRUNNING\n\tSUCCEEDED\n\tSKIPPED\n\tFAILED\n\tERROR\n\tOMITTED\n}\n\nscalar Template\n\n\"\"\"\nInformation about where the template is stored\n\"\"\"\ntype TemplateSource {\n\t\"\"\"\n\tThe URL of the GitHub repository\n\t\"\"\"\n\trepositoryUrl: String!\n\t\"\"\"\n\tThe path to the template within the repository\n\t\"\"\"\n\tpath: String!\n\t\"\"\"\n\tThe current tracked branch of the repository\n\t\"\"\"\n\ttargetRevision: String!\n}\n\n\"\"\"\nURL is a String implementing the [URL Standard](http://url.spec.whatwg.org/)\n\"\"\"\nscalar Url\n\n\"\"\"\nA visit to an instrument as part of a session\n\"\"\"\ntype Visit {\n\t\"\"\"\n\tProject Proposal Code\n\t\"\"\"\n\tproposalCode: String!\n\t\"\"\"\n\tProject Proposal Number\n\t\"\"\"\n\tproposalNumber: Int!\n\t\"\"\"\n\tSession visit Number\n\t\"\"\"\n\tnumber: Int!\n}\n\n\"\"\"\nA visit to an instrument as part of a session\n\"\"\"\ninput VisitInput {\n\t\"\"\"\n\tProject Proposal Code\n\t\"\"\"\n\tproposalCode: String!\n\t\"\"\"\n\tProject Proposal Number\n\t\"\"\"\n\tproposalNumber: Int!\n\t\"\"\"\n\tSession visit Number\n\t\"\"\"\n\tnumber: Int!\n}\n\ntype Workflow {\n\t\"\"\"\n\tThe unique ID derived from the visit and name\n\t\"\"\"\n\tid: ID!\n\t\"\"\"\n\tThe name given to the workflow, unique within a given visit\n\t\"\"\"\n\tname: String!\n\t\"\"\"\n\tThe visit the Workflow was run against\n\t\"\"\"\n\tvisit: Visit!\n\t\"\"\"\n\tThe current status of the workflow\n\t\"\"\"\n\tstatus: WorkflowStatus\n\t\"\"\"\n\tThe top-level workflow parameters\n\t\"\"\"\n\tparameters: JSONObject\n\t\"\"\"\n\tThe name of the template used to run the workflow\n\t\"\"\"\n\ttemplateRef: String\n\t\"\"\"\n\tThe workflow creator\n\t\"\"\"\n\tcreator: WorkflowCreator!\n}\n\ntype WorkflowConnection @shareable {\n\t\"\"\"\n\tInformation to aid in pagination.\n\t\"\"\"\n\tpageInfo: PageInfo!\n\t\"\"\"\n\tA list of edges.\n\t\"\"\"\n\tedges: [WorkflowEdge!]!\n\t\"\"\"\n\tA list of nodes.\n\t\"\"\"\n\tnodes: [Workflow!]!\n}\n\n\"\"\"\nInformation about the creator of a workflow.\n\"\"\"\ntype WorkflowCreator {\n\t\"\"\"\n\tAn identifier unique to the creator of the workflow.\n\tTypically this is the creator's Fed-ID.\n\t\"\"\"\n\tcreatorId: String!\n}\n\n\"\"\"\nAn edge in a connection.\n\"\"\"\ntype WorkflowEdge @shareable {\n\t\"\"\"\n\tThe item at the end of the edge\n\t\"\"\"\n\tnode: Workflow!\n\t\"\"\"\n\tA cursor for use in pagination\n\t\"\"\"\n\tcursor: String!\n}\n\n\"\"\"\nAll tasks in the workflow have errored\n\"\"\"\ntype WorkflowErroredStatus {\n\t\"\"\"\n\tTime at which this workflow started\n\t\"\"\"\n\tstartTime: DateTime!\n\t\"\"\"\n\tTime at which this workflow completed\n\t\"\"\"\n\tendTime: DateTime!\n\t\"\"\"\n\tA human readable message indicating details about why the workflow is in this condition\n\t\"\"\"\n\tmessage: String\n\t\"\"\"\n\tTasks created by the workflow\n\t\"\"\"\n\ttasks: [Task!]!\n}\n\n\"\"\"\nAll tasks in the workflow have failed\n\"\"\"\ntype WorkflowFailedStatus {\n\t\"\"\"\n\tTime at which this workflow started\n\t\"\"\"\n\tstartTime: DateTime!\n\t\"\"\"\n\tTime at which this workflow completed\n\t\"\"\"\n\tendTime: DateTime!\n\t\"\"\"\n\tA human readable message indicating details about why the workflow is in this condition\n\t\"\"\"\n\tmessage: String\n\t\"\"\"\n\tTasks created by the workflow\n\t\"\"\"\n\ttasks: [Task!]!\n}\n\n\"\"\"\nAll the supported Workflows filters\n\"\"\"\ninput WorkflowFilter {\n\t\"\"\"\n\tThe status field for a workflow\n\t\"\"\"\n\tworkflowStatusFilter: WorkflowStatusFilter\n\t\"\"\"\n\tThe fedid of the user who created the workflow\n\t\"\"\"\n\tcreator: Creator\n\t\"\"\"\n\tThe name of the workflow template\n\t\"\"\"\n\ttemplate: Template\n}\n\ntype WorkflowPendingStatus {\n\t\"\"\"\n\tA human readable message indicating details about why the workflow is in this condition\n\t\"\"\"\n\tmessage: String\n}\n\ntype WorkflowRunningStatus {\n\t\"\"\"\n\tTime at which this workflow started\n\t\"\"\"\n\tstartTime: DateTime!\n\t\"\"\"\n\tA human readable message indicating details about why the workflow is in this condition\n\t\"\"\"\n\tmessage: String\n\t\"\"\"\n\tTasks created by the workflow\n\t\"\"\"\n\ttasks: [Task!]!\n}\n\n\"\"\"\nThe status of a workflow\n\"\"\"\nunion WorkflowStatus = WorkflowPendingStatus | WorkflowRunningStatus | WorkflowSucceededStatus | WorkflowFailedStatus | WorkflowErroredStatus\n\n\"\"\"\nRepresents workflow status filters\n\"\"\"\ninput WorkflowStatusFilter {\n\tpending: Boolean! = false\n\trunning: Boolean! = false\n\tsucceeded: Boolean! = false\n\tfailed: Boolean! = false\n\terror: Boolean! = false\n}\n\n\"\"\"\nAll tasks in the workflow have succeded\n\"\"\"\ntype WorkflowSucceededStatus {\n\t\"\"\"\n\tTime at which this workflow started\n\t\"\"\"\n\tstartTime: DateTime!\n\t\"\"\"\n\tTime at which this workflow completed\n\t\"\"\"\n\tendTime: DateTime!\n\t\"\"\"\n\tA human readable message indicating details about why the workflow is in this condition\n\t\"\"\"\n\tmessage: String\n\t\"\"\"\n\tTasks created by the workflow\n\t\"\"\"\n\ttasks: [Task!]!\n}\n\ntype WorkflowTemplate {\n\t\"\"\"\n\tThe name given to the workflow template, globally unique\n\t\"\"\"\n\tname: String!\n\t\"\"\"\n\tThe group who maintains the workflow template\n\t\"\"\"\n\tmaintainer: String!\n\t\"\"\"\n\tA human readable title for the workflow template\n\t\"\"\"\n\ttitle: String\n\t\"\"\"\n\tA human readable description of the workflow which is created\n\t\"\"\"\n\tdescription: String\n\t\"\"\"\n\tThe repository storing the code associated with this template.\n\t\"\"\"\n\trepository: String\n\t\"\"\"\n\tA JSON Schema describing the arguments of a Workflow Template\n\t\"\"\"\n\targuments: JSON!\n\t\"\"\"\n\tA JSON Forms UI Schema describing how to render the arguments of the Workflow Template\n\t\"\"\"\n\tuiSchema: JSON\n\t\"\"\"\n\tInformation about where the template is obtained from\n\t\"\"\"\n\ttemplateSource: TemplateSource\n}\n\ntype WorkflowTemplateConnection @shareable {\n\t\"\"\"\n\tInformation to aid in pagination.\n\t\"\"\"\n\tpageInfo: PageInfo!\n\t\"\"\"\n\tA list of edges.\n\t\"\"\"\n\tedges: [WorkflowTemplateEdge!]!\n\t\"\"\"\n\tA list of nodes.\n\t\"\"\"\n\tnodes: [WorkflowTemplate!]!\n}\n\n\"\"\"\nAn edge in a connection.\n\"\"\"\ntype WorkflowTemplateEdge @shareable {\n\t\"\"\"\n\tThe item at the end of the edge\n\t\"\"\"\n\tnode: WorkflowTemplate!\n\t\"\"\"\n\tA cursor for use in pagination\n\t\"\"\"\n\tcursor: String!\n}\n\n\"\"\"\nSupported label filters for ClusterWorkflowTemplates\n\"\"\"\ninput WorkflowTemplatesFilter {\n\t\"\"\"\n\tThe science group owning the template eg imaging\n\t\"\"\"\n\tscienceGroup: [ScienceGroup!]\n}\n\n\"\"\"\nDirects the executor to include this field or fragment only when the `if` argument is true.\n\"\"\"\ndirective @include(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT\n\"\"\"\nDirects the executor to skip this field or fragment when the `if` argument is true.\n\"\"\"\ndirective @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT\n\"\"\"\nProvides a scalar specification URL for specifying the behavior of custom scalar types.\n\"\"\"\ndirective @specifiedBy(url: String!) on SCALAR\nextend schema @link(\n\turl: \"https://specs.apollo.dev/federation/v2.5\",\n\timport: [\"@key\", \"@tag\", \"@shareable\", \"@inaccessible\", \"@override\", \"@external\", \"@provides\", \"@requires\", \"@composeDirective\", \"@interfaceObject\", \"@requiresScopes\"]\n)\n"
+          },
+          "fetch": {
+            "baseUrl": {},
+            "body": {},
+            "method": "POST",
+            "path": {},
+            "url": {
+              "staticVariableContent": "https://workflows.diamond.ac.uk/graphql"
+            }
+          },
+          "subscription": {
+            "enabled": true,
+            "protocol": "GRAPHQL_SUBSCRIPTION_PROTOCOL_WS",
+            "url": {
+              "staticVariableContent": "https://workflows.diamond.ac.uk/graphql"
+            },
+            "websocketSubprotocol": "GRAPHQL_WEBSOCKET_SUBPROTOCOL_AUTO"
+          },
+          "upstreamSchema": {
+            "key": "9a94e595184badd514b2996e26945dd3a01edbf4"
+          }
+        },
+        "id": "3",
+        "kind": "GRAPHQL",
+        "overrideFieldPathFromAlias": true,
+        "requestTimeoutSeconds": "10",
+        "rootNodes": [
+          {
+            "fieldNames": [
+              "submitWorkflowTemplate"
+            ],
+            "typeName": "Mutation"
+          },
+          {
+            "fieldNames": [
+              "node",
+              "workflow",
+              "workflows",
+              "workflowTemplate",
+              "workflowTemplates"
+            ],
+            "typeName": "Query"
+          },
+          {
+            "fieldNames": [
+              "logs",
+              "workflow"
+            ],
+            "typeName": "Subscription"
+          }
+        ]
       }
     ],
     "defaultFlushInterval": "500",
@@ -660,34 +660,32 @@
       {
         "argumentsConfiguration": [
           {
-            "name": "name",
+            "name": "first",
             "sourceType": "FIELD_ARGUMENT"
           },
           {
-            "name": "visit",
+            "name": "filter",
             "sourceType": "FIELD_ARGUMENT"
           },
           {
-            "name": "parameters",
+            "name": "before",
             "sourceType": "FIELD_ARGUMENT"
-          }
-        ],
-        "fieldName": "submitWorkflowTemplate",
-        "typeName": "Mutation"
-      },
-      {
-        "argumentsConfiguration": [
+          },
           {
-            "name": "proposalNumber",
+            "name": "after",
             "sourceType": "FIELD_ARGUMENT"
           },
           {
-            "name": "instrumentSessionNumber",
+            "name": "last",
+            "sourceType": "FIELD_ARGUMENT"
+          },
+          {
+            "name": "orderBy",
             "sourceType": "FIELD_ARGUMENT"
           }
         ],
-        "fieldName": "instrumentSession",
-        "typeName": "Mutation"
+        "fieldName": "samples",
+        "typeName": "InstrumentSession"
       },
       {
         "argumentsConfiguration": [
@@ -697,101 +695,69 @@
           }
         ],
         "fieldName": "createOrValidateSamples",
-        "typeName": "Mutation"
+        "typeName": "InstrumentSessionMutations"
       },
       {
         "argumentsConfiguration": [
           {
-            "name": "input",
+            "name": "proposalNumber",
             "sourceType": "FIELD_ARGUMENT"
-          }
-        ],
-        "fieldName": "createSamples",
-        "typeName": "Mutation"
-      },
-      {
-        "argumentsConfiguration": [
+          },
           {
-            "name": "sampleId",
+            "name": "instrumentSessionNumber",
             "sourceType": "FIELD_ARGUMENT"
           }
         ],
-        "fieldName": "sample",
+        "fieldName": "instrumentSession",
         "typeName": "Mutation"
       },
       {
         "argumentsConfiguration": [
           {
-            "name": "id",
+            "name": "input",
             "sourceType": "FIELD_ARGUMENT"
           }
         ],
-        "fieldName": "node",
-        "typeName": "Query"
+        "fieldName": "createOrValidateSamples",
+        "typeName": "Mutation"
       },
       {
         "argumentsConfiguration": [
           {
-            "name": "visit",
-            "sourceType": "FIELD_ARGUMENT"
-          },
-          {
-            "name": "name",
+            "name": "input",
             "sourceType": "FIELD_ARGUMENT"
           }
         ],
-        "fieldName": "workflow",
-        "typeName": "Query"
+        "fieldName": "createSamples",
+        "typeName": "Mutation"
       },
       {
         "argumentsConfiguration": [
           {
-            "name": "visit",
-            "sourceType": "FIELD_ARGUMENT"
-          },
-          {
-            "name": "cursor",
-            "sourceType": "FIELD_ARGUMENT"
-          },
-          {
-            "name": "limit",
-            "sourceType": "FIELD_ARGUMENT"
-          },
-          {
-            "name": "filter",
+            "name": "sampleId",
             "sourceType": "FIELD_ARGUMENT"
           }
         ],
-        "fieldName": "workflows",
-        "typeName": "Query"
+        "fieldName": "sample",
+        "typeName": "Mutation"
       },
       {
         "argumentsConfiguration": [
           {
             "name": "name",
             "sourceType": "FIELD_ARGUMENT"
-          }
-        ],
-        "fieldName": "workflowTemplate",
-        "typeName": "Query"
-      },
-      {
-        "argumentsConfiguration": [
-          {
-            "name": "cursor",
-            "sourceType": "FIELD_ARGUMENT"
           },
           {
-            "name": "limit",
+            "name": "visit",
             "sourceType": "FIELD_ARGUMENT"
           },
           {
-            "name": "filter",
+            "name": "parameters",
             "sourceType": "FIELD_ARGUMENT"
           }
         ],
-        "fieldName": "workflowTemplates",
-        "typeName": "Query"
+        "fieldName": "submitWorkflowTemplate",
+        "typeName": "Mutation"
       },
       {
         "argumentsConfiguration": [
@@ -958,20 +924,12 @@
       {
         "argumentsConfiguration": [
           {
-            "name": "visit",
-            "sourceType": "FIELD_ARGUMENT"
-          },
-          {
-            "name": "workflowName",
-            "sourceType": "FIELD_ARGUMENT"
-          },
-          {
-            "name": "taskId",
+            "name": "id",
             "sourceType": "FIELD_ARGUMENT"
           }
         ],
-        "fieldName": "logs",
-        "typeName": "Subscription"
+        "fieldName": "node",
+        "typeName": "Query"
       },
       {
         "argumentsConfiguration": [
@@ -985,47 +943,57 @@
           }
         ],
         "fieldName": "workflow",
-        "typeName": "Subscription"
+        "typeName": "Query"
       },
       {
         "argumentsConfiguration": [
           {
-            "name": "first",
-            "sourceType": "FIELD_ARGUMENT"
-          },
-          {
-            "name": "filter",
+            "name": "visit",
             "sourceType": "FIELD_ARGUMENT"
           },
           {
-            "name": "before",
+            "name": "cursor",
             "sourceType": "FIELD_ARGUMENT"
           },
           {
-            "name": "after",
+            "name": "limit",
             "sourceType": "FIELD_ARGUMENT"
           },
           {
-            "name": "last",
+            "name": "filter",
             "sourceType": "FIELD_ARGUMENT"
-          },
+          }
+        ],
+        "fieldName": "workflows",
+        "typeName": "Query"
+      },
+      {
+        "argumentsConfiguration": [
           {
-            "name": "orderBy",
+            "name": "name",
             "sourceType": "FIELD_ARGUMENT"
           }
         ],
-        "fieldName": "samples",
-        "typeName": "InstrumentSession"
+        "fieldName": "workflowTemplate",
+        "typeName": "Query"
       },
       {
         "argumentsConfiguration": [
           {
-            "name": "input",
+            "name": "cursor",
+            "sourceType": "FIELD_ARGUMENT"
+          },
+          {
+            "name": "limit",
+            "sourceType": "FIELD_ARGUMENT"
+          },
+          {
+            "name": "filter",
             "sourceType": "FIELD_ARGUMENT"
           }
         ],
-        "fieldName": "createOrValidateSamples",
-        "typeName": "InstrumentSessionMutations"
+        "fieldName": "workflowTemplates",
+        "typeName": "Query"
       },
       {
         "argumentsConfiguration": [
@@ -1134,9 +1102,41 @@
         ],
         "fieldName": "createSampleImageUploadUrl",
         "typeName": "SampleMutations"
+      },
+      {
+        "argumentsConfiguration": [
+          {
+            "name": "visit",
+            "sourceType": "FIELD_ARGUMENT"
+          },
+          {
+            "name": "workflowName",
+            "sourceType": "FIELD_ARGUMENT"
+          },
+          {
+            "name": "taskId",
+            "sourceType": "FIELD_ARGUMENT"
+          }
+        ],
+        "fieldName": "logs",
+        "typeName": "Subscription"
+      },
+      {
+        "argumentsConfiguration": [
+          {
+            "name": "visit",
+            "sourceType": "FIELD_ARGUMENT"
+          },
+          {
+            "name": "name",
+            "sourceType": "FIELD_ARGUMENT"
+          }
+        ],
+        "fieldName": "workflow",
+        "typeName": "Subscription"
       }
     ],
-    "graphqlSchema": "schema {\n  query: Query\n  mutation: Mutation\n  subscription: Subscription\n}\n\ntype Artifact {\n  \"\"\"The file name of the artifact\"\"\"\n  name: String!\n  \"\"\"The download URL for the artifact\"\"\"\n  url: Url!\n  \"\"\"The MIME type of the artifact data\"\"\"\n  mimeType: String!\n}\n\nscalar Creator\n\n\"\"\"\nImplement the DateTime<Utc> scalar\n\nThe input/output is a string in RFC3339 format.\n\"\"\"\nscalar DateTime\n\n\"\"\"\nThe `JSON` scalar type represents JSON values as specified by [ECMA-404](https://ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf).\n\"\"\"\nscalar JSON\n\n\"\"\"A scalar that can represent any JSON Object value.\"\"\"\nscalar JSONObject\n\n\"\"\"A single log line streamed from a pod\"\"\"\ntype LogEntry {\n  \"\"\"The log line content\"\"\"\n  content: String!\n  \"\"\"The name of the pod producing the log\"\"\"\n  podName: String!\n}\n\n\"\"\"The root mutation of the service\"\"\"\ntype Mutation {\n  submitWorkflowTemplate(name: String!, visit: VisitInput!, parameters: JSON!): Workflow!\n  instrumentSession(proposalNumber: Int!, instrumentSessionNumber: Int!): InstrumentSessionMutations\n  createOrValidateSamples(input: CreateOrValidateSampleInput!): CreateSamplesResponse!\n  createSamples(input: CreateSampleInput!): [Sample!]! @deprecated(reason: \"Will be replaced by createOrValidateSamples\")\n  sample(sampleId: UUID!): SampleMutations\n}\n\n\"\"\"Represents Relay Node types\"\"\"\nunion NodeValue = Workflow\n\n\"\"\"Information about pagination in a connection\"\"\"\ntype PageInfo {\n  \"\"\"When paginating backwards, are there more items?\"\"\"\n  hasPreviousPage: Boolean!\n  \"\"\"When paginating forwards, are there more items?\"\"\"\n  hasNextPage: Boolean!\n  \"\"\"When paginating backwards, the cursor to continue.\"\"\"\n  startCursor: String\n  \"\"\"When paginating forwards, the cursor to continue.\"\"\"\n  endCursor: String\n}\n\n\"\"\"The root query of the service\"\"\"\ntype Query {\n  node(id: ID!): NodeValue\n  \"\"\"Get a single [`Workflow`] by proposal, visit, and name\"\"\"\n  workflow(visit: VisitInput!, name: String!): Workflow!\n  workflows(visit: VisitInput!, cursor: String, limit: Int, filter: WorkflowFilter): WorkflowConnection!\n  workflowTemplate(name: String!): WorkflowTemplate!\n  workflowTemplates(cursor: String, limit: Int, filter: WorkflowTemplatesFilter): WorkflowTemplateConnection!\n  \"\"\"Get a proposal by its number\"\"\"\n  proposal(proposalNumber: Int!): Proposal\n  \"\"\"Get a list of proposals\"\"\"\n  proposals(proposalCategory: String = null, first: Int = null, last: Int = null, after: String = null, before: String = null): ProposalConnection!\n  \"\"\"Get a instrument session\"\"\"\n  instrumentSession(proposalNumber: Int!, instrumentSessionNumber: Int!): InstrumentSession\n  \"\"\"Get a instrument session\"\"\"\n  instrumentSessions(proposalNumber: Int = null, proposalCategory: String = null): [InstrumentSession!]\n  \"\"\"Get an instrument\"\"\"\n  instrument(instrumentName: String!): Instrument\n  \"\"\"Get a list of instruments\"\"\"\n  instruments(scienceGroup: String = null): [Instrument!]!\n  \"\"\"Get an account\"\"\"\n  account(username: String!): Account\n  \"\"\"Get a list of samples associated with a given instrument session\"\"\"\n  samples(first: Int!, instrumentSessions: [InstrumentSessionInput!] = null, filter: SampleFilterInput! = {schemaUrl: null, createdTime: null, updatedTime: null, name: null, data: null}, before: String = null, after: String = null, last: Int = null, orderBy: SampleOrder! = {name: null, createdTime: null, updatedTime: null}): SampleConnection!\n  \"\"\"Get a sample by its id\"\"\"\n  sample(sampleId: UUID!): Sample\n  jsonSchema(url: String!): JSONSchema\n  jsonSchemas(type: String = null, instrument: String = null): [JSONSchema!]!\n}\n\n\"\"\"Supported DLS science groups\"\"\"\nenum ScienceGroup {\n  \"\"\"Macromolecular Crystallography\"\"\"\n  MX\n  \"\"\"Workflows Examples\"\"\"\n  EXAMPLES\n  \"\"\"Magnetic Materials\"\"\"\n  MAGNETIC_MATERIALS\n  \"\"\"Soft Condensed Matter\"\"\"\n  CONDENSED_MATTER\n  \"\"\"Imaging and Microscopy\"\"\"\n  IMAGING\n  \"\"\"Biological Cryo-Imaging\"\"\"\n  BIO_CRYO_IMAGING\n  \"\"\"Structures and Surfaces\"\"\"\n  SURFACES\n  \"\"\"Crystallography\"\"\"\n  CRYSTALLOGRAPHY\n  \"\"\"Spectroscopy\"\"\"\n  SPECTROSCOPY\n}\n\n\"\"\"The root mutation of the service\"\"\"\ntype Subscription {\n  \"\"\"Processing to subscribe to logs for a single pod of a workflow\"\"\"\n  logs(visit: VisitInput!, workflowName: String!, taskId: String!): LogEntry!\n  \"\"\"Processing to subscribe to data for all workflows in a session\"\"\"\n  workflow(visit: VisitInput!, name: String!): Workflow!\n}\n\ntype Task {\n  \"\"\"Unique name of the task\"\"\"\n  id: String!\n  \"\"\"Display name of the task\"\"\"\n  name: String!\n  \"\"\"Current status of a task\"\"\"\n  status: TaskStatus!\n  \"\"\"Parent of a task\"\"\"\n  depends: [String!]!\n  \"\"\"Children of a task\"\"\"\n  dependencies: [String!]!\n  \"\"\"Artifacts produced by a task\"\"\"\n  artifacts: [Artifact!]!\n  \"\"\"Node type - Pod, DAG, etc\"\"\"\n  stepType: String!\n  \"\"\"Start time for a task on a workflow\"\"\"\n  startTime: DateTime\n  \"\"\"End time for a task on a workflow\"\"\"\n  endTime: DateTime\n  \"\"\"\n  A human readable message indicating details about why this step is in this condition\n  \"\"\"\n  message: String\n}\n\nenum TaskStatus {\n  PENDING\n  RUNNING\n  SUCCEEDED\n  SKIPPED\n  FAILED\n  ERROR\n  OMITTED\n}\n\nscalar Template\n\n\"\"\"Information about where the template is stored\"\"\"\ntype TemplateSource {\n  \"\"\"The URL of the GitHub repository\"\"\"\n  repositoryUrl: String!\n  \"\"\"The path to the template within the repository\"\"\"\n  path: String!\n  \"\"\"The current tracked branch of the repository\"\"\"\n  targetRevision: String!\n}\n\n\"\"\"\nURL is a String implementing the [URL Standard](http://url.spec.whatwg.org/)\n\"\"\"\nscalar Url\n\n\"\"\"A visit to an instrument as part of a session\"\"\"\ntype Visit {\n  \"\"\"Project Proposal Code\"\"\"\n  proposalCode: String!\n  \"\"\"Project Proposal Number\"\"\"\n  proposalNumber: Int!\n  \"\"\"Session visit Number\"\"\"\n  number: Int!\n}\n\n\"\"\"A visit to an instrument as part of a session\"\"\"\ninput VisitInput {\n  \"\"\"Project Proposal Code\"\"\"\n  proposalCode: String!\n  \"\"\"Project Proposal Number\"\"\"\n  proposalNumber: Int!\n  \"\"\"Session visit Number\"\"\"\n  number: Int!\n}\n\ntype Workflow {\n  \"\"\"The unique ID derived from the visit and name\"\"\"\n  id: ID!\n  \"\"\"The name given to the workflow, unique within a given visit\"\"\"\n  name: String!\n  \"\"\"The visit the Workflow was run against\"\"\"\n  visit: Visit!\n  \"\"\"The current status of the workflow\"\"\"\n  status: WorkflowStatus\n  \"\"\"The top-level workflow parameters\"\"\"\n  parameters: JSONObject\n  \"\"\"The name of the template used to run the workflow\"\"\"\n  templateRef: String\n  \"\"\"The workflow creator\"\"\"\n  creator: WorkflowCreator!\n}\n\ntype WorkflowConnection {\n  \"\"\"Information to aid in pagination.\"\"\"\n  pageInfo: PageInfo!\n  \"\"\"A list of edges.\"\"\"\n  edges: [WorkflowEdge!]!\n  \"\"\"A list of nodes.\"\"\"\n  nodes: [Workflow!]!\n}\n\n\"\"\"Information about the creator of a workflow.\"\"\"\ntype WorkflowCreator {\n  \"\"\"\n  An identifier unique to the creator of the workflow.\n  Typically this is the creator's Fed-ID.\n  \"\"\"\n  creatorId: String!\n}\n\n\"\"\"An edge in a connection.\"\"\"\ntype WorkflowEdge {\n  \"\"\"The item at the end of the edge\"\"\"\n  node: Workflow!\n  \"\"\"A cursor for use in pagination\"\"\"\n  cursor: String!\n}\n\n\"\"\"All tasks in the workflow have errored\"\"\"\ntype WorkflowErroredStatus {\n  \"\"\"Time at which this workflow started\"\"\"\n  startTime: DateTime!\n  \"\"\"Time at which this workflow completed\"\"\"\n  endTime: DateTime!\n  \"\"\"\n  A human readable message indicating details about why the workflow is in this condition\n  \"\"\"\n  message: String\n  \"\"\"Tasks created by the workflow\"\"\"\n  tasks: [Task!]!\n}\n\n\"\"\"All tasks in the workflow have failed\"\"\"\ntype WorkflowFailedStatus {\n  \"\"\"Time at which this workflow started\"\"\"\n  startTime: DateTime!\n  \"\"\"Time at which this workflow completed\"\"\"\n  endTime: DateTime!\n  \"\"\"\n  A human readable message indicating details about why the workflow is in this condition\n  \"\"\"\n  message: String\n  \"\"\"Tasks created by the workflow\"\"\"\n  tasks: [Task!]!\n}\n\n\"\"\"All the supported Workflows filters\"\"\"\ninput WorkflowFilter {\n  \"\"\"The status field for a workflow\"\"\"\n  workflowStatusFilter: WorkflowStatusFilter\n  \"\"\"The fedid of the user who created the workflow\"\"\"\n  creator: Creator\n  \"\"\"The name of the workflow template\"\"\"\n  template: Template\n}\n\ntype WorkflowPendingStatus {\n  \"\"\"\n  A human readable message indicating details about why the workflow is in this condition\n  \"\"\"\n  message: String\n}\n\ntype WorkflowRunningStatus {\n  \"\"\"Time at which this workflow started\"\"\"\n  startTime: DateTime!\n  \"\"\"\n  A human readable message indicating details about why the workflow is in this condition\n  \"\"\"\n  message: String\n  \"\"\"Tasks created by the workflow\"\"\"\n  tasks: [Task!]!\n}\n\n\"\"\"The status of a workflow\"\"\"\nunion WorkflowStatus = WorkflowPendingStatus | WorkflowRunningStatus | WorkflowSucceededStatus | WorkflowFailedStatus | WorkflowErroredStatus\n\n\"\"\"Represents workflow status filters\"\"\"\ninput WorkflowStatusFilter {\n  pending: Boolean! = false\n  running: Boolean! = false\n  succeeded: Boolean! = false\n  failed: Boolean! = false\n  error: Boolean! = false\n}\n\n\"\"\"All tasks in the workflow have succeded\"\"\"\ntype WorkflowSucceededStatus {\n  \"\"\"Time at which this workflow started\"\"\"\n  startTime: DateTime!\n  \"\"\"Time at which this workflow completed\"\"\"\n  endTime: DateTime!\n  \"\"\"\n  A human readable message indicating details about why the workflow is in this condition\n  \"\"\"\n  message: String\n  \"\"\"Tasks created by the workflow\"\"\"\n  tasks: [Task!]!\n}\n\ntype WorkflowTemplate {\n  \"\"\"The name given to the workflow template, globally unique\"\"\"\n  name: String!\n  \"\"\"The group who maintains the workflow template\"\"\"\n  maintainer: String!\n  \"\"\"A human readable title for the workflow template\"\"\"\n  title: String\n  \"\"\"A human readable description of the workflow which is created\"\"\"\n  description: String\n  \"\"\"The repository storing the code associated with this template.\"\"\"\n  repository: String\n  \"\"\"A JSON Schema describing the arguments of a Workflow Template\"\"\"\n  arguments: JSON!\n  \"\"\"\n  A JSON Forms UI Schema describing how to render the arguments of the Workflow Template\n  \"\"\"\n  uiSchema: JSON\n  \"\"\"Information about where the template is obtained from\"\"\"\n  templateSource: TemplateSource\n}\n\ntype WorkflowTemplateConnection {\n  \"\"\"Information to aid in pagination.\"\"\"\n  pageInfo: PageInfo!\n  \"\"\"A list of edges.\"\"\"\n  edges: [WorkflowTemplateEdge!]!\n  \"\"\"A list of nodes.\"\"\"\n  nodes: [WorkflowTemplate!]!\n}\n\n\"\"\"An edge in a connection.\"\"\"\ntype WorkflowTemplateEdge {\n  \"\"\"The item at the end of the edge\"\"\"\n  node: WorkflowTemplate!\n  \"\"\"A cursor for use in pagination\"\"\"\n  cursor: String!\n}\n\n\"\"\"Supported label filters for ClusterWorkflowTemplates\"\"\"\ninput WorkflowTemplatesFilter {\n  \"\"\"The science group owning the template eg imaging\"\"\"\n  scienceGroup: [ScienceGroup!]\n}\n\ntype Account {\n  accountId: Int!\n  username: String!\n  emailAddress: String\n  title: String\n  givenName: String\n  familyName: String\n  type: AccountType!\n  state: AccountState!\n  proposalRoles: [ProposalAccount!]!\n  instrumentSessionRoles: [InstrumentSessionRole!]!\n}\n\nenum AccountState {\n  enabled\n  disabled\n}\n\nenum AccountType {\n  user\n  staff\n  functional\n}\n\ntype Instrument {\n  name: String!\n  scienceGroup: String\n  description: String\n  proposals: [Proposal!]!\n  instrumentSessions: [InstrumentSession!]!\n}\n\ntype InstrumentSession {\n  instrumentSessionId: Int!\n  instrumentSessionNumber: Int!\n  startTime: DateTime\n  endTime: DateTime\n  type: String\n  state: String\n  riskRating: String\n  proposal: Proposal\n  instrument: Instrument!\n  roles: [InstrumentSessionRole!]!\n  \"\"\"Samples associated with a given instrument session\"\"\"\n  samples(first: Int!, filter: SampleFilterInput! = {schemaUrl: null, createdTime: null, updatedTime: null, name: null, data: null}, before: String = null, after: String = null, last: Int = null, orderBy: SampleOrder! = {name: null, createdTime: null, updatedTime: null}): SampleConnection!\n}\n\ntype InstrumentSessionMutations {\n  instrumentSessionNumber: Int!\n  proposalNumber: Int!\n  \"\"\"Create or validate samples associated with this instrument session\"\"\"\n  createOrValidateSamples(input: CreateOrValidateSampleInputBase!): CreateSamplesResponse!\n}\n\ntype InstrumentSessionRole {\n  instrumentSession: InstrumentSession!\n  account: Account!\n  role: String!\n  onSite: Boolean!\n}\n\ntype Proposal {\n  proposalNumber: Int!\n  proposalCategory: String\n  title: String\n  summary: String\n  state: ProposalState!\n  instrumentSessions: [InstrumentSession!]!\n  instruments: [Instrument!]!\n  roles: [ProposalAccount!]!\n}\n\ntype ProposalAccount {\n  proposal: Proposal!\n  account: Account!\n  role: String!\n}\n\ntype ProposalConnection {\n  edges: [ProposalEdge!]!\n  pageInfo: PageInfo!\n}\n\ntype ProposalEdge {\n  cursor: String!\n  node: Proposal!\n}\n\nenum ProposalState {\n  Open\n  Closed\n  Cancelled\n}\n\ninput AddSampleEventInput {\n  description: String!\n}\n\ninput CreateOrValidateSampleInput {\n  \"\"\"URL of the JSON schema the samples' `data` should be validated against\"\"\"\n  dataSchemaUrl: String!\n  \"\"\"Samples to be created\"\"\"\n  samples: [SampleIn!]!\n  \"\"\"\n  Whether or not the provided samples should only be validated and not created\n  \"\"\"\n  validateOnly: Boolean! = false\n  \"\"\"Number of the proposal the samples should be associated with\"\"\"\n  proposalNumber: Int!\n  \"\"\"Number of the instrument session the samples should be associated with\"\"\"\n  instrumentSessionNumber: Int!\n}\n\ninput CreateOrValidateSampleInputBase {\n  \"\"\"URL of the JSON schema the samples' `data` should be validated against\"\"\"\n  dataSchemaUrl: String!\n  \"\"\"Samples to be created\"\"\"\n  samples: [SampleIn!]!\n  \"\"\"\n  Whether or not the provided samples should only be validated and not created\n  \"\"\"\n  validateOnly: Boolean! = false\n}\n\ninput CreateSampleInput {\n  proposalNumber: Int!\n  instrumentSessionNumber: Int!\n  samples: [SampleInLegacy!]!\n  validateOnly: Boolean! = false\n}\n\n\"\"\"Return type when creating or validating samples\"\"\"\ntype CreateSamplesResponse {\n  \"\"\"Whether the operation has succeeded without validation errors\"\"\"\n  success: Boolean!\n  \"\"\"Samples that have been created\"\"\"\n  samples: [Sample!]!\n  \"\"\"Errors that occurred during sample validation\"\"\"\n  errors: [SampleValidationError!]!\n}\n\ninput DatetimeOperatorInput {\n  \"\"\"\n  Will filter to items where the `DateTime` field is greater than (i.e. after) the provided value\n  \"\"\"\n  gt: DateTime = null\n  \"\"\"\n  Will filter to items where the `DateTime` field is less than (i.e. before) the provided value\n  \"\"\"\n  lt: DateTime = null\n}\n\n\"\"\"The details of sample validation error\"\"\"\ntype ErrorDetails {\n  \"\"\"The type of error that occurred\"\"\"\n  type: String!\n  \"\"\"\n  Tuple of strings identifying where in the sample schema the error occurred.\n  \"\"\"\n  location: [String!]!\n  \"\"\"A human readable error message.\"\"\"\n  message: String!\n}\n\ntype InstrumentSessionConnection {\n  edges: [InstrumentSessionEdge!]!\n  pageInfo: PageInfo!\n}\n\ntype InstrumentSessionEdge {\n  cursor: String!\n  node: InstrumentSession!\n}\n\ninput InstrumentSessionInput {\n  proposalNumber: Int!\n  instrumentSessionNumber: Int!\n}\n\ninput JSONOperator @oneOf {\n  stringOperator: StringOperatorInput = null\n  datetimeOperator: DatetimeOperatorInput = null\n  numericOperator: NumericOperatorInput = null\n}\n\ninput JSONOperatorInput {\n  \"\"\"A JSON path specifying the value to filter. Must start with '$.'\"\"\"\n  path: String!\n  \"\"\"The operator to apply to the JSON field\"\"\"\n  operator: JSONOperator!\n}\n\ninput NumericOperatorInput {\n  \"\"\"\n  Will filter to items where the numeric field is greater than the provided value\n  \"\"\"\n  gt: Float = null\n  \"\"\"\n  Will filter to items where the numeric field is less than the provided value\n  \"\"\"\n  lt: Float = null\n}\n\ntype Sample {\n  id: UUID!\n  name: String!\n  data: JSON!\n  createdTime: DateTime!\n  updatedTime: DateTime!\n  dataSchemaUrl: String!\n  \"\"\"Samples from which this sample is derived\"\"\"\n  parents(first: Int = null, before: String = null, after: String = null, last: Int = null): SampleConnection!\n  \"\"\"Samples derived from this sample\"\"\"\n  children(first: Int = null, before: String = null, after: String = null, last: Int = null): SampleConnection!\n  \"\"\"Events linked to this sample\"\"\"\n  events(first: Int = null, before: String = null, after: String = null, last: Int = null): SampleEventConnection!\n  \"\"\"The JSON schema that the sample's `data` conforms to\"\"\"\n  dataSchema: JSON!\n  \"\"\"The instrument sessions that this sample is associated with\"\"\"\n  instrumentSessions: InstrumentSessionConnection!\n  images: [SampleImage!]!\n}\n\ntype SampleConnection {\n  edges: [SampleEdge!]!\n  pageInfo: PageInfo!\n}\n\ntype SampleEdge {\n  cursor: String!\n  node: Sample!\n}\n\ntype SampleEvent {\n  id: UUID!\n  timestamp: DateTime!\n  description: String!\n}\n\ntype SampleEventConnection {\n  edges: [SampleEventEdge!]!\n  pageInfo: PageInfo!\n}\n\ntype SampleEventEdge {\n  cursor: String!\n  node: SampleEvent!\n}\n\ninput SampleFilterInput {\n  \"\"\"Filter on the `schemaUrl` field of `Sample`\"\"\"\n  schemaUrl: StringOperatorInput = null\n  \"\"\"Filter on the `createdTime` field of `Sample`\"\"\"\n  createdTime: DatetimeOperatorInput = null\n  \"\"\"Filter on the `createdTime` field of `Sample`\"\"\"\n  updatedTime: DatetimeOperatorInput = null\n  \"\"\"Filter on the `name` field of `Sample`\"\"\"\n  name: StringOperatorInput = null\n  \"\"\"Filter on the `data` field of `Sample`\"\"\"\n  data: [JSONOperatorInput!] = null\n}\n\ntype SampleImage {\n  url: String!\n  filename: String!\n}\n\ninput SampleIn {\n  \"\"\"Name of the sample\"\"\"\n  name: String!\n  \"\"\"Data of the sample\"\"\"\n  data: JSON!\n}\n\ninput SampleInLegacy {\n  name: String!\n  data: JSON!\n  dataSchemaUrl: String!\n  parentIds: [Int!] = null\n  children: [SampleInLegacy!] = null\n}\n\ntype SampleMutations {\n  sampleId: UUID!\n  linkInstrumentSessionToSample(proposalNumber: Int!, instrumentSessionNumber: Int!): Void\n  addSampleEvent(sampleEvent: AddSampleEventInput!): SampleEvent!\n  createSampleImageUploadUrl(filename: String!, contentType: String!, contentLength: Int!): String!\n}\n\ninput SampleOrder {\n  name: SortingOrder = null\n  createdTime: SortingOrder = null\n  updatedTime: SortingOrder = null\n}\n\n\"\"\"The details of errors occurred when validating a sample\"\"\"\ntype SampleValidationError {\n  \"\"\"\n  The index of the sample in CreateSampleInput.samples for which the error occurred\n  \"\"\"\n  index: Int!\n  \"\"\"Errors that occurred when validating the sample\"\"\"\n  errors: [ErrorDetails!]!\n}\n\nenum SortingOrder {\n  ASC\n  DESC\n}\n\n\"\"\"Conditions used to filter results based on the value of a String field\"\"\"\ninput StringOperatorInput {\n  \"\"\"\n  Will filter to items where the `String` field is equal to the provided value\n  \"\"\"\n  eq: String = null\n  \"\"\"\n  Will filter to items where the `String` field is not equal to the provided value\n  \"\"\"\n  ne: String = null\n  \"\"\"\n  Will filter to items where the `String` field is a member of the provided value\n  \"\"\"\n  in: [String!] = null\n  \"\"\"\n  Will filter to items where the `String` field is not a member of the provided value\n  \"\"\"\n  nin: [String!] = null\n  \"\"\"\n  Will filter to items where the `String` field is contains the provided value\n  \"\"\"\n  contains: String = null\n}\n\nscalar UUID\n\n\"\"\"Represents NULL values\"\"\"\nscalar Void\n\n\"\"\"A JSON schema\"\"\"\ntype JSONSchema {\n  \"\"\"The identifier of the schema\"\"\"\n  id: String!\n  \"\"\"A URL from which the schema can be accessed\"\"\"\n  url: String!\n  \"\"\"The type of object the shema describes (if known)\"\"\"\n  type: String\n  \"\"\"The title of the schema\"\"\"\n  title: String\n  \"\"\"The version of the schema\"\"\"\n  version: String\n  \"\"\"The instrument the schema was created for\"\"\"\n  instrument: String\n  \"\"\"The description og the schema\"\"\"\n  description: String\n}",
+    "graphqlSchema": "schema {\n  query: Query\n  mutation: Mutation\n  subscription: Subscription\n}\n\ntype Account {\n  accountId: Int!\n  username: String!\n  emailAddress: String\n  title: String\n  givenName: String\n  familyName: String\n  type: AccountType!\n  state: AccountState!\n  proposalRoles: [ProposalAccount!]!\n  instrumentSessionRoles: [InstrumentSessionRole!]!\n}\n\nenum AccountState {\n  enabled\n  disabled\n}\n\nenum AccountType {\n  user\n  staff\n  functional\n}\n\n\"\"\"\nImplement the DateTime<Utc> scalar\n\nThe input/output is a string in RFC3339 format.\n\"\"\"\nscalar DateTime\n\ntype Instrument {\n  name: String!\n  scienceGroup: String\n  description: String\n  proposals: [Proposal!]!\n  instrumentSessions: [InstrumentSession!]!\n}\n\ntype InstrumentSession {\n  instrumentSessionId: Int!\n  instrumentSessionNumber: Int!\n  startTime: DateTime\n  endTime: DateTime\n  type: String\n  state: String\n  riskRating: String\n  proposal: Proposal\n  instrument: Instrument!\n  roles: [InstrumentSessionRole!]!\n  \"\"\"Samples associated with a given instrument session\"\"\"\n  samples(first: Int!, filter: SampleFilterInput! = {schemaUrl: null, createdTime: null, updatedTime: null, name: null, data: null}, before: String = null, after: String = null, last: Int = null, orderBy: SampleOrder! = {name: null, createdTime: null, updatedTime: null}): SampleConnection!\n}\n\ntype InstrumentSessionMutations {\n  instrumentSessionNumber: Int!\n  proposalNumber: Int!\n  \"\"\"Create or validate samples associated with this instrument session\"\"\"\n  createOrValidateSamples(input: CreateOrValidateSampleInputBase!): CreateSamplesResponse!\n}\n\ntype InstrumentSessionRole {\n  instrumentSession: InstrumentSession!\n  account: Account!\n  role: String!\n  onSite: Boolean!\n}\n\n\"\"\"The root mutation of the service\"\"\"\ntype Mutation {\n  instrumentSession(proposalNumber: Int!, instrumentSessionNumber: Int!): InstrumentSessionMutations\n  createOrValidateSamples(input: CreateOrValidateSampleInput!): CreateSamplesResponse!\n  createSamples(input: CreateSampleInput!): [Sample!]! @deprecated(reason: \"Will be replaced by createOrValidateSamples\")\n  sample(sampleId: UUID!): SampleMutations\n  submitWorkflowTemplate(name: String!, visit: VisitInput!, parameters: JSON!): Workflow!\n}\n\n\"\"\"Information about pagination in a connection\"\"\"\ntype PageInfo {\n  \"\"\"When paginating backwards, the cursor to continue.\"\"\"\n  startCursor: String\n  \"\"\"When paginating forwards, the cursor to continue.\"\"\"\n  endCursor: String\n  \"\"\"When paginating forwards, are there more items?\"\"\"\n  hasNextPage: Boolean!\n  \"\"\"When paginating backwards, are there more items?\"\"\"\n  hasPreviousPage: Boolean!\n}\n\ntype Proposal {\n  proposalNumber: Int!\n  proposalCategory: String\n  title: String\n  summary: String\n  state: ProposalState!\n  instrumentSessions: [InstrumentSession!]!\n  instruments: [Instrument!]!\n  roles: [ProposalAccount!]!\n}\n\ntype ProposalAccount {\n  proposal: Proposal!\n  account: Account!\n  role: String!\n}\n\ntype ProposalConnection {\n  edges: [ProposalEdge!]!\n  pageInfo: PageInfo!\n}\n\ntype ProposalEdge {\n  cursor: String!\n  node: Proposal!\n}\n\nenum ProposalState {\n  Open\n  Closed\n  Cancelled\n}\n\n\"\"\"The root query of the service\"\"\"\ntype Query {\n  \"\"\"Get a proposal by its number\"\"\"\n  proposal(proposalNumber: Int!): Proposal\n  \"\"\"Get a list of proposals\"\"\"\n  proposals(proposalCategory: String = null, first: Int = null, last: Int = null, after: String = null, before: String = null): ProposalConnection!\n  \"\"\"Get a instrument session\"\"\"\n  instrumentSession(proposalNumber: Int!, instrumentSessionNumber: Int!): InstrumentSession\n  \"\"\"Get a instrument session\"\"\"\n  instrumentSessions(proposalNumber: Int = null, proposalCategory: String = null): [InstrumentSession!]\n  \"\"\"Get an instrument\"\"\"\n  instrument(instrumentName: String!): Instrument\n  \"\"\"Get a list of instruments\"\"\"\n  instruments(scienceGroup: String = null): [Instrument!]!\n  \"\"\"Get an account\"\"\"\n  account(username: String!): Account\n  \"\"\"Get a list of samples associated with a given instrument session\"\"\"\n  samples(first: Int!, instrumentSessions: [InstrumentSessionInput!] = null, filter: SampleFilterInput! = {schemaUrl: null, createdTime: null, updatedTime: null, name: null, data: null}, before: String = null, after: String = null, last: Int = null, orderBy: SampleOrder! = {name: null, createdTime: null, updatedTime: null}): SampleConnection!\n  \"\"\"Get a sample by its id\"\"\"\n  sample(sampleId: UUID!): Sample\n  jsonSchema(url: String!): JSONSchema\n  jsonSchemas(type: String = null, instrument: String = null): [JSONSchema!]!\n  node(id: ID!): NodeValue\n  \"\"\"Get a single [`Workflow`] by proposal, visit, and name\"\"\"\n  workflow(visit: VisitInput!, name: String!): Workflow!\n  workflows(visit: VisitInput!, cursor: String, limit: Int, filter: WorkflowFilter): WorkflowConnection!\n  workflowTemplate(name: String!): WorkflowTemplate!\n  workflowTemplates(cursor: String, limit: Int, filter: WorkflowTemplatesFilter): WorkflowTemplateConnection!\n}\n\ninput AddSampleEventInput {\n  description: String!\n}\n\ninput CreateOrValidateSampleInput {\n  \"\"\"URL of the JSON schema the samples' `data` should be validated against\"\"\"\n  dataSchemaUrl: String!\n  \"\"\"Samples to be created\"\"\"\n  samples: [SampleIn!]!\n  \"\"\"\n  Whether or not the provided samples should only be validated and not created\n  \"\"\"\n  validateOnly: Boolean! = false\n  \"\"\"Number of the proposal the samples should be associated with\"\"\"\n  proposalNumber: Int!\n  \"\"\"Number of the instrument session the samples should be associated with\"\"\"\n  instrumentSessionNumber: Int!\n}\n\ninput CreateOrValidateSampleInputBase {\n  \"\"\"URL of the JSON schema the samples' `data` should be validated against\"\"\"\n  dataSchemaUrl: String!\n  \"\"\"Samples to be created\"\"\"\n  samples: [SampleIn!]!\n  \"\"\"\n  Whether or not the provided samples should only be validated and not created\n  \"\"\"\n  validateOnly: Boolean! = false\n}\n\ninput CreateSampleInput {\n  proposalNumber: Int!\n  instrumentSessionNumber: Int!\n  samples: [SampleInLegacy!]!\n  validateOnly: Boolean! = false\n}\n\n\"\"\"Return type when creating or validating samples\"\"\"\ntype CreateSamplesResponse {\n  \"\"\"Whether the operation has succeeded without validation errors\"\"\"\n  success: Boolean!\n  \"\"\"Samples that have been created\"\"\"\n  samples: [Sample!]!\n  \"\"\"Errors that occurred during sample validation\"\"\"\n  errors: [SampleValidationError!]!\n}\n\ninput DatetimeOperatorInput {\n  \"\"\"\n  Will filter to items where the `DateTime` field is greater than (i.e. after) the provided value\n  \"\"\"\n  gt: DateTime = null\n  \"\"\"\n  Will filter to items where the `DateTime` field is less than (i.e. before) the provided value\n  \"\"\"\n  lt: DateTime = null\n}\n\n\"\"\"The details of sample validation error\"\"\"\ntype ErrorDetails {\n  \"\"\"The type of error that occurred\"\"\"\n  type: String!\n  \"\"\"\n  Tuple of strings identifying where in the sample schema the error occurred.\n  \"\"\"\n  location: [String!]!\n  \"\"\"A human readable error message.\"\"\"\n  message: String!\n}\n\ntype InstrumentSessionConnection {\n  edges: [InstrumentSessionEdge!]!\n  pageInfo: PageInfo!\n}\n\ntype InstrumentSessionEdge {\n  cursor: String!\n  node: InstrumentSession!\n}\n\ninput InstrumentSessionInput {\n  proposalNumber: Int!\n  instrumentSessionNumber: Int!\n}\n\n\"\"\"\nThe `JSON` scalar type represents JSON values as specified by [ECMA-404](https://ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf).\n\"\"\"\nscalar JSON\n\ninput JSONOperator @oneOf {\n  stringOperator: StringOperatorInput = null\n  datetimeOperator: DatetimeOperatorInput = null\n  numericOperator: NumericOperatorInput = null\n}\n\ninput JSONOperatorInput {\n  \"\"\"A JSON path specifying the value to filter. Must start with '$.'\"\"\"\n  path: String!\n  \"\"\"The operator to apply to the JSON field\"\"\"\n  operator: JSONOperator!\n}\n\ninput NumericOperatorInput {\n  \"\"\"\n  Will filter to items where the numeric field is greater than the provided value\n  \"\"\"\n  gt: Float = null\n  \"\"\"\n  Will filter to items where the numeric field is less than the provided value\n  \"\"\"\n  lt: Float = null\n}\n\ntype Sample {\n  id: UUID!\n  name: String!\n  data: JSON!\n  createdTime: DateTime!\n  updatedTime: DateTime!\n  dataSchemaUrl: String!\n  \"\"\"Samples from which this sample is derived\"\"\"\n  parents(first: Int = null, before: String = null, after: String = null, last: Int = null): SampleConnection!\n  \"\"\"Samples derived from this sample\"\"\"\n  children(first: Int = null, before: String = null, after: String = null, last: Int = null): SampleConnection!\n  \"\"\"Events linked to this sample\"\"\"\n  events(first: Int = null, before: String = null, after: String = null, last: Int = null): SampleEventConnection!\n  \"\"\"The JSON schema that the sample's `data` conforms to\"\"\"\n  dataSchema: JSON!\n  \"\"\"The instrument sessions that this sample is associated with\"\"\"\n  instrumentSessions: InstrumentSessionConnection!\n  images: [SampleImage!]!\n}\n\ntype SampleConnection {\n  edges: [SampleEdge!]!\n  pageInfo: PageInfo!\n}\n\ntype SampleEdge {\n  cursor: String!\n  node: Sample!\n}\n\ntype SampleEvent {\n  id: UUID!\n  timestamp: DateTime!\n  description: String!\n}\n\ntype SampleEventConnection {\n  edges: [SampleEventEdge!]!\n  pageInfo: PageInfo!\n}\n\ntype SampleEventEdge {\n  cursor: String!\n  node: SampleEvent!\n}\n\ninput SampleFilterInput {\n  \"\"\"Filter on the `schemaUrl` field of `Sample`\"\"\"\n  schemaUrl: StringOperatorInput = null\n  \"\"\"Filter on the `createdTime` field of `Sample`\"\"\"\n  createdTime: DatetimeOperatorInput = null\n  \"\"\"Filter on the `createdTime` field of `Sample`\"\"\"\n  updatedTime: DatetimeOperatorInput = null\n  \"\"\"Filter on the `name` field of `Sample`\"\"\"\n  name: StringOperatorInput = null\n  \"\"\"Filter on the `data` field of `Sample`\"\"\"\n  data: [JSONOperatorInput!] = null\n}\n\ntype SampleImage {\n  url: String!\n  filename: String!\n}\n\ninput SampleIn {\n  \"\"\"Name of the sample\"\"\"\n  name: String!\n  \"\"\"Data of the sample\"\"\"\n  data: JSON!\n}\n\ninput SampleInLegacy {\n  name: String!\n  data: JSON!\n  dataSchemaUrl: String!\n  parentIds: [Int!] = null\n  children: [SampleInLegacy!] = null\n}\n\ntype SampleMutations {\n  sampleId: UUID!\n  linkInstrumentSessionToSample(proposalNumber: Int!, instrumentSessionNumber: Int!): Void\n  addSampleEvent(sampleEvent: AddSampleEventInput!): SampleEvent!\n  createSampleImageUploadUrl(filename: String!, contentType: String!, contentLength: Int!): String!\n}\n\ninput SampleOrder {\n  name: SortingOrder = null\n  createdTime: SortingOrder = null\n  updatedTime: SortingOrder = null\n}\n\n\"\"\"The details of errors occurred when validating a sample\"\"\"\ntype SampleValidationError {\n  \"\"\"\n  The index of the sample in CreateSampleInput.samples for which the error occurred\n  \"\"\"\n  index: Int!\n  \"\"\"Errors that occurred when validating the sample\"\"\"\n  errors: [ErrorDetails!]!\n}\n\nenum SortingOrder {\n  ASC\n  DESC\n}\n\n\"\"\"Conditions used to filter results based on the value of a String field\"\"\"\ninput StringOperatorInput {\n  \"\"\"\n  Will filter to items where the `String` field is equal to the provided value\n  \"\"\"\n  eq: String = null\n  \"\"\"\n  Will filter to items where the `String` field is not equal to the provided value\n  \"\"\"\n  ne: String = null\n  \"\"\"\n  Will filter to items where the `String` field is a member of the provided value\n  \"\"\"\n  in: [String!] = null\n  \"\"\"\n  Will filter to items where the `String` field is not a member of the provided value\n  \"\"\"\n  nin: [String!] = null\n  \"\"\"\n  Will filter to items where the `String` field is contains the provided value\n  \"\"\"\n  contains: String = null\n}\n\nscalar UUID\n\n\"\"\"Represents NULL values\"\"\"\nscalar Void\n\n\"\"\"A JSON schema\"\"\"\ntype JSONSchema {\n  \"\"\"The identifier of the schema\"\"\"\n  id: String!\n  \"\"\"A URL from which the schema can be accessed\"\"\"\n  url: String!\n  \"\"\"The type of object the shema describes (if known)\"\"\"\n  type: String\n  \"\"\"The title of the schema\"\"\"\n  title: String\n  \"\"\"The version of the schema\"\"\"\n  version: String\n  \"\"\"The instrument the schema was created for\"\"\"\n  instrument: String\n  \"\"\"The description og the schema\"\"\"\n  description: String\n}\n\ntype Artifact {\n  \"\"\"The file name of the artifact\"\"\"\n  name: String!\n  \"\"\"The download URL for the artifact\"\"\"\n  url: Url!\n  \"\"\"The MIME type of the artifact data\"\"\"\n  mimeType: String!\n}\n\nscalar Creator\n\n\"\"\"A scalar that can represent any JSON Object value.\"\"\"\nscalar JSONObject\n\n\"\"\"A single log line streamed from a pod\"\"\"\ntype LogEntry {\n  \"\"\"The log line content\"\"\"\n  content: String!\n  \"\"\"The name of the pod producing the log\"\"\"\n  podName: String!\n}\n\n\"\"\"Represents Relay Node types\"\"\"\nunion NodeValue = Workflow\n\n\"\"\"Supported DLS science groups\"\"\"\nenum ScienceGroup {\n  \"\"\"Macromolecular Crystallography\"\"\"\n  MX\n  \"\"\"Workflows Examples\"\"\"\n  EXAMPLES\n  \"\"\"Magnetic Materials\"\"\"\n  MAGNETIC_MATERIALS\n  \"\"\"Soft Condensed Matter\"\"\"\n  CONDENSED_MATTER\n  \"\"\"Imaging and Microscopy\"\"\"\n  IMAGING\n  \"\"\"Biological Cryo-Imaging\"\"\"\n  BIO_CRYO_IMAGING\n  \"\"\"Structures and Surfaces\"\"\"\n  SURFACES\n  \"\"\"Crystallography\"\"\"\n  CRYSTALLOGRAPHY\n  \"\"\"Spectroscopy\"\"\"\n  SPECTROSCOPY\n}\n\n\"\"\"The root mutation of the service\"\"\"\ntype Subscription {\n  \"\"\"Processing to subscribe to logs for a single pod of a workflow\"\"\"\n  logs(visit: VisitInput!, workflowName: String!, taskId: String!): LogEntry!\n  \"\"\"Processing to subscribe to data for all workflows in a session\"\"\"\n  workflow(visit: VisitInput!, name: String!): Workflow!\n}\n\ntype Task {\n  \"\"\"Unique name of the task\"\"\"\n  id: String!\n  \"\"\"Display name of the task\"\"\"\n  name: String!\n  \"\"\"Current status of a task\"\"\"\n  status: TaskStatus!\n  \"\"\"Parent of a task\"\"\"\n  depends: [String!]!\n  \"\"\"Children of a task\"\"\"\n  dependencies: [String!]!\n  \"\"\"Artifacts produced by a task\"\"\"\n  artifacts: [Artifact!]!\n  \"\"\"Node type - Pod, DAG, etc\"\"\"\n  stepType: String!\n  \"\"\"Start time for a task on a workflow\"\"\"\n  startTime: DateTime\n  \"\"\"End time for a task on a workflow\"\"\"\n  endTime: DateTime\n  \"\"\"\n  A human readable message indicating details about why this step is in this condition\n  \"\"\"\n  message: String\n}\n\nenum TaskStatus {\n  PENDING\n  RUNNING\n  SUCCEEDED\n  SKIPPED\n  FAILED\n  ERROR\n  OMITTED\n}\n\nscalar Template\n\n\"\"\"Information about where the template is stored\"\"\"\ntype TemplateSource {\n  \"\"\"The URL of the GitHub repository\"\"\"\n  repositoryUrl: String!\n  \"\"\"The path to the template within the repository\"\"\"\n  path: String!\n  \"\"\"The current tracked branch of the repository\"\"\"\n  targetRevision: String!\n}\n\n\"\"\"\nURL is a String implementing the [URL Standard](http://url.spec.whatwg.org/)\n\"\"\"\nscalar Url\n\n\"\"\"A visit to an instrument as part of a session\"\"\"\ntype Visit {\n  \"\"\"Project Proposal Code\"\"\"\n  proposalCode: String!\n  \"\"\"Project Proposal Number\"\"\"\n  proposalNumber: Int!\n  \"\"\"Session visit Number\"\"\"\n  number: Int!\n}\n\n\"\"\"A visit to an instrument as part of a session\"\"\"\ninput VisitInput {\n  \"\"\"Project Proposal Code\"\"\"\n  proposalCode: String!\n  \"\"\"Project Proposal Number\"\"\"\n  proposalNumber: Int!\n  \"\"\"Session visit Number\"\"\"\n  number: Int!\n}\n\ntype Workflow {\n  \"\"\"The unique ID derived from the visit and name\"\"\"\n  id: ID!\n  \"\"\"The name given to the workflow, unique within a given visit\"\"\"\n  name: String!\n  \"\"\"The visit the Workflow was run against\"\"\"\n  visit: Visit!\n  \"\"\"The current status of the workflow\"\"\"\n  status: WorkflowStatus\n  \"\"\"The top-level workflow parameters\"\"\"\n  parameters: JSONObject\n  \"\"\"The name of the template used to run the workflow\"\"\"\n  templateRef: String\n  \"\"\"The workflow creator\"\"\"\n  creator: WorkflowCreator!\n}\n\ntype WorkflowConnection {\n  \"\"\"Information to aid in pagination.\"\"\"\n  pageInfo: PageInfo!\n  \"\"\"A list of edges.\"\"\"\n  edges: [WorkflowEdge!]!\n  \"\"\"A list of nodes.\"\"\"\n  nodes: [Workflow!]!\n}\n\n\"\"\"Information about the creator of a workflow.\"\"\"\ntype WorkflowCreator {\n  \"\"\"\n  An identifier unique to the creator of the workflow.\n  Typically this is the creator's Fed-ID.\n  \"\"\"\n  creatorId: String!\n}\n\n\"\"\"An edge in a connection.\"\"\"\ntype WorkflowEdge {\n  \"\"\"The item at the end of the edge\"\"\"\n  node: Workflow!\n  \"\"\"A cursor for use in pagination\"\"\"\n  cursor: String!\n}\n\n\"\"\"All tasks in the workflow have errored\"\"\"\ntype WorkflowErroredStatus {\n  \"\"\"Time at which this workflow started\"\"\"\n  startTime: DateTime!\n  \"\"\"Time at which this workflow completed\"\"\"\n  endTime: DateTime!\n  \"\"\"\n  A human readable message indicating details about why the workflow is in this condition\n  \"\"\"\n  message: String\n  \"\"\"Tasks created by the workflow\"\"\"\n  tasks: [Task!]!\n}\n\n\"\"\"All tasks in the workflow have failed\"\"\"\ntype WorkflowFailedStatus {\n  \"\"\"Time at which this workflow started\"\"\"\n  startTime: DateTime!\n  \"\"\"Time at which this workflow completed\"\"\"\n  endTime: DateTime!\n  \"\"\"\n  A human readable message indicating details about why the workflow is in this condition\n  \"\"\"\n  message: String\n  \"\"\"Tasks created by the workflow\"\"\"\n  tasks: [Task!]!\n}\n\n\"\"\"All the supported Workflows filters\"\"\"\ninput WorkflowFilter {\n  \"\"\"The status field for a workflow\"\"\"\n  workflowStatusFilter: WorkflowStatusFilter\n  \"\"\"The fedid of the user who created the workflow\"\"\"\n  creator: Creator\n  \"\"\"The name of the workflow template\"\"\"\n  template: Template\n}\n\ntype WorkflowPendingStatus {\n  \"\"\"\n  A human readable message indicating details about why the workflow is in this condition\n  \"\"\"\n  message: String\n}\n\ntype WorkflowRunningStatus {\n  \"\"\"Time at which this workflow started\"\"\"\n  startTime: DateTime!\n  \"\"\"\n  A human readable message indicating details about why the workflow is in this condition\n  \"\"\"\n  message: String\n  \"\"\"Tasks created by the workflow\"\"\"\n  tasks: [Task!]!\n}\n\n\"\"\"The status of a workflow\"\"\"\nunion WorkflowStatus = WorkflowPendingStatus | WorkflowRunningStatus | WorkflowSucceededStatus | WorkflowFailedStatus | WorkflowErroredStatus\n\n\"\"\"Represents workflow status filters\"\"\"\ninput WorkflowStatusFilter {\n  pending: Boolean! = false\n  running: Boolean! = false\n  succeeded: Boolean! = false\n  failed: Boolean! = false\n  error: Boolean! = false\n}\n\n\"\"\"All tasks in the workflow have succeded\"\"\"\ntype WorkflowSucceededStatus {\n  \"\"\"Time at which this workflow started\"\"\"\n  startTime: DateTime!\n  \"\"\"Time at which this workflow completed\"\"\"\n  endTime: DateTime!\n  \"\"\"\n  A human readable message indicating details about why the workflow is in this condition\n  \"\"\"\n  message: String\n  \"\"\"Tasks created by the workflow\"\"\"\n  tasks: [Task!]!\n}\n\ntype WorkflowTemplate {\n  \"\"\"The name given to the workflow template, globally unique\"\"\"\n  name: String!\n  \"\"\"The group who maintains the workflow template\"\"\"\n  maintainer: String!\n  \"\"\"A human readable title for the workflow template\"\"\"\n  title: String\n  \"\"\"A human readable description of the workflow which is created\"\"\"\n  description: String\n  \"\"\"The repository storing the code associated with this template.\"\"\"\n  repository: String\n  \"\"\"A JSON Schema describing the arguments of a Workflow Template\"\"\"\n  arguments: JSON!\n  \"\"\"\n  A JSON Forms UI Schema describing how to render the arguments of the Workflow Template\n  \"\"\"\n  uiSchema: JSON\n  \"\"\"Information about where the template is obtained from\"\"\"\n  templateSource: TemplateSource\n}\n\ntype WorkflowTemplateConnection {\n  \"\"\"Information to aid in pagination.\"\"\"\n  pageInfo: PageInfo!\n  \"\"\"A list of edges.\"\"\"\n  edges: [WorkflowTemplateEdge!]!\n  \"\"\"A list of nodes.\"\"\"\n  nodes: [WorkflowTemplate!]!\n}\n\n\"\"\"An edge in a connection.\"\"\"\ntype WorkflowTemplateEdge {\n  \"\"\"The item at the end of the edge\"\"\"\n  node: WorkflowTemplate!\n  \"\"\"A cursor for use in pagination\"\"\"\n  cursor: String!\n}\n\n\"\"\"Supported label filters for ClusterWorkflowTemplates\"\"\"\ninput WorkflowTemplatesFilter {\n  \"\"\"The science group owning the template eg imaging\"\"\"\n  scienceGroup: [ScienceGroup!]\n}",
     "stringStorage": {
       "636412ec8e6e8e278df46ce7da59047a6182733c": "schema @link(url: \"https://specs.apollo.dev/federation/v2.7\", import: [\"@key\", \"@shareable\"]) {\n  query: Query\n  mutation: Mutation\n}\n\ndirective @key(fields: openfed__FieldSet!, resolvable: Boolean = true) repeatable on INTERFACE | OBJECT\n\ndirective @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA\n\ndirective @shareable repeatable on FIELD_DEFINITION | OBJECT\n\ntype Account {\n  accountId: Int!\n  emailAddress: String\n  familyName: String\n  givenName: String\n  instrumentSessionRoles: [InstrumentSessionRole!]!\n  proposalRoles: [ProposalAccount!]!\n  state: AccountState!\n  title: String\n  type: AccountType!\n  username: String!\n}\n\nenum AccountState {\n  disabled\n  enabled\n}\n\nenum AccountType {\n  functional\n  staff\n  user\n}\n\n\"\"\"Date with time (isoformat)\"\"\"\nscalar DateTime\n\ntype Instrument {\n  description: String\n  instrumentSessions: [InstrumentSession!]!\n  name: String!\n  proposals: [Proposal!]!\n  scienceGroup: String\n}\n\ntype InstrumentSession @key(fields: \"instrumentSessionNumber proposal {proposalNumber}\") {\n  endTime: DateTime\n  instrument: Instrument!\n  instrumentSessionId: Int!\n  instrumentSessionNumber: Int!\n  proposal: Proposal\n  riskRating: String\n  roles: [InstrumentSessionRole!]!\n  startTime: DateTime\n  state: String\n  type: String\n}\n\ntype InstrumentSessionMutations @key(fields: \"instrumentSessionNumber proposalNumber\") {\n  instrumentSessionNumber: Int!\n  proposalNumber: Int!\n}\n\ntype InstrumentSessionRole {\n  account: Account!\n  instrumentSession: InstrumentSession!\n  onSite: Boolean!\n  role: String!\n}\n\ntype Mutation {\n  instrumentSession(instrumentSessionNumber: Int!, proposalNumber: Int!): InstrumentSessionMutations\n}\n\ntype PageInfo {\n  endCursor: String @shareable\n  hasNextPage: Boolean! @shareable\n  hasPreviousPage: Boolean! @shareable\n  startCursor: String @shareable\n}\n\ntype Proposal @key(fields: \"proposalNumber\") {\n  instrumentSessions: [InstrumentSession!]!\n  instruments: [Instrument!]!\n  proposalCategory: String\n  proposalNumber: Int!\n  roles: [ProposalAccount!]!\n  state: ProposalState!\n  summary: String\n  title: String\n}\n\ntype ProposalAccount {\n  account: Account!\n  proposal: Proposal!\n  role: String!\n}\n\ntype ProposalConnection {\n  edges: [ProposalEdge!]! @shareable\n  pageInfo: PageInfo! @shareable\n}\n\ntype ProposalEdge {\n  cursor: String! @shareable\n  node: Proposal! @shareable\n}\n\nenum ProposalState {\n  Cancelled\n  Closed\n  Open\n}\n\ntype Query {\n  \"\"\"Get an account\"\"\"\n  account(username: String!): Account\n  \"\"\"Get an instrument\"\"\"\n  instrument(instrumentName: String!): Instrument\n  \"\"\"Get a instrument session\"\"\"\n  instrumentSession(instrumentSessionNumber: Int!, proposalNumber: Int!): InstrumentSession\n  \"\"\"Get a instrument session\"\"\"\n  instrumentSessions(proposalCategory: String = null, proposalNumber: Int = null): [InstrumentSession!]\n  \"\"\"Get a list of instruments\"\"\"\n  instruments(scienceGroup: String = null): [Instrument!]!\n  \"\"\"Get a proposal by its number\"\"\"\n  proposal(proposalNumber: Int!): Proposal\n  \"\"\"Get a list of proposals\"\"\"\n  proposals(after: String = null, before: String = null, first: Int = null, last: Int = null, proposalCategory: String = null): ProposalConnection!\n}\n\nscalar link__Import\n\nenum link__Purpose {\n  EXECUTION\n  SECURITY\n}\n\nscalar openfed__FieldSet",
       "6f02287e3cbb3840d5136c3ef6f75c1e24560b94": "schema @link(url: \"https://specs.apollo.dev/federation/v2.7\", import: [\"@external\", \"@key\", \"@provides\", \"@shareable\"]) {\n  query: Query\n  mutation: Mutation\n}\n\ndirective @external on FIELD_DEFINITION | OBJECT\n\ndirective @key(fields: openfed__FieldSet!, resolvable: Boolean = true) repeatable on INTERFACE | OBJECT\n\ndirective @link(as: String, for: link__Purpose, import: [link__Import], url: String!) repeatable on SCHEMA\n\ndirective @provides(fields: openfed__FieldSet!) on FIELD_DEFINITION\n\ndirective @shareable repeatable on FIELD_DEFINITION | OBJECT\n\ninput AddSampleEventInput {\n  description: String!\n}\n\ninput CreateOrValidateSampleInput {\n  \"\"\"URL of the JSON schema the samples' `data` should be validated against\"\"\"\n  dataSchemaUrl: String!\n  \"\"\"Number of the instrument session the samples should be associated with\"\"\"\n  instrumentSessionNumber: Int!\n  \"\"\"Number of the proposal the samples should be associated with\"\"\"\n  proposalNumber: Int!\n  \"\"\"Samples to be created\"\"\"\n  samples: [SampleIn!]!\n  \"\"\"\n  Whether or not the provided samples should only be validated and not created\n  \"\"\"\n  validateOnly: Boolean! = false\n}\n\ninput CreateOrValidateSampleInputBase {\n  \"\"\"URL of the JSON schema the samples' `data` should be validated against\"\"\"\n  dataSchemaUrl: String!\n  \"\"\"Samples to be created\"\"\"\n  samples: [SampleIn!]!\n  \"\"\"\n  Whether or not the provided samples should only be validated and not created\n  \"\"\"\n  validateOnly: Boolean! = false\n}\n\ninput CreateSampleInput {\n  instrumentSessionNumber: Int!\n  proposalNumber: Int!\n  samples: [SampleInLegacy!]!\n  validateOnly: Boolean! = false\n}\n\n\"\"\"Return type when creating or validating samples\"\"\"\ntype CreateSamplesResponse {\n  \"\"\"Errors that occurred during sample validation\"\"\"\n  errors: [SampleValidationError!]!\n  \"\"\"Samples that have been created\"\"\"\n  samples: [Sample!]!\n  \"\"\"Whether the operation has succeeded without validation errors\"\"\"\n  success: Boolean!\n}\n\n\"\"\"Date with time (isoformat)\"\"\"\nscalar DateTime\n\ninput DatetimeOperatorInput {\n  \"\"\"\n  Will filter to items where the `DateTime` field is greater than (i.e. after) the provided value\n  \"\"\"\n  gt: DateTime = null\n  \"\"\"\n  Will filter to items where the `DateTime` field is less than (i.e. before) the provided value\n  \"\"\"\n  lt: DateTime = null\n}\n\n\"\"\"The details of sample validation error\"\"\"\ntype ErrorDetails {\n  \"\"\"\n  Tuple of strings identifying where in the sample schema the error occurred.\n  \"\"\"\n  location: [String!]!\n  \"\"\"A human readable error message.\"\"\"\n  message: String!\n  \"\"\"The type of error that occurred\"\"\"\n  type: String!\n}\n\ntype InstrumentSession @key(fields: \"instrumentSessionNumber proposal { proposalNumber }\") {\n  instrumentSessionNumber: Int! @external\n  proposal: Proposal @external\n  \"\"\"Samples associated with a given instrument session\"\"\"\n  samples(after: String = null, before: String = null, filter: SampleFilterInput! = {createdTime: null, data: null, name: null, schemaUrl: null, updatedTime: null}, first: Int!, last: Int = null, orderBy: SampleOrder! = {createdTime: null, name: null, updatedTime: null}): SampleConnection!\n}\n\ntype InstrumentSessionConnection {\n  edges: [InstrumentSessionEdge!]!\n  pageInfo: PageInfo!\n}\n\ntype InstrumentSessionEdge {\n  cursor: String!\n  node: InstrumentSession!\n}\n\ninput InstrumentSessionInput {\n  instrumentSessionNumber: Int!\n  proposalNumber: Int!\n}\n\ntype InstrumentSessionMutations @key(fields: \"instrumentSessionNumber proposalNumber\") {\n  \"\"\"Create or validate samples associated with this instrument session\"\"\"\n  createOrValidateSamples(input: CreateOrValidateSampleInputBase!): CreateSamplesResponse!\n  instrumentSessionNumber: Int! @external\n  proposalNumber: Int! @external\n}\n\n\"\"\"\nThe `JSON` scalar type represents JSON values as specified by [ECMA-404](https://ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf).\n\"\"\"\nscalar JSON @specifiedBy(url: \"https://ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf\")\n\ninput JSONOperator @oneOf {\n  datetimeOperator: DatetimeOperatorInput = null\n  numericOperator: NumericOperatorInput = null\n  stringOperator: StringOperatorInput = null\n}\n\ninput JSONOperatorInput {\n  \"\"\"The operator to apply to the JSON field\"\"\"\n  operator: JSONOperator!\n  \"\"\"A JSON path specifying the value to filter. Must start with '$.'\"\"\"\n  path: String!\n}\n\ntype Mutation {\n  createOrValidateSamples(input: CreateOrValidateSampleInput!): CreateSamplesResponse!\n  createSamples(input: CreateSampleInput!): [Sample!]! @deprecated(reason: \"Will be replaced by createOrValidateSamples\")\n  sample(sampleId: UUID!): SampleMutations\n}\n\ninput NumericOperatorInput {\n  \"\"\"\n  Will filter to items where the numeric field is greater than the provided value\n  \"\"\"\n  gt: Float = null\n  \"\"\"\n  Will filter to items where the numeric field is less than the provided value\n  \"\"\"\n  lt: Float = null\n}\n\ntype PageInfo {\n  endCursor: String @shareable\n  hasNextPage: Boolean! @shareable\n  hasPreviousPage: Boolean! @shareable\n  startCursor: String @shareable\n}\n\ntype Proposal @key(fields: \"proposalNumber\") {\n  proposalNumber: Int! @external\n}\n\ntype Query {\n  \"\"\"Get a sample by its id\"\"\"\n  sample(sampleId: UUID!): Sample\n  \"\"\"Get a list of samples associated with a given instrument session\"\"\"\n  samples(after: String = null, before: String = null, filter: SampleFilterInput! = {createdTime: null, data: null, name: null, schemaUrl: null, updatedTime: null}, first: Int!, instrumentSessions: [InstrumentSessionInput!] = null, last: Int = null, orderBy: SampleOrder! = {createdTime: null, name: null, updatedTime: null}): SampleConnection!\n}\n\ntype Sample {\n  \"\"\"Samples derived from this sample\"\"\"\n  children(after: String = null, before: String = null, first: Int = null, last: Int = null): SampleConnection!\n  createdTime: DateTime!\n  data: JSON!\n  \"\"\"The JSON schema that the sample's `data` conforms to\"\"\"\n  dataSchema: JSON!\n  dataSchemaUrl: String!\n  \"\"\"Events linked to this sample\"\"\"\n  events(after: String = null, before: String = null, first: Int = null, last: Int = null): SampleEventConnection!\n  id: UUID!\n  images: [SampleImage!]!\n  \"\"\"The instrument sessions that this sample is associated with\"\"\"\n  instrumentSessions: InstrumentSessionConnection! @provides(fields: \"edges{ node{ instrumentSessionNumber proposal{ proposalNumber }}}\")\n  name: String!\n  \"\"\"Samples from which this sample is derived\"\"\"\n  parents(after: String = null, before: String = null, first: Int = null, last: Int = null): SampleConnection!\n  updatedTime: DateTime!\n}\n\ntype SampleConnection {\n  edges: [SampleEdge!]!\n  pageInfo: PageInfo!\n}\n\ntype SampleEdge {\n  cursor: String!\n  node: Sample!\n}\n\ntype SampleEvent {\n  description: String!\n  id: UUID!\n  timestamp: DateTime!\n}\n\ntype SampleEventConnection {\n  edges: [SampleEventEdge!]!\n  pageInfo: PageInfo!\n}\n\ntype SampleEventEdge {\n  cursor: String!\n  node: SampleEvent!\n}\n\ninput SampleFilterInput {\n  \"\"\"Filter on the `createdTime` field of `Sample`\"\"\"\n  createdTime: DatetimeOperatorInput = null\n  \"\"\"Filter on the `data` field of `Sample`\"\"\"\n  data: [JSONOperatorInput!] = null\n  \"\"\"Filter on the `name` field of `Sample`\"\"\"\n  name: StringOperatorInput = null\n  \"\"\"Filter on the `schemaUrl` field of `Sample`\"\"\"\n  schemaUrl: StringOperatorInput = null\n  \"\"\"Filter on the `createdTime` field of `Sample`\"\"\"\n  updatedTime: DatetimeOperatorInput = null\n}\n\ntype SampleImage {\n  filename: String!\n  url: String!\n}\n\ninput SampleIn {\n  \"\"\"Data of the sample\"\"\"\n  data: JSON!\n  \"\"\"Name of the sample\"\"\"\n  name: String!\n}\n\ninput SampleInLegacy {\n  children: [SampleInLegacy!] = null\n  data: JSON!\n  dataSchemaUrl: String!\n  name: String!\n  parentIds: [Int!] = null\n}\n\ntype SampleMutations {\n  addSampleEvent(sampleEvent: AddSampleEventInput!): SampleEvent!\n  createSampleImageUploadUrl(contentLength: Int!, contentType: String!, filename: String!): String!\n  linkInstrumentSessionToSample(instrumentSessionNumber: Int!, proposalNumber: Int!): Void\n  sampleId: UUID!\n}\n\ninput SampleOrder {\n  createdTime: SortingOrder = null\n  name: SortingOrder = null\n  updatedTime: SortingOrder = null\n}\n\n\"\"\"The details of errors occurred when validating a sample\"\"\"\ntype SampleValidationError {\n  \"\"\"Errors that occurred when validating the sample\"\"\"\n  errors: [ErrorDetails!]!\n  \"\"\"\n  The index of the sample in CreateSampleInput.samples for which the error occurred\n  \"\"\"\n  index: Int!\n}\n\nenum SortingOrder {\n  ASC\n  DESC\n}\n\n\"\"\"Conditions used to filter results based on the value of a String field\"\"\"\ninput StringOperatorInput {\n  \"\"\"\n  Will filter to items where the `String` field is contains the provided value\n  \"\"\"\n  contains: String = null\n  \"\"\"\n  Will filter to items where the `String` field is equal to the provided value\n  \"\"\"\n  eq: String = null\n  \"\"\"\n  Will filter to items where the `String` field is a member of the provided value\n  \"\"\"\n  in: [String!] = null\n  \"\"\"\n  Will filter to items where the `String` field is not equal to the provided value\n  \"\"\"\n  ne: String = null\n  \"\"\"\n  Will filter to items where the `String` field is not a member of the provided value\n  \"\"\"\n  nin: [String!] = null\n}\n\nscalar UUID\n\n\"\"\"Represents NULL values\"\"\"\nscalar Void\n\nscalar link__Import\n\nenum link__Purpose {\n  EXECUTION\n  SECURITY\n}\n\nscalar openfed__FieldSet",
@@ -1147,23 +1147,23 @@
   "subgraphs": [
     {
       "id": "0",
-      "name": "workflows",
-      "routingUrl": "https://workflows.diamond.ac.uk/graphql"
-    },
-    {
-      "id": "1",
       "name": "instrument_sessions",
       "routingUrl": "https://instrument-sessions.diamond.ac.uk/api/graphql"
     },
     {
-      "id": "2",
+      "id": "1",
       "name": "samples",
       "routingUrl": "https://sample-information.diamond.ac.uk/api/graphql"
     },
     {
-      "id": "3",
+      "id": "2",
       "name": "schemas",
       "routingUrl": "https://schemas.diamond.ac.uk/graphql"
+    },
+    {
+      "id": "3",
+      "name": "workflows",
+      "routingUrl": "https://workflows.diamond.ac.uk/graphql"
     }
   ],
   "version": "00000000-0000-0000-0000-000000000000"

@github-actions
Copy link
Copy Markdown

diff --git a/tmp/old_supergraph.graphql b/tmp/new_supergraph.graphql
index 36ce517..d7e3a1a 100644
--- a/tmp/old_supergraph.graphql
+++ b/tmp/new_supergraph.graphql
@@ -1,434 +1,3 @@
-type Artifact {
-  """The file name of the artifact"""
-  name: String!
-
-  """The download URL for the artifact"""
-  url: Url!
-
-  """The MIME type of the artifact data"""
-  mimeType: String!
-}
-
-scalar Creator
-
-"""
-Implement the DateTime<Utc> scalar
-
-The input/output is a string in RFC3339 format.
-"""
-scalar DateTime
-
-"""
-The `JSON` scalar type represents JSON values as specified by [ECMA-404](https://ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf).
-"""
-scalar JSON
-
-"""A scalar that can represent any JSON Object value."""
-scalar JSONObject
-
-"""A single log line streamed from a pod"""
-type LogEntry {
-  """The log line content"""
-  content: String!
-
-  """The name of the pod producing the log"""
-  podName: String!
-}
-
-"""The root mutation of the service"""
-type Mutation {
-  submitWorkflowTemplate(name: String!, visit: VisitInput!, parameters: JSON!): Workflow!
-  instrumentSession(proposalNumber: Int!, instrumentSessionNumber: Int!): InstrumentSessionMutations
-  createOrValidateSamples(input: CreateOrValidateSampleInput!): CreateSamplesResponse!
-  createSamples(input: CreateSampleInput!): [Sample!]! @deprecated(reason: "Will be replaced by createOrValidateSamples")
-  sample(sampleId: UUID!): SampleMutations
-}
-
-"""Represents Relay Node types"""
-union NodeValue = Workflow
-
-"""Information about pagination in a connection"""
-type PageInfo {
-  """When paginating backwards, are there more items?"""
-  hasPreviousPage: Boolean!
-
-  """When paginating forwards, are there more items?"""
-  hasNextPage: Boolean!
-
-  """When paginating backwards, the cursor to continue."""
-  startCursor: String
-
-  """When paginating forwards, the cursor to continue."""
-  endCursor: String
-}
-
-"""The root query of the service"""
-type Query {
-  node(id: ID!): NodeValue
-
-  """Get a single [`Workflow`] by proposal, visit, and name"""
-  workflow(visit: VisitInput!, name: String!): Workflow!
-  workflows(visit: VisitInput!, cursor: String, limit: Int, filter: WorkflowFilter): WorkflowConnection!
-  workflowTemplate(name: String!): WorkflowTemplate!
-  workflowTemplates(cursor: String, limit: Int, filter: WorkflowTemplatesFilter): WorkflowTemplateConnection!
-
-  """Get a proposal by its number"""
-  proposal(proposalNumber: Int!): Proposal
-
-  """Get a list of proposals"""
-  proposals(proposalCategory: String = null, first: Int = null, last: Int = null, after: String = null, before: String = null): ProposalConnection!
-
-  """Get a instrument session"""
-  instrumentSession(proposalNumber: Int!, instrumentSessionNumber: Int!): InstrumentSession
-
-  """Get a instrument session"""
-  instrumentSessions(proposalNumber: Int = null, proposalCategory: String = null): [InstrumentSession!]
-
-  """Get an instrument"""
-  instrument(instrumentName: String!): Instrument
-
-  """Get a list of instruments"""
-  instruments(scienceGroup: String = null): [Instrument!]!
-
-  """Get an account"""
-  account(username: String!): Account
-
-  """Get a list of samples associated with a given instrument session"""
-  samples(first: Int!, instrumentSessions: [InstrumentSessionInput!] = null, filter: SampleFilterInput! = {schemaUrl: null, createdTime: null, updatedTime: null, name: null, data: null}, before: String = null, after: String = null, last: Int = null, orderBy: SampleOrder! = {name: null, createdTime: null, updatedTime: null}): SampleConnection!
-
-  """Get a sample by its id"""
-  sample(sampleId: UUID!): Sample
-  jsonSchema(url: String!): JSONSchema
-  jsonSchemas(type: String = null, instrument: String = null): [JSONSchema!]!
-}
-
-"""Supported DLS science groups"""
-enum ScienceGroup {
-  """Macromolecular Crystallography"""
-  MX
-
-  """Workflows Examples"""
-  EXAMPLES
-
-  """Magnetic Materials"""
-  MAGNETIC_MATERIALS
-
-  """Soft Condensed Matter"""
-  CONDENSED_MATTER
-
-  """Imaging and Microscopy"""
-  IMAGING
-
-  """Biological Cryo-Imaging"""
-  BIO_CRYO_IMAGING
-
-  """Structures and Surfaces"""
-  SURFACES
-
-  """Crystallography"""
-  CRYSTALLOGRAPHY
-
-  """Spectroscopy"""
-  SPECTROSCOPY
-}
-
-"""The root mutation of the service"""
-type Subscription {
-  """Processing to subscribe to logs for a single pod of a workflow"""
-  logs(visit: VisitInput!, workflowName: String!, taskId: String!): LogEntry!
-
-  """Processing to subscribe to data for all workflows in a session"""
-  workflow(visit: VisitInput!, name: String!): Workflow!
-}
-
-type Task {
-  """Unique name of the task"""
-  id: String!
-
-  """Display name of the task"""
-  name: String!
-
-  """Current status of a task"""
-  status: TaskStatus!
-
-  """Parent of a task"""
-  depends: [String!]!
-
-  """Children of a task"""
-  dependencies: [String!]!
-
-  """Artifacts produced by a task"""
-  artifacts: [Artifact!]!
-
-  """Node type - Pod, DAG, etc"""
-  stepType: String!
-
-  """Start time for a task on a workflow"""
-  startTime: DateTime
-
-  """End time for a task on a workflow"""
-  endTime: DateTime
-
-  """
-  A human readable message indicating details about why this step is in this condition
-  """
-  message: String
-}
-
-enum TaskStatus {
-  PENDING
-  RUNNING
-  SUCCEEDED
-  SKIPPED
-  FAILED
-  ERROR
-  OMITTED
-}
-
-scalar Template
-
-"""Information about where the template is stored"""
-type TemplateSource {
-  """The URL of the GitHub repository"""
-  repositoryUrl: String!
-
-  """The path to the template within the repository"""
-  path: String!
-
-  """The current tracked branch of the repository"""
-  targetRevision: String!
-}
-
-"""
-URL is a String implementing the [URL Standard](http://url.spec.whatwg.org/)
-"""
-scalar Url
-
-"""A visit to an instrument as part of a session"""
-type Visit {
-  """Project Proposal Code"""
-  proposalCode: String!
-
-  """Project Proposal Number"""
-  proposalNumber: Int!
-
-  """Session visit Number"""
-  number: Int!
-}
-
-"""A visit to an instrument as part of a session"""
-input VisitInput {
-  """Project Proposal Code"""
-  proposalCode: String!
-
-  """Project Proposal Number"""
-  proposalNumber: Int!
-
-  """Session visit Number"""
-  number: Int!
-}
-
-type Workflow {
-  """The unique ID derived from the visit and name"""
-  id: ID!
-
-  """The name given to the workflow, unique within a given visit"""
-  name: String!
-
-  """The visit the Workflow was run against"""
-  visit: Visit!
-
-  """The current status of the workflow"""
-  status: WorkflowStatus
-
-  """The top-level workflow parameters"""
-  parameters: JSONObject
-
-  """The name of the template used to run the workflow"""
-  templateRef: String
-
-  """The workflow creator"""
-  creator: WorkflowCreator!
-}
-
-type WorkflowConnection {
-  """Information to aid in pagination."""
-  pageInfo: PageInfo!
-
-  """A list of edges."""
-  edges: [WorkflowEdge!]!
-
-  """A list of nodes."""
-  nodes: [Workflow!]!
-}
-
-"""Information about the creator of a workflow."""
-type WorkflowCreator {
-  """
-  An identifier unique to the creator of the workflow.
-  Typically this is the creator's Fed-ID.
-  """
-  creatorId: String!
-}
-
-"""An edge in a connection."""
-type WorkflowEdge {
-  """The item at the end of the edge"""
-  node: Workflow!
-
-  """A cursor for use in pagination"""
-  cursor: String!
-}
-
-"""All tasks in the workflow have errored"""
-type WorkflowErroredStatus {
-  """Time at which this workflow started"""
-  startTime: DateTime!
-
-  """Time at which this workflow completed"""
-  endTime: DateTime!
-
-  """
-  A human readable message indicating details about why the workflow is in this condition
-  """
-  message: String
-
-  """Tasks created by the workflow"""
-  tasks: [Task!]!
-}
-
-"""All tasks in the workflow have failed"""
-type WorkflowFailedStatus {
-  """Time at which this workflow started"""
-  startTime: DateTime!
-
-  """Time at which this workflow completed"""
-  endTime: DateTime!
-
-  """
-  A human readable message indicating details about why the workflow is in this condition
-  """
-  message: String
-
-  """Tasks created by the workflow"""
-  tasks: [Task!]!
-}
-
-"""All the supported Workflows filters"""
-input WorkflowFilter {
-  """The status field for a workflow"""
-  workflowStatusFilter: WorkflowStatusFilter
-
-  """The fedid of the user who created the workflow"""
-  creator: Creator
-
-  """The name of the workflow template"""
-  template: Template
-}
-
-type WorkflowPendingStatus {
-  """
-  A human readable message indicating details about why the workflow is in this condition
-  """
-  message: String
-}
-
-type WorkflowRunningStatus {
-  """Time at which this workflow started"""
-  startTime: DateTime!
-
-  """
-  A human readable message indicating details about why the workflow is in this condition
-  """
-  message: String
-
-  """Tasks created by the workflow"""
-  tasks: [Task!]!
-}
-
-"""The status of a workflow"""
-union WorkflowStatus = WorkflowPendingStatus | WorkflowRunningStatus | WorkflowSucceededStatus | WorkflowFailedStatus | WorkflowErroredStatus
-
-"""Represents workflow status filters"""
-input WorkflowStatusFilter {
-  pending: Boolean! = false
-  running: Boolean! = false
-  succeeded: Boolean! = false
-  failed: Boolean! = false
-  error: Boolean! = false
-}
-
-"""All tasks in the workflow have succeded"""
-type WorkflowSucceededStatus {
-  """Time at which this workflow started"""
-  startTime: DateTime!
-
-  """Time at which this workflow completed"""
-  endTime: DateTime!
-
-  """
-  A human readable message indicating details about why the workflow is in this condition
-  """
-  message: String
-
-  """Tasks created by the workflow"""
-  tasks: [Task!]!
-}
-
-type WorkflowTemplate {
-  """The name given to the workflow template, globally unique"""
-  name: String!
-
-  """The group who maintains the workflow template"""
-  maintainer: String!
-
-  """A human readable title for the workflow template"""
-  title: String
-
-  """A human readable description of the workflow which is created"""
-  description: String
-
-  """The repository storing the code associated with this template."""
-  repository: String
-
-  """A JSON Schema describing the arguments of a Workflow Template"""
-  arguments: JSON!
-
-  """
-  A JSON Forms UI Schema describing how to render the arguments of the Workflow Template
-  """
-  uiSchema: JSON
-
-  """Information about where the template is obtained from"""
-  templateSource: TemplateSource
-}
-
-type WorkflowTemplateConnection {
-  """Information to aid in pagination."""
-  pageInfo: PageInfo!
-
-  """A list of edges."""
-  edges: [WorkflowTemplateEdge!]!
-
-  """A list of nodes."""
-  nodes: [WorkflowTemplate!]!
-}
-
-"""An edge in a connection."""
-type WorkflowTemplateEdge {
-  """The item at the end of the edge"""
-  node: WorkflowTemplate!
-
-  """A cursor for use in pagination"""
-  cursor: String!
-}
-
-"""Supported label filters for ClusterWorkflowTemplates"""
-input WorkflowTemplatesFilter {
-  """The science group owning the template eg imaging"""
-  scienceGroup: [ScienceGroup!]
-}
-
 type Account {
   accountId: Int!
   username: String!
@@ -453,6 +22,13 @@ enum AccountType {
   functional
 }
 
+"""
+Implement the DateTime<Utc> scalar
+
+The input/output is a string in RFC3339 format.
+"""
+scalar DateTime
+
 type Instrument {
   name: String!
   scienceGroup: String
@@ -492,6 +68,30 @@ type InstrumentSessionRole {
   onSite: Boolean!
 }
 
+"""The root mutation of the service"""
+type Mutation {
+  instrumentSession(proposalNumber: Int!, instrumentSessionNumber: Int!): InstrumentSessionMutations
+  createOrValidateSamples(input: CreateOrValidateSampleInput!): CreateSamplesResponse!
+  createSamples(input: CreateSampleInput!): [Sample!]! @deprecated(reason: "Will be replaced by createOrValidateSamples")
+  sample(sampleId: UUID!): SampleMutations
+  submitWorkflowTemplate(name: String!, visit: VisitInput!, parameters: JSON!): Workflow!
+}
+
+"""Information about pagination in a connection"""
+type PageInfo {
+  """When paginating backwards, the cursor to continue."""
+  startCursor: String
+
+  """When paginating forwards, the cursor to continue."""
+  endCursor: String
+
+  """When paginating forwards, are there more items?"""
+  hasNextPage: Boolean!
+
+  """When paginating backwards, are there more items?"""
+  hasPreviousPage: Boolean!
+}
+
 type Proposal {
   proposalNumber: Int!
   proposalCategory: String
@@ -525,6 +125,45 @@ enum ProposalState {
   Cancelled
 }
 
+"""The root query of the service"""
+type Query {
+  """Get a proposal by its number"""
+  proposal(proposalNumber: Int!): Proposal
+
+  """Get a list of proposals"""
+  proposals(proposalCategory: String = null, first: Int = null, last: Int = null, after: String = null, before: String = null): ProposalConnection!
+
+  """Get a instrument session"""
+  instrumentSession(proposalNumber: Int!, instrumentSessionNumber: Int!): InstrumentSession
+
+  """Get a instrument session"""
+  instrumentSessions(proposalNumber: Int = null, proposalCategory: String = null): [InstrumentSession!]
+
+  """Get an instrument"""
+  instrument(instrumentName: String!): Instrument
+
+  """Get a list of instruments"""
+  instruments(scienceGroup: String = null): [Instrument!]!
+
+  """Get an account"""
+  account(username: String!): Account
+
+  """Get a list of samples associated with a given instrument session"""
+  samples(first: Int!, instrumentSessions: [InstrumentSessionInput!] = null, filter: SampleFilterInput! = {schemaUrl: null, createdTime: null, updatedTime: null, name: null, data: null}, before: String = null, after: String = null, last: Int = null, orderBy: SampleOrder! = {name: null, createdTime: null, updatedTime: null}): SampleConnection!
+
+  """Get a sample by its id"""
+  sample(sampleId: UUID!): Sample
+  jsonSchema(url: String!): JSONSchema
+  jsonSchemas(type: String = null, instrument: String = null): [JSONSchema!]!
+  node(id: ID!): NodeValue
+
+  """Get a single [`Workflow`] by proposal, visit, and name"""
+  workflow(visit: VisitInput!, name: String!): Workflow!
+  workflows(visit: VisitInput!, cursor: String, limit: Int, filter: WorkflowFilter): WorkflowConnection!
+  workflowTemplate(name: String!): WorkflowTemplate!
+  workflowTemplates(cursor: String, limit: Int, filter: WorkflowTemplatesFilter): WorkflowTemplateConnection!
+}
+
 input AddSampleEventInput {
   description: String!
 }
@@ -621,6 +260,11 @@ input InstrumentSessionInput {
   instrumentSessionNumber: Int!
 }
 
+"""
+The `JSON` scalar type represents JSON values as specified by [ECMA-404](https://ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf).
+"""
+scalar JSON
+
 input JSONOperator @oneOf {
   stringOperator: StringOperatorInput = null
   datetimeOperator: DatetimeOperatorInput = null
@@ -820,4 +464,359 @@ type JSONSchema {
 
   """The description og the schema"""
   description: String
+}
+
+type Artifact {
+  """The file name of the artifact"""
+  name: String!
+
+  """The download URL for the artifact"""
+  url: Url!
+
+  """The MIME type of the artifact data"""
+  mimeType: String!
+}
+
+scalar Creator
+
+"""A scalar that can represent any JSON Object value."""
+scalar JSONObject
+
+"""A single log line streamed from a pod"""
+type LogEntry {
+  """The log line content"""
+  content: String!
+
+  """The name of the pod producing the log"""
+  podName: String!
+}
+
+"""Represents Relay Node types"""
+union NodeValue = Workflow
+
+"""Supported DLS science groups"""
+enum ScienceGroup {
+  """Macromolecular Crystallography"""
+  MX
+
+  """Workflows Examples"""
+  EXAMPLES
+
+  """Magnetic Materials"""
+  MAGNETIC_MATERIALS
+
+  """Soft Condensed Matter"""
+  CONDENSED_MATTER
+
+  """Imaging and Microscopy"""
+  IMAGING
+
+  """Biological Cryo-Imaging"""
+  BIO_CRYO_IMAGING
+
+  """Structures and Surfaces"""
+  SURFACES
+
+  """Crystallography"""
+  CRYSTALLOGRAPHY
+
+  """Spectroscopy"""
+  SPECTROSCOPY
+}
+
+"""The root mutation of the service"""
+type Subscription {
+  """Processing to subscribe to logs for a single pod of a workflow"""
+  logs(visit: VisitInput!, workflowName: String!, taskId: String!): LogEntry!
+
+  """Processing to subscribe to data for all workflows in a session"""
+  workflow(visit: VisitInput!, name: String!): Workflow!
+}
+
+type Task {
+  """Unique name of the task"""
+  id: String!
+
+  """Display name of the task"""
+  name: String!
+
+  """Current status of a task"""
+  status: TaskStatus!
+
+  """Parent of a task"""
+  depends: [String!]!
+
+  """Children of a task"""
+  dependencies: [String!]!
+
+  """Artifacts produced by a task"""
+  artifacts: [Artifact!]!
+
+  """Node type - Pod, DAG, etc"""
+  stepType: String!
+
+  """Start time for a task on a workflow"""
+  startTime: DateTime
+
+  """End time for a task on a workflow"""
+  endTime: DateTime
+
+  """
+  A human readable message indicating details about why this step is in this condition
+  """
+  message: String
+}
+
+enum TaskStatus {
+  PENDING
+  RUNNING
+  SUCCEEDED
+  SKIPPED
+  FAILED
+  ERROR
+  OMITTED
+}
+
+scalar Template
+
+"""Information about where the template is stored"""
+type TemplateSource {
+  """The URL of the GitHub repository"""
+  repositoryUrl: String!
+
+  """The path to the template within the repository"""
+  path: String!
+
+  """The current tracked branch of the repository"""
+  targetRevision: String!
+}
+
+"""
+URL is a String implementing the [URL Standard](http://url.spec.whatwg.org/)
+"""
+scalar Url
+
+"""A visit to an instrument as part of a session"""
+type Visit {
+  """Project Proposal Code"""
+  proposalCode: String!
+
+  """Project Proposal Number"""
+  proposalNumber: Int!
+
+  """Session visit Number"""
+  number: Int!
+}
+
+"""A visit to an instrument as part of a session"""
+input VisitInput {
+  """Project Proposal Code"""
+  proposalCode: String!
+
+  """Project Proposal Number"""
+  proposalNumber: Int!
+
+  """Session visit Number"""
+  number: Int!
+}
+
+type Workflow {
+  """The unique ID derived from the visit and name"""
+  id: ID!
+
+  """The name given to the workflow, unique within a given visit"""
+  name: String!
+
+  """The visit the Workflow was run against"""
+  visit: Visit!
+
+  """The current status of the workflow"""
+  status: WorkflowStatus
+
+  """The top-level workflow parameters"""
+  parameters: JSONObject
+
+  """The name of the template used to run the workflow"""
+  templateRef: String
+
+  """The workflow creator"""
+  creator: WorkflowCreator!
+}
+
+type WorkflowConnection {
+  """Information to aid in pagination."""
+  pageInfo: PageInfo!
+
+  """A list of edges."""
+  edges: [WorkflowEdge!]!
+
+  """A list of nodes."""
+  nodes: [Workflow!]!
+}
+
+"""Information about the creator of a workflow."""
+type WorkflowCreator {
+  """
+  An identifier unique to the creator of the workflow.
+  Typically this is the creator's Fed-ID.
+  """
+  creatorId: String!
+}
+
+"""An edge in a connection."""
+type WorkflowEdge {
+  """The item at the end of the edge"""
+  node: Workflow!
+
+  """A cursor for use in pagination"""
+  cursor: String!
+}
+
+"""All tasks in the workflow have errored"""
+type WorkflowErroredStatus {
+  """Time at which this workflow started"""
+  startTime: DateTime!
+
+  """Time at which this workflow completed"""
+  endTime: DateTime!
+
+  """
+  A human readable message indicating details about why the workflow is in this condition
+  """
+  message: String
+
+  """Tasks created by the workflow"""
+  tasks: [Task!]!
+}
+
+"""All tasks in the workflow have failed"""
+type WorkflowFailedStatus {
+  """Time at which this workflow started"""
+  startTime: DateTime!
+
+  """Time at which this workflow completed"""
+  endTime: DateTime!
+
+  """
+  A human readable message indicating details about why the workflow is in this condition
+  """
+  message: String
+
+  """Tasks created by the workflow"""
+  tasks: [Task!]!
+}
+
+"""All the supported Workflows filters"""
+input WorkflowFilter {
+  """The status field for a workflow"""
+  workflowStatusFilter: WorkflowStatusFilter
+
+  """The fedid of the user who created the workflow"""
+  creator: Creator
+
+  """The name of the workflow template"""
+  template: Template
+}
+
+type WorkflowPendingStatus {
+  """
+  A human readable message indicating details about why the workflow is in this condition
+  """
+  message: String
+}
+
+type WorkflowRunningStatus {
+  """Time at which this workflow started"""
+  startTime: DateTime!
+
+  """
+  A human readable message indicating details about why the workflow is in this condition
+  """
+  message: String
+
+  """Tasks created by the workflow"""
+  tasks: [Task!]!
+}
+
+"""The status of a workflow"""
+union WorkflowStatus = WorkflowPendingStatus | WorkflowRunningStatus | WorkflowSucceededStatus | WorkflowFailedStatus | WorkflowErroredStatus
+
+"""Represents workflow status filters"""
+input WorkflowStatusFilter {
+  pending: Boolean! = false
+  running: Boolean! = false
+  succeeded: Boolean! = false
+  failed: Boolean! = false
+  error: Boolean! = false
+}
+
+"""All tasks in the workflow have succeded"""
+type WorkflowSucceededStatus {
+  """Time at which this workflow started"""
+  startTime: DateTime!
+
+  """Time at which this workflow completed"""
+  endTime: DateTime!
+
+  """
+  A human readable message indicating details about why the workflow is in this condition
+  """
+  message: String
+
+  """Tasks created by the workflow"""
+  tasks: [Task!]!
+}
+
+type WorkflowTemplate {
+  """The name given to the workflow template, globally unique"""
+  name: String!
+
+  """The group who maintains the workflow template"""
+  maintainer: String!
+
+  """A human readable title for the workflow template"""
+  title: String
+
+  """A human readable description of the workflow which is created"""
+  description: String
+
+  """The repository storing the code associated with this template."""
+  repository: String
+
+  """A JSON Schema describing the arguments of a Workflow Template"""
+  arguments: JSON!
+
+  """
+  A JSON Forms UI Schema describing how to render the arguments of the Workflow Template
+  """
+  uiSchema: JSON
+
+  """Information about where the template is obtained from"""
+  templateSource: TemplateSource
+}
+
+type WorkflowTemplateConnection {
+  """Information to aid in pagination."""
+  pageInfo: PageInfo!
+
+  """A list of edges."""
+  edges: [WorkflowTemplateEdge!]!
+
+  """A list of nodes."""
+  nodes: [WorkflowTemplate!]!
+}
+
+"""An edge in a connection."""
+type WorkflowTemplateEdge {
+  """The item at the end of the edge"""
+  node: WorkflowTemplate!
+
+  """A cursor for use in pagination"""
+  cursor: String!
+}
+
+"""Supported label filters for ClusterWorkflowTemplates"""
+input WorkflowTemplatesFilter {
+  """The science group owning the template eg imaging"""
+  scienceGroup: [ScienceGroup!]
 }
\ No newline at end of file

Copy link
Copy Markdown
Collaborator

@VictoriaBeilsten-Edmands VictoriaBeilsten-Edmands left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking into subscription problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant