Skip to content
Back to skills

Documents

ASecurity

ファイル取込処理を非同期化する。APIは受信したファイル本体をオブジェクトストレージへ保存し、保存先情報をキューへ登録する。ワーカーはキューから保存先情報を受け取り、オブジェクトストレージ上のファイルを読み込んで解析し、解析結果をDBへ保存する。

  • 50 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
content-marketingapi

Works with

  • api

Security analysis

A100/100

Pro scans all 21 files and shows the line behind each finding

Scanned November 7, 2026

npx -y skills add iwasa-kosui/tanteki --skill documents --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Documents?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Documents
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/iwasa-kosui-documents-e8bb32b3/badge)](https://www.skillsdirectory.com/skills/iwasa-kosui-documents-e8bb32b3)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# ファイル取込 Design Doc

## 1. 概要

ファイル取込処理を非同期化する。APIは受信したファイル本体をオブジェクトストレージへ保存し、保存先情報をキューへ登録する。ワーカーはキューから保存先情報を受け取り、オブジェクトストレージ上のファイルを読み込んで解析し、解析結果をDBへ保存する。

ファイル本体をキューへ登録する方式は、キューのメッセージサイズ上限が1MBであり、最大10MBのファイルを扱えないため採用しない。

## 2. 背景・目的

### 目的

- APIのリクエスト処理とファイル解析処理を分離する
- APIの応答時間を短縮し、解析処理の負荷をワーカーへ分散する
- 大容量ファイルを安全に取り扱う

### 前提

- 取込対象ファイルの最大サイズは10MB
- キューのメッセージサイズ上限は1MB
- オブジェクトストレージを利用可能
- 解析結果はDBへ保存する
- 非同期化により、利用者が解析結果を確認できるまでの時間は延長される

## 3. 採用方式

```text
利用者
  │ ファイル送信
  ▼
API
  │ 1. ファイル保存
  ▼
オブジェクトストレージ
  │
  │ 2. 保存先をキューへ登録
  ▼
キュー
  │ 3. 保存先を取得
  ▼
ワーカー
  │ 4. オブジェクトストレージから読み込み
  │ 5. 解析
  │ 6. 解析結果を保存
  ▼
DB
```

### APIの責務

1. リクエストを受け付ける
2. ファイルをオブジェクトストレージへ保存する
3. 保存先を示すメッセージをキューへ登録する
4. 受付結果を利用者へ返す

### ワーカーの責務

1. キューから保存先情報を取得する
2. オブジェクトストレージからファイルを読み込む
3. ファイルを解析する
4. 解析結果をDBへ保存する
5. 処理済みメッセージをキューから確定する

## 4. API仕様

### 4.1 リクエスト

- `POST /imports`
- `multipart/form-data`
- ファイルサイズ上限: 10MB

### 4.2 正常時の処理

1. 取込IDを発行する
2. `imports` または同等の管理テーブルへ受付情報を保存する
3. オブジェクトストレージへファイルを保存する
4. 保存先情報をキューへ登録する
5. 受付済みステータスを返す

レスポンス例:

```json
{
  "import_id": "imp_123456",
  "status": "accepted"
}
```

HTTPステータスは、既存APIの規約に合わせて `202 Accepted` を基本とする。

### 4.3 オブジェクトストレージの保存先

保存キーには、外部から推測されにくく、取込単位で一意になる値を使用する。

例:

```text
imports/{import_id}/{random_id}/original
```

キューにはファイル本体を含めず、以下のような参照情報のみを登録する。

```json
{
  "event_type": "file_import_requested",
  "import_id": "imp_123456",
  "object_key": "imports/imp_123456/abc123/original",
  "bucket": "file-imports",
  "created_at": "2026-09-20T00:00:00Z"
}
```

実際には、バケット名をアプリケーション設定から解決できる場合は、メッセージにバケット名を含めず、`import_id` と `object_key` のみを持たせてもよい。キューのメッセージは小さく保ち、将来の項目追加に備えてバージョンを持たせる。

## 5. エラー処理

### 5.1 オブジェクトストレージへの保存失敗

確定事項:

- APIは `503 Service Unavailable` を返す
- キューには登録しない

処理方針:

1. ファイル保存を実行する
2. 保存が失敗した場合はキュー登録処理を実行しない
3. 必要に応じて、作成済みの受付レコードを失敗状態へ更新する
4. `503` とエラーコードを返す

レスポンス例:

```json
{
  "code": "OBJECT_STORAGE_UNAVAILABLE",
  "message": "ファイルを保存できませんでした。時間をおいて再試行してください。"
}
```

### 5.2 キューへの登録失敗

回復方法は未決定である。実装では以下を暫定方針とする。

- キュー登録失敗を検知し、受付レコードを `queue_registration_failed` などの状態へ更新する
- APIは成功扱いにせず、運用上再処理可能なエラーとして扱う
- 再送を自動で行うか、管理者・バッチによる再送とするかは別途決定する
- 再送時に同一ファイルが二重処理されても結果が壊れないよう、ワーカー側で冪等性を確保する

キュー登録失敗時のAPIレスポンスコード、再送回数、再送間隔、保存済みファイルの保持期間は未確定事項として残す。実装前に決定すること。

### 5.3 ワーカーでの読み込み失敗

- 一時的なオブジェクトストレージ障害は、キューの再試行機能またはリトライで再実行する
- ファイルが存在しないなど恒久的なエラーは、取込状態を失敗に更新し、無限リトライを防止する
- 再試行回数を超えたメッセージは、既存のDLQ等の運用方針に従う

### 5.4 解析失敗

- 解析不能なファイルは取込状態を `failed` に更新する
- エラー理由は利用者に提示可能な情報と、ログにのみ出す内部情報を分離する
- 同一メッセージの再実行で重複した解析結果を作らない

## 6. 状態管理

取込単位で、少なくとも以下の状態を管理する。

| 状態 | 意味 |
|---|---|
| `accepted` | APIが受付を完了した |
| `stored` | オブジェクトストレージへの保存が完了した |
| `queued` | キュー登録が完了した |
| `processing` | ワーカーが解析中 |
| `completed` | 解析結果をDBへ保存した |
| `failed` | 解析または回復不能な処理に失敗した |
| `queue_registration_failed` | ファイル保存後、キュー登録に失敗した |

状態遷移例:

```text
accepted → stored → queued → processing → completed
                    │           │
                    │           └→ failed
                    └→ queue_registration_failed
```

APIの受付情報、オブジェクトストレージのキー、解析結果、エラー情報は同じ `import_id` で関連付ける。

## 7. 整合性・冪等性

オブジェクトストレージ保存とキュー登録は単一トランザクションではないため、以下の不整合が発生し得る。

- ファイル保存成功後にキュー登録が失敗する
- キュー登録成功後にAPI応答が失敗する
- ワーカーが同一メッセージを複数回処理する

対策:

- `import_id` を一意キーとして扱う
- 解析結果の保存時に一意制約またはUPSERTを利用する
- ワーカーは処理開始前・保存前に現在状態を確認する
- キューの再配信を前提に、処理を冪等にする
- APIの再送で同じ取込IDを再利用するか、新規取込として扱うかをAPI仕様で明確化する

キュー登録失敗の回復方法を決定する際には、Outboxパターンなど、DB上の登録情報を起点にキューへ再送できる方式を候補とする。

## 8. 非同期化による利用者影響

解析結果はAPIレスポンス時点では確定しない。利用者には以下のいずれかの結果確認方法を提供する。

- `GET /imports/{import_id}` による状態確認
- 完了時の通知
- 既存画面でのポーリング

最低限、取込IDと現在状態を返し、利用者が処理中・完了・失敗を判別できるようにする。結果提示までの遅延が発生することをAPI仕様および画面仕様に明記する。

## 9. セキュリティ・運用

- オブジェクトストレージは公開せず、APIとワーカーのサービスアカウントだけがアクセスできるようにする
- キューのメッセージにファイル本体や機密情報を含めない
- ファイル名は表示用情報として扱い、保存キーにはそのまま使用しない
- ファイルサイズ、拡張子、Content-TypeをAPIで検証する
- ログにはファイル本体、認証情報、機密データを出力しない
- 保存済みファイルの削除タイミングと保持期間を別途定義する
- キュー滞留数、ワーカー失敗数、処理時間、DLQ件数を監視する

## 10. 実装タスク

### 今週の範囲: API実装

担当: 佐藤

- `POST /imports` の実装
- ファイルサイズ・入力値のバリデーション
- 取込IDの発行
- オブジェクトストレージへの保存
- 保存失敗時の `503` 応答
- 保存失敗時にキュー登録しない制御
- キュー登録用メッセージの生成・登録
- 受付状態の保存
- API単体テスト、保存失敗時のテスト、キュー登録失敗時のテスト
- DATA-64への進捗反映

### 後続タスク

- ワーカーの実装
- オブジェクトストレージからの読み込み
- 解析処理
- 解析結果のDB保存
- 冪等性制御
- 状態確認APIまたは画面連携
- キュー登録失敗の回復方式決定・実装
- リトライ、DLQ、監視設計

## 11. 未決事項

1. キュー登録失敗時の回復方式
   - Outboxパターン
   - 再送バッチ
   - API内リトライ
   - 手動再送
2. キュー登録失敗時のAPIレスポンスコードと利用者向けメッセージ
3. キュー登録のリトライ回数・間隔
4. 保存済みファイルの保持期間と削除方式
5. 取込状態確認APIの詳細
6. 解析失敗時のリトライ条件とDLQ運用
7. APIの再送時における重複取込の扱い

## 12. 進行情報

- チケット: DATA-64
- 関連PR: #203
- 今週の実装対象: API
- 担当: 佐藤

Files in this skill

  • adr-boundary.1.with_skill.md1 KB
  • adr-boundary.1.without_skill.md2.6 KB
  • adr-boundary.2.with_skill.md884 B
  • adr-boundary.2.without_skill.md2.3 KB
  • canonical-reference.1.without_skill.md216 B
  • canonical-reference.2.with_skill.md188 B
  • canonical-reference.2.without_skill.md289 B
  • comparison-rfc.1.with_skill.md1.6 KB
  • comparison-rfc.2.with_skill.md1.4 KB
  • comparison-rfc.2.without_skill.md1.7 KB
  • design-tradeoff.1.with_skill.md4.1 KB
  • design-tradeoff.1.without_skill.md7.6 KB
  • design-tradeoff.2.with_skill.md3.6 KB
  • design-tradeoff.2.without_skill.md9.7 KB
  • incident-record.1.with_skill.md510 B
  • incident-record.1.without_skill.md517 B
  • incident-record.2.with_skill.md702 B
  • incident-record.2.without_skill.md751 B
  • no-document.1.without_skill.md329 B
  • no-document.2.with_skill.md341 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.