# ------------------------------------------------------ # 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! } type BoardColumn { issues: [Issue!]! status: IssueStatus! total: Int! } input ChangeIssueStatusInput { issueId: ID! """ Required for QA_FAILED and CANCELLED """ reason: String status: IssueStatus! } """ 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! key: IssueStatus! } input CreateIssueInput { area: IssueArea assigneeId: ID description: String dueDate: String """ Figma frame for UI changes """ figmaUrl: String labels: [String!] priority: IssuePriority projectId: ID! releaseId: ID storyPoints: Int title: String! type: IssueType! } input CreateProjectInput { description: String """ 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 } type Issue { """ Statuses this ticket can move to next """ allowedTransitions: [IssueStatus!]! area: IssueArea assignee: UserRef 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! priority: IssuePriority! projectId: ID! projectKey: String! release: ReleaseRef reporter: UserRef! status: IssueStatus! storyPoints: Int title: String! type: IssueType! updatedAt: String! version: Int! } """ Team/layer: links FE ↔ BE ↔ QA work """ enum IssueArea { BACKEND DESIGN DEVOPS FRONTEND MOBILE QA } type IssueChange { action: String! actorId: ID! issue: Issue! version: Int! } input IssueFilterInput { areas: [IssueArea!] assigneeId: ID labels: [String!] priorities: [IssuePriority!] projectId: ID! releaseId: ID """ Matches key, title or description """ search: String statuses: [IssueStatus!] types: [IssueType!] 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! } enum IssuePriority { CRITICAL HIGH LOW LOWEST MEDIUM } enum IssueStatus { BACKLOG CANCELLED DONE IN_PROGRESS IN_QA IN_REVIEW QA_FAILED READY_FOR_QA TODO } enum IssueType { BUG FEATURE QA TASK UI_CHANGE } 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 { 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! createIssue(input: CreateIssueInput!): CommandResult! createProject(input: CreateProjectInput!): CommandResult! createRelease(input: CreateReleaseInput!): CommandResult! """ Author or project admin """ deleteComment(commentId: ID!): CommandResult! editComment(body: String!, commentId: ID!): CommandResult! """ Relate tickets, e.g. FE DEPENDS_ON BE, QA TESTS FE """ linkIssues(input: LinkIssuesInput!): CommandResult! """ Ship the release. Fails while it has unfinished tickets unless force = true. """ publishRelease(force: Boolean! = false, releaseId: ID!): CommandResult! removeProjectMember(projectId: ID!, userId: ID!): CommandResult! """ Put a ticket in a release (null removes it) """ setIssueRelease(issueId: ID!, releaseId: ID): CommandResult! unlinkIssues(input: LinkIssuesInput!): CommandResult! updateIssue(input: UpdateIssueInput!): CommandResult! updateProject(input: UpdateProjectInput!): CommandResult! updateRelease(input: UpdateReleaseInput!): CommandResult! } type Project { """ Kanban board, one column per status """ board( area: IssueArea assigneeId: ID perColumn: Int! = 50 releaseId: ID ): [BoardColumn!]! createdAt: String! description: String id: ID! key: String! members: [ProjectMember!]! name: String! owner: UserRef! releases: [Release!]! """ Project tracking dashboard """ stats: ProjectStats! updatedAt: String! version: Int! } 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 } type ProjectStats { byArea: [CountByKey!]! """ Open tickets per person """ byAssignee: [CountByAssignee!]! byPriority: [CountByKey!]! byStatus: [CountByStatus!]! byType: [CountByKey!]! open: Int! total: Int! } type Query { """ Project activity feed (newest first) """ activity( """ ISO date cursor """ before: String issueId: ID limit: Int! = 50 projectId: ID! ): [Activity!]! 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! """ Projects where I am a member """ myProjects: [Project!]! project( """ Project id or key (e.g. "TS") """ idOrKey: String! ): Project! release(id: ID!): Release! user(id: String!): User """ Search users by name or email (to assign / add members) """ users(limit: Int! = 20, search: String! = ""): [User!]! } type Release { 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 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 } 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! projectChanged(projectId: ID!): ProjectChange! releaseChanged(projectId: ID!): ReleaseChange! } input UpdateIssueInput { area: IssueArea description: String dueDate: String """ Figma frame for UI changes """ figmaUrl: String issueId: ID! labels: [String!] priority: IssuePriority storyPoints: Int title: String type: IssueType } input UpdateProjectInput { description: String name: String projectId: ID! } input UpdateReleaseInput { description: String name: String releaseId: ID! targetDate: String } """ User managed by the Pireon identity server """ type User { email: String! id: ID! isActive: Boolean! name: String! } type UserRef { id: ID! name: String! }