Files
task-stream/apps/api/schema.gql
Josep Piguillem 8994590b54 feat: automation rules
Owners and admins can set rules of the kind «when a ticket is created,
moves, gets assigned, gets a comment or its pull request merges; if it is
of this type, priority, area or label; then move it, assign it, label it,
change its priority, comment or put it in the active sprint». Rules act as
TaskStream within the workflow, run once per event and trigger no others.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 15:53:31 +02:00

1251 lines
25 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!
}
"""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 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 CreateAutomationInput {
action: AutomationActionInput!
conditions: AutomationConditionsInput
name: String!
projectId: ID!
trigger: AutomationTriggerInput!
}
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!
}
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 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!
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!
}
type FlowSeries {
counts: [Int!]!
status: String!
}
"""
Webhook from GitHub, Gitea or GitLab: commits, branches and pull requests naming a ticket key are linked to it
"""
type GitIntegration {
enabled: Boolean!
"""Webhook secret; only owners and admins see it"""
secret: String
"""Path of the webhook on this API"""
webhookPath: 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
"""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
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!
"""
Add a rule. It acts as TaskStream, within the workflow, and what it does triggers no other rule.
"""
createAutomation(input: CreateAutomationInput!): Automation!
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 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!
disableGitIntegration(projectId: ID!): Boolean!
editComment(body: String!, commentId: ID!): CommandResult!
"""Turn the Git webhook on, with a new secret (also to rotate it)"""
enableGitIntegration(projectId: ID!): GitIntegration!
"""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!
"""Send a ping now and tell how it went"""
testWebhook(webhookId: ID!): WebhookDelivery!
unlinkIssues(input: LinkIssuesInput!): CommandResult!
"""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!
"""
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!
}
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!]!
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!
"""
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!]!
"""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!
}
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
}
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
}