# ------------------------------------------------------ # 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 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 """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 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! } input WorkflowStatusInput { archived: Boolean! = false category: StatusCategory! color: String! id: String! name: String! requiresReason: Boolean! = false }