978 lines
25 KiB
GraphQL
978 lines
25 KiB
GraphQL
# This schema definition is available in the public domain, or under the terms
|
|
# of CC-0, at your choice.
|
|
scalar Cursor
|
|
scalar Time
|
|
scalar URL
|
|
scalar Upload
|
|
|
|
"Used to provide a human-friendly description of an access scope"
|
|
directive @scopehelp(details: String!) on ENUM_VALUE
|
|
|
|
"""
|
|
This is used to decorate fields which are only accessible with a personal
|
|
access token, and are not available to clients using OAuth 2.0 access tokens.
|
|
"""
|
|
directive @private on FIELD_DEFINITION
|
|
|
|
"""
|
|
This is used to decorate fields which are for internal use, and are not
|
|
available to normal API users.
|
|
"""
|
|
directive @internal on FIELD_DEFINITION
|
|
|
|
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
|
|
|
|
"Returns a specific tracker."
|
|
tracker(name: String!): Tracker @access(scope: TRACKERS, kind: RO)
|
|
|
|
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
|
|
}
|
|
|
|
enum Visibility {
|
|
PUBLIC
|
|
UNLISTED
|
|
PRIVATE
|
|
}
|
|
|
|
type Tracker {
|
|
id: Int!
|
|
created: Time!
|
|
updated: Time!
|
|
owner: Entity! @access(scope: PROFILE, kind: RO)
|
|
name: String!
|
|
description: String
|
|
visibility: Visibility!
|
|
|
|
ticket(id: Int!): Ticket! @access(scope: TICKETS, kind: RO)
|
|
tickets(cursor: Cursor): TicketCursor! @access(scope: TICKETS, kind: RO)
|
|
labels(cursor: Cursor): LabelCursor!
|
|
|
|
"""
|
|
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
|
|
|
|
# Only available to the tracker owner:
|
|
defaultACL: DefaultACL!
|
|
acls(cursor: Cursor): ACLCursor! @access(scope: ACLS, kind: RO)
|
|
|
|
"""
|
|
Returns a URL from which the tracker owner may download a gzipped JSON
|
|
archive of the tracker.
|
|
"""
|
|
export: URL!
|
|
|
|
"""
|
|
Returns a list of tracker webhook subscriptions. For clients
|
|
authenticated with a personal access token, this returns all webhooks
|
|
configured by all GraphQL clients for your account. For clients
|
|
authenticated with an OAuth 2.0 access token, this returns only webhooks
|
|
registered for your client.
|
|
"""
|
|
webhooks(cursor: Cursor): WebhookSubscriptionCursor!
|
|
|
|
"Returns details of a tracker webhook subscription by its ID."
|
|
webhook(id: Int!): WebhookSubscription
|
|
}
|
|
|
|
type OAuthClient {
|
|
uuid: String!
|
|
}
|
|
|
|
enum WebhookEvent {
|
|
TRACKER_CREATED @access(scope: TRACKERS, kind: RO)
|
|
TRACKER_UPDATE @access(scope: TRACKERS, kind: RO)
|
|
TRACKER_DELETED @access(scope: TRACKERS, kind: RO)
|
|
TICKET_CREATED @access(scope: TICKETS, kind: RO)
|
|
TICKET_UPDATE @access(scope: TICKETS, kind: RO)
|
|
LABEL_CREATED @access(scope: TRACKERS, kind: RO)
|
|
LABEL_UPDATE @access(scope: TRACKERS, kind: RO)
|
|
LABEL_DELETED @access(scope: TRACKERS, kind: RO)
|
|
EVENT_CREATED @access(scope: EVENTS, kind: RO)
|
|
}
|
|
|
|
interface WebhookSubscription {
|
|
id: Int!
|
|
events: [WebhookEvent!]!
|
|
query: String!
|
|
url: String!
|
|
|
|
"""
|
|
If this webhook was registered by an authorized OAuth 2.0 client, this
|
|
field is non-null.
|
|
"""
|
|
client: OAuthClient @private
|
|
|
|
"All deliveries which have been sent to this webhook."
|
|
deliveries(cursor: Cursor): WebhookDeliveryCursor!
|
|
|
|
"Returns a sample payload for this subscription, for testing purposes"
|
|
sample(event: WebhookEvent!): String!
|
|
}
|
|
|
|
type UserWebhookSubscription implements WebhookSubscription {
|
|
id: Int!
|
|
events: [WebhookEvent!]!
|
|
query: String!
|
|
url: String!
|
|
client: OAuthClient @private
|
|
deliveries(cursor: Cursor): WebhookDeliveryCursor!
|
|
sample(event: WebhookEvent): String!
|
|
}
|
|
|
|
type TrackerWebhookSubscription implements WebhookSubscription {
|
|
id: Int!
|
|
events: [WebhookEvent!]!
|
|
query: String!
|
|
url: String!
|
|
client: OAuthClient @private
|
|
deliveries(cursor: Cursor): WebhookDeliveryCursor!
|
|
sample(event: WebhookEvent!): String!
|
|
|
|
tracker: Tracker!
|
|
}
|
|
|
|
type TicketWebhookSubscription implements WebhookSubscription {
|
|
id: Int!
|
|
events: [WebhookEvent!]!
|
|
query: String!
|
|
url: String!
|
|
client: OAuthClient @private
|
|
deliveries(cursor: Cursor): WebhookDeliveryCursor!
|
|
sample(event: WebhookEvent!): String!
|
|
|
|
ticket: Ticket!
|
|
}
|
|
|
|
type WebhookDelivery {
|
|
uuid: String!
|
|
date: Time!
|
|
event: WebhookEvent!
|
|
subscription: WebhookSubscription!
|
|
requestBody: String!
|
|
|
|
"""
|
|
These details are provided only after a response is received from the
|
|
remote server. If a response is sent whose Content-Type is not text/*, or
|
|
cannot be decoded as UTF-8, the response body will be null. It will be
|
|
truncated after 64 KiB.
|
|
"""
|
|
responseBody: String
|
|
responseHeaders: String
|
|
responseStatus: Int
|
|
}
|
|
|
|
interface WebhookPayload {
|
|
uuid: String!
|
|
event: WebhookEvent!
|
|
date: Time!
|
|
}
|
|
|
|
type TrackerEvent implements WebhookPayload {
|
|
uuid: String!
|
|
event: WebhookEvent!
|
|
date: Time!
|
|
|
|
tracker: Tracker!
|
|
}
|
|
|
|
type TicketEvent implements WebhookPayload {
|
|
uuid: String!
|
|
event: WebhookEvent!
|
|
date: Time!
|
|
|
|
ticket: Ticket!
|
|
}
|
|
|
|
type EventCreated implements WebhookPayload {
|
|
uuid: String!
|
|
event: WebhookEvent!
|
|
date: Time!
|
|
|
|
newEvent: Event!
|
|
}
|
|
|
|
type LabelEvent implements WebhookPayload {
|
|
uuid: String!
|
|
event: WebhookEvent!
|
|
date: Time!
|
|
|
|
label: Label!
|
|
}
|
|
|
|
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 {
|
|
"""
|
|
The ticket ID is unique within each tracker, but is not globally unique.
|
|
The first ticket opened on a given tracker will have ID 1, then 2, and so
|
|
on.
|
|
"""
|
|
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)
|
|
|
|
"""
|
|
Returns a list of ticket webhook subscriptions. For clients
|
|
authenticated with a personal access token, this returns all webhooks
|
|
configured by all GraphQL clients for your account. For clients
|
|
authenticated with an OAuth 2.0 access token, this returns only webhooks
|
|
registered for your client.
|
|
"""
|
|
webhooks(cursor: Cursor): WebhookSubscriptionCursor!
|
|
|
|
"Returns details of a ticket webhook subscription by its ID."
|
|
webhook(id: Int!): WebhookSubscription
|
|
}
|
|
|
|
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! @access(scope: TICKETS, kind: RO)
|
|
}
|
|
|
|
type Created implements EventDetail {
|
|
eventType: EventType!
|
|
ticket: Ticket! @access(scope: TICKETS, kind: RO)
|
|
author: Entity! @access(scope: PROFILE, kind: RO)
|
|
}
|
|
|
|
type Assignment implements EventDetail {
|
|
eventType: EventType!
|
|
ticket: Ticket! @access(scope: TICKETS, kind: RO)
|
|
|
|
assigner: Entity! @access(scope: PROFILE, kind: RO)
|
|
assignee: Entity! @access(scope: PROFILE, kind: RO)
|
|
}
|
|
|
|
type Comment implements EventDetail {
|
|
eventType: EventType!
|
|
ticket: Ticket! @access(scope: TICKETS, kind: RO)
|
|
author: Entity! @access(scope: PROFILE, kind: RO)
|
|
|
|
text: String!
|
|
authenticity: Authenticity!
|
|
|
|
"If this comment has been edited, this field points to the new revision."
|
|
supersededBy: Comment
|
|
}
|
|
|
|
type LabelUpdate implements EventDetail {
|
|
eventType: EventType!
|
|
ticket: Ticket! @access(scope: TICKETS, kind: RO)
|
|
labeler: Entity! @access(scope: PROFILE, kind: RO)
|
|
label: Label!
|
|
}
|
|
|
|
type StatusChange implements EventDetail {
|
|
eventType: EventType!
|
|
ticket: Ticket! @access(scope: TICKETS, kind: RO)
|
|
editor: Entity! @access(scope: PROFILE, kind: RO)
|
|
|
|
oldStatus: TicketStatus!
|
|
newStatus: TicketStatus!
|
|
oldResolution: TicketResolution!
|
|
newResolution: TicketResolution!
|
|
}
|
|
|
|
type UserMention implements EventDetail {
|
|
eventType: EventType!
|
|
ticket: Ticket! @access(scope: TICKETS, kind: RO)
|
|
author: Entity! @access(scope: PROFILE, kind: RO)
|
|
mentioned: Entity! @access(scope: PROFILE, kind: RO)
|
|
}
|
|
|
|
type TicketMention implements EventDetail {
|
|
eventType: EventType!
|
|
ticket: Ticket! @access(scope: TICKETS, kind: RO)
|
|
author: Entity! @access(scope: PROFILE, kind: RO)
|
|
mentioned: Ticket! @access(scope: TICKETS, kind: RO)
|
|
}
|
|
|
|
interface ActivitySubscription {
|
|
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 ActivitySubscription {
|
|
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 ActivitySubscription {
|
|
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 ActivitySubscriptionCursor {
|
|
results: [ActivitySubscription!]!
|
|
cursor: Cursor
|
|
}
|
|
|
|
"""
|
|
A cursor for enumerating a list of webhook deliveries
|
|
|
|
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 WebhookDeliveryCursor {
|
|
results: [WebhookDelivery!]!
|
|
cursor: Cursor
|
|
}
|
|
|
|
"""
|
|
A cursor for enumerating a list of webhook 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 WebhookSubscriptionCursor {
|
|
results: [WebhookSubscription!]!
|
|
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)
|
|
|
|
"""
|
|
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): ActivitySubscriptionCursor @access(scope: SUBSCRIPTIONS, kind: RO)
|
|
|
|
"""
|
|
Returns a list of user webhook subscriptions. For clients
|
|
authenticated with a personal access token, this returns all webhooks
|
|
configured by all GraphQL clients for your account. For clients
|
|
authenticated with an OAuth 2.0 access token, this returns only webhooks
|
|
registered for your client.
|
|
"""
|
|
userWebhooks(cursor: Cursor): WebhookSubscriptionCursor!
|
|
|
|
"Returns details of a user webhook subscription by its ID."
|
|
userWebhook(id: Int!): WebhookSubscription
|
|
|
|
"""
|
|
Returns information about the webhook currently being processed. This is
|
|
not valid during normal queries over HTTP, and will return an error if used
|
|
outside of a webhook context.
|
|
"""
|
|
webhook: WebhookPayload!
|
|
}
|
|
|
|
"You may omit any fields to leave them unchanged."
|
|
# TODO: Allow users to change the name of a tracker
|
|
input TrackerInput {
|
|
description: String
|
|
visibility: Visibility
|
|
}
|
|
|
|
"You may omit any fields to leave them unchanged."
|
|
input UpdateLabelInput {
|
|
name: String
|
|
foregroundColor: String
|
|
backgroundColor: String
|
|
}
|
|
|
|
input ACLInput {
|
|
"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!
|
|
}
|
|
|
|
"""
|
|
This is used for importing tickets from third-party services, and may only be
|
|
used by the tracker owner. It causes a ticket submission, update, or comment
|
|
to be attributed to an external user and appear as if it were submitted at a
|
|
specific time.
|
|
"""
|
|
input ImportInput {
|
|
created: Time!
|
|
"""
|
|
External user ID. By convention this should be "service:username", e.g.
|
|
"codeberg:ddevault".
|
|
"""
|
|
externalId: String!
|
|
"""
|
|
A URL at which the user's external profile may be found, e.g.
|
|
"https://codeberg.org/ddevault".
|
|
"""
|
|
externalUrl: String!
|
|
}
|
|
|
|
input SubmitTicketInput {
|
|
subject: String!
|
|
body: String
|
|
|
|
# These fields are meant for use when importing tickets from third-party
|
|
# services, and may only be used by the tracker owner.
|
|
# TODO: Use ImportInput here
|
|
created: Time
|
|
externalId: String
|
|
externalUrl: String
|
|
}
|
|
|
|
# For internal use only.
|
|
input SubmitTicketEmailInput {
|
|
subject: String!
|
|
body: String
|
|
senderId: Int!
|
|
messageId: String!
|
|
}
|
|
|
|
# For internal use only.
|
|
enum EmailCmd {
|
|
RESOLVE
|
|
REOPEN
|
|
LABEL
|
|
UNLABEL
|
|
}
|
|
|
|
# For internal use only.
|
|
input SubmitCommentEmailInput {
|
|
text: String!
|
|
senderId: Int!
|
|
cmd: EmailCmd
|
|
resolution: TicketResolution
|
|
labelIds: [Int!]
|
|
}
|
|
|
|
"""
|
|
You may omit any fields to leave them unchanged. To remove the ticket body,
|
|
set it to null.
|
|
"""
|
|
input UpdateTicketInput {
|
|
subject: String
|
|
body: String
|
|
|
|
"For use by the tracker owner only"
|
|
import: ImportInput
|
|
}
|
|
|
|
"""
|
|
You may omit the status or resolution fields to leave them unchanged (or if
|
|
you do not have permission to change them). "resolution" is required if
|
|
status is RESOLVED.
|
|
"""
|
|
input SubmitCommentInput {
|
|
text: String!
|
|
status: TicketStatus
|
|
resolution: TicketResolution
|
|
|
|
"For use by the tracker owner only"
|
|
import: ImportInput
|
|
}
|
|
|
|
"""
|
|
"resolution" is required if status is RESOLVED.
|
|
"""
|
|
input UpdateStatusInput {
|
|
status: TicketStatus!
|
|
resolution: TicketResolution
|
|
|
|
"For use by the tracker owner only"
|
|
import: ImportInput
|
|
}
|
|
|
|
input UserWebhookInput {
|
|
url: String!
|
|
events: [WebhookEvent!]!
|
|
query: String!
|
|
}
|
|
|
|
input TrackerWebhookInput {
|
|
url: String!
|
|
events: [WebhookEvent!]!
|
|
query: String!
|
|
}
|
|
|
|
input TicketWebhookInput {
|
|
url: String!
|
|
events: [WebhookEvent!]!
|
|
query: String!
|
|
}
|
|
|
|
type Mutation {
|
|
"""
|
|
Creates a new bug tracker. If specified, the 'import' field specifies a
|
|
gzipped dump of a tracker to populate tickets from; see Tracker.export.
|
|
"""
|
|
createTracker(
|
|
name: String!,
|
|
description: String,
|
|
visibility: Visibility!,
|
|
import: Upload): Tracker! @access(scope: TRACKERS, kind: RW)
|
|
|
|
"Updates an existing bug tracker"
|
|
updateTracker(
|
|
id: Int!,
|
|
input: TrackerInput!): Tracker! @access(scope: TRACKERS, kind: RW)
|
|
|
|
"Deletes a bug tracker"
|
|
deleteTracker(id: Int!): Tracker! @access(scope: TRACKERS, kind: RW)
|
|
|
|
"Adds or updates the ACL for a specific user on a bug tracker"
|
|
updateUserACL(
|
|
trackerId: Int!,
|
|
userId: Int!,
|
|
input: ACLInput!): TrackerACL! @access(scope: ACLS, kind: RW)
|
|
|
|
# "Adds or updates the ACL for an email address on a bug tracker"
|
|
# TODO: This requires internal changes
|
|
#updateSenderACL(
|
|
# trackerId: Int!,
|
|
# address: String!,
|
|
# input: ACLInput!): TrackerACL! @access(scope: ACLS, kind: RW)
|
|
|
|
"""
|
|
Updates the default ACL for a bug tracker, which applies to users and
|
|
senders for whom a more specific ACL does not exist.
|
|
"""
|
|
updateTrackerACL(
|
|
trackerId: Int!,
|
|
input: ACLInput!): DefaultACL! @access(scope: ACLS, kind: RW)
|
|
|
|
"""
|
|
Removes a tracker ACL. Following this change, the default tracker ACL will
|
|
apply to this user.
|
|
"""
|
|
deleteACL(id: Int!): TrackerACL! @access(scope: ACLS, kind: RW)
|
|
|
|
"Subscribes to all email notifications for a tracker"
|
|
trackerSubscribe(
|
|
trackerId: Int!): TrackerSubscription! @access(scope: SUBSCRIPTIONS, kind: RW)
|
|
|
|
"""
|
|
Unsubscribes from email notifications for a tracker. If "tickets" is true,
|
|
also unsubscribe from all tickets on this tracker.
|
|
"""
|
|
trackerUnsubscribe(
|
|
trackerId: Int!,
|
|
tickets: Boolean!): TrackerSubscription! @access(scope: SUBSCRIPTIONS, kind: RW)
|
|
|
|
"Subscribes to all email notifications for a ticket"
|
|
ticketSubscribe(
|
|
trackerId: Int!,
|
|
ticketId: Int!): TicketSubscription! @access(scope: SUBSCRIPTIONS, kind: RW)
|
|
|
|
"Unsubscribes from email notifications for a ticket"
|
|
ticketUnsubscribe(
|
|
trackerId: Int!,
|
|
ticketId: Int!): TicketSubscription! @access(scope: SUBSCRIPTIONS, kind: RW)
|
|
|
|
"""
|
|
Creates a new ticket label for a tracker. The colors must be in CSS
|
|
hexadecimal RGB format "#RRGGBB", i.e. "#000000" for black and "#FF0000" for
|
|
red.
|
|
"""
|
|
createLabel(trackerId: Int!, name: String!,
|
|
foregroundColor: String!, backgroundColor: String!): Label! @access(scope: TRACKERS, kind: RW)
|
|
|
|
"Changes the name or colors for a label."
|
|
updateLabel(id: Int!, input: UpdateLabelInput!): Label! @access(scope: TRACKERS, kind: RW)
|
|
|
|
"""
|
|
Deletes a label, removing it from any tickets which currently have it
|
|
applied.
|
|
"""
|
|
deleteLabel(id: Int!): Label! @access(scope: TRACKERS, kind: RW)
|
|
|
|
"Creates a new ticket."
|
|
submitTicket(trackerId: Int!,
|
|
input: SubmitTicketInput!): Ticket! @access(scope: TICKETS, kind: RW)
|
|
|
|
# Creates a new ticket from an incoming email. (For internal use only)
|
|
submitTicketEmail(trackerId: Int!,
|
|
input: SubmitTicketEmailInput!): Ticket! @internal
|
|
|
|
# Creates a new comment from an incoming email. (For internal use only)
|
|
submitCommentEmail(trackerId: Int!, ticketId: Int!,
|
|
input: SubmitCommentEmailInput!): Event! @internal
|
|
|
|
"Updates a ticket's subject or body"
|
|
updateTicket(trackerId: Int!, ticketId: Int!,
|
|
input: UpdateTicketInput!): Ticket! @access(scope: TICKETS, kind: RW)
|
|
|
|
"Updates the status or resolution of a ticket"
|
|
updateTicketStatus(trackerId: Int!, ticketId: Int!,
|
|
input: UpdateStatusInput!): Event! @access(scope: TICKETS, kind: RW)
|
|
|
|
"Submits a comment for a ticket"
|
|
submitComment(trackerId: Int!, ticketId: Int!,
|
|
input: SubmitCommentInput!): Event! @access(scope: TICKETS, kind: RW)
|
|
|
|
"Adds a user to the list of assigned users for a ticket"
|
|
assignUser(trackerId: Int!, ticketId: Int!,
|
|
userId: Int!): Event! @access(scope: TICKETS, kind: RW)
|
|
|
|
"Removes a user from the list of assigned users for a ticket"
|
|
unassignUser(trackerId: Int!, ticketId: Int!,
|
|
userId: Int!): Event! @access(scope: TICKETS, kind: RW)
|
|
|
|
"Adds a label to the list of labels for a ticket"
|
|
labelTicket(trackerId: Int!, ticketId: Int!,
|
|
labelId: Int!): Event! @access(scope: TICKETS, kind: RW)
|
|
|
|
"Removes a list from the list of labels for a ticket"
|
|
unlabelTicket(trackerId: Int!, ticketId: Int!,
|
|
labelId: Int!): Event! @access(scope: TICKETS, kind: RW)
|
|
|
|
"""
|
|
Creates a new user webhook subscription. When an event from the
|
|
provided list of events occurs, the 'query' parameter (a GraphQL query)
|
|
will be evaluated and the results will be sent to the provided URL as the
|
|
body of an HTTP POST request. The list of events must include at least one
|
|
event, and no duplicates.
|
|
|
|
This query is evaluated in the webhook context, such that query { webhook }
|
|
may be used to access details of the event which trigged the webhook. The
|
|
query may not make any mutations.
|
|
"""
|
|
createUserWebhook(config: UserWebhookInput!): WebhookSubscription!
|
|
|
|
"""
|
|
Deletes a user webhook. Any events already queued may still be
|
|
delivered after this request completes. Clients authenticated with a
|
|
personal access token may delete any webhook registered for their account,
|
|
but authorized OAuth 2.0 clients may only delete their own webhooks.
|
|
Manually deleting a webhook configured by a third-party client may cause
|
|
unexpected behavior with the third-party integration.
|
|
"""
|
|
deleteUserWebhook(id: Int!): WebhookSubscription!
|
|
|
|
"Creates a new tracker webhook."
|
|
createTrackerWebhook(trackerId: Int!, config: TrackerWebhookInput!): WebhookSubscription!
|
|
|
|
"Deletes a tracker webhook."
|
|
deleteTrackerWebhook(id: Int!): WebhookSubscription!
|
|
|
|
"Creates a new ticket webhook."
|
|
createTicketWebhook(trackerId: Int!, ticketId: Int!, config: TicketWebhookInput!): WebhookSubscription!
|
|
|
|
"Deletes a ticket webhook."
|
|
deleteTicketWebhook(id: Int!): WebhookSubscription!
|
|
}
|