On the project dashboard, a day with activity can be picked on the map: a side panel lists that day's moves grouped by ticket (each key opens it), with the time of each, and the project's own (sprints, releases, members) apart. The activity feed takes an `after` date (GraphQL, REST), so with `before` it reads a window such as a day; the MCP's get_project_activity takes a `day`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2115 lines
43 KiB
GraphQL
2115 lines
43 KiB
GraphQL
# ------------------------------------------------------
|
||
# THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY)
|
||
# ------------------------------------------------------
|
||
|
||
type Activity {
|
||
actor: UserRef!
|
||
id: ID!
|
||
issueId: ID
|
||
issueKey: String
|
||
occurredAt: String!
|
||
projectId: ID!
|
||
summary: String!
|
||
type: String!
|
||
}
|
||
|
||
"""How much happened on one day"""
|
||
type ActivityDay {
|
||
count: Int!
|
||
|
||
"""YYYY-MM-DD"""
|
||
day: String!
|
||
}
|
||
|
||
input AddChecklistItemInput {
|
||
issueId: ID!
|
||
text: String!
|
||
}
|
||
|
||
"""Something on a day of my week"""
|
||
type AgendaItem {
|
||
"""YYYY-MM-DD"""
|
||
day: String!
|
||
issueKey: String
|
||
|
||
"""ISSUE, SPRINT_END or RELEASE"""
|
||
kind: String!
|
||
projectKey: String!
|
||
title: String!
|
||
}
|
||
|
||
type Aging {
|
||
issues: [InsightIssue!]!
|
||
|
||
"""p85 cycle time of the last 90 days"""
|
||
thresholdDays: Float
|
||
}
|
||
|
||
type AreaOption {
|
||
archived: Boolean!
|
||
id: String!
|
||
name: String!
|
||
}
|
||
|
||
input AreaOptionInput {
|
||
archived: Boolean! = false
|
||
id: String!
|
||
name: String!
|
||
}
|
||
|
||
"""
|
||
A file on a ticket. Download it from the REST API: GET /api/issues/{issueId}/attachments/{id}
|
||
"""
|
||
type Attachment {
|
||
"""The comment it was attached to, if any"""
|
||
commentId: ID
|
||
fileName: String!
|
||
id: ID!
|
||
mimeType: String!
|
||
|
||
"""Bytes"""
|
||
size: Int!
|
||
uploadedAt: String!
|
||
uploadedBy: UserRef!
|
||
}
|
||
|
||
"""When this happens to a ticket, if it is like this, do that"""
|
||
type Automation {
|
||
action: AutomationActionSpec!
|
||
active: Boolean!
|
||
conditions: AutomationConditions!
|
||
createdAt: String!
|
||
createdBy: UserRef!
|
||
id: ID!
|
||
|
||
"""Why the last run did nothing"""
|
||
lastError: String
|
||
lastRunAt: String
|
||
name: String!
|
||
projectId: ID!
|
||
runs: Int!
|
||
trigger: AutomationTriggerSpec!
|
||
}
|
||
|
||
"""What a rule does to the ticket"""
|
||
enum AutomationAction {
|
||
ADD_COMMENT
|
||
ADD_LABEL
|
||
ADD_TO_ACTIVE_SPRINT
|
||
ASSIGN
|
||
ASSIGN_REPORTER
|
||
SET_PRIORITY
|
||
SET_STATUS
|
||
}
|
||
|
||
input AutomationActionInput {
|
||
kind: AutomationAction!
|
||
value: String
|
||
}
|
||
|
||
type AutomationActionSpec {
|
||
kind: AutomationAction!
|
||
|
||
"""Status, member id, label, priority or comment text"""
|
||
value: String
|
||
}
|
||
|
||
type AutomationConditions {
|
||
areas: [String!]
|
||
label: String
|
||
priorities: [IssuePriority!]
|
||
types: [String!]
|
||
}
|
||
|
||
input AutomationConditionsInput {
|
||
areas: [String!]
|
||
label: String
|
||
priorities: [IssuePriority!]
|
||
types: [String!]
|
||
}
|
||
|
||
"""What starts a rule"""
|
||
enum AutomationTrigger {
|
||
COMMENT_ADDED
|
||
ISSUE_ASSIGNED
|
||
ISSUE_CREATED
|
||
PULL_REQUEST_MERGED
|
||
STATUS_CHANGED
|
||
}
|
||
|
||
input AutomationTriggerInput {
|
||
kind: AutomationTrigger!
|
||
status: String
|
||
}
|
||
|
||
type AutomationTriggerSpec {
|
||
kind: AutomationTrigger!
|
||
|
||
"""STATUS_CHANGED: only into this status"""
|
||
status: String
|
||
}
|
||
|
||
type BacklogHealth {
|
||
noArea: Int!
|
||
open: Int!
|
||
stale: Int!
|
||
staleDays: Int!
|
||
unassigned: Int!
|
||
unestimated: Int!
|
||
}
|
||
|
||
type BoardColumn {
|
||
issues: [Issue!]!
|
||
status: String!
|
||
total: Int!
|
||
}
|
||
|
||
"""Bugs created and closed in a week"""
|
||
type BugWeek {
|
||
closed: Int!
|
||
created: Int!
|
||
|
||
"""Monday (UTC), YYYY-MM-DD"""
|
||
week: String!
|
||
}
|
||
|
||
type BulkIssueResult {
|
||
error: String
|
||
issueId: ID!
|
||
ok: Boolean!
|
||
}
|
||
|
||
type BulkResult {
|
||
results: [BulkIssueResult!]!
|
||
updated: Int!
|
||
}
|
||
|
||
input BulkUpdateIssuesInput {
|
||
addLabels: [String!]
|
||
assigneeId: ID
|
||
issueIds: [ID!]!
|
||
|
||
"""Out of their release"""
|
||
noRelease: Boolean
|
||
|
||
"""Back to the backlog"""
|
||
noSprint: Boolean
|
||
priority: IssuePriority
|
||
releaseId: ID
|
||
sprintId: ID
|
||
status: String
|
||
|
||
"""Unassign everything"""
|
||
unassign: Boolean
|
||
}
|
||
|
||
type CalendarFeed {
|
||
createdAt: String!
|
||
|
||
"""
|
||
Secret of the calendar URL: GET /api/calendar/{token}.ics (iCalendar, no session)
|
||
"""
|
||
token: String!
|
||
}
|
||
|
||
input ChangeIssueStatusInput {
|
||
issueId: ID!
|
||
|
||
"""Required by statuses with requiresReason"""
|
||
reason: String
|
||
|
||
"""A status id"""
|
||
status: String!
|
||
}
|
||
|
||
"""What happened after a moment"""
|
||
type ChangesSince {
|
||
created: [InsightIssue!]!
|
||
createdCount: Int!
|
||
finished: [InsightIssue!]!
|
||
finishedCount: Int!
|
||
|
||
"""Times I was mentioned here"""
|
||
mentions: Int!
|
||
|
||
"""Sent back from QA"""
|
||
returned: [InsightIssue!]!
|
||
returnedCount: Int!
|
||
since: String!
|
||
}
|
||
|
||
"""A step inside a ticket that does not deserve a ticket of its own"""
|
||
type ChecklistItem {
|
||
done: Boolean!
|
||
id: ID!
|
||
text: String!
|
||
}
|
||
|
||
"""How far the tickets hanging from one have got"""
|
||
type ChildProgress {
|
||
"""Done or cancelled"""
|
||
finished: Int!
|
||
finishedStoryPoints: Int!
|
||
percent: Int!
|
||
storyPoints: Int!
|
||
total: Int!
|
||
}
|
||
|
||
"""
|
||
Writes are acknowledged immediately; the read model catches up asynchronously. Wait for a subscription event with version >= this version to see the change.
|
||
"""
|
||
type CommandResult {
|
||
id: ID!
|
||
key: String
|
||
version: Int!
|
||
}
|
||
|
||
type Comment {
|
||
author: UserRef!
|
||
|
||
"""Empty on a deleted comment kept for its replies"""
|
||
body: String!
|
||
createdAt: String!
|
||
|
||
"""Deleted, but kept (without its text) while it has replies"""
|
||
deleted: Boolean!
|
||
editedAt: String
|
||
id: ID!
|
||
issueId: ID!
|
||
|
||
"""In the order they are offered; only the ones somebody chose"""
|
||
reactions: [CommentReaction!]!
|
||
|
||
"""The top-level comment it answers; null for a top-level one"""
|
||
replyTo: ID
|
||
version: Int!
|
||
}
|
||
|
||
type CommentChange {
|
||
action: String!
|
||
actorId: ID!
|
||
|
||
"""Null when deleted"""
|
||
comment: Comment
|
||
commentId: ID!
|
||
issueId: ID!
|
||
version: Int!
|
||
}
|
||
|
||
type CommentPage {
|
||
items: [Comment!]!
|
||
total: Int!
|
||
}
|
||
|
||
"""One emoji on a comment"""
|
||
type CommentReaction {
|
||
emoji: String!
|
||
|
||
"""Who chose it"""
|
||
users: [UserRef!]!
|
||
}
|
||
|
||
type CountByAssignee {
|
||
count: Int!
|
||
|
||
"""Null = unassigned"""
|
||
user: UserRef
|
||
}
|
||
|
||
type CountByKey {
|
||
count: Int!
|
||
key: String!
|
||
}
|
||
|
||
type CountByStatus {
|
||
count: Int!
|
||
|
||
"""Status id"""
|
||
key: String!
|
||
}
|
||
|
||
input CreateAutomationInput {
|
||
action: AutomationActionInput!
|
||
conditions: AutomationConditionsInput
|
||
name: String!
|
||
projectId: ID!
|
||
trigger: AutomationTriggerInput!
|
||
}
|
||
|
||
input CreateIssueInput {
|
||
"""An area id"""
|
||
area: String
|
||
assigneeId: ID
|
||
|
||
"""Only the fields to change"""
|
||
customFields: [CustomFieldValueInput!]
|
||
description: String
|
||
dueDate: String
|
||
|
||
"""Figma frame for UI changes"""
|
||
figmaUrl: String
|
||
labels: [String!]
|
||
|
||
"""Epic or ticket of the same project the new one breaks down"""
|
||
parentId: ID
|
||
priority: IssuePriority
|
||
projectId: ID!
|
||
releaseId: ID
|
||
|
||
"""When work should start (roadmap), YYYY-MM-DD"""
|
||
startDate: String
|
||
storyPoints: Int
|
||
|
||
"""A team id"""
|
||
team: String
|
||
title: String!
|
||
|
||
"""A ticket type id"""
|
||
type: String!
|
||
}
|
||
|
||
input CreateProjectInput {
|
||
description: String
|
||
|
||
"""Readable by anyone, also without signing in"""
|
||
isPublic: Boolean
|
||
|
||
"""2-10 chars, e.g. "TS" → tickets TS-1, TS-2..."""
|
||
key: String!
|
||
name: String!
|
||
|
||
"""
|
||
A project you own or administer to start from: its statuses, transitions, types, areas, custom fields and automation rules are copied
|
||
"""
|
||
templateProjectId: ID
|
||
}
|
||
|
||
input CreateReleaseInput {
|
||
description: String
|
||
|
||
"""e.g. v1.4.0"""
|
||
name: String!
|
||
projectId: ID!
|
||
targetDate: String
|
||
}
|
||
|
||
input CreateSprintInput {
|
||
"""YYYY-MM-DD, included"""
|
||
endDate: String!
|
||
goal: String
|
||
name: String!
|
||
projectId: ID!
|
||
|
||
"""YYYY-MM-DD"""
|
||
startDate: String!
|
||
}
|
||
|
||
input CreateWebhookInput {
|
||
"""Event names, family.* or *"""
|
||
events: [String!]!
|
||
projectId: ID!
|
||
url: String!
|
||
}
|
||
|
||
type CreatedResolved {
|
||
created: Int!
|
||
resolved: Int!
|
||
|
||
"""Monday of the week (YYYY-MM-DD)"""
|
||
week: String!
|
||
}
|
||
|
||
type CumulativeFlow {
|
||
dates: [String!]!
|
||
series: [FlowSeries!]!
|
||
}
|
||
|
||
"""A field the project adds to its tickets; its type never changes"""
|
||
type CustomFieldDefinition {
|
||
archived: Boolean!
|
||
id: String!
|
||
name: String!
|
||
|
||
"""The choices of a SELECT field"""
|
||
options: [String!]!
|
||
type: CustomFieldType!
|
||
}
|
||
|
||
input CustomFieldDefinitionInput {
|
||
archived: Boolean! = false
|
||
id: String!
|
||
name: String!
|
||
|
||
"""The choices of a SELECT field"""
|
||
options: [String!]! = []
|
||
type: CustomFieldType!
|
||
}
|
||
|
||
"""What a custom field holds (DATE: YYYY-MM-DD)"""
|
||
enum CustomFieldType {
|
||
DATE
|
||
NUMBER
|
||
SELECT
|
||
TEXT
|
||
}
|
||
|
||
"""A ticket's value of a field"""
|
||
type CustomFieldValue {
|
||
fieldId: String!
|
||
value: String!
|
||
}
|
||
|
||
"""A custom field's value; null or '' clears it"""
|
||
input CustomFieldValueInput {
|
||
fieldId: String!
|
||
value: String
|
||
}
|
||
|
||
"""The project's link for clients (owners and admins)"""
|
||
type DashboardShare {
|
||
blocks: [String!]!
|
||
createdAt: String!
|
||
projectId: ID!
|
||
|
||
"""Secret of the link /share/{token}"""
|
||
token: String!
|
||
}
|
||
|
||
"""A commit, branch or pull request that mentions the ticket"""
|
||
type DevLink {
|
||
at: String!
|
||
author: String
|
||
kind: DevLinkKind!
|
||
|
||
"""github, gitea or gitlab"""
|
||
provider: String!
|
||
|
||
"""Short SHA, branch or PR number"""
|
||
ref: String!
|
||
|
||
"""The project's name for the repository it came from"""
|
||
repository: String
|
||
state: DevLinkState
|
||
title: String!
|
||
url: String!
|
||
}
|
||
|
||
enum DevLinkKind {
|
||
BRANCH
|
||
COMMIT
|
||
PULL_REQUEST
|
||
}
|
||
|
||
enum DevLinkState {
|
||
CLOSED
|
||
MERGED
|
||
OPEN
|
||
}
|
||
|
||
type DurationStats {
|
||
averageDays: Float
|
||
count: Int!
|
||
|
||
"""85% of tickets take at most this long"""
|
||
p85Days: Float
|
||
}
|
||
|
||
"""A top-level ticket that groups others, with their progress"""
|
||
type Epic {
|
||
issue: Issue!
|
||
progress: ChildProgress!
|
||
}
|
||
|
||
"""Bugs reported in the 14 days after a release shipped"""
|
||
type EscapedBugs {
|
||
bugs: Int!
|
||
name: String!
|
||
releaseId: ID!
|
||
releasedAt: String!
|
||
}
|
||
|
||
"""Open tickets per option of a list custom field"""
|
||
type FieldBreakdown {
|
||
counts: [OptionCount!]!
|
||
fieldId: String!
|
||
|
||
"""Open tickets with no value"""
|
||
none: Int!
|
||
}
|
||
|
||
type FirstSteps {
|
||
calendar: Boolean!
|
||
invited: Boolean!
|
||
project: Boolean!
|
||
ticket: Boolean!
|
||
}
|
||
|
||
type FlowSeries {
|
||
counts: [Int!]!
|
||
status: String!
|
||
}
|
||
|
||
"""
|
||
Webhooks from GitHub, Gitea or GitLab: commits, branches and pull requests naming a ticket key are linked to it
|
||
"""
|
||
type GitIntegration {
|
||
"""On while there is at least one repository"""
|
||
enabled: Boolean!
|
||
repositories: [GitRepository!]!
|
||
|
||
"""Path of the webhook on this API, the same for every repository"""
|
||
webhookPath: String!
|
||
}
|
||
|
||
"""A repository whose webhooks the project accepts"""
|
||
type GitRepository {
|
||
createdAt: String!
|
||
id: ID!
|
||
|
||
"""The project's name for it: api, web, admin…"""
|
||
name: String!
|
||
|
||
"""Webhook secret of this repository; only owners and admins see it"""
|
||
secret: String
|
||
}
|
||
|
||
"""The home page beyond my work"""
|
||
type Home {
|
||
activity: [Activity!]!
|
||
agenda: [AgendaItem!]!
|
||
firstSteps: FirstSteps!
|
||
me: MyWeek!
|
||
online: [Online!]!
|
||
projects: [HomeProject!]!
|
||
sprints: [HomeSprint!]!
|
||
suggestions: [Suggestion!]!
|
||
team: TeamWeek!
|
||
}
|
||
|
||
type HomeProject {
|
||
"""Activity per day, last 14, oldest first"""
|
||
activity: [Int!]!
|
||
open: Int!
|
||
overdue: Int!
|
||
projectId: ID!
|
||
sprint: HomeSprintBrief
|
||
}
|
||
|
||
type HomeSprint {
|
||
projectKey: String!
|
||
projectName: String!
|
||
sprint: SprintPulse!
|
||
}
|
||
|
||
type HomeSprintBrief {
|
||
behind: Boolean!
|
||
name: String!
|
||
percent: Int!
|
||
}
|
||
|
||
"""A ticket the dashboard names, with the number that put it there"""
|
||
type InsightIssue {
|
||
assignee: UserRef
|
||
|
||
"""Days in its status (aging, stuck) or past / to its due date"""
|
||
days: Float!
|
||
dueDate: String
|
||
id: ID!
|
||
key: String!
|
||
status: String!
|
||
title: String!
|
||
}
|
||
|
||
type Issue {
|
||
"""Statuses this ticket can move to next (project's workflow)"""
|
||
allowedTransitions: [String!]!
|
||
|
||
"""An area id"""
|
||
area: String
|
||
assignee: UserRef
|
||
attachments: [Attachment!]!
|
||
|
||
"""
|
||
Open tickets it waits for: the ones that block it and the ones it depends on
|
||
"""
|
||
blockedBy: [IssueParent!]!
|
||
checklist: [ChecklistItem!]!
|
||
commentCount: Int!
|
||
comments(limit: Int! = 50, offset: Int! = 0): CommentPage!
|
||
createdAt: String!
|
||
|
||
"""Values of the project's custom fields (only those set)"""
|
||
customFields: [CustomFieldValue!]!
|
||
description: String
|
||
|
||
"""Commits, branches and pull requests that mention it"""
|
||
devLinks: [DevLink!]!
|
||
dueDate: String
|
||
figmaUrl: String
|
||
|
||
"""History of this ticket"""
|
||
history(limit: Int! = 50): [Activity!]!
|
||
id: ID!
|
||
|
||
"""Human key, e.g. TS-42"""
|
||
key: String!
|
||
labels: [String!]!
|
||
|
||
"""Linked tickets I can see"""
|
||
linkedIssues: [Issue!]!
|
||
links: [IssueLink!]!
|
||
number: Int!
|
||
|
||
"""The epic or ticket this one breaks down"""
|
||
parent: IssueParent
|
||
priority: IssuePriority!
|
||
projectId: ID!
|
||
projectKey: String!
|
||
|
||
"""
|
||
Place in the backlog and in its board column (ascending, compare as text)
|
||
"""
|
||
rank: String!
|
||
release: ReleaseRef
|
||
reporter: UserRef!
|
||
sprint: SprintRef
|
||
|
||
"""When work should start (roadmap)"""
|
||
startDate: String
|
||
|
||
"""A status id of the project's settings"""
|
||
status: String!
|
||
statusCategory: StatusCategory!
|
||
storyPoints: Int
|
||
|
||
"""A team id"""
|
||
team: String
|
||
title: String!
|
||
|
||
"""In the trash since then; null when it is not"""
|
||
trashedAt: String
|
||
|
||
"""A ticket type id of the project's settings"""
|
||
type: String!
|
||
updatedAt: String!
|
||
version: Int!
|
||
|
||
"""Whether I voted for it"""
|
||
voted: Boolean!
|
||
|
||
"""How many want it done"""
|
||
votes: Int!
|
||
|
||
"""People following the ticket"""
|
||
watchers: [UserRef!]!
|
||
}
|
||
|
||
type IssueChange {
|
||
action: String!
|
||
actorId: ID!
|
||
issue: Issue!
|
||
version: Int!
|
||
}
|
||
|
||
input IssueFilterInput {
|
||
areas: [String!]
|
||
assigneeId: ID
|
||
categories: [StatusCategory!]
|
||
|
||
"""Only tickets holding these custom values"""
|
||
customFields: [CustomFieldValueInput!]
|
||
|
||
"""Due on or after this day (YYYY-MM-DD)"""
|
||
dueFrom: String
|
||
|
||
"""Due on or before this day (YYYY-MM-DD)"""
|
||
dueTo: String
|
||
labels: [String!]
|
||
|
||
"""Only tickets with no area"""
|
||
noArea: Boolean
|
||
|
||
"""Only tickets nobody estimated"""
|
||
noEstimate: Boolean
|
||
|
||
"""Only tickets in no sprint"""
|
||
noSprint: Boolean
|
||
|
||
"""Only the tickets hanging from this one"""
|
||
parentId: ID
|
||
priorities: [IssuePriority!]
|
||
projectId: ID!
|
||
releaseId: ID
|
||
|
||
"""Matches key, title or description"""
|
||
search: String
|
||
sort: IssueSort = RECENT
|
||
sprintId: ID
|
||
statuses: [String!]
|
||
|
||
"""Team ids"""
|
||
teams: [String!]
|
||
types: [String!]
|
||
unassigned: Boolean
|
||
|
||
"""Only tickets not updated since this instant (ISO)"""
|
||
updatedBefore: String
|
||
|
||
"""Only the tickets I follow (none when anonymous)"""
|
||
watching: Boolean
|
||
}
|
||
|
||
type IssueLink {
|
||
"""OUTWARD: this issue → other. INWARD: other → this issue."""
|
||
direction: LinkDirection!
|
||
issueId: ID!
|
||
issueKey: String!
|
||
type: IssueLinkType!
|
||
}
|
||
|
||
enum IssueLinkType {
|
||
BLOCKS
|
||
DEPENDS_ON
|
||
DUPLICATES
|
||
RELATES_TO
|
||
TESTS
|
||
}
|
||
|
||
type IssuePage {
|
||
items: [Issue!]!
|
||
total: Int!
|
||
}
|
||
|
||
"""The ticket another one hangs from"""
|
||
type IssueParent {
|
||
id: ID!
|
||
key: String!
|
||
title: String!
|
||
}
|
||
|
||
enum IssuePriority {
|
||
CRITICAL
|
||
HIGH
|
||
LOW
|
||
LOWEST
|
||
MEDIUM
|
||
}
|
||
|
||
"""RECENT: last updated first. RANK: backlog order."""
|
||
enum IssueSort {
|
||
RANK
|
||
RECENT
|
||
}
|
||
|
||
"""What a new ticket of the type starts with"""
|
||
type IssueTemplate {
|
||
"""Steps added to every new ticket"""
|
||
checklist: [String!]!
|
||
|
||
"""Used when the ticket comes without a description"""
|
||
description: String
|
||
}
|
||
|
||
input IssueTemplateInput {
|
||
checklist: [String!]! = []
|
||
description: String
|
||
}
|
||
|
||
type IssueTypeOption {
|
||
archived: Boolean!
|
||
color: String!
|
||
icon: String!
|
||
id: String!
|
||
name: String!
|
||
template: IssueTemplate
|
||
}
|
||
|
||
input IssueTypeOptionInput {
|
||
archived: Boolean! = false
|
||
color: String!
|
||
icon: String!
|
||
id: String!
|
||
name: String!
|
||
template: IssueTemplateInput
|
||
}
|
||
|
||
"""
|
||
Where the time of the tickets done in the last 90 days went, created to done
|
||
"""
|
||
type Journey {
|
||
"""Part of the lead time in an in-progress status, 0-100"""
|
||
flowEfficiency: Int
|
||
leadDays: Float
|
||
samples: Int!
|
||
steps: [JourneyStep!]!
|
||
}
|
||
|
||
type JourneyStep {
|
||
"""Average days a closed ticket spent in it"""
|
||
days: Float!
|
||
|
||
"""Its part of the whole lead time, 0-100"""
|
||
share: Int!
|
||
|
||
"""Status id of the project settings"""
|
||
status: String!
|
||
}
|
||
|
||
enum LinkDirection {
|
||
INWARD
|
||
OUTWARD
|
||
}
|
||
|
||
input LinkIssuesInput {
|
||
issueId: ID!
|
||
targetIssueId: ID!
|
||
type: IssueLinkType!
|
||
}
|
||
|
||
type Me {
|
||
"""Roles inside the task-stream OAuth client"""
|
||
appRoles: [String!]!
|
||
email: String!
|
||
id: ID!
|
||
isActive: Boolean!
|
||
name: String!
|
||
|
||
"""Global roles in Pireon"""
|
||
roles: [String!]!
|
||
}
|
||
|
||
type Mutation {
|
||
"""Add a step to a ticket's checklist"""
|
||
addChecklistItem(input: AddChecklistItemInput!): CommandResult!
|
||
|
||
"""
|
||
Comment on a ticket, or answer a comment (replyTo; one level of replies)
|
||
"""
|
||
addComment(body: String!, issueId: ID!, replyTo: ID): CommandResult!
|
||
|
||
"""
|
||
Add a repository with its own secret (the first turns the integration on)
|
||
"""
|
||
addGitRepository(name: String!, projectId: ID!): GitRepository!
|
||
|
||
"""Add a Pireon user to the project"""
|
||
addProjectMember(input: ProjectMemberInput!): CommandResult!
|
||
|
||
"""
|
||
Archive the project (owner only): everything stays readable, nothing changes until it is unarchived
|
||
"""
|
||
archiveProject(projectId: ID!): CommandResult!
|
||
archiveRelease(
|
||
"""
|
||
Open release of the same project that takes its unfinished tickets; none: they leave it
|
||
"""
|
||
moveTo: ID
|
||
releaseId: ID!
|
||
): CommandResult!
|
||
|
||
"""Assign (or unassign with null) a project member"""
|
||
assignIssue(assigneeId: ID, issueId: ID!): CommandResult!
|
||
|
||
"""
|
||
The same change on up to 100 tickets; each goes through the normal rules and may refuse on its own
|
||
"""
|
||
bulkUpdateIssues(input: BulkUpdateIssuesInput!): BulkResult!
|
||
|
||
"""Move a ticket through the workflow (incl. QA)"""
|
||
changeIssueStatus(input: ChangeIssueStatusInput!): CommandResult!
|
||
changeProjectMemberRole(input: ProjectMemberInput!): CommandResult!
|
||
|
||
"""
|
||
Close the sprint under way. Unfinished tickets move to carryOverToSprintId, or back to the backlog when it is null.
|
||
"""
|
||
closeSprint(carryOverToSprintId: ID, sprintId: ID!): CommandResult!
|
||
|
||
"""
|
||
Add a rule. It acts as TaskStream, within the workflow, and what it does triggers no other rule.
|
||
"""
|
||
createAutomation(input: CreateAutomationInput!): Automation!
|
||
|
||
"""A new secret calendar URL; the previous one stops working"""
|
||
createCalendarFeed: CalendarFeed!
|
||
createIssue(input: CreateIssueInput!): CommandResult!
|
||
createProject(input: CreateProjectInput!): CommandResult!
|
||
createRelease(input: CreateReleaseInput!): CommandResult!
|
||
|
||
"""Plan a sprint (owners and admins)"""
|
||
createSprint(input: CreateSprintInput!): CommandResult!
|
||
createWebhook(input: CreateWebhookInput!): WebhookCreated!
|
||
deleteAutomation(automationId: ID!): Boolean!
|
||
|
||
"""Author or project admin"""
|
||
deleteComment(commentId: ID!): CommandResult!
|
||
|
||
"""Delete one of my views"""
|
||
deleteMyView(id: ID!): Boolean!
|
||
|
||
"""
|
||
Delete the project (owner only), with its tickets, comments and releases. `confirmKey` must be the project key.
|
||
"""
|
||
deleteProject(confirmKey: String!, projectId: ID!): CommandResult!
|
||
|
||
"""Delete a view: whoever saved it, or an admin if it is shared"""
|
||
deleteSavedFilter(id: ID!): Boolean!
|
||
|
||
"""Delete a sprint that never started; its tickets go back to the backlog"""
|
||
deleteSprint(sprintId: ID!): CommandResult!
|
||
deleteWebhook(webhookId: ID!): Boolean!
|
||
|
||
"""
|
||
A new ticket like this one: what it says, not where it stands (the key comes in the result)
|
||
"""
|
||
duplicateIssue(issueId: ID!): CommandResult!
|
||
editComment(body: String!, commentId: ID!): CommandResult!
|
||
|
||
"""I left this ticket's page"""
|
||
leavePresence(issueId: ID!): Boolean!
|
||
|
||
"""Relate tickets, e.g. FE DEPENDS_ON BE, QA TESTS FE"""
|
||
linkIssues(input: LinkIssuesInput!): CommandResult!
|
||
|
||
"""Mark these as read, or all of them when `ids` is omitted"""
|
||
markNotificationsRead(ids: [ID!]): Boolean!
|
||
|
||
"""
|
||
Ship the release. Fails while it has unfinished tickets unless force = true.
|
||
"""
|
||
publishRelease(force: Boolean! = false, releaseId: ID!): CommandResult!
|
||
|
||
"""Move a ticket in the backlog, between two others of the same project"""
|
||
rankIssue(input: RankIssueInput!): CommandResult!
|
||
|
||
"""React (👍 👎 😄 🎉 😕 ❤️ 🚀 👀) or take it back (on: false)"""
|
||
reactToComment(commentId: ID!, emoji: String!, on: Boolean!): CommandResult!
|
||
|
||
"""
|
||
Remove a file from a ticket (whoever uploaded it, or an owner/admin). Upload with the REST API.
|
||
"""
|
||
removeAttachment(attachmentId: ID!, issueId: ID!): CommandResult!
|
||
removeChecklistItem(issueId: ID!, itemId: ID!): CommandResult!
|
||
|
||
"""Remove a repository; what it linked stays on the tickets"""
|
||
removeGitRepository(projectId: ID!, repositoryId: ID!): Boolean!
|
||
removeProjectMember(projectId: ID!, userId: ID!): CommandResult!
|
||
|
||
"""Back from the trash"""
|
||
restoreIssue(issueId: ID!): CommandResult!
|
||
|
||
"""My calendar URL stops working"""
|
||
revokeCalendarFeed: Boolean!
|
||
|
||
"""A new secret for a repository; the old one stops working"""
|
||
rotateGitRepositorySecret(projectId: ID!, repositoryId: ID!): GitRepository!
|
||
|
||
"""Save the current board filters under a name (members of the project)"""
|
||
saveFilter(input: SaveFilterInput!): ID!
|
||
|
||
"""Save a view of my work under a name"""
|
||
saveMyView(input: SaveMyViewInput!): ID!
|
||
|
||
"""
|
||
Place a ticket under an epic or another ticket of the same project (null: back to the top). Three levels at most: epic → ticket → subtask.
|
||
"""
|
||
setIssueParent(issueId: ID!, parentId: ID): CommandResult!
|
||
|
||
"""Put a ticket in a release (null removes it)"""
|
||
setIssueRelease(issueId: ID!, releaseId: ID): CommandResult!
|
||
|
||
"""Put a ticket in a sprint (null: back to the backlog)"""
|
||
setIssueSprint(issueId: ID!, sprintId: ID): CommandResult!
|
||
|
||
"""Turn the link on or change its blocks; renew for a new secret"""
|
||
shareDashboard(input: ShareDashboardInput!): DashboardShare!
|
||
|
||
"""Start a planned sprint (only one under way per project)"""
|
||
startSprint(sprintId: ID!): CommandResult!
|
||
|
||
"""Push on this device"""
|
||
subscribePush(subscription: PushSubscriptionInput!): Boolean!
|
||
|
||
"""Send a ping now and tell how it went"""
|
||
testWebhook(webhookId: ID!): WebhookDelivery!
|
||
|
||
"""
|
||
I am on this ticket (send every ~10 s while the page is open): answers who else is, the ones editing first
|
||
"""
|
||
touchPresence(editing: Boolean! = false, issueId: ID!): [Presence!]!
|
||
|
||
"""
|
||
To the trash (whoever opened it, or an owner/admin): hidden everywhere, deleted for good after 30 days
|
||
"""
|
||
trashIssue(issueId: ID!): CommandResult!
|
||
|
||
"""Bring an archived project back (owner only)"""
|
||
unarchiveProject(projectId: ID!): CommandResult!
|
||
unlinkIssues(input: LinkIssuesInput!): CommandResult!
|
||
|
||
"""The link stops working"""
|
||
unshareDashboard(projectId: ID!): Boolean!
|
||
|
||
"""Push off on this device"""
|
||
unsubscribePush(endpoint: String!): Boolean!
|
||
|
||
"""Stop following a ticket"""
|
||
unwatchIssue(issueId: ID!): CommandResult!
|
||
|
||
"""Rename, pause or resume"""
|
||
updateAutomation(active: Boolean, automationId: ID!, name: String): Automation!
|
||
|
||
"""Reword, tick or untick a checklist step"""
|
||
updateChecklistItem(input: UpdateChecklistItemInput!): CommandResult!
|
||
updateIssue(input: UpdateIssueInput!): CommandResult!
|
||
updateNotificationSettings(email: Boolean!): NotificationSettings!
|
||
updateProject(input: UpdateProjectInput!): CommandResult!
|
||
|
||
"""
|
||
Replace statuses, transitions, ticket types and areas (owners and admins). Values can be archived, not deleted.
|
||
"""
|
||
updateProjectSettings(projectId: ID!, settings: ProjectSettingsInput!): CommandResult!
|
||
updateRelease(input: UpdateReleaseInput!): CommandResult!
|
||
updateSprint(input: UpdateSprintInput!): CommandResult!
|
||
updateWebhook(input: UpdateWebhookInput!): Webhook!
|
||
|
||
"""
|
||
Vote for a ticket (on) or take the vote back: anyone signed in on a public project, members on a private one
|
||
"""
|
||
voteIssue(issueId: ID!, on: Boolean!): CommandResult!
|
||
|
||
"""
|
||
Follow a ticket: be told when it moves, is reassigned or gets a comment
|
||
"""
|
||
watchIssue(issueId: ID!): CommandResult!
|
||
|
||
"""
|
||
Write the release notes (Markdown; null removes them). Also after shipping.
|
||
"""
|
||
writeReleaseNotes(notes: String, releaseId: ID!): CommandResult!
|
||
}
|
||
|
||
type MyNotifications {
|
||
items: [Notification!]!
|
||
|
||
"""All my unread ones, not just these"""
|
||
unread: Int!
|
||
}
|
||
|
||
"""A named view of my work (private)"""
|
||
type MyView {
|
||
createdAt: String!
|
||
criteria: MyViewCriteria!
|
||
id: ID!
|
||
name: String!
|
||
}
|
||
|
||
"""What a view of my work narrows to; empty: every ticket of my projects"""
|
||
type MyViewCriteria {
|
||
assignedToMe: Boolean
|
||
|
||
"""Only types with the bug icon"""
|
||
bugsOnly: Boolean
|
||
categories: [StatusCategory!]
|
||
|
||
"""Only open tickets past due"""
|
||
overdue: Boolean
|
||
priorities: [IssuePriority!]
|
||
|
||
"""Empty: all my projects"""
|
||
projectIds: [ID!]
|
||
search: String
|
||
watching: Boolean
|
||
}
|
||
|
||
input MyViewCriteriaInput {
|
||
assignedToMe: Boolean
|
||
bugsOnly: Boolean
|
||
categories: [StatusCategory!]
|
||
overdue: Boolean
|
||
priorities: [IssuePriority!]
|
||
|
||
"""Empty: all my projects"""
|
||
projectIds: [ID!]
|
||
search: String
|
||
watching: Boolean
|
||
}
|
||
|
||
type MyWeek {
|
||
lastWeek: Int!
|
||
|
||
"""Days in a row with something finished"""
|
||
streak: Int!
|
||
thisWeek: Int!
|
||
}
|
||
|
||
type Notification {
|
||
actor: UserRef!
|
||
createdAt: String!
|
||
id: ID!
|
||
issueId: ID
|
||
issueKey: String
|
||
kind: NotificationKind!
|
||
projectId: ID!
|
||
projectKey: String!
|
||
|
||
"""Null: unread"""
|
||
readAt: String
|
||
summary: String!
|
||
}
|
||
|
||
"""Why someone is told"""
|
||
enum NotificationKind {
|
||
ADDED_TO_PROJECT
|
||
ASSIGNED
|
||
COMMENTED
|
||
MENTIONED
|
||
PROPOSED
|
||
QA_FAILED
|
||
REMINDER
|
||
REPLIED
|
||
STATUS_CHANGED
|
||
WATCHED
|
||
}
|
||
|
||
type NotificationSettings {
|
||
"""Copies by e-mail"""
|
||
email: Boolean!
|
||
|
||
"""Whether this installation can send e-mail at all"""
|
||
emailAvailable: Boolean!
|
||
|
||
"""
|
||
VAPID public key to subscribe a device to push with; null: no push here
|
||
"""
|
||
pushPublicKey: String
|
||
}
|
||
|
||
"""Someone of my projects on a ticket now"""
|
||
type Online {
|
||
at: String!
|
||
editing: Boolean!
|
||
issueKey: String
|
||
issueTitle: String
|
||
projectKey: String!
|
||
user: UserRef!
|
||
}
|
||
|
||
type OptionCount {
|
||
count: Int!
|
||
value: String!
|
||
}
|
||
|
||
"""
|
||
One of my active projects at a glance: open work, risks, sprint, releases and epics
|
||
"""
|
||
type PortfolioProject {
|
||
blocked: Int!
|
||
|
||
"""Open epics, nearest due date first (six at most)"""
|
||
epics: [Epic!]!
|
||
isPublic: Boolean!
|
||
key: String!
|
||
name: String!
|
||
open: Int!
|
||
overdue: Int!
|
||
projectId: ID!
|
||
releases: [ReleaseForecast!]!
|
||
sprint: SprintPulse
|
||
stuck: Int!
|
||
total: Int!
|
||
updatedAt: String!
|
||
}
|
||
|
||
"""Someone on a ticket right now (heartbeat in the last 30 s)"""
|
||
type Presence {
|
||
"""Last heartbeat"""
|
||
at: String!
|
||
|
||
"""Editing the ticket or writing a comment"""
|
||
editing: Boolean!
|
||
user: UserRef!
|
||
}
|
||
|
||
type PriorityCount {
|
||
count: Int!
|
||
priority: IssuePriority!
|
||
}
|
||
|
||
type Project {
|
||
"""Takes bug reports and ideas from anyone (while public)"""
|
||
acceptsProposals: Boolean!
|
||
|
||
"""
|
||
Statistics of the last `days` days (7-365): created vs resolved, cumulative flow, cycle/lead time, throughput and QA
|
||
"""
|
||
analytics(days: Int! = 90): ProjectAnalytics!
|
||
|
||
"""Archived since then (read-only); null while active"""
|
||
archivedAt: String
|
||
|
||
"""Kanban board, one column per status"""
|
||
board(
|
||
area: String
|
||
assigneeId: ID
|
||
labels: [String!]
|
||
perColumn: Int! = 50
|
||
priorities: [IssuePriority!]
|
||
releaseId: ID
|
||
|
||
"""Matches key, title or description"""
|
||
search: String
|
||
sprintId: ID
|
||
types: [String!]
|
||
unassigned: Boolean
|
||
): [BoardColumn!]!
|
||
createdAt: String!
|
||
description: String
|
||
id: ID!
|
||
|
||
"""
|
||
The dashboard: sprint under way, overdue / blocked / stuck tickets, aging and bottlenecks
|
||
"""
|
||
insights(
|
||
"""ISO instant (e.g. my last visit): also tell what changed after it"""
|
||
since: String
|
||
): ProjectInsights!
|
||
|
||
"""Anyone can read it, also without signing in"""
|
||
isPublic: Boolean!
|
||
key: String!
|
||
members: [ProjectMember!]!
|
||
name: String!
|
||
owner: UserRef!
|
||
releases: [Release!]!
|
||
settings: ProjectSettings!
|
||
|
||
"""Project tracking dashboard"""
|
||
stats: ProjectStats!
|
||
updatedAt: String!
|
||
version: Int!
|
||
}
|
||
|
||
type ProjectAnalytics {
|
||
createdVsResolved: [CreatedResolved!]!
|
||
|
||
"""Tickets in each status at the end of every day"""
|
||
cumulativeFlow: CumulativeFlow!
|
||
|
||
"""Start of work → done"""
|
||
cycleTime: DurationStats!
|
||
from: String!
|
||
|
||
"""Creation → done"""
|
||
leadTime: DurationStats!
|
||
qa: QaStats!
|
||
|
||
"""Finished per person and week"""
|
||
throughput: [Throughput!]!
|
||
to: String!
|
||
}
|
||
|
||
type ProjectChange {
|
||
action: String!
|
||
actorId: ID!
|
||
project: Project!
|
||
version: Int!
|
||
}
|
||
|
||
"""
|
||
The dashboard: sprint under way, risks, aging, bottlenecks, release forecasts, team load, backlog health and changes
|
||
"""
|
||
type ProjectInsights {
|
||
aging: Aging!
|
||
backlog: BacklogHealth!
|
||
bottlenecks: [StatusTime!]!
|
||
|
||
"""Only when asked with `since`"""
|
||
changes: ChangesSince
|
||
|
||
"""One per active list custom field"""
|
||
fields: [FieldBreakdown!]!
|
||
generatedAt: String!
|
||
|
||
"""The last 12 weeks from a Monday, oldest first (84 days)"""
|
||
heatmap: [ActivityDay!]!
|
||
journey: Journey!
|
||
|
||
"""Null while the project has never had a proposal"""
|
||
proposals: ProposalsFunnel
|
||
quality: Quality!
|
||
releases: [ReleaseForecast!]!
|
||
risks: Risks!
|
||
sprint: SprintPulse
|
||
team: [TeamLoad!]!
|
||
}
|
||
|
||
type ProjectMember {
|
||
role: ProjectRole!
|
||
user: UserRef!
|
||
}
|
||
|
||
input ProjectMemberInput {
|
||
projectId: ID!
|
||
role: ProjectRole! = MEMBER
|
||
|
||
"""Pireon user id"""
|
||
userId: ID!
|
||
}
|
||
|
||
enum ProjectRole {
|
||
ADMIN
|
||
GUEST
|
||
MEMBER
|
||
OWNER
|
||
VIEWER
|
||
}
|
||
|
||
"""
|
||
Statuses (board order), transitions, ticket types, areas and custom fields
|
||
"""
|
||
type ProjectSettings {
|
||
areas: [AreaOption!]!
|
||
|
||
"""
|
||
Definition of done: tickets reach DONE only with their checklist ticked (owners and admins may override)
|
||
"""
|
||
checklistBeforeDone: Boolean!
|
||
customFields: [CustomFieldDefinition!]!
|
||
issueTypes: [IssueTypeOption!]!
|
||
statuses: [WorkflowStatus!]!
|
||
teams: [Team!]!
|
||
transitions: [StatusTransitions!]!
|
||
}
|
||
|
||
"""
|
||
The whole configuration (replaces the previous one). Statuses go in board order.
|
||
"""
|
||
input ProjectSettingsInput {
|
||
areas: [AreaOptionInput!]!
|
||
|
||
"""
|
||
Definition of done: DONE only with the checklist ticked. Absent: unchanged
|
||
"""
|
||
checklistBeforeDone: Boolean
|
||
|
||
"""Absent: unchanged. Fields cannot be removed: archive them."""
|
||
customFields: [CustomFieldDefinitionInput!]
|
||
issueTypes: [IssueTypeOptionInput!]!
|
||
statuses: [WorkflowStatusInput!]!
|
||
|
||
"""Absent: unchanged. Teams cannot be removed: archive them."""
|
||
teams: [TeamInput!]
|
||
transitions: [StatusTransitionsInput!]!
|
||
}
|
||
|
||
type ProjectStats {
|
||
byArea: [CountByKey!]!
|
||
|
||
"""Open tickets per person"""
|
||
byAssignee: [CountByAssignee!]!
|
||
byPriority: [CountByKey!]!
|
||
byStatus: [CountByStatus!]!
|
||
byType: [CountByKey!]!
|
||
open: Int!
|
||
total: Int!
|
||
}
|
||
|
||
"""The public's proposals, from received to done or discarded"""
|
||
type ProposalsFunnel {
|
||
discarded: Int!
|
||
done: Int!
|
||
received: Int!
|
||
|
||
"""In the last 30 days"""
|
||
receivedLately: Int!
|
||
|
||
"""Most voted waiting, at most 5"""
|
||
topWaiting: [WaitingProposal!]!
|
||
underWay: Int!
|
||
|
||
"""Open, not started, in no sprint nor release"""
|
||
waiting: Int!
|
||
}
|
||
|
||
"""A browser's Web Push subscription (PushSubscription.toJSON())"""
|
||
input PushSubscriptionInput {
|
||
auth: String!
|
||
endpoint: String!
|
||
p256dh: String!
|
||
}
|
||
|
||
"""QA verdicts per area (90 days)"""
|
||
type QaByArea {
|
||
"""Null: no area"""
|
||
area: String
|
||
passed: Int!
|
||
returned: Int!
|
||
}
|
||
|
||
type QaStats {
|
||
failed: Int!
|
||
failureRate: Float
|
||
passed: Int!
|
||
}
|
||
|
||
"""Bugs (types with the bug icon) and QA"""
|
||
type Quality {
|
||
"""Last 8 weeks, oldest first"""
|
||
bugWeeks: [BugWeek!]!
|
||
escaped: [EscapedBugs!]!
|
||
openBugsByPriority: [PriorityCount!]!
|
||
qaByArea: [QaByArea!]!
|
||
}
|
||
|
||
type Query {
|
||
"""Project activity feed (newest first)"""
|
||
activity(
|
||
"""
|
||
ISO date: only activity at or after it (with before, a window such as a day)
|
||
"""
|
||
after: String
|
||
|
||
"""ISO date cursor"""
|
||
before: String
|
||
issueId: ID
|
||
limit: Int! = 50
|
||
projectId: ID!
|
||
): [Activity!]!
|
||
automations(projectId: ID!): [Automation!]!
|
||
|
||
"""The project's link for clients, if any (owners and admins)"""
|
||
dashboardShare(projectId: ID!): DashboardShare
|
||
|
||
"""
|
||
A project's epics: top-level tickets that group others, with the progress of those
|
||
"""
|
||
epics(projectId: ID!): [Epic!]!
|
||
gitIntegration(projectId: ID!): GitIntegration!
|
||
issue(
|
||
"""Issue id or key (e.g. "TS-42")"""
|
||
idOrKey: String!
|
||
): Issue!
|
||
issues(filter: IssueFilterInput!, limit: Int! = 50, offset: Int! = 0): IssuePage!
|
||
|
||
"""The authenticated user"""
|
||
me: Me!
|
||
|
||
"""My calendar URL, if I made one"""
|
||
myCalendarFeed: CalendarFeed
|
||
|
||
"""
|
||
The home page beyond my work: agenda of the week, activity of my projects, the week in numbers, sprints, project cards, suggestions, first steps and who is on what now
|
||
"""
|
||
myHome: Home!
|
||
|
||
"""
|
||
Tickets across all my projects: assigned to me (default) or any (e.g. categories [QA])
|
||
"""
|
||
myIssues(
|
||
assignedToMe: Boolean! = true
|
||
|
||
"""Only types drawn with the bug icon"""
|
||
bugsOnly: Boolean
|
||
categories: [StatusCategory!]
|
||
limit: Int! = 50
|
||
offset: Int! = 0
|
||
|
||
"""Only open tickets past their due date"""
|
||
overdue: Boolean
|
||
priorities: [IssuePriority!]
|
||
|
||
"""Only these of my projects"""
|
||
projectIds: [ID!]
|
||
|
||
"""Matches key, title or description (global search)"""
|
||
search: String
|
||
statuses: [String!]
|
||
|
||
"""Only the tickets I follow"""
|
||
watching: Boolean! = false
|
||
): IssuePage!
|
||
|
||
"""My notifications, newest first, and how many are unread"""
|
||
myNotifications(limit: Int! = 30, unreadOnly: Boolean! = false): MyNotifications!
|
||
|
||
"""Projects where I am a member"""
|
||
myProjects: [Project!]!
|
||
|
||
"""My saved views of my work, across my projects"""
|
||
myViews: [MyView!]!
|
||
notificationSettings: NotificationSettings!
|
||
|
||
"""
|
||
My active projects (not archived, not as a guest) at a glance: open work, risks, sprint, release forecasts and epics
|
||
"""
|
||
portfolio: [PortfolioProject!]!
|
||
|
||
"""A project of mine, or any public one (no sign-in needed)"""
|
||
project(
|
||
"""Project id or key (e.g. "TS")"""
|
||
idOrKey: String!
|
||
): Project!
|
||
|
||
"""Projects anyone can read, also without signing in"""
|
||
publicProjects: [Project!]!
|
||
release(id: ID!): Release!
|
||
|
||
"""My views of the project's board, then the shared ones"""
|
||
savedFilters(projectId: ID!): [SavedFilter!]!
|
||
|
||
"""What a link for clients shows, for anyone with it"""
|
||
sharedDashboard(token: String!): SharedDashboard
|
||
sprint(id: ID!): Sprint!
|
||
|
||
"""
|
||
A project's sprints: the one under way, the planned ones, then the closed ones
|
||
"""
|
||
sprints(projectId: ID!): [Sprint!]!
|
||
|
||
"""A project's tickets in the trash, newest first"""
|
||
trash(projectId: ID!): [Issue!]!
|
||
|
||
"""Planned releases of all my projects, soonest target date first"""
|
||
upcomingReleases(limit: Int! = 10): [Release!]!
|
||
user(id: String!): User
|
||
|
||
"""Search users by name or email (to assign / add members)"""
|
||
users(limit: Int! = 20, search: String! = ""): [User!]!
|
||
|
||
"""Event names a webhook can subscribe to (also family.* and *)"""
|
||
webhookEvents: [String!]!
|
||
webhooks(projectId: ID!): [Webhook!]!
|
||
}
|
||
|
||
input RankIssueInput {
|
||
"""The ticket that ends up right above (null: the top)"""
|
||
aboveIssueId: ID
|
||
|
||
"""The ticket that ends up right below (null: the bottom)"""
|
||
belowIssueId: ID
|
||
issueId: ID!
|
||
}
|
||
|
||
type Release {
|
||
"""Scope vs finished tickets, day by day"""
|
||
burnup: ReleaseBurnup!
|
||
createdAt: String!
|
||
description: String
|
||
id: ID!
|
||
|
||
"""Tickets included in this release"""
|
||
issues(limit: Int! = 100, offset: Int! = 0): IssuePage!
|
||
name: String!
|
||
|
||
"""What shipped, told for people (Markdown)"""
|
||
notes: String
|
||
|
||
"""
|
||
A Markdown draft of the notes from its finished tickets, by type (not saved)
|
||
"""
|
||
notesDraft: String!
|
||
progress: ReleaseProgress!
|
||
projectId: ID!
|
||
releasedAt: String
|
||
status: ReleaseStatus!
|
||
targetDate: String
|
||
version: Int!
|
||
}
|
||
|
||
type ReleaseBurnup {
|
||
dates: [String!]!
|
||
done: [Int!]!
|
||
releaseId: ID!
|
||
|
||
"""Tickets in the release (not cancelled)"""
|
||
scope: [Int!]!
|
||
targetDate: String
|
||
}
|
||
|
||
type ReleaseChange {
|
||
action: String!
|
||
actorId: ID!
|
||
release: Release!
|
||
version: Int!
|
||
}
|
||
|
||
"""When a planned release would be finished, at the real pace"""
|
||
type ReleaseForecast {
|
||
finished: Int!
|
||
|
||
"""Half of the simulated futures finish by then"""
|
||
likelyDate: String
|
||
name: String!
|
||
releaseId: ID!
|
||
|
||
"""85% finish by then"""
|
||
safeDate: String
|
||
targetDate: String
|
||
total: Int!
|
||
|
||
"""DONE, NO_DATE, UNKNOWN (no pace yet), ON_TRACK, AT_RISK or LATE"""
|
||
verdict: String!
|
||
}
|
||
|
||
type ReleaseProgress {
|
||
byStatus: [CountByStatus!]!
|
||
finished: Int!
|
||
percent: Int!
|
||
total: Int!
|
||
}
|
||
|
||
type ReleaseRef {
|
||
id: ID!
|
||
name: String!
|
||
}
|
||
|
||
enum ReleaseStatus {
|
||
ARCHIVED
|
||
PLANNED
|
||
RELEASED
|
||
}
|
||
|
||
"""Tickets to look at now (worst first)"""
|
||
type Risks {
|
||
blocked: [InsightIssue!]!
|
||
blockedCount: Int!
|
||
|
||
"""Due within 7 days"""
|
||
dueSoon: [InsightIssue!]!
|
||
dueSoonCount: Int!
|
||
overdue: [InsightIssue!]!
|
||
overdueCount: Int!
|
||
stuck: [InsightIssue!]!
|
||
stuckCount: Int!
|
||
stuckDays: Int!
|
||
}
|
||
|
||
input SaveFilterInput {
|
||
criteria: SavedFilterCriteriaInput!
|
||
name: String!
|
||
projectId: ID!
|
||
|
||
"""Visible to the whole project (members, not viewers, share)"""
|
||
shared: Boolean! = false
|
||
}
|
||
|
||
input SaveMyViewInput {
|
||
criteria: MyViewCriteriaInput!
|
||
name: String!
|
||
}
|
||
|
||
"""
|
||
A named view of the board: private to whoever saved it, or shared with the project
|
||
"""
|
||
type SavedFilter {
|
||
createdAt: String!
|
||
criteria: SavedFilterCriteria!
|
||
id: ID!
|
||
name: String!
|
||
owner: UserRef!
|
||
projectId: ID!
|
||
shared: Boolean!
|
||
}
|
||
|
||
"""What a saved view narrows the board to; empty: everything"""
|
||
type SavedFilterCriteria {
|
||
areas: [String!]
|
||
assigneeId: ID
|
||
labels: [String!]
|
||
priorities: [IssuePriority!]
|
||
releaseId: ID
|
||
search: String
|
||
types: [String!]
|
||
unassigned: Boolean
|
||
}
|
||
|
||
input SavedFilterCriteriaInput {
|
||
areas: [String!]
|
||
assigneeId: ID
|
||
labels: [String!]
|
||
priorities: [IssuePriority!]
|
||
releaseId: ID
|
||
search: String
|
||
types: [String!]
|
||
unassigned: Boolean
|
||
}
|
||
|
||
"""The project's link for clients"""
|
||
input ShareDashboardInput {
|
||
"""Blocks to show: flow, sprint, releases, epics, activity"""
|
||
blocks: [String!]!
|
||
projectId: ID!
|
||
|
||
"""A new secret: the old link stops working"""
|
||
renew: Boolean
|
||
}
|
||
|
||
"""
|
||
What a link for clients shows: only the chosen blocks (the others are null)
|
||
"""
|
||
type SharedDashboard {
|
||
activity: [ActivityDay!]
|
||
blocks: [String!]!
|
||
epics: [SharedEpic!]
|
||
flow: [SharedFlow!]
|
||
generatedAt: String!
|
||
projectKey: String!
|
||
projectName: String!
|
||
releases: [ReleaseForecast!]
|
||
sprint: SprintPulse
|
||
}
|
||
|
||
"""An open epic and how far it got"""
|
||
type SharedEpic {
|
||
done: Int!
|
||
dueDate: String
|
||
key: String!
|
||
percent: Int!
|
||
title: String!
|
||
total: Int!
|
||
}
|
||
|
||
"""Tickets in one status"""
|
||
type SharedFlow {
|
||
"""A colour name of the project settings"""
|
||
color: String!
|
||
count: Int!
|
||
name: String!
|
||
status: String!
|
||
}
|
||
|
||
"""A time-boxed iteration: the tickets the team commits to"""
|
||
type Sprint {
|
||
burndown: SprintBurndown!
|
||
closedAt: String
|
||
createdAt: String!
|
||
|
||
"""Last day (included), YYYY-MM-DD"""
|
||
endDate: String!
|
||
goal: String
|
||
id: ID!
|
||
|
||
"""Tickets in this sprint, in backlog order"""
|
||
issues(limit: Int! = 100, offset: Int! = 0): IssuePage!
|
||
name: String!
|
||
progress: SprintProgress!
|
||
projectId: ID!
|
||
|
||
"""First day, YYYY-MM-DD"""
|
||
startDate: String!
|
||
startedAt: String
|
||
status: SprintStatus!
|
||
version: Int!
|
||
}
|
||
|
||
"""
|
||
Per day of the sprint: tickets in it, still open, and their points (null: days to come). `ideal` falls from the first day to zero.
|
||
"""
|
||
type SprintBurndown {
|
||
dates: [String!]!
|
||
ideal: [Float!]!
|
||
remaining: [Int]!
|
||
remainingPoints: [Int]!
|
||
scope: [Int]!
|
||
sprintId: ID!
|
||
}
|
||
|
||
type SprintChange {
|
||
action: String!
|
||
actorId: ID!
|
||
|
||
"""Null: deleted"""
|
||
sprint: Sprint
|
||
sprintId: ID!
|
||
version: Int!
|
||
}
|
||
|
||
type SprintProgress {
|
||
"""Done or cancelled"""
|
||
finished: Int!
|
||
finishedStoryPoints: Int!
|
||
percent: Int!
|
||
storyPoints: Int!
|
||
total: Int!
|
||
}
|
||
|
||
"""The sprint under way: time gone against work done"""
|
||
type SprintPulse {
|
||
"""At this pace, what is open would not be closed"""
|
||
behind: Boolean!
|
||
|
||
"""Days left after today"""
|
||
daysLeft: Int!
|
||
donePoints: Int!
|
||
doneTickets: Int!
|
||
endDate: String!
|
||
name: String!
|
||
neededPerDay: Float
|
||
pacePerDay: Float
|
||
points: Int!
|
||
sprintId: ID!
|
||
startDate: String!
|
||
tickets: Int!
|
||
totalDays: Int!
|
||
}
|
||
|
||
type SprintRef {
|
||
id: ID!
|
||
name: String!
|
||
}
|
||
|
||
"""PLANNED, ACTIVE (one per project at a time) or CLOSED"""
|
||
enum SprintStatus {
|
||
ACTIVE
|
||
CLOSED
|
||
PLANNED
|
||
}
|
||
|
||
"""
|
||
What a status means, whatever each project calls it. DONE and CANCELLED are finished.
|
||
"""
|
||
enum StatusCategory {
|
||
CANCELLED
|
||
DONE
|
||
IN_PROGRESS
|
||
QA
|
||
TODO
|
||
}
|
||
|
||
type StatusTime {
|
||
averageDays: Float
|
||
open: Int!
|
||
overLimit: Boolean!
|
||
samples: Int!
|
||
status: String!
|
||
wipLimit: Int
|
||
}
|
||
|
||
type StatusTransitions {
|
||
from: String!
|
||
to: [String!]!
|
||
}
|
||
|
||
input StatusTransitionsInput {
|
||
from: String!
|
||
to: [String!]!
|
||
}
|
||
|
||
type Subscription {
|
||
"""Live activity feed"""
|
||
activityAdded(projectId: ID!): Activity!
|
||
commentChanged(issueId: ID!): CommentChange!
|
||
|
||
"""Tickets created/updated/moved in a project (board in realtime)"""
|
||
issueChanged(projectId: ID!): IssueChange!
|
||
|
||
"""Projects I am added to / removed from"""
|
||
myProjectsChanged: ProjectChange!
|
||
|
||
"""My notifications, as they happen"""
|
||
notificationAdded: Notification!
|
||
projectChanged(projectId: ID!): ProjectChange!
|
||
releaseChanged(projectId: ID!): ReleaseChange!
|
||
sprintChanged(projectId: ID!): SprintChange!
|
||
}
|
||
|
||
type Suggestion {
|
||
count: Int!
|
||
|
||
"""UNASSIGNED, PROPOSALS or QA_WAITING"""
|
||
kind: String!
|
||
projectKey: String!
|
||
}
|
||
|
||
"""A group of members: tickets go to it; @team mentions tell them all"""
|
||
type Team {
|
||
archived: Boolean!
|
||
id: String!
|
||
memberIds: [ID!]!
|
||
name: String!
|
||
}
|
||
|
||
input TeamInput {
|
||
archived: Boolean! = false
|
||
id: String!
|
||
memberIds: [ID!]! = []
|
||
name: String!
|
||
}
|
||
|
||
type TeamLoad {
|
||
blocked: Int!
|
||
openPoints: Int!
|
||
openTickets: Int!
|
||
overloaded: Boolean!
|
||
|
||
"""Points closed per sprint, last three closed sprints"""
|
||
pointsPerSprint: Float
|
||
user: UserRef!
|
||
}
|
||
|
||
type TeamWeek {
|
||
lastWeek: Int!
|
||
|
||
"""Finished per day, last 14, oldest first"""
|
||
perDay: [Int!]!
|
||
thisWeek: Int!
|
||
}
|
||
|
||
type Throughput {
|
||
count: Int!
|
||
user: UserRef
|
||
week: String!
|
||
}
|
||
|
||
input UpdateChecklistItemInput {
|
||
done: Boolean
|
||
issueId: ID!
|
||
itemId: ID!
|
||
text: String
|
||
}
|
||
|
||
input UpdateIssueInput {
|
||
"""An area id"""
|
||
area: String
|
||
|
||
"""Only the fields to change"""
|
||
customFields: [CustomFieldValueInput!]
|
||
description: String
|
||
dueDate: String
|
||
|
||
"""Figma frame for UI changes"""
|
||
figmaUrl: String
|
||
issueId: ID!
|
||
labels: [String!]
|
||
priority: IssuePriority
|
||
|
||
"""When work should start (roadmap), YYYY-MM-DD"""
|
||
startDate: String
|
||
storyPoints: Int
|
||
|
||
"""A team id"""
|
||
team: String
|
||
title: String
|
||
type: String
|
||
}
|
||
|
||
input UpdateProjectInput {
|
||
"""
|
||
Take bug reports and ideas from anyone through the public form (while public)
|
||
"""
|
||
acceptsProposals: Boolean
|
||
description: String
|
||
isPublic: Boolean
|
||
name: String
|
||
projectId: ID!
|
||
}
|
||
|
||
input UpdateReleaseInput {
|
||
description: String
|
||
name: String
|
||
releaseId: ID!
|
||
targetDate: String
|
||
}
|
||
|
||
input UpdateSprintInput {
|
||
endDate: String
|
||
goal: String
|
||
name: String
|
||
sprintId: ID!
|
||
startDate: String
|
||
}
|
||
|
||
input UpdateWebhookInput {
|
||
active: Boolean
|
||
events: [String!]
|
||
url: String
|
||
webhookId: ID!
|
||
}
|
||
|
||
"""User managed by the Pireon identity server"""
|
||
type User {
|
||
email: String!
|
||
id: ID!
|
||
isActive: Boolean!
|
||
name: String!
|
||
}
|
||
|
||
type UserRef {
|
||
id: ID!
|
||
name: String!
|
||
}
|
||
|
||
type WaitingProposal {
|
||
"""Days since it came in"""
|
||
days: Int!
|
||
id: ID!
|
||
key: String!
|
||
title: String!
|
||
votes: Int!
|
||
}
|
||
|
||
"""
|
||
Where the project tells another system what happened (signed POST, HMAC-SHA256)
|
||
"""
|
||
type Webhook {
|
||
active: Boolean!
|
||
createdAt: String!
|
||
createdBy: UserRef!
|
||
|
||
"""Event names, family.* or *"""
|
||
events: [String!]!
|
||
id: ID!
|
||
lastDelivery: WebhookDelivery
|
||
projectId: ID!
|
||
url: String!
|
||
}
|
||
|
||
type WebhookCreated {
|
||
id: ID!
|
||
|
||
"""Signs every delivery. Shown only now: keep it."""
|
||
secret: String!
|
||
}
|
||
|
||
type WebhookDelivery {
|
||
at: String!
|
||
error: String
|
||
event: String!
|
||
ok: Boolean!
|
||
|
||
"""HTTP status"""
|
||
status: Int
|
||
}
|
||
|
||
type WorkflowStatus {
|
||
"""No new tickets or transitions into it"""
|
||
archived: Boolean!
|
||
category: StatusCategory!
|
||
|
||
"""Colour token: slate, violet, green…"""
|
||
color: String!
|
||
|
||
"""Stable id stored on tickets, e.g. IN_REVIEW"""
|
||
id: String!
|
||
name: String!
|
||
|
||
"""Entering it needs a reason"""
|
||
requiresReason: Boolean!
|
||
|
||
"""
|
||
Work-in-progress limit: most tickets the column should hold (a warning, not a lock)
|
||
"""
|
||
wipLimit: Int
|
||
}
|
||
|
||
input WorkflowStatusInput {
|
||
archived: Boolean! = false
|
||
category: StatusCategory!
|
||
color: String!
|
||
id: String!
|
||
name: String!
|
||
requiresReason: Boolean! = false
|
||
|
||
"""Work-in-progress limit (null: none)"""
|
||
wipLimit: Int
|
||
} |