diff --git a/schema/samples.graphql b/schema/samples.graphql index fa4247c..536916f 100644 --- a/schema/samples.graphql +++ b/schema/samples.graphql @@ -1,3 +1,10 @@ +directive @oneOf on INPUT_OBJECT + +schema @link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@external", "@key", "@provides", "@shareable"]) { + query: Query + mutation: Mutation +} + input AddSampleEventInput { description: String! } @@ -6,11 +13,24 @@ input CreateOrValidateSampleInput { """URL of the JSON schema the samples' `data` should be validated against""" dataSchemaUrl: String! + """Samples to be created""" + samples: [SampleIn!]! + + """ + Whether or not the provided samples should only be validated and not created + """ + validateOnly: Boolean! = false + """Number of the proposal the samples should be associated with""" proposalNumber: Int! """Number of the instrument session the samples should be associated with""" instrumentSessionNumber: Int! +} + +input CreateOrValidateSampleInputBase { + """URL of the JSON schema the samples' `data` should be validated against""" + dataSchemaUrl: String! """Samples to be created""" samples: [SampleIn!]! @@ -69,30 +89,94 @@ type ErrorDetails { message: String! } +type InstrumentSession @key(fields: "instrumentSessionNumber proposal { proposalNumber }") { + instrumentSessionNumber: Int! @external + proposal: Proposal @external + + """Samples associated with a given instrument session""" + samples(first: Int!, filter: SampleFilterInput! = {}, before: String = null, after: String = null, last: Int = null, orderBy: SampleOrder! = {}): SampleConnection! +} + +type InstrumentSessionConnection { + edges: [InstrumentSessionEdge!]! + pageInfo: PageInfo! +} + +type InstrumentSessionEdge { + cursor: String! + node: InstrumentSession! +} + +input InstrumentSessionInput { + proposalNumber: Int! + instrumentSessionNumber: Int! +} + +type InstrumentSessionMutations @key(fields: "instrumentSessionNumber proposalNumber") { + instrumentSessionNumber: Int! @external + proposalNumber: Int! @external + + """Create or validate samples associated with this instrument session""" + createOrValidateSamples(input: CreateOrValidateSampleInputBase!): CreateSamplesResponse! +} + """ 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 @specifiedBy(url: "https://ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf") +input JSONOperator @oneOf { + stringOperator: StringOperatorInput = null + datetimeOperator: DatetimeOperatorInput = null + numericOperator: NumericOperatorInput = null +} + +input JSONOperatorInput { + """A JSON path specifying the value to filter. Must start with '$.'""" + path: String! + + """The operator to apply to the JSON field""" + operator: JSONOperator! +} + type Mutation { - createSamples(input: CreateSampleInput!): [Sample!]! @deprecated(reason: "Will be replaced by createOrValidateSamples") createOrValidateSamples(input: CreateOrValidateSampleInput!): CreateSamplesResponse! + createSamples(input: CreateSampleInput!): [Sample!]! @deprecated(reason: "Will be replaced by createOrValidateSamples") sample(sampleId: UUID!): SampleMutations } -type PageInfo { +input NumericOperatorInput { + """ + Will filter to items where the numeric field is greater than the provided value + """ + gt: Float = null + + """ + Will filter to items where the numeric field is less than the provided value + """ + lt: Float = null +} + +type PageInfo @shareable { startCursor: String endCursor: String hasPreviousPage: Boolean! hasNextPage: Boolean! } +type Proposal @key(fields: "proposalNumber") { + proposalNumber: Int! @external +} + type Query { - """Get a sample by its id""" - sample(sampleId: UUID!): Sample + _entities(representations: [_Any!]!): [_Entity]! + _service: _Service! """Get a list of samples associated with a given instrument session""" - samples(proposalNumber: Int!, instrumentSessionNumber: Int!, first: Int!, filter: SampleFilterInput! = {}, before: String = null, after: String = null, last: Int = null, orderBy: SampleOrder! = {}): SampleConnection! + samples(first: Int!, instrumentSessions: [InstrumentSessionInput!] = null, filter: SampleFilterInput! = {}, before: String = null, after: String = null, last: Int = null, orderBy: SampleOrder! = {}): SampleConnection! + + """Get a sample by its id""" + sample(sampleId: UUID!): Sample } type Sample { @@ -114,6 +198,10 @@ type Sample { """The JSON schema that the sample's `data` conforms to""" dataSchema: JSON! + + """The instrument sessions that this sample is associated with""" + instrumentSessions: InstrumentSessionConnection! @provides(fields: "edges{ node{ instrumentSessionNumber proposal{ proposalNumber }}}") + images: [SampleImage!]! } type SampleConnection { @@ -154,6 +242,14 @@ input SampleFilterInput { """Filter on the `name` field of `Sample`""" name: StringOperatorInput = null + + """Filter on the `data` field of `Sample`""" + data: [JSONOperatorInput!] = null +} + +type SampleImage { + url: String! + filename: String! } input SampleIn { @@ -176,6 +272,7 @@ type SampleMutations { sampleId: UUID! linkInstrumentSessionToSample(proposalNumber: Int!, instrumentSessionNumber: Int!): Void addSampleEvent(sampleEvent: AddSampleEventInput!): SampleEvent! + createSampleImageUploadUrl(filename: String!, contentType: String!, contentLength: Int!): String! } input SampleOrder { @@ -232,3 +329,11 @@ scalar UUID """Represents NULL values""" scalar Void + +scalar _Any + +union _Entity = InstrumentSession | InstrumentSessionMutations | Proposal + +type _Service { + sdl: String! +}