---
title: 修正作業とPR
description: フィードバックから修正作業を作成し、GitHub PRを関連付け、安全に再試行する方法です。
---

# 修正作業とPR {#change-requests-and-prs}

修正作業はフィードバックID、修正指示、完了条件、PR URLを記録します。作成には`work-items:write`、参照には`work-items:read`が必要です。

## 修正作業を作成する {#create-a-change-request}

```http
POST /api/v1/apps/:appId/automation/change-requests
Content-Type: application/json
```

| フィールド | 必須 | 制約 |
| --- | --- | --- |
| `title` | 必須 | 前後空白除去後1–160文字 |
| `instructions` | 必須 | 前後空白除去後1–10000文字 |
| `acceptanceCriteria` | 任意 | 前後空白除去後最大10000文字。既定は空文字列 |
| `issueIds` | 必須 | 同じアプリの重複しないフィードバックUUID 1–20件 |
| `clientRequestId` | 必須 | 作成リクエストを識別するUUID |

フィードバックIDは実際のIDに置き換えます。新規作成前に`clientRequestId`を生成し、応答が不明な場合の再試行でも維持します。

```sh
curl --fail-with-body \
  "$OPENTESTER_API_URL/apps/$OPENTESTER_APP_ID/automation/change-requests" \
  --header "Authorization: Bearer $OPENTESTER_AGENT_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "title": "保存直後の一覧更新を修正",
    "instructions": "保存成功後に一覧を更新し、重複追加を防ぎます。",
    "acceptanceCriteria": "新しい項目がすぐに一度だけ表示され、画面を開き直しても残ります。",
    "issueIds": ["bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb"],
    "clientRequestId": "dddddddd-dddd-4ddd-8ddd-dddddddddddd"
  }'
```

`201`応答の例です。

```json
{
  "changeRequest": {
    "id": "cccccccc-cccc-4ccc-8ccc-cccccccccccc",
    "appId": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
    "title": "保存直後の一覧更新を修正",
    "instructions": "保存成功後に一覧を更新し、重複追加を防ぎます。",
    "acceptanceCriteria": "新しい項目がすぐに一度だけ表示され、画面を開き直しても残ります。",
    "issueIds": ["bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb"],
    "status": "open",
    "pullRequestUrl": null,
    "createdBy": "eeeeeeee-eeee-4eee-8eee-eeeeeeeeeeee",
    "createdAt": "2026-10-28T02:00:00.000Z",
    "updatedAt": "2026-10-28T02:00:00.000Z"
  }
}
```

### 重複作成を防ぐ {#prevent-duplicate-creation}

サーバーはアプリ・作成者・`clientRequestId`で識別します。同じ所有者の別トークンで再試行しても同じ基準です。

- 同じIDと内容: 既存の作業を返します。
- 同じIDで異なる内容: `409 Conflict`です。
- 異なるID: 同じ内容・フィードバックでも新しい作業を作成します。

比較時に前後空白を除去し、UUIDを小文字にし、`issueIds`を並べ替えます。配列順だけが違う再試行は同一です。作業のロックや自動統合ではないため、作成前に既存作業を確認します。

## 一覧と詳細を取得する {#list-and-retrieve-requests}

```http
GET /api/v1/apps/:appId/automation/change-requests?limit=20&offset=0
GET /api/v1/apps/:appId/automation/change-requests/:requestId
```

一覧は新しい順です。`limit`は既定20・最大50、`offset`は既定0・最大100000です。状態フィルターはありません。各項目は作成結果と同じ構造です。

```json
{
  "changeRequests": [],
  "total": 0,
  "limit": 20,
  "offset": 0
}
```

```sh
export CHANGE_REQUEST_ID="cccccccc-cccc-4ccc-8ccc-cccccccccccc"

curl --fail-with-body \
  "$OPENTESTER_API_URL/apps/$OPENTESTER_APP_ID/automation/change-requests/$CHANGE_REQUEST_ID" \
  --header "Authorization: Bearer $OPENTESTER_AGENT_TOKEN"
```

詳細は`200`と`{ "changeRequest": { ... } }`を返します。対象アプリに作業がなければ`404`です。

## PRを関連付ける {#attach-a-pr}

実装・テスト後、`work-items:write`で既存のGitHub PR URLを関連付けます。

```http
POST /api/v1/apps/:appId/automation/change-requests/:requestId/pull-request
Content-Type: application/json
```

```sh
curl --fail-with-body \
  "$OPENTESTER_API_URL/apps/$OPENTESTER_APP_ID/automation/change-requests/$CHANGE_REQUEST_ID/pull-request" \
  --header "Authorization: Bearer $OPENTESTER_AGENT_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{"url":"https://github.com/your-org/your-app/pull/42"}'
```

`201`応答の`changeRequest`には更新されたオブジェクトが入り、`status`は`pr_linked`、`pullRequestUrl`は保存されたURLになります。

| 規則 | 動作 |
| --- | --- |
| 許可URL | `https://github.com/{owner}/{repo}/pull/{number}` |
| PR番号 | 先頭ゼロなしの正の整数、最大10桁 |
| 追加URL要素 | query、fragment、認証情報、ポートは不可 |
| 正規化 | owner/repoを小文字化し、末尾スラッシュを除去 |
| 同じURLの再送 | 既存作業を返す。再試行可能 |
| 別のURL | `409`。1作業につきPRは1件 |

GitHub.comのみ対応し、GitLabやGitHub Enterpriseの別ホストは未対応です。

::: info PR関連付けの意味
サーバーはURLを検証して保存します。PRの存在、アクセス権、CI、マージ状態はGitHubで確認します。`pr_linked`は修正完了を意味しません。PR作成・マージ、Playデプロイ、フィードバック状態変更、報酬付与は行いません。
:::

## 修正作業オブジェクト {#change-request-object}

| フィールド | 型 | 意味 |
| --- | --- | --- |
| `id`, `appId` | UUID | 作業とアプリのID |
| `title`, `instructions`, `acceptanceCriteria` | string | タイトル、修正指示、完了条件 |
| `issueIds` | UUID[] | 並べ替え済みの関連フィードバックID |
| `status` | `open` \| `pr_linked` | 作成済みまたはPR関連付け済み |
| `pullRequestUrl` | string \| null | 関連付け前は`null` |
| `createdBy` | UUID | 作業を作成したアプリ所有者 |
| `createdAt`, `updatedAt` | ISO 8601 string | 作成・最終更新日時 |

本文の編集・削除、PRの交換・解除、実行担当者の割り当てAPIは現在ありません。
