feat: mentions and following tickets
Mention project members in comments with @, follow and unfollow tickets, and get told when something changes on the tickets you follow. Commenting on a ticket starts following it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1719,6 +1719,207 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/issues/{issue}/watch": {
|
||||
"put": {
|
||||
"description": "Followers are told when it moves, is reassigned or gets a comment. Commenting follows it too.",
|
||||
"operationId": "IssuesController_watch",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "issue",
|
||||
"required": true,
|
||||
"in": "path",
|
||||
"description": "Ticket id or key",
|
||||
"schema": {
|
||||
"example": "WEB-12",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/CommandResultDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid input",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Missing or rejected Pireon token",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Not a member of the project (or not allowed)",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not found",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"409": {
|
||||
"description": "Someone changed it at the same time: retry",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Business rule (e.g. a transition the workflow forbids)",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"pireon-oauth": []
|
||||
},
|
||||
{
|
||||
"pireon": []
|
||||
}
|
||||
],
|
||||
"summary": "Follow a ticket (members, viewers included)",
|
||||
"tags": [
|
||||
"Issues"
|
||||
]
|
||||
},
|
||||
"delete": {
|
||||
"operationId": "IssuesController_unwatch",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "issue",
|
||||
"required": true,
|
||||
"in": "path",
|
||||
"description": "Ticket id or key",
|
||||
"schema": {
|
||||
"example": "WEB-12",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/CommandResultDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid input",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Missing or rejected Pireon token",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Not a member of the project (or not allowed)",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not found",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"409": {
|
||||
"description": "Someone changed it at the same time: retry",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Business rule (e.g. a transition the workflow forbids)",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ApiErrorDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"pireon-oauth": []
|
||||
},
|
||||
{
|
||||
"pireon": []
|
||||
}
|
||||
],
|
||||
"summary": "Stop following a ticket",
|
||||
"tags": [
|
||||
"Issues"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/me/issues": {
|
||||
"get": {
|
||||
"description": "Assigned to me by default; with assignedToMe=false, any ticket of my projects (e.g. waiting for QA).",
|
||||
@@ -6132,6 +6333,13 @@
|
||||
"$ref": "#/components/schemas/AttachmentDto"
|
||||
}
|
||||
},
|
||||
"watchers": {
|
||||
"description": "People following it",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/UserRefDto"
|
||||
}
|
||||
},
|
||||
"commentCount": {
|
||||
"type": "number"
|
||||
},
|
||||
@@ -6170,6 +6378,7 @@
|
||||
"dueDate",
|
||||
"links",
|
||||
"attachments",
|
||||
"watchers",
|
||||
"commentCount",
|
||||
"createdAt",
|
||||
"updatedAt",
|
||||
|
||||
@@ -220,6 +220,9 @@ type Issue {
|
||||
type: String!
|
||||
updatedAt: String!
|
||||
version: Int!
|
||||
|
||||
"""People following the ticket"""
|
||||
watchers: [UserRef!]!
|
||||
}
|
||||
|
||||
type IssueChange {
|
||||
@@ -359,6 +362,9 @@ type Mutation {
|
||||
"""Put a ticket in a release (null removes it)"""
|
||||
setIssueRelease(issueId: ID!, releaseId: ID): CommandResult!
|
||||
unlinkIssues(input: LinkIssuesInput!): CommandResult!
|
||||
|
||||
"""Stop following a ticket"""
|
||||
unwatchIssue(issueId: ID!): CommandResult!
|
||||
updateIssue(input: UpdateIssueInput!): CommandResult!
|
||||
updateNotificationSettings(email: Boolean!): NotificationSettings!
|
||||
updateProject(input: UpdateProjectInput!): CommandResult!
|
||||
@@ -368,6 +374,11 @@ type Mutation {
|
||||
"""
|
||||
updateProjectSettings(projectId: ID!, settings: ProjectSettingsInput!): CommandResult!
|
||||
updateRelease(input: UpdateReleaseInput!): CommandResult!
|
||||
|
||||
"""
|
||||
Follow a ticket: be told when it moves, is reassigned or gets a comment
|
||||
"""
|
||||
watchIssue(issueId: ID!): CommandResult!
|
||||
}
|
||||
|
||||
type MyNotifications {
|
||||
|
||||
@@ -301,6 +301,27 @@ export interface paths {
|
||||
patch: operations["ProjectsController_changeMemberRole"];
|
||||
trace?: never;
|
||||
};
|
||||
"/api/issues/{issue}/watch": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
/**
|
||||
* Follow a ticket (members, viewers included)
|
||||
* @description Followers are told when it moves, is reassigned or gets a comment. Commenting follows it too.
|
||||
*/
|
||||
put: operations["IssuesController_watch"];
|
||||
post?: never;
|
||||
/** Stop following a ticket */
|
||||
delete: operations["IssuesController_unwatch"];
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/me/issues": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
@@ -1093,6 +1114,8 @@ export interface components {
|
||||
dueDate: string | null;
|
||||
links: components["schemas"]["IssueLinkDto"][];
|
||||
attachments: components["schemas"]["AttachmentDto"][];
|
||||
/** @description People following it */
|
||||
watchers: components["schemas"]["UserRefDto"][];
|
||||
commentCount: number;
|
||||
/** Format: date-time */
|
||||
createdAt: string;
|
||||
@@ -2632,6 +2655,158 @@ export interface operations {
|
||||
};
|
||||
};
|
||||
};
|
||||
IssuesController_watch: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
/** @description Ticket id or key */
|
||||
issue: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["CommandResultDto"];
|
||||
};
|
||||
};
|
||||
/** @description Invalid input */
|
||||
400: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Missing or rejected Pireon token */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Not a member of the project (or not allowed) */
|
||||
403: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Not found */
|
||||
404: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Someone changed it at the same time: retry */
|
||||
409: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Business rule (e.g. a transition the workflow forbids) */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
IssuesController_unwatch: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
/** @description Ticket id or key */
|
||||
issue: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["CommandResultDto"];
|
||||
};
|
||||
};
|
||||
/** @description Invalid input */
|
||||
400: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Missing or rejected Pireon token */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Not a member of the project (or not allowed) */
|
||||
403: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Not found */
|
||||
404: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Someone changed it at the same time: retry */
|
||||
409: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
/** @description Business rule (e.g. a transition the workflow forbids) */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ApiErrorDto"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
IssuesController_mine: {
|
||||
parameters: {
|
||||
query?: {
|
||||
|
||||
Reference in New Issue
Block a user