graphql: now that it's possible, split the schema for clarity

Michael Muré created

Change summary

README.md                    |   2 
bug/timeline.go              |   1 
graphql/bug.graphql          | 122 +++++++++
graphql/gqlgen.yml           |   2 
graphql/graph/gen_graph.go   | 478 +++++++++++++++++++------------------
graphql/models/gen_models.go |   4 
graphql/operations.graphql   | 100 +++++++
graphql/root.graphql         |  38 +++
graphql/schema.graphql       | 332 --------------------------
graphql/timeline.graphql     |  84 ++++++
10 files changed, 597 insertions(+), 566 deletions(-)

Detailed changes

README.md 🔗

@@ -97,7 +97,7 @@ You can launch a rich Web UI with `git bug webui`.
 
 This web UI is entirely packed inside the same go binary and serve static content through a localhost http server.
 
-The web UI interact with the backend through a GraphQL API. The schema is available [here](graphql/schema.graphql).
+The web UI interact with the backend through a GraphQL API. The schema is available [here](graphql/).
 
 ## Internals
 

bug/timeline.go 🔗

@@ -9,6 +9,7 @@ type TimelineItem interface {
 	Hash() git.Hash
 }
 
+// CommentHistoryStep hold one version of a message in the history
 type CommentHistoryStep struct {
 	// The author of the edition, not necessarily the same as the author of the
 	// original comment

graphql/bug.graphql 🔗

@@ -0,0 +1,122 @@
+"""Represents an person"""
+type Person {
+  """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 string containing the either the name of the person, its login or both"""
+  displayName: String!
+  """An url to an avatar"""
+  avatarUrl: String
+}
+
+"""Represents a comment on a bug."""
+type Comment implements Authored {
+  """The author of this comment."""
+  author: Person!
+
+  """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 {
+  id: String!
+  humanId: String!
+  status: Status!
+  title: String!
+  labels: [Label!]!
+  author: Person!
+  createdAt: Time!
+  lastEdit: Time!
+
+  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!
+}
+
+type Repository {
+  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
+}
+

graphql/gqlgen.yml 🔗

@@ -1,4 +1,4 @@
-schema: schema.graphql
+schema: "*.graphql"
 exec:
   filename: graph/gen_graph.go
 model:

graphql/graph/gen_graph.go 🔗

@@ -8685,6 +8685,8 @@ func (ec *executionContext) _Authored(ctx context.Context, sel ast.SelectionSet,
 	switch obj := (*obj).(type) {
 	case nil:
 		return graphql.Null
+	case bug.Comment:
+		return ec._Comment(ctx, sel, &obj)
 	case *bug.Comment:
 		return ec._Comment(ctx, sel, obj)
 	case *bug.CreateOperation:
@@ -8780,52 +8782,20 @@ func (ec *executionContext) introspectType(name string) (*introspection.Type, er
 }
 
 var parsedSchema = gqlparser.MustLoadSchema(
-	&ast.Source{Name: "schema.graphql", Input: `scalar Time
-scalar Label
-scalar Hash
-
-"""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!
-}
-
-"""Represents an person in a git object."""
+	&ast.Source{Name: "bug.graphql", Input: `"""Represents an person"""
 type Person {
   """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 string containing the either the name of the person, its login or both"""
   displayName: String!
-
   """An url to an avatar"""
   avatarUrl: String
 }
 
-type CommentConnection {
-  edges: [CommentEdge!]!
-  nodes: [Comment!]!
-  pageInfo: PageInfo!
-  totalCount: Int!
-}
-
-type CommentEdge {
-  cursor: String!
-  node: Comment!
-}
-
 """Represents a comment on a bug."""
 type Comment implements Authored {
   """The author of this comment."""
@@ -8838,202 +8808,21 @@ type Comment implements Authored {
   files: [Hash!]!
 }
 
-enum Status {
-  OPEN
-  CLOSED
-}
-
-"""An object that has an author."""
-interface Authored {
-  """The author of this object."""
-  author: Person!
-}
-
-type OperationConnection {
-  edges: [OperationEdge!]!
-  nodes: [Operation!]!
-  pageInfo: PageInfo!
-  totalCount: Int!
-}
-
-type OperationEdge {
-  cursor: String!
-  node: Operation!
-}
-
-"""An item in the timeline of events"""
-interface TimelineItem {
-  """The hash of the source operation"""
-  hash: Hash!
-}
-
-"""An operation applied to a bug."""
-interface Operation {
-  """The hash of the operation"""
-  hash: Hash!
-  """The operations author."""
-  author: Person!
-  """The datetime when this operation was issued."""
-  date: Time!
-}
-
-type CreateOperation implements Operation & Authored {
-  """The hash of the operation"""
-  hash: Hash!
-  """The author of this object."""
-  author: Person!
-  """The datetime when this operation was issued."""
-  date: Time!
-
-  title: String!
-  message: String!
-  files: [Hash!]!
-}
-
-type SetTitleOperation implements Operation & Authored {
-  """The hash of the operation"""
-  hash: Hash!
-  """The author of this object."""
-  author: Person!
-  """The datetime when this operation was issued."""
-  date: Time!
-
-  title: String!
-  was: String!
-}
-
-type AddCommentOperation implements Operation & Authored {
-  """The hash of the operation"""
-  hash: Hash!
-  """The author of this object."""
-  author: Person!
-  """The datetime when this operation was issued."""
-  date: Time!
-
-  message: String!
-  files: [Hash!]!
-}
-
-type EditCommentOperation implements Operation & Authored {
-  """The hash of the operation"""
-  hash: Hash!
-  """The author of this object."""
-  author: Person!
-  """The datetime when this operation was issued."""
-  date: Time!
-
-  target: Hash!
-  message: String!
-  files: [Hash!]!
-}
-
-type SetStatusOperation implements Operation & Authored {
-  """The hash of the operation"""
-  hash: Hash!
-  """The author of this object."""
-  author: Person!
-  """The datetime when this operation was issued."""
-  date: Time!
-
-  status: Status!
-}
-
-type LabelChangeOperation implements Operation & Authored {
-  """The hash of the operation"""
-  hash: Hash!
-  """The author of this object."""
-  author: Person!
-  """The datetime when this operation was issued."""
-  date: Time!
-
-  added: [Label!]!
-  removed: [Label!]!
-}
-
-type TimelineItemConnection {
-  edges: [TimelineItemEdge!]!
-  nodes: [TimelineItem!]!
+type CommentConnection {
+  edges: [CommentEdge!]!
+  nodes: [Comment!]!
   pageInfo: PageInfo!
   totalCount: Int!
 }
 
-type TimelineItemEdge {
+type CommentEdge {
   cursor: String!
-  node: TimelineItem!
-}
-
-type CommentHistoryStep {
-  message: String!
-  date: Time!
-}
-
-type CreateTimelineItem implements TimelineItem {
-  """The hash of the source operation"""
-  hash: Hash!
-  author: Person!
-  message: String!
-  files: [Hash!]!
-  createdAt: Time!
-  lastEdit: Time!
-  edited: Boolean!
-  history: [CommentHistoryStep!]!
-}
-
-type AddCommentTimelineItem implements TimelineItem {
-  """The hash of the source operation"""
-  hash: Hash!
-  author: Person!
-  message: String!
-  files: [Hash!]!
-  createdAt: Time!
-  lastEdit: Time!
-  edited: Boolean!
-  history: [CommentHistoryStep!]!
-}
-
-type LabelChangeTimelineItem implements TimelineItem {
-  """The hash of the source operation"""
-  hash: Hash!
-  author: Person!
-  date: Time!
-  added: [Label!]!
-  removed: [Label!]!
-}
-
-type SetStatusTimelineItem implements TimelineItem {
-  """The hash of the source operation"""
-  hash: Hash!
-  author: Person!
-  date: Time!
-  status: Status!
-}
-
-type SetTitleTimelineItem implements TimelineItem {
-  """The hash of the source operation"""
-  hash: Hash!
-  author: Person!
-  date: Time!
-  title: String!
-  was: String!
-}
-
-"""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!
+  node: Comment!
 }
 
-"""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!
+enum Status {
+  OPEN
+  CLOSED
 }
 
 type Bug {
@@ -9080,6 +8869,25 @@ type Bug {
   ): 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!
+}
+
 type Repository {
   allBugs(
     """Returns the elements in the list that come after the specified cursor."""
@@ -9096,21 +8904,227 @@ type Repository {
   bug(prefix: String!): Bug
 }
 
+`},
+	&ast.Source{Name: "operations.graphql", Input: `"""An operation applied to a bug."""
+interface Operation {
+    """The hash of the operation"""
+    hash: Hash!
+    """The operations author."""
+    author: Person!
+    """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 hash of the operation"""
+    hash: Hash!
+    """The author of this object."""
+    author: Person!
+    """The datetime when this operation was issued."""
+    date: Time!
+
+    title: String!
+    message: String!
+    files: [Hash!]!
+}
+
+type SetTitleOperation implements Operation & Authored {
+    """The hash of the operation"""
+    hash: Hash!
+    """The author of this object."""
+    author: Person!
+    """The datetime when this operation was issued."""
+    date: Time!
+
+    title: String!
+    was: String!
+}
+
+type AddCommentOperation implements Operation & Authored {
+    """The hash of the operation"""
+    hash: Hash!
+    """The author of this object."""
+    author: Person!
+    """The datetime when this operation was issued."""
+    date: Time!
+
+    message: String!
+    files: [Hash!]!
+}
+
+type EditCommentOperation implements Operation & Authored {
+    """The hash of the operation"""
+    hash: Hash!
+    """The author of this object."""
+    author: Person!
+    """The datetime when this operation was issued."""
+    date: Time!
+
+    target: Hash!
+    message: String!
+    files: [Hash!]!
+}
+
+type SetStatusOperation implements Operation & Authored {
+    """The hash of the operation"""
+    hash: Hash!
+    """The author of this object."""
+    author: Person!
+    """The datetime when this operation was issued."""
+    date: Time!
+
+    status: Status!
+}
+
+type LabelChangeOperation implements Operation & Authored {
+    """The hash of the operation"""
+    hash: Hash!
+    """The author of this object."""
+    author: Person!
+    """The datetime when this operation was issued."""
+    date: Time!
+
+    added: [Label!]!
+    removed: [Label!]!
+}`},
+	&ast.Source{Name: "root.graphql", Input: `scalar Time
+scalar Label
+scalar Hash
+
+"""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: Person!
+}
+
 type Query {
-  defaultRepository: Repository
-  repository(id: String!): Repository
+    defaultRepository: Repository
+    repository(id: String!): Repository
 }
 
 type Mutation {
-  newBug(repoRef: String, title: String!, message: String!, files: [Hash!]): Bug!
+    newBug(repoRef: String, title: String!, message: String!, files: [Hash!]): Bug!
 
-  addComment(repoRef: String, prefix: String!, message: String!, files: [Hash!]): Bug!
-  changeLabels(repoRef: String, prefix: String!, added: [String!], removed: [String!]): Bug!
-  open(repoRef: String, prefix: String!): Bug!
-  close(repoRef: String, prefix: String!): Bug!
-  setTitle(repoRef: String, prefix: String!, title: String!): Bug!
+    addComment(repoRef: String, prefix: String!, message: String!, files: [Hash!]): Bug!
+    changeLabels(repoRef: String, prefix: String!, added: [String!], removed: [String!]): Bug!
+    open(repoRef: String, prefix: String!): Bug!
+    close(repoRef: String, prefix: String!): Bug!
+    setTitle(repoRef: String, prefix: String!, title: String!): Bug!
 
-  commit(repoRef: String, prefix: String!): Bug!
+    commit(repoRef: String, prefix: String!): Bug!
+}`},
+	&ast.Source{Name: "timeline.graphql", Input: `"""An item in the timeline of events"""
+interface TimelineItem {
+    """The hash of the source operation"""
+    hash: Hash!
 }
-`},
+
+"""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 {
+    """The hash of the source operation"""
+    hash: Hash!
+    author: Person!
+    message: String!
+    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 {
+    """The hash of the source operation"""
+    hash: Hash!
+    author: Person!
+    message: String!
+    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 {
+    """The hash of the source operation"""
+    hash: Hash!
+    author: Person!
+    date: Time!
+    added: [Label!]!
+    removed: [Label!]!
+}
+
+"""SetStatusTimelineItem is a TimelineItem that represent a change in the status of a bug"""
+type SetStatusTimelineItem implements TimelineItem {
+    """The hash of the source operation"""
+    hash: Hash!
+    author: Person!
+    date: Time!
+    status: Status!
+}
+
+"""LabelChangeTimelineItem is a TimelineItem that represent a change in the title of a bug"""
+type SetTitleTimelineItem implements TimelineItem {
+    """The hash of the source operation"""
+    hash: Hash!
+    author: Person!
+    date: Time!
+    title: String!
+    was: String!
+}`},
 )

graphql/models/gen_models.go 🔗

@@ -41,6 +41,7 @@ type CommentEdge struct {
 	Node   bug.Comment `json:"node"`
 }
 
+// The connection type for an Operation
 type OperationConnection struct {
 	Edges      []OperationEdge `json:"edges"`
 	Nodes      []bug.Operation `json:"nodes"`
@@ -48,6 +49,7 @@ type OperationConnection struct {
 	TotalCount int             `json:"totalCount"`
 }
 
+// Represent an Operation
 type OperationEdge struct {
 	Cursor string        `json:"cursor"`
 	Node   bug.Operation `json:"node"`
@@ -61,6 +63,7 @@ type PageInfo struct {
 	EndCursor       string `json:"endCursor"`
 }
 
+// The connection type for TimelineItem
 type TimelineItemConnection struct {
 	Edges      []TimelineItemEdge `json:"edges"`
 	Nodes      []bug.TimelineItem `json:"nodes"`
@@ -68,6 +71,7 @@ type TimelineItemConnection struct {
 	TotalCount int                `json:"totalCount"`
 }
 
+// Represent a TimelineItem
 type TimelineItemEdge struct {
 	Cursor string           `json:"cursor"`
 	Node   bug.TimelineItem `json:"node"`

graphql/operations.graphql 🔗

@@ -0,0 +1,100 @@
+"""An operation applied to a bug."""
+interface Operation {
+    """The hash of the operation"""
+    hash: Hash!
+    """The operations author."""
+    author: Person!
+    """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 hash of the operation"""
+    hash: Hash!
+    """The author of this object."""
+    author: Person!
+    """The datetime when this operation was issued."""
+    date: Time!
+
+    title: String!
+    message: String!
+    files: [Hash!]!
+}
+
+type SetTitleOperation implements Operation & Authored {
+    """The hash of the operation"""
+    hash: Hash!
+    """The author of this object."""
+    author: Person!
+    """The datetime when this operation was issued."""
+    date: Time!
+
+    title: String!
+    was: String!
+}
+
+type AddCommentOperation implements Operation & Authored {
+    """The hash of the operation"""
+    hash: Hash!
+    """The author of this object."""
+    author: Person!
+    """The datetime when this operation was issued."""
+    date: Time!
+
+    message: String!
+    files: [Hash!]!
+}
+
+type EditCommentOperation implements Operation & Authored {
+    """The hash of the operation"""
+    hash: Hash!
+    """The author of this object."""
+    author: Person!
+    """The datetime when this operation was issued."""
+    date: Time!
+
+    target: Hash!
+    message: String!
+    files: [Hash!]!
+}
+
+type SetStatusOperation implements Operation & Authored {
+    """The hash of the operation"""
+    hash: Hash!
+    """The author of this object."""
+    author: Person!
+    """The datetime when this operation was issued."""
+    date: Time!
+
+    status: Status!
+}
+
+type LabelChangeOperation implements Operation & Authored {
+    """The hash of the operation"""
+    hash: Hash!
+    """The author of this object."""
+    author: Person!
+    """The datetime when this operation was issued."""
+    date: Time!
+
+    added: [Label!]!
+    removed: [Label!]!
+}

graphql/root.graphql 🔗

@@ -0,0 +1,38 @@
+scalar Time
+scalar Label
+scalar Hash
+
+"""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: Person!
+}
+
+type Query {
+    defaultRepository: Repository
+    repository(id: String!): Repository
+}
+
+type Mutation {
+    newBug(repoRef: String, title: String!, message: String!, files: [Hash!]): Bug!
+
+    addComment(repoRef: String, prefix: String!, message: String!, files: [Hash!]): Bug!
+    changeLabels(repoRef: String, prefix: String!, added: [String!], removed: [String!]): Bug!
+    open(repoRef: String, prefix: String!): Bug!
+    close(repoRef: String, prefix: String!): Bug!
+    setTitle(repoRef: String, prefix: String!, title: String!): Bug!
+
+    commit(repoRef: String, prefix: String!): Bug!
+}

graphql/schema.graphql 🔗

@@ -1,332 +0,0 @@
-scalar Time
-scalar Label
-scalar Hash
-
-"""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!
-}
-
-"""Represents an person in a git object."""
-type Person {
-  """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 string containing the either the name of the person, its login or both"""
-  displayName: String!
-
-  """An url to an avatar"""
-  avatarUrl: String
-}
-
-type CommentConnection {
-  edges: [CommentEdge!]!
-  nodes: [Comment!]!
-  pageInfo: PageInfo!
-  totalCount: Int!
-}
-
-type CommentEdge {
-  cursor: String!
-  node: Comment!
-}
-
-"""Represents a comment on a bug."""
-type Comment implements Authored {
-  """The author of this comment."""
-  author: Person!
-
-  """The message of this comment."""
-  message: String!
-
-  """All media's hash referenced in this comment"""
-  files: [Hash!]!
-}
-
-enum Status {
-  OPEN
-  CLOSED
-}
-
-"""An object that has an author."""
-interface Authored {
-  """The author of this object."""
-  author: Person!
-}
-
-type OperationConnection {
-  edges: [OperationEdge!]!
-  nodes: [Operation!]!
-  pageInfo: PageInfo!
-  totalCount: Int!
-}
-
-type OperationEdge {
-  cursor: String!
-  node: Operation!
-}
-
-"""An item in the timeline of events"""
-interface TimelineItem {
-  """The hash of the source operation"""
-  hash: Hash!
-}
-
-"""An operation applied to a bug."""
-interface Operation {
-  """The hash of the operation"""
-  hash: Hash!
-  """The operations author."""
-  author: Person!
-  """The datetime when this operation was issued."""
-  date: Time!
-}
-
-type CreateOperation implements Operation & Authored {
-  """The hash of the operation"""
-  hash: Hash!
-  """The author of this object."""
-  author: Person!
-  """The datetime when this operation was issued."""
-  date: Time!
-
-  title: String!
-  message: String!
-  files: [Hash!]!
-}
-
-type SetTitleOperation implements Operation & Authored {
-  """The hash of the operation"""
-  hash: Hash!
-  """The author of this object."""
-  author: Person!
-  """The datetime when this operation was issued."""
-  date: Time!
-
-  title: String!
-  was: String!
-}
-
-type AddCommentOperation implements Operation & Authored {
-  """The hash of the operation"""
-  hash: Hash!
-  """The author of this object."""
-  author: Person!
-  """The datetime when this operation was issued."""
-  date: Time!
-
-  message: String!
-  files: [Hash!]!
-}
-
-type EditCommentOperation implements Operation & Authored {
-  """The hash of the operation"""
-  hash: Hash!
-  """The author of this object."""
-  author: Person!
-  """The datetime when this operation was issued."""
-  date: Time!
-
-  target: Hash!
-  message: String!
-  files: [Hash!]!
-}
-
-type SetStatusOperation implements Operation & Authored {
-  """The hash of the operation"""
-  hash: Hash!
-  """The author of this object."""
-  author: Person!
-  """The datetime when this operation was issued."""
-  date: Time!
-
-  status: Status!
-}
-
-type LabelChangeOperation implements Operation & Authored {
-  """The hash of the operation"""
-  hash: Hash!
-  """The author of this object."""
-  author: Person!
-  """The datetime when this operation was issued."""
-  date: Time!
-
-  added: [Label!]!
-  removed: [Label!]!
-}
-
-type TimelineItemConnection {
-  edges: [TimelineItemEdge!]!
-  nodes: [TimelineItem!]!
-  pageInfo: PageInfo!
-  totalCount: Int!
-}
-
-type TimelineItemEdge {
-  cursor: String!
-  node: TimelineItem!
-}
-
-type CommentHistoryStep {
-  message: String!
-  date: Time!
-}
-
-type CreateTimelineItem implements TimelineItem {
-  """The hash of the source operation"""
-  hash: Hash!
-  author: Person!
-  message: String!
-  files: [Hash!]!
-  createdAt: Time!
-  lastEdit: Time!
-  edited: Boolean!
-  history: [CommentHistoryStep!]!
-}
-
-type AddCommentTimelineItem implements TimelineItem {
-  """The hash of the source operation"""
-  hash: Hash!
-  author: Person!
-  message: String!
-  files: [Hash!]!
-  createdAt: Time!
-  lastEdit: Time!
-  edited: Boolean!
-  history: [CommentHistoryStep!]!
-}
-
-type LabelChangeTimelineItem implements TimelineItem {
-  """The hash of the source operation"""
-  hash: Hash!
-  author: Person!
-  date: Time!
-  added: [Label!]!
-  removed: [Label!]!
-}
-
-type SetStatusTimelineItem implements TimelineItem {
-  """The hash of the source operation"""
-  hash: Hash!
-  author: Person!
-  date: Time!
-  status: Status!
-}
-
-type SetTitleTimelineItem implements TimelineItem {
-  """The hash of the source operation"""
-  hash: Hash!
-  author: Person!
-  date: Time!
-  title: String!
-  was: String!
-}
-
-"""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!
-}
-
-type Bug {
-  id: String!
-  humanId: String!
-  status: Status!
-  title: String!
-  labels: [Label!]!
-  author: Person!
-  createdAt: Time!
-  lastEdit: Time!
-
-  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!
-}
-
-type Repository {
-  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
-}
-
-type Query {
-  defaultRepository: Repository
-  repository(id: String!): Repository
-}
-
-type Mutation {
-  newBug(repoRef: String, title: String!, message: String!, files: [Hash!]): Bug!
-
-  addComment(repoRef: String, prefix: String!, message: String!, files: [Hash!]): Bug!
-  changeLabels(repoRef: String, prefix: String!, added: [String!], removed: [String!]): Bug!
-  open(repoRef: String, prefix: String!): Bug!
-  close(repoRef: String, prefix: String!): Bug!
-  setTitle(repoRef: String, prefix: String!, title: String!): Bug!
-
-  commit(repoRef: String, prefix: String!): Bug!
-}

graphql/timeline.graphql 🔗

@@ -0,0 +1,84 @@
+"""An item in the timeline of events"""
+interface TimelineItem {
+    """The hash of the source operation"""
+    hash: Hash!
+}
+
+"""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 {
+    """The hash of the source operation"""
+    hash: Hash!
+    author: Person!
+    message: String!
+    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 {
+    """The hash of the source operation"""
+    hash: Hash!
+    author: Person!
+    message: String!
+    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 {
+    """The hash of the source operation"""
+    hash: Hash!
+    author: Person!
+    date: Time!
+    added: [Label!]!
+    removed: [Label!]!
+}
+
+"""SetStatusTimelineItem is a TimelineItem that represent a change in the status of a bug"""
+type SetStatusTimelineItem implements TimelineItem {
+    """The hash of the source operation"""
+    hash: Hash!
+    author: Person!
+    date: Time!
+    status: Status!
+}
+
+"""LabelChangeTimelineItem is a TimelineItem that represent a change in the title of a bug"""
+type SetTitleTimelineItem implements TimelineItem {
+    """The hash of the source operation"""
+    hash: Hash!
+    author: Person!
+    date: Time!
+    title: String!
+    was: String!
+}