現在、機能なしで実行できるWebサービスやアプリケーションはほとんどありません。テキストの文法エラー、誤った表現、興味のない、または有益ではないコンテンツ(演習、レッスン、記事など)であっても、ユーザーはさまざまなタイプのコンテンツに不満(通知、レポート)を出すことができます。、トレーニング資料または機能の一部)。 「問題を報告する」ことができることは、製品にユーザーを引き込み、フィードバック収集の形式を実装し、アプリケーション全体を改善することができるために不可欠です。
すべてのユーザーの苦情はどこかに保存され、優先順位が付けられ、簡単に追跡され、さらに時間どおりに処理される必要があります。しかし、バックログには常に優先度の高いタスクが存在するため、このようなシステムの開発と保守に十分なリソースを割り当てることが常に可能とは限りません。以下では、JIRA REST APIを使用して、Uxcelでこの問題を効率的かつ迅速に解決した方法を説明します。
「問題を報告する」必要があるのはなぜですか?
— ?
Uxcel — - UI/UX . “” — 2 , , — . . (hint — ) (description) , .
— , - , - , , . “ ” , , . , , , , .
, backlog-, , JIRA + REST API.
JIRA
1 BUG JIRA Practices Reports. -. , Label ( : Course, Gym, UEye). :
, - ( ) .
.
JIRA REST API
API token JIRA, JIRA API. , , .
API :
- -> Create
. - , .
API JIRA. , ( ) — HTTP basic authentication.
( TypeScript NodeJS):
private generateAuthHeader(): string {
// email:apiToken Base64
const basicAuthValue = Buffer.from(`${this.jiraEmail}:${this.jiraApiToken}`).toString('base64');
return `Basic ${basicAuthValue}`;
}
: AWS Secrets Manager. . .
API
. , Issue ID JIRA. — GET :
GET https://{id}.atlassian.net/rest/api/3/issuetype
, Postman:
Authorization Type: Basic Auth, email api token.
:
{
"self": "https://{id}.atlassian.net/rest/api/3/issuetype/10004",
"id": "10001",
"description": "A problem or error.",
"iconUrl": "https://${id}.atlassian.net/secure/viewavatar?size=medium&avatarId=10303&avatarType=issuetype",
"name": "Bug",
"untranslatedName": "Bug",
"subtask": false,
"avatarId": 10303
}
Issue Id BUG (“10001”) Project Id, . id .
GET
GET https://{id}.atlassian.net/rest/api/3/project/search
: , (Jira Epic). id , Key ( , , UX-1).
API.
npm Got HTTP NodeJS.
await got.post({
url: `${this.jiraApiHost}/issue`, // jiraApiHost = https://{id}.atlassian.net/rest/api/3
headers: {
Authorization: authorization, // Basic Auth Header generateAuthHeader
'Content-Type': 'application/json'
},
responseType: 'json',
json: {
update: {},
fields: {
issuetype: { id: this.jiraBugTypeId }, // id BUG ( - ‘10001’)
project: { id: this.jiraPracticeReportProjectId }, // id ( - ‘10005’)
parent: { key: this.jiraPracticeReportEpicKey }, // Epic ( - UX-1)
summary: practiceTicketName, // - [practiceId] practiceName (#reports)
labels: [practice.label]
}
}
});
. JIRA, : , , , .
API
API . , , .
:
// JQL , BUG id ( )
const jql = `issuetype = Bug AND project = CNT AND parent = ${this.jiraEpicKey} AND text ~ "${practiceId}" order by created DESC`;
const response = await got.get({
url: `${this.jiraApiHost}/search?jql=${jql}`,
headers: {
Authorization: authorization
},
responseType: 'json'
});
const practiceJiraTicket = response.body['issues'] && response.body['issues'][0];
, , CLOSED.
API
, Transitions. Status ID TODO / OPENED ( JIRA).
Postman:
GET https://{id}.atlassian.net/rest/api/3/project/{projectIdOrKey}/statuses
id , , id.
:
await got.post({
url: `${this.jiraApiHost}/issue/${practiceJiraTicket.key}/transitions`, // practiceJiraTicket -
headers: {
Authorization: authorization,
'Content-Type': 'application/json'
},
responseType: 'json',
json: {
transition: {
id: this.jiraToDoStatusId // id ( - ‘10006’)
}
}
});
— ( , ).
API
, id . . , n — .
API :
await got.put({
url: `${this.jiraApiHost}/issue/${practiceJiraTicket.key}`,
headers: {
Authorization: authorization,
'Content-Type': 'application/json'
},
responseType: 'json',
json: {
update: {
summary: [{ set: newPracticeTicketName }]
}
}
});
.
API
-.
:
await got.post({
url: `${this.jiraApiHost}/issue/${practiceJiraTicket.key}/comment`,
headers: {
Authorization: authorization,
'Content-Type': 'application/json'
},
responseType: 'json',
json: comment //
});
comment Atlassian Document Format.
Builder, : — JSON .
! , , , JIRA.
:
JIRA ( id, #N — , % — ):
. , :
- , JIRA ( AWS SNS)
- priority
- Slack (slack/webhook — )
- JIRA Webhooks, ,
- , .
! , :)
!