Back to skills
SKILL.md
Documents
ASecurityファイル取込処理を非同期化する。APIは受信したファイル本体をオブジェクトストレージへ保存し、保存先情報をキューへ登録する。ワーカーはキューから保存先情報を受け取り、オブジェクトストレージ上のファイルを読み込んで解析し、解析結果をDBへ保存する。
- 50 stars
- 0 votes
- 0 copies
- 0 views
- Added November 7, 2026
Works with
Security analysis
100/100Pro scans all 21 files and shows the line behind each finding
npx -y skills add iwasa-kosui/tanteki --skill documents --agent claude-codeAre you the author of Documents?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/iwasa-kosui-documents-e8bb32b3)# ファイル取込 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.md
- adr-boundary.1.without_skill.md
- adr-boundary.2.with_skill.md
- adr-boundary.2.without_skill.md
- canonical-reference.1.without_skill.md
- canonical-reference.2.with_skill.md
- canonical-reference.2.without_skill.md
- comparison-rfc.1.with_skill.md
- comparison-rfc.2.with_skill.md
- comparison-rfc.2.without_skill.md
- design-tradeoff.1.with_skill.md
- design-tradeoff.1.without_skill.md
- design-tradeoff.2.with_skill.md
- design-tradeoff.2.without_skill.md
- incident-record.1.with_skill.md
- incident-record.1.without_skill.md
- incident-record.2.with_skill.md
- incident-record.2.without_skill.md
- no-document.1.without_skill.md
- no-document.2.with_skill.md
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.