> ## Documentation Index
> Fetch the complete documentation index at: https://docs.legitmark.com/llms.txt
> Use this file to discover all available pages before exploring further.

# ワークフロー

> サービスリクエスト作成から画像アップロードと検証までのステップバイステッププロセス。

## ステップバイステップ実装

<Steps>
  <Step title="サービスリクエストを作成">
    アイテムが認証の準備ができたら、サービスリクエストを作成します。これにより、選択したアイテムカテゴリの具体的な画像要件が提供されます。

    **API リファレンス：** [`POST /api/v2/sr`](/api-reference#tag/Service-Requests/operation/initiate-service-request)

    **必須ヘッダー：**

    ```javascript theme={null}
    const headers = {
      'Authorization': 'Bearer leo_xxxxxxxxx',      // API キー
      'Content-Type': 'application/json'
    };
    ```

    **リクエストデータ：**

    * **サービス UUID**（オプション）：パートナーサービス識別子。省略した場合、組織とアイテムタイプに基づいて自動的に解決されます。
    * **アイテムタクソノミー**：タクソノミーマッピングからのカテゴリ、タイプ、ブランド UUID
    * **外部 ID**（オプション）：相関用の内部アイテム識別子

    <CodeGroup>
      ```javascript HTTP theme={null}
      const response = await fetch('https://api.legitmark.com/api/v2/sr', {
        method: 'POST',
        headers,
        body: JSON.stringify({
          // service はオプション - 省略した場合は自動解決
          external_id: 'your-internal-ref-123',
          item: {
            category: 'category-uuid',
            type: 'type-uuid',
            brand: 'brand-uuid',
          }
        })
      });
      ```

      ```typescript SDK theme={null}
      const { sr } = await legitmark.sr.create({
        // service はオプション - 省略した場合は自動解決
        external_id: 'your-internal-ref-123',
        item: {
          category: 'category-uuid',
          type: 'type-uuid',
          brand: 'brand-uuid',
        },
      });
      ```
    </CodeGroup>

    **依存関係：**

    * タクソノミーマッピングが設定済み（[タクソノミー](/ja/partner/taxonomy)を参照）
  </Step>

  <Step title="画像要件を取得">
    アイテムカテゴリに必要な具体的な画像面を取得します。これにより、どの写真を撮影する必要があるかがわかります。

    **API リファレンス：** [`GET /api/v2/sr/{sr_uuid}`](/api-reference#tag/Service-Requests/operation/get-service-request) クエリパラメータ付き

    `requirements=true` と `sides=true` でサービスリクエストを取得して、完全な画像要件を取得します：

    <CodeGroup>
      ```javascript HTTP theme={null}
      const response = await fetch(
        `https://api.legitmark.com/api/v2/sr/${srUuid}?requirements=true&sides=true&item=true`,
        { headers }
      );
      const { sr } = await response.json();

      // sr.requirements にはサイドグループと必須/オプションサイドが含まれます
      for (const group of sr.requirements.side_groups) {
        for (const side of group.sides) {
          console.log(`${side.name}: ${side.required ? '必須' : 'オプション'}`);
        }
      }
      ```

      ```typescript SDK theme={null}
      const { sr } = await legitmark.sr.getWithRequirements(srUuid);

      console.log(`必須写真: ${sr.requirements?.total_required}`);

      for (const group of sr.requirements?.side_groups || []) {
        for (const side of group.sides) {
          console.log(`${side.name}: ${side.required ? '必須' : 'オプション'}`);
        }
      }
      ```
    </CodeGroup>

    **レスポンスデータ：**

    * **サイドグループ** - グループ別に整理された画像要件
    * **必須サイド** - 認証に必須の画像
    * **オプションサイド** - 認証を強化する追加画像
    * **テンプレート画像** - 各必須角度のビジュアルガイド

    **画像要件：**

    * **形式：** JPG/JPEG/PNG
    * **サイズ：** 最小 600 x 600 ピクセル
    * **ファイルサイズ：** 画像あたり最大 5 MB
    * **品質：** 鮮明で、十分な照明、ピントが合った画像
  </Step>

  <Step title="画像をアップロード">
    Legitmark のセキュア CDN システムを使用して画像をアップロードします。各必須サイドごとに、署名付き URL を取得して S3 に直接アップロードします。

    **API リファレンス：** メディア管理エンドポイント

    * [`GET https://asset.legitmark.com/intent`](/api-reference/media-management/generate-upload-url) - 署名付きアップロード URL を取得
    * [`PUT /{presigned-url}`](/api-reference/media-management/upload-image) - 直接 S3 アップロード

    **アップロードプロセス：**

    1. **アップロード URL を取得**、クエリパラメータ付き：`sr`（サービスリクエスト UUID）と `side`（ファイル拡張子付きサイド UUID）
    2. **直接アップロード**署名付き S3 URL に PUT リクエストとバイナリデータで

    <CodeGroup>
      ```javascript HTTP theme={null}
      // ステップ 1：署名付きアップロード URL を取得
      const intentResponse = await fetch(
        `https://asset.legitmark.com/intent?sr=${srUuid}&side=${sideUuid}.jpg`,
        { headers }
      );
      const { url: presignedUrl } = await intentResponse.json();

      // ステップ 2：署名付き URL にバイナリ画像データをアップロード
      await fetch(presignedUrl, {
        method: 'PUT',
        body: imageFile,
        headers: { 'Content-Type': 'image/jpeg' }
      });
      ```

      ```typescript SDK theme={null}
      // ファイルパスからアップロード
      await legitmark.images.uploadForSide(srUuid, sideUuid, './photo.jpg');

      // またはバッファからアップロード
      await legitmark.images.uploadForSide(srUuid, sideUuid, imageBuffer);
      ```
    </CodeGroup>
  </Step>

  <Step title="進捗を確認">
    提出前にすべての必須画像がアップロードされていることを確認します。

    `sides=true` でサービスリクエストを取得して、アップロード済みの必須およびオプション画像の数を含む現在の進捗を取得します：

    <CodeGroup>
      ```javascript HTTP theme={null}
      const response = await fetch(
        `https://api.legitmark.com/api/v2/sr/${srUuid}?sides=true`,
        { headers }
      );
      const { sr } = await response.json();

      const progress = sr.sides.progress;
      console.log(`アップロード済み: ${progress.current_required}/${progress.total_required}`);
      console.log(`提出準備完了: ${progress.met}`);
      ```

      ```typescript SDK theme={null}
      const progress = await legitmark.sr.getProgress(srUuid);

      console.log(`アップロード済み: ${progress.current_required}/${progress.total_required}`);
      console.log(`提出準備完了: ${progress.met}`);
      ```
    </CodeGroup>

    **進捗レスポンス：**

    ```json theme={null}
    {
      "current_required": 2,
      "total_required": 2,
      "current_optional": 1,
      "total_optional": 3,
      "met": true
    }
    ```

    `met` が `true` の場合、すべての必須画像がアップロードされ、サービスリクエストを提出できます。
  </Step>

  <Step title="認証のために提出">
    進捗要件が満たされたら、サービスリクエストを専門家認証に提出します。

    **API リファレンス：** [`POST /api/v2/sr/{sr_uuid}/submit`](/api-reference#tag/Service-Requests/operation/submit-service-request)

    <CodeGroup>
      ```javascript HTTP theme={null}
      const response = await fetch(
        `https://api.legitmark.com/api/v2/sr/${srUuid}/submit`,
        { method: 'POST', headers }
      );
      const { sr } = await response.json();
      console.log(`提出完了！ 状態: ${sr.state.primary}/${sr.state.supplement}`);
      ```

      ```typescript SDK theme={null}
      const progress = await legitmark.sr.getProgress(srUuid);

      if (progress.met) {
        const { sr } = await legitmark.sr.submit(srUuid);
        console.log(`提出完了！ 状態: ${sr.state.primary}/${sr.state.supplement}`);
      }
      ```
    </CodeGroup>

    **提出後のプロセス：**

    1. **品質管理レビュー**：画像とデータの検証
    2. **認証レビュー**：専門家による認証
    3. **結果通知**：各段階での Webhook 更新（[ステータス](/ja/partner/service-request-states)を参照）
  </Step>
</Steps>

## 実装パターン

### エラー処理

```javascript theme={null}
async function createServiceRequest(itemData) {
  try {
    const response = await fetch('/api/v2/sr', {
      method: 'POST',
      headers,
      body: JSON.stringify(itemData)
    });

    if (!response.ok) {
      const error = await response.json();
      throw new Error(`サービスリクエスト失敗: ${error.message}`);
    }

    return await response.json();
  } catch (error) {
    console.error('サービスリクエストの作成に失敗:', error);
    // 再試行ロジックまたはユーザー通知を実装
  }
}
```

### 進捗追跡

```javascript theme={null}
class AuthenticationProgress {
  constructor(srUuid) {
    this.srUuid = srUuid;
    this.steps = {
      created: false,
      requirements_fetched: false,
      images_uploaded: false,
      validated: false,
      finalized: false
    };
  }

  async checkProgress() {
    const response = await fetch(`/api/side-groups/progress?sr_id=${this.srUuid}`, {
      headers
    });
    const data = await response.json();
    
    this.steps.validated = data.progress.met;
    return this.steps;
  }
}
```

## ベストプラクティス

### 販売前の最適化

* 頻繁に使用されるカテゴリの**画像要件をキャッシュ**
* 保存前に**クライアント側で画像を検証**
* 品質基準を維持しながら**画像を圧縮**
* アイテムが販売されるまで**画像をローカルに保存**

### アップロードの最適化

* 複数画像には**並列アップロードを使用**
* 失敗したアップロードには**再試行ロジックを実装**
* ユーザーに**アップロード進捗を表示**
* 続行前に**アップロード完了を確認**

## 次のステップ

ワークフロー実装が完了したら：

1. **設定** [Webhooks](/ja/webhook-reference/introduction) - Webhook 通知とステータス更新処理
2. サンプルアイテムで**エンドツーエンドの**ワークフローをテスト
3. 認証処理と成功率を**監視**
