Files
task-stream/apps/api/schema.gql
2026-10-03 13:40:26 +02:00

563 lines
9.0 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!
}
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!
}