/cartera (and GraphQL portfolio, REST /api/me/portfolio, MCP get_portfolio) shows every active project I belong to (not archived, not as a guest) at a glance: open, overdue, blocked and stuck tickets, the sprint under way and whether it gets there, planned releases with their forecast, and the open epics with their progress. It reuses the dashboard's computations. A release with no tickets now reads «Sin tickets» instead of «Todo hecho», here and on the dashboard. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1889 lines
39 KiB
GraphQL
1889 lines
39 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!
|
||
}
|
||
|
||
input AddChecklistItemInput {
|
||
issueId: ID!
|
||
text: 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
|
||
}
|
||
|
||
"""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 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
|
||
}
|
||
|
||
"""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
|
||
}
|
||
|
||
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!
|
||
|
||
"""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!
|
||
|
||
"""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 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
|
||
}
|
||
|
||
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!
|
||
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!
|
||
}
|
||
|
||
"""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 cursor"""
|
||
before: String
|
||
issueId: ID
|
||
limit: Int! = 50
|
||
projectId: ID!
|
||
): [Activity!]!
|
||
automations(projectId: ID!): [Automation!]!
|
||
|
||
"""
|
||
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
|
||
|
||
"""
|
||
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!]!
|
||
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
|
||
}
|
||
|
||
"""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!
|
||
}
|
||
|
||
"""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 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!
|
||
}
|
||
|
||
"""
|
||
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
|
||
} |