Tickets get a start date next to their due date, both editable on the ticket page. The Hoja de ruta tab lays the epics out over the months as bars filled with their progress, with sprints and releases as landmarks and a line for today. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1038 lines
21 KiB
GraphQL
1038 lines
21 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 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!
|
|
}
|
|
|
|
type BoardColumn {
|
|
issues: [Issue!]!
|
|
status: String!
|
|
total: Int!
|
|
}
|
|
|
|
input ChangeIssueStatusInput {
|
|
issueId: ID!
|
|
|
|
"""Required by statuses with requiresReason"""
|
|
reason: String
|
|
|
|
"""A status id"""
|
|
status: 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!
|
|
body: String!
|
|
createdAt: String!
|
|
editedAt: String
|
|
id: ID!
|
|
issueId: 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!
|
|
}
|
|
|
|
type CountByAssignee {
|
|
count: Int!
|
|
|
|
"""Null = unassigned"""
|
|
user: UserRef
|
|
}
|
|
|
|
type CountByKey {
|
|
count: Int!
|
|
key: String!
|
|
}
|
|
|
|
type CountByStatus {
|
|
count: Int!
|
|
|
|
"""Status id"""
|
|
key: String!
|
|
}
|
|
|
|
input CreateIssueInput {
|
|
"""An area id"""
|
|
area: String
|
|
assigneeId: ID
|
|
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
|
|
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!
|
|
}
|
|
|
|
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!
|
|
}
|
|
|
|
type CreatedResolved {
|
|
created: Int!
|
|
resolved: Int!
|
|
|
|
"""Monday of the week (YYYY-MM-DD)"""
|
|
week: String!
|
|
}
|
|
|
|
type CumulativeFlow {
|
|
dates: [String!]!
|
|
series: [FlowSeries!]!
|
|
}
|
|
|
|
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!
|
|
}
|
|
|
|
type FlowSeries {
|
|
counts: [Int!]!
|
|
status: String!
|
|
}
|
|
|
|
type Issue {
|
|
"""Statuses this ticket can move to next (project's workflow)"""
|
|
allowedTransitions: [String!]!
|
|
|
|
"""An area id"""
|
|
area: String
|
|
assignee: UserRef
|
|
attachments: [Attachment!]!
|
|
checklist: [ChecklistItem!]!
|
|
commentCount: Int!
|
|
comments(limit: Int! = 50, offset: Int! = 0): CommentPage!
|
|
createdAt: String!
|
|
description: String
|
|
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
|
|
title: String!
|
|
|
|
"""A ticket type id of the project's settings"""
|
|
type: String!
|
|
updatedAt: String!
|
|
version: 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!]
|
|
labels: [String!]
|
|
|
|
"""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!]
|
|
types: [String!]
|
|
unassigned: 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
|
|
}
|
|
|
|
type IssueTypeOption {
|
|
archived: Boolean!
|
|
color: String!
|
|
icon: String!
|
|
id: String!
|
|
name: String!
|
|
}
|
|
|
|
input IssueTypeOptionInput {
|
|
archived: Boolean! = false
|
|
color: String!
|
|
icon: String!
|
|
id: String!
|
|
name: 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!
|
|
addComment(body: String!, issueId: ID!): CommandResult!
|
|
|
|
"""Add a Pireon user to the project"""
|
|
addProjectMember(input: ProjectMemberInput!): CommandResult!
|
|
archiveRelease(releaseId: ID!): CommandResult!
|
|
|
|
"""Assign (or unassign with null) a project member"""
|
|
assignIssue(assigneeId: ID, issueId: ID!): CommandResult!
|
|
|
|
"""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!
|
|
createIssue(input: CreateIssueInput!): CommandResult!
|
|
createProject(input: CreateProjectInput!): CommandResult!
|
|
createRelease(input: CreateReleaseInput!): CommandResult!
|
|
|
|
"""Plan a sprint (owners and admins)"""
|
|
createSprint(input: CreateSprintInput!): CommandResult!
|
|
|
|
"""Author or project admin"""
|
|
deleteComment(commentId: ID!): CommandResult!
|
|
|
|
"""
|
|
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!
|
|
editComment(body: String!, commentId: ID!): CommandResult!
|
|
|
|
"""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!
|
|
|
|
"""
|
|
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!
|
|
removeProjectMember(projectId: ID!, userId: ID!): CommandResult!
|
|
|
|
"""Save the current board filters under a name (members of the project)"""
|
|
saveFilter(input: SaveFilterInput!): 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!
|
|
unlinkIssues(input: LinkIssuesInput!): CommandResult!
|
|
|
|
"""Stop following a ticket"""
|
|
unwatchIssue(issueId: ID!): CommandResult!
|
|
|
|
"""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!
|
|
|
|
"""
|
|
Follow a ticket: be told when it moves, is reassigned or gets a comment
|
|
"""
|
|
watchIssue(issueId: ID!): CommandResult!
|
|
}
|
|
|
|
type MyNotifications {
|
|
items: [Notification!]!
|
|
|
|
"""All my unread ones, not just these"""
|
|
unread: 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
|
|
QA_FAILED
|
|
REMINDER
|
|
STATUS_CHANGED
|
|
WATCHED
|
|
}
|
|
|
|
type NotificationSettings {
|
|
"""Copies by e-mail"""
|
|
email: Boolean!
|
|
|
|
"""Whether this installation can send e-mail at all"""
|
|
emailAvailable: Boolean!
|
|
}
|
|
|
|
type Project {
|
|
"""
|
|
Statistics of the last `days` days (7-365): created vs resolved, cumulative flow, cycle/lead time, throughput and QA
|
|
"""
|
|
analytics(days: Int! = 90): ProjectAnalytics!
|
|
|
|
"""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!
|
|
|
|
"""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!
|
|
}
|
|
|
|
type ProjectMember {
|
|
role: ProjectRole!
|
|
user: UserRef!
|
|
}
|
|
|
|
input ProjectMemberInput {
|
|
projectId: ID!
|
|
role: ProjectRole! = MEMBER
|
|
|
|
"""Pireon user id"""
|
|
userId: ID!
|
|
}
|
|
|
|
enum ProjectRole {
|
|
ADMIN
|
|
MEMBER
|
|
OWNER
|
|
VIEWER
|
|
}
|
|
|
|
"""Statuses (board order), transitions, ticket types and areas"""
|
|
type ProjectSettings {
|
|
areas: [AreaOption!]!
|
|
issueTypes: [IssueTypeOption!]!
|
|
statuses: [WorkflowStatus!]!
|
|
transitions: [StatusTransitions!]!
|
|
}
|
|
|
|
"""
|
|
The whole configuration (replaces the previous one). Statuses go in board order.
|
|
"""
|
|
input ProjectSettingsInput {
|
|
areas: [AreaOptionInput!]!
|
|
issueTypes: [IssueTypeOptionInput!]!
|
|
statuses: [WorkflowStatusInput!]!
|
|
transitions: [StatusTransitionsInput!]!
|
|
}
|
|
|
|
type ProjectStats {
|
|
byArea: [CountByKey!]!
|
|
|
|
"""Open tickets per person"""
|
|
byAssignee: [CountByAssignee!]!
|
|
byPriority: [CountByKey!]!
|
|
byStatus: [CountByStatus!]!
|
|
byType: [CountByKey!]!
|
|
open: Int!
|
|
total: Int!
|
|
}
|
|
|
|
type QaStats {
|
|
failed: Int!
|
|
failureRate: Float
|
|
passed: Int!
|
|
}
|
|
|
|
type Query {
|
|
"""Project activity feed (newest first)"""
|
|
activity(
|
|
"""ISO date cursor"""
|
|
before: String
|
|
issueId: ID
|
|
limit: Int! = 50
|
|
projectId: ID!
|
|
): [Activity!]!
|
|
|
|
"""
|
|
A project's epics: top-level tickets that group others, with the progress of those
|
|
"""
|
|
epics(projectId: ID!): [Epic!]!
|
|
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!
|
|
|
|
"""
|
|
Tickets across all my projects: assigned to me (default) or any (e.g. categories [QA])
|
|
"""
|
|
myIssues(assignedToMe: Boolean! = true, categories: [StatusCategory!], limit: Int! = 50, offset: Int! = 0, statuses: [String!]): 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!]!
|
|
notificationSettings: NotificationSettings!
|
|
|
|
"""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!]!
|
|
|
|
"""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!]!
|
|
}
|
|
|
|
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!
|
|
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!
|
|
}
|
|
|
|
type ReleaseProgress {
|
|
byStatus: [CountByStatus!]!
|
|
finished: Int!
|
|
percent: Int!
|
|
total: Int!
|
|
}
|
|
|
|
type ReleaseRef {
|
|
id: ID!
|
|
name: String!
|
|
}
|
|
|
|
enum ReleaseStatus {
|
|
ARCHIVED
|
|
PLANNED
|
|
RELEASED
|
|
}
|
|
|
|
input SaveFilterInput {
|
|
criteria: SavedFilterCriteriaInput!
|
|
name: String!
|
|
projectId: ID!
|
|
|
|
"""Visible to the whole project (members, not viewers, share)"""
|
|
shared: Boolean! = false
|
|
}
|
|
|
|
"""
|
|
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!
|
|
}
|
|
|
|
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 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 Throughput {
|
|
count: Int!
|
|
user: UserRef
|
|
week: String!
|
|
}
|
|
|
|
input UpdateChecklistItemInput {
|
|
done: Boolean
|
|
issueId: ID!
|
|
itemId: ID!
|
|
text: String
|
|
}
|
|
|
|
input UpdateIssueInput {
|
|
"""An area id"""
|
|
area: String
|
|
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
|
|
title: String
|
|
type: String
|
|
}
|
|
|
|
input UpdateProjectInput {
|
|
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
|
|
}
|
|
|
|
"""User managed by the Pireon identity server"""
|
|
type User {
|
|
email: String!
|
|
id: ID!
|
|
isActive: Boolean!
|
|
name: String!
|
|
}
|
|
|
|
type UserRef {
|
|
id: ID!
|
|
name: String!
|
|
}
|
|
|
|
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
|
|
} |