diff options
author | Michael Muré <batolettre@gmail.com> | 2020-06-21 22:12:04 +0200 |
---|---|---|
committer | Michael Muré <batolettre@gmail.com> | 2020-06-27 23:03:05 +0200 |
commit | 2ab6381a94d55fa22b80acdbb18849d6b24951f9 (patch) | |
tree | 99942b000955623ea7466b9fa4cc7dab37645df6 /api/graphql/schema | |
parent | 5f72b04ef8e84b1c367ca6874519706318e351f5 (diff) | |
download | git-bug-2ab6381a94d55fa22b80acdbb18849d6b24951f9.tar.gz |
Reorganize the webUI and API code
Included in the changes:
- create a new /api root package to hold all API code, migrate /graphql in there
- git API handlers all use the cache instead of the repo directly
- git API handlers are now tested
- git API handlers now require a "repo" mux parameter
- lots of untangling of API/handlers/middleware
- less code in commands/webui.go
Diffstat (limited to 'api/graphql/schema')
-rw-r--r-- | api/graphql/schema/bug.graphql | 118 | ||||
-rw-r--r-- | api/graphql/schema/identity.graphql | 32 | ||||
-rw-r--r-- | api/graphql/schema/label.graphql | 19 | ||||
-rw-r--r-- | api/graphql/schema/mutations.graphql | 138 | ||||
-rw-r--r-- | api/graphql/schema/operations.graphql | 100 | ||||
-rw-r--r-- | api/graphql/schema/repository.graphql | 50 | ||||
-rw-r--r-- | api/graphql/schema/root.graphql | 19 | ||||
-rw-r--r-- | api/graphql/schema/timeline.graphql | 86 | ||||
-rw-r--r-- | api/graphql/schema/types.graphql | 30 |
9 files changed, 592 insertions, 0 deletions
diff --git a/api/graphql/schema/bug.graphql b/api/graphql/schema/bug.graphql new file mode 100644 index 00000000..03aa95b8 --- /dev/null +++ b/api/graphql/schema/bug.graphql @@ -0,0 +1,118 @@ +"""Represents a comment on a bug.""" +type Comment implements Authored { + """The author of this comment.""" + author: Identity! + + """The message of this comment.""" + message: String! + + """All media's hash referenced in this comment""" + files: [Hash!]! +} + +type CommentConnection { + edges: [CommentEdge!]! + nodes: [Comment!]! + pageInfo: PageInfo! + totalCount: Int! +} + +type CommentEdge { + cursor: String! + node: Comment! +} + +enum Status { + OPEN + CLOSED +} + +type Bug implements Authored { + """The identifier for this bug""" + id: String! + """The human version (truncated) identifier for this bug""" + humanId: String! + status: Status! + title: String! + labels: [Label!]! + author: Identity! + createdAt: Time! + lastEdit: Time! + + """The actors of the bug. Actors are Identity that have interacted with the bug.""" + actors( + """Returns the elements in the list that come after the specified cursor.""" + after: String + """Returns the elements in the list that come before the specified cursor.""" + before: String + """Returns the first _n_ elements from the list.""" + first: Int + """Returns the last _n_ elements from the list.""" + last: Int + ): IdentityConnection! + + """The participants of the bug. Participants are Identity that have created or + added a comment on the bug.""" + participants( + """Returns the elements in the list that come after the specified cursor.""" + after: String + """Returns the elements in the list that come before the specified cursor.""" + before: String + """Returns the first _n_ elements from the list.""" + first: Int + """Returns the last _n_ elements from the list.""" + last: Int + ): IdentityConnection! + + comments( + """Returns the elements in the list that come after the specified cursor.""" + after: String + """Returns the elements in the list that come before the specified cursor.""" + before: String + """Returns the first _n_ elements from the list.""" + first: Int + """Returns the last _n_ elements from the list.""" + last: Int + ): CommentConnection! + + timeline( + """Returns the elements in the list that come after the specified cursor.""" + after: String + """Returns the elements in the list that come before the specified cursor.""" + before: String + """Returns the first _n_ elements from the list.""" + first: Int + """Returns the last _n_ elements from the list.""" + last: Int + ): TimelineItemConnection! + + operations( + """Returns the elements in the list that come after the specified cursor.""" + after: String + """Returns the elements in the list that come before the specified cursor.""" + before: String + """Returns the first _n_ elements from the list.""" + first: Int + """Returns the last _n_ elements from the list.""" + last: Int + ): OperationConnection! +} + +"""The connection type for Bug.""" +type BugConnection { + """A list of edges.""" + edges: [BugEdge!]! + nodes: [Bug!]! + """Information to aid in pagination.""" + pageInfo: PageInfo! + """Identifies the total count of items in the connection.""" + totalCount: Int! +} + +"""An edge in a connection.""" +type BugEdge { + """A cursor for use in pagination.""" + cursor: String! + """The item at the end of the edge.""" + node: Bug! +} diff --git a/api/graphql/schema/identity.graphql b/api/graphql/schema/identity.graphql new file mode 100644 index 00000000..93154a90 --- /dev/null +++ b/api/graphql/schema/identity.graphql @@ -0,0 +1,32 @@ +"""Represents an identity""" +type Identity { + """The identifier for this identity""" + id: String! + """The human version (truncated) identifier for this identity""" + humanId: String! + """The name of the person, if known.""" + name: String + """The email of the person, if known.""" + email: String + """The login of the person, if known.""" + login: String + """A non-empty string to display, representing the identity, based on the non-empty values.""" + displayName: String! + """An url to an avatar""" + avatarUrl: String + """isProtected is true if the chain of git commits started to be signed. + If that's the case, only signed commit with a valid key for this identity can be added.""" + isProtected: Boolean! +} + +type IdentityConnection { + edges: [IdentityEdge!]! + nodes: [Identity!]! + pageInfo: PageInfo! + totalCount: Int! +} + +type IdentityEdge { + cursor: String! + node: Identity! +}
\ No newline at end of file diff --git a/api/graphql/schema/label.graphql b/api/graphql/schema/label.graphql new file mode 100644 index 00000000..1205915c --- /dev/null +++ b/api/graphql/schema/label.graphql @@ -0,0 +1,19 @@ +"""Label for a bug.""" +type Label { + """The name of the label.""" + name: String! + """Color of the label.""" + color: Color! +} + +type LabelConnection { + edges: [LabelEdge!]! + nodes: [Label!]! + pageInfo: PageInfo! + totalCount: Int! +} + +type LabelEdge { + cursor: String! + node: Label! +}
\ No newline at end of file diff --git a/api/graphql/schema/mutations.graphql b/api/graphql/schema/mutations.graphql new file mode 100644 index 00000000..e6b70faf --- /dev/null +++ b/api/graphql/schema/mutations.graphql @@ -0,0 +1,138 @@ +input NewBugInput { + """A unique identifier for the client performing the mutation.""" + clientMutationId: String + """"The name of the repository. If not set, the default repository is used.""" + repoRef: String + """The title of the new bug.""" + title: String! + """The first message of the new bug.""" + message: String! + """The collection of file's hash required for the first message.""" + files: [Hash!] +} + +type NewBugPayload { + """A unique identifier for the client performing the mutation.""" + clientMutationId: String + """The created bug.""" + bug: Bug! + """The resulting operation.""" + operation: CreateOperation! +} + +input AddCommentInput { + """A unique identifier for the client performing the mutation.""" + clientMutationId: String + """"The name of the repository. If not set, the default repository is used.""" + repoRef: String + """The bug ID's prefix.""" + prefix: String! + """The first message of the new bug.""" + message: String! + """The collection of file's hash required for the first message.""" + files: [Hash!] +} + +type AddCommentPayload { + """A unique identifier for the client performing the mutation.""" + clientMutationId: String + """The affected bug.""" + bug: Bug! + """The resulting operation.""" + operation: AddCommentOperation! +} + +input ChangeLabelInput { + """A unique identifier for the client performing the mutation.""" + clientMutationId: String + """"The name of the repository. If not set, the default repository is used.""" + repoRef: String + """The bug ID's prefix.""" + prefix: String! + """The list of label to add.""" + added: [String!] + """The list of label to remove.""" + Removed: [String!] +} + +enum LabelChangeStatus { + ADDED + REMOVED + DUPLICATE_IN_OP + ALREADY_EXIST + DOESNT_EXIST +} + +type LabelChangeResult { + """The source label.""" + label: Label! + """The effect this label had.""" + status: LabelChangeStatus! +} + +type ChangeLabelPayload { + """A unique identifier for the client performing the mutation.""" + clientMutationId: String + """The affected bug.""" + bug: Bug! + """The resulting operation.""" + operation: LabelChangeOperation! + """The effect each source label had.""" + results: [LabelChangeResult]! +} + +input OpenBugInput { + """A unique identifier for the client performing the mutation.""" + clientMutationId: String + """"The name of the repository. If not set, the default repository is used.""" + repoRef: String + """The bug ID's prefix.""" + prefix: String! +} + +type OpenBugPayload { + """A unique identifier for the client performing the mutation.""" + clientMutationId: String + """The affected bug.""" + bug: Bug! + """The resulting operation.""" + operation: SetStatusOperation! +} + +input CloseBugInput { + """A unique identifier for the client performing the mutation.""" + clientMutationId: String + """"The name of the repository. If not set, the default repository is used.""" + repoRef: String + """The bug ID's prefix.""" + prefix: String! +} + +type CloseBugPayload { + """A unique identifier for the client performing the mutation.""" + clientMutationId: String + """The affected bug.""" + bug: Bug! + """The resulting operation.""" + operation: SetStatusOperation! +} + +input SetTitleInput { + """A unique identifier for the client performing the mutation.""" + clientMutationId: String + """"The name of the repository. If not set, the default repository is used.""" + repoRef: String + """The bug ID's prefix.""" + prefix: String! + """The new title.""" + title: String! +} + +type SetTitlePayload { + """A unique identifier for the client performing the mutation.""" + clientMutationId: String + """The affected bug.""" + bug: Bug! + """The resulting operation""" + operation: SetTitleOperation! +} diff --git a/api/graphql/schema/operations.graphql b/api/graphql/schema/operations.graphql new file mode 100644 index 00000000..18e0929c --- /dev/null +++ b/api/graphql/schema/operations.graphql @@ -0,0 +1,100 @@ +"""An operation applied to a bug.""" +interface Operation { + """The identifier of the operation""" + id: String! + """The operations author.""" + author: Identity! + """The datetime when this operation was issued.""" + date: Time! +} + +# Connection + +"""The connection type for an Operation""" +type OperationConnection { + edges: [OperationEdge!]! + nodes: [Operation!]! + pageInfo: PageInfo! + totalCount: Int! +} + +"""Represent an Operation""" +type OperationEdge { + cursor: String! + node: Operation! +} + +# Operations + +type CreateOperation implements Operation & Authored { + """The identifier of the operation""" + id: String! + """The author of this object.""" + author: Identity! + """The datetime when this operation was issued.""" + date: Time! + + title: String! + message: String! + files: [Hash!]! +} + +type SetTitleOperation implements Operation & Authored { + """The identifier of the operation""" + id: String! + """The author of this object.""" + author: Identity! + """The datetime when this operation was issued.""" + date: Time! + + title: String! + was: String! +} + +type AddCommentOperation implements Operation & Authored { + """The identifier of the operation""" + id: String! + """The author of this object.""" + author: Identity! + """The datetime when this operation was issued.""" + date: Time! + + message: String! + files: [Hash!]! +} + +type EditCommentOperation implements Operation & Authored { + """The identifier of the operation""" + id: String! + """The author of this object.""" + author: Identity! + """The datetime when this operation was issued.""" + date: Time! + + target: String! + message: String! + files: [Hash!]! +} + +type SetStatusOperation implements Operation & Authored { + """The identifier of the operation""" + id: String! + """The author of this object.""" + author: Identity! + """The datetime when this operation was issued.""" + date: Time! + + status: Status! +} + +type LabelChangeOperation implements Operation & Authored { + """The identifier of the operation""" + id: String! + """The author of this object.""" + author: Identity! + """The datetime when this operation was issued.""" + date: Time! + + added: [Label!]! + removed: [Label!]! +} diff --git a/api/graphql/schema/repository.graphql b/api/graphql/schema/repository.graphql new file mode 100644 index 00000000..2b98fe37 --- /dev/null +++ b/api/graphql/schema/repository.graphql @@ -0,0 +1,50 @@ + +type Repository { + """The name of the repository""" + name: String + + """All the bugs""" + allBugs( + """Returns the elements in the list that come after the specified cursor.""" + after: String + """Returns the elements in the list that come before the specified cursor.""" + before: String + """Returns the first _n_ elements from the list.""" + first: Int + """Returns the last _n_ elements from the list.""" + last: Int + """A query to select and order bugs.""" + query: String + ): BugConnection! + + bug(prefix: String!): Bug + + """All the identities""" + allIdentities( + """Returns the elements in the list that come after the specified cursor.""" + after: String + """Returns the elements in the list that come before the specified cursor.""" + before: String + """Returns the first _n_ elements from the list.""" + first: Int + """Returns the last _n_ elements from the list.""" + last: Int + ): IdentityConnection! + + identity(prefix: String!): Identity + + """The identity created or selected by the user as its own""" + userIdentity: Identity + + """List of valid labels.""" + validLabels( + """Returns the elements in the list that come after the specified cursor.""" + after: String + """Returns the elements in the list that come before the specified cursor.""" + before: String + """Returns the first _n_ elements from the list.""" + first: Int + """Returns the last _n_ elements from the list.""" + last: Int + ): LabelConnection! +}
\ No newline at end of file diff --git a/api/graphql/schema/root.graphql b/api/graphql/schema/root.graphql new file mode 100644 index 00000000..94a0b530 --- /dev/null +++ b/api/graphql/schema/root.graphql @@ -0,0 +1,19 @@ +type Query { + """Access a repository by reference/name. If no ref is given, the default repository is returned if any.""" + repository(ref: String): Repository +} + +type Mutation { + """Create a new bug""" + newBug(input: NewBugInput!): NewBugPayload! + """Add a new comment to a bug""" + addComment(input: AddCommentInput!): AddCommentPayload! + """Add or remove a set of label on a bug""" + changeLabels(input: ChangeLabelInput): ChangeLabelPayload! + """Change a bug's status to open""" + openBug(input: OpenBugInput!): OpenBugPayload! + """Change a bug's status to closed""" + closeBug(input: CloseBugInput!): CloseBugPayload! + """Change a bug's title""" + setTitle(input: SetTitleInput!): SetTitlePayload! +} diff --git a/api/graphql/schema/timeline.graphql b/api/graphql/schema/timeline.graphql new file mode 100644 index 00000000..12462aa3 --- /dev/null +++ b/api/graphql/schema/timeline.graphql @@ -0,0 +1,86 @@ +"""An item in the timeline of events""" +interface TimelineItem { + """The identifier of the source operation""" + id: String! +} + +"""CommentHistoryStep hold one version of a message in the history""" +type CommentHistoryStep { + message: String! + date: Time! +} + +# Connection + +"""The connection type for TimelineItem""" +type TimelineItemConnection { + edges: [TimelineItemEdge!]! + nodes: [TimelineItem!]! + pageInfo: PageInfo! + totalCount: Int! +} + +"""Represent a TimelineItem""" +type TimelineItemEdge { + cursor: String! + node: TimelineItem! +} + +# Items + +"""CreateTimelineItem is a TimelineItem that represent the creation of a bug and its message edition history""" +type CreateTimelineItem implements TimelineItem & Authored { + """The identifier of the source operation""" + id: String! + author: Identity! + message: String! + messageIsEmpty: Boolean! + files: [Hash!]! + createdAt: Time! + lastEdit: Time! + edited: Boolean! + history: [CommentHistoryStep!]! +} + +"""AddCommentTimelineItem is a TimelineItem that represent a Comment and its edition history""" +type AddCommentTimelineItem implements TimelineItem & Authored { + """The identifier of the source operation""" + id: String! + author: Identity! + message: String! + messageIsEmpty: Boolean! + files: [Hash!]! + createdAt: Time! + lastEdit: Time! + edited: Boolean! + history: [CommentHistoryStep!]! +} + +"""LabelChangeTimelineItem is a TimelineItem that represent a change in the labels of a bug""" +type LabelChangeTimelineItem implements TimelineItem & Authored { + """The identifier of the source operation""" + id: String! + author: Identity! + date: Time! + added: [Label!]! + removed: [Label!]! +} + +"""SetStatusTimelineItem is a TimelineItem that represent a change in the status of a bug""" +type SetStatusTimelineItem implements TimelineItem & Authored { + """The identifier of the source operation""" + id: String! + author: Identity! + date: Time! + status: Status! +} + +"""LabelChangeTimelineItem is a TimelineItem that represent a change in the title of a bug""" +type SetTitleTimelineItem implements TimelineItem & Authored { + """The identifier of the source operation""" + id: String! + author: Identity! + date: Time! + title: String! + was: String! +} diff --git a/api/graphql/schema/types.graphql b/api/graphql/schema/types.graphql new file mode 100644 index 00000000..0182885e --- /dev/null +++ b/api/graphql/schema/types.graphql @@ -0,0 +1,30 @@ +scalar Time +scalar Hash + +"""Defines a color by red, green and blue components.""" +type Color { + """Red component of the color.""" + R: Int! + """Green component of the color.""" + G: Int! + """Blue component of the color.""" + B: Int! +} + +"""Information about pagination in a connection.""" +type PageInfo { + """When paginating forwards, are there more items?""" + hasNextPage: Boolean! + """When paginating backwards, are there more items?""" + hasPreviousPage: Boolean! + """When paginating backwards, the cursor to continue.""" + startCursor: String! + """When paginating forwards, the cursor to continue.""" + endCursor: String! +} + +"""An object that has an author.""" +interface Authored { + """The author of this object.""" + author: Identity! +} |