409 lines
10 KiB
GraphQL
409 lines
10 KiB
GraphQL
scalar Cursor
|
|
scalar Time
|
|
|
|
# Used to provide a human-friendly description of an access scope
|
|
directive @scopehelp(details: String!) on ENUM_VALUE
|
|
|
|
enum AccessScope {
|
|
PROFILE @scopehelp(details: "profile information")
|
|
TRACKERS @scopehelp(details: "trackers")
|
|
TICKETS @scopehelp(details: "tickets")
|
|
ACLS @scopehelp(details: "access control lists")
|
|
EVENTS @scopehelp(details: "events")
|
|
SUBSCRIPTIONS @scopehelp(details: "tracker & ticket subscriptions")
|
|
}
|
|
|
|
enum AccessKind {
|
|
RO @scopehelp(details: "read")
|
|
RW @scopehelp(details: "read and write")
|
|
}
|
|
|
|
# Decorates fields for which access requires a particular OAuth 2.0 scope with
|
|
# read or write access.
|
|
directive @access(scope: AccessScope!, kind: AccessKind!) on FIELD_DEFINITION
|
|
|
|
# https://semver.org
|
|
type Version {
|
|
major: Int!
|
|
minor: Int!
|
|
patch: Int!
|
|
|
|
# If this API version is scheduled for deprecation, this is the date on which
|
|
# it will stop working; or null if this API version is not scheduled for
|
|
# deprecation.
|
|
deprecationDate: Time
|
|
}
|
|
|
|
interface Entity {
|
|
canonicalName: String!
|
|
}
|
|
|
|
type User implements Entity {
|
|
id: Int!
|
|
created: Time!
|
|
updated: Time!
|
|
canonicalName: String!
|
|
username: String!
|
|
email: String!
|
|
url: String
|
|
location: String
|
|
bio: String
|
|
|
|
trackers(cursor: Cursor): TrackerCursor! @access(scope: TRACKERS, kind: RO)
|
|
}
|
|
|
|
type EmailAddress implements Entity {
|
|
canonicalName: String!
|
|
|
|
# "jdoe@example.org" of "Jane Doe <jdoe@example.org>"
|
|
mailbox: String!
|
|
# "Jane Doe" of "Jane Doe <jdoe@example.org>"
|
|
name: String
|
|
}
|
|
|
|
type ExternalUser implements Entity {
|
|
canonicalName: String!
|
|
|
|
# <service>:<service specific details...>
|
|
# e.g. github:ddevault
|
|
externalId: String!
|
|
# The canonical external URL for this user, e.g. https://github.com/ddevault
|
|
externalUrl: String
|
|
}
|
|
|
|
type Tracker {
|
|
id: Int!
|
|
created: Time!
|
|
updated: Time!
|
|
owner: Entity!
|
|
name: String!
|
|
description: String
|
|
|
|
tickets(cursor: Cursor): TicketCursor! @access(scope: TICKETS, kind: RO)
|
|
labels(cursor: Cursor): LabelCursor!
|
|
|
|
# Only available to the tracker owner:
|
|
acls(cursor: Cursor): ACLCursor! @access(scope: ACLS, kind: RO)
|
|
|
|
# If the authenticated user is subscribed to this tracker, this is that
|
|
# subscription.
|
|
subscription: TrackerSubscription @access(scope: SUBSCRIPTIONS, kind: RO)
|
|
|
|
# The access control list entry (or the default ACL) which describes the
|
|
# authenticated user's permissions with respect to this tracker.
|
|
acl: ACL
|
|
}
|
|
|
|
enum TicketStatus {
|
|
REPORTED
|
|
CONFIRMED
|
|
IN_PROGRESS
|
|
PENDING
|
|
RESOLVED
|
|
}
|
|
|
|
enum TicketResolution {
|
|
UNRESOLVED
|
|
FIXED
|
|
IMPLEMENTED
|
|
WONT_FIX
|
|
BY_DESIGN
|
|
INVALID
|
|
DUPLICATE
|
|
NOT_OUR_BUG
|
|
}
|
|
|
|
enum Authenticity {
|
|
# The server vouches for this information as entered verbatim by the
|
|
# attributed entity.
|
|
AUTHENTIC
|
|
# The server does not vouch for this information as entered by the attributed
|
|
# entity, no authentication was provided.
|
|
UNAUTHENTICATED
|
|
# The server has evidence that the information has likely been manipulated by
|
|
# a third-party.
|
|
TAMPERED
|
|
}
|
|
|
|
type Ticket {
|
|
id: Int!
|
|
created: Time!
|
|
updated: Time!
|
|
submitter: Entity! @access(scope: PROFILE, kind: RO)
|
|
tracker: Tracker! @access(scope: TRACKERS, kind: RO)
|
|
|
|
# Canonical ticket reference string; may be used in comments to identify the
|
|
# ticket from anywhere.
|
|
ref: String!
|
|
|
|
subject: String!
|
|
body: String
|
|
status: TicketStatus!
|
|
resolution: TicketResolution!
|
|
authenticity: Authenticity!
|
|
|
|
labels: [Label]!
|
|
assignees: [Entity]! @access(scope: PROFILE, kind: RO)
|
|
events(cursor: Cursor): EventCursor! @access(scope: EVENTS, kind: RO)
|
|
|
|
# If the authenticated user is subscribed to this ticket, this is that
|
|
# subscription.
|
|
subscription: TicketSubscription @access(scope: SUBSCRIPTIONS, kind: RO)
|
|
|
|
# The access control list entry (or the default ACL) which describes the
|
|
# authenticated user's permissions with respect to this ticket.
|
|
acl: ACL
|
|
}
|
|
|
|
interface ACL {
|
|
# Permission to view tickets
|
|
browse: Boolean!
|
|
# Permission to submit tickets
|
|
submit: Boolean!
|
|
# Permission to comment on tickets
|
|
comment: Boolean!
|
|
# Permission to edit tickets
|
|
edit: Boolean!
|
|
# Permission to resolve, re-open, transfer, or label tickets
|
|
triage: Boolean!
|
|
}
|
|
|
|
# These ACLs are configured for specific entities, and may be used to expand or
|
|
# constrain the rights of a participant.
|
|
type TrackerACL implements ACL {
|
|
id: Int!
|
|
created: Time!
|
|
tracker: Tracker! @access(scope: TRACKERS, kind: RO)
|
|
entity: Entity! @access(scope: PROFILE, kind: RO)
|
|
|
|
browse: Boolean!
|
|
submit: Boolean!
|
|
comment: Boolean!
|
|
edit: Boolean!
|
|
triage: Boolean!
|
|
}
|
|
|
|
# These ACL policies are applied non-specifically, e.g. the default ACL for all
|
|
# authenticated users.
|
|
type DefaultACL implements ACL {
|
|
browse: Boolean!
|
|
submit: Boolean!
|
|
comment: Boolean!
|
|
edit: Boolean!
|
|
triage: Boolean!
|
|
}
|
|
|
|
type Label {
|
|
id: Int!
|
|
created: Time!
|
|
name: String!
|
|
tracker: Tracker! @access(scope: TRACKERS, kind: RO)
|
|
|
|
# In CSS hexadecimal format
|
|
backgroundColor: String!
|
|
foregroundColor: String!
|
|
|
|
tickets(cursor: Cursor): TicketCursor! @access(scope: TICKETS, kind: RO)
|
|
}
|
|
|
|
enum EventType {
|
|
CREATED
|
|
COMMENT
|
|
STATUS_CHANGE
|
|
LABEL_ADDED
|
|
LABEL_REMOVED
|
|
ASSIGNED_USER
|
|
UNASSIGNED_USER
|
|
USER_MENTIONED
|
|
TICKET_MENTIONED
|
|
}
|
|
|
|
# Represents an event which affects a ticket. Multiple changes can occur in a
|
|
# single event, and are enumerated in the "changes" field.
|
|
type Event {
|
|
id: Int!
|
|
created: Time!
|
|
changes: [EventDetail]!
|
|
|
|
ticket: Ticket! @access(scope: TICKETS, kind: RO)
|
|
}
|
|
|
|
interface EventDetail {
|
|
eventType: EventType!
|
|
ticket: Ticket!
|
|
}
|
|
|
|
type Created implements EventDetail {
|
|
eventType: EventType!
|
|
ticket: Ticket!
|
|
author: Entity!
|
|
}
|
|
|
|
type Assignment implements EventDetail {
|
|
eventType: EventType!
|
|
ticket: Ticket!
|
|
|
|
assigner: Entity!
|
|
assignee: Entity!
|
|
}
|
|
|
|
type Comment implements EventDetail {
|
|
eventType: EventType!
|
|
ticket: Ticket!
|
|
author: Entity!
|
|
|
|
text: String!
|
|
authenticity: Authenticity!
|
|
|
|
# If this comment has been edited, this field points to the new revision.
|
|
superceededBy: Comment
|
|
}
|
|
|
|
type LabelUpdate implements EventDetail {
|
|
eventType: EventType!
|
|
ticket: Ticket!
|
|
labeler: Entity!
|
|
label: Label!
|
|
}
|
|
|
|
type StatusChange implements EventDetail {
|
|
eventType: EventType!
|
|
ticket: Ticket!
|
|
editor: Entity!
|
|
|
|
oldStatus: TicketStatus!
|
|
newStatus: TicketStatus!
|
|
oldResolution: TicketResolution!
|
|
newResolution: TicketResolution!
|
|
}
|
|
|
|
type UserMention implements EventDetail {
|
|
eventType: EventType!
|
|
ticket: Ticket!
|
|
author: Entity!
|
|
mentioned: Entity!
|
|
}
|
|
|
|
type TicketMention implements EventDetail {
|
|
eventType: EventType!
|
|
ticket: Ticket!
|
|
author: Entity!
|
|
mentioned: Ticket!
|
|
}
|
|
|
|
interface Subscription {
|
|
id: Int!
|
|
created: Time!
|
|
}
|
|
|
|
# A tracker subscription will notify a participant of all activity for a
|
|
# tracker, including all new tickets and their events.
|
|
type TrackerSubscription implements Subscription {
|
|
id: Int!
|
|
created: Time!
|
|
tracker: Tracker! @access(scope: TRACKERS, kind: RO)
|
|
}
|
|
|
|
# A ticket subscription will notify a participant when activity occurs on a
|
|
# ticket.
|
|
type TicketSubscription implements Subscription {
|
|
id: Int!
|
|
created: Time!
|
|
ticket: Ticket! @access(scope: TICKETS, kind: RO)
|
|
}
|
|
|
|
# A cursor for enumerating trackers
|
|
#
|
|
# If there are additional results available, the cursor object may be passed
|
|
# back into the same endpoint to retrieve another page. If the cursor is null,
|
|
# there are no remaining results to return.
|
|
type TrackerCursor {
|
|
results: [Tracker]!
|
|
cursor: Cursor
|
|
}
|
|
|
|
# A cursor for enumerating tickets
|
|
#
|
|
# If there are additional results available, the cursor object may be passed
|
|
# back into the same endpoint to retrieve another page. If the cursor is null,
|
|
# there are no remaining results to return.
|
|
type TicketCursor {
|
|
results: [Ticket]!
|
|
cursor: Cursor
|
|
}
|
|
|
|
# A cursor for enumerating labels
|
|
#
|
|
# If there are additional results available, the cursor object may be passed
|
|
# back into the same endpoint to retrieve another page. If the cursor is null,
|
|
# there are no remaining results to return.
|
|
type LabelCursor {
|
|
results: [Label]!
|
|
cursor: Cursor
|
|
}
|
|
|
|
# A cursor for enumerating access control list entries
|
|
#
|
|
# If there are additional results available, the cursor object may be passed
|
|
# back into the same endpoint to retrieve another page. If the cursor is null,
|
|
# there are no remaining results to return.
|
|
type ACLCursor {
|
|
results: [TrackerACL]!
|
|
cursor: Cursor
|
|
}
|
|
|
|
# A cursor for enumerating events
|
|
#
|
|
# If there are additional results available, the cursor object may be passed
|
|
# back into the same endpoint to retrieve another page. If the cursor is null,
|
|
# there are no remaining results to return.
|
|
type EventCursor {
|
|
results: [Event]!
|
|
cursor: Cursor
|
|
}
|
|
|
|
# A cursor for enumerating subscriptions
|
|
#
|
|
# If there are additional results available, the cursor object may be passed
|
|
# back into the same endpoint to retrieve another page. If the cursor is null,
|
|
# there are no remaining results to return.
|
|
type SubscriptionCursor {
|
|
results: [Subscription]!
|
|
cursor: Cursor
|
|
}
|
|
|
|
type Query {
|
|
# Returns API version information.
|
|
version: Version!
|
|
|
|
# Returns the authenticated user.
|
|
me: User! @access(scope: PROFILE, kind: RO)
|
|
|
|
# Returns a specific user.
|
|
user(username: String!): User @access(scope: PROFILE, kind: RO)
|
|
|
|
# Returns trackers that the authenticated user has access to.
|
|
#
|
|
# NOTE: in this version of the API, only trackers owned by the authenticated
|
|
# user are returned, but in the future the default behavior will be to return
|
|
# all trackers that the user either (1) has been given explicit access to via
|
|
# ACLs or (2) has implicit access to either by ownership or group membership.
|
|
trackers(cursor: Cursor): TrackerCursor @access(scope: TRACKERS, kind: RO)
|
|
|
|
tracker(id: Int!): Tracker @access(scope: TRACKERS, kind: RO)
|
|
|
|
# Returns a specific tracker, owned by the authenticated user.
|
|
trackerByName(name: String!): Tracker @access(scope: TRACKERS, kind: RO)
|
|
|
|
# Returns a specific tracker, owned by the given canonical name (e.g.
|
|
# "~sircmpwn").
|
|
trackerByOwner(owner: String!, tracker: String!): Tracker @access(scope: TRACKERS, kind: RO)
|
|
|
|
# List of events which the authenticated user is subscribed to or implicated
|
|
# in, ordered by the event date (recent events first).
|
|
events(cursor: Cursor): EventCursor @access(scope: EVENTS, kind: RO)
|
|
|
|
# List of subscriptions of the authenticated user.
|
|
subscriptions(cursor: Cursor): SubscriptionCursor @access(scope: SUBSCRIPTIONS, kind: RO)
|
|
}
|