Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ enum class DosageForm {
- `Disease` (詳細)
- `DiseaseListResponse` (一覧 envelope)

加えて `ErrorResponse` (エラーボディ) の root にも `disclaimer: String` が必須付与される
エラーボディは RFC 9457 `application/problem+json` で返し、`disclaimer` は付与しない

`CategoriesResponse` には `disclaimer` を付けない (規約: フィルタ選択肢取得は医療判断に直接関与しない)。

Expand All @@ -220,7 +220,7 @@ enum class DosageForm {
| `precaution_category` | String | - | 8 値 (患者背景 `PrecautionPopulationCategory` の **enum constant 名**、例: `PREGNANT`、`GERIATRIC`) | 可 (OR) |
| `sort` | String | `-revised_at` | `-revised_at` \| `brand_name_kana` \| `atc_code` \| `therapeutic_category_name` | 不可 |

`therapeutic_category` および `precaution_category` の未知の値は HTTP 400 + `ErrorResponse(code="INVALID_THERAPEUTIC_CATEGORY"|"INVALID_PRECAUTION_CATEGORY")` を返す。`sort` の未知の値は `ErrorResponse(code="INVALID_SORT_KEY")`
`therapeutic_category` / `precaution_category` / `sort` の未知の値は HTTP 422 + `application/problem+json` を返す。`type` は `.../validation`、`errors[].field` は該当する snake_case クエリ名 (`therapeutic_category` / `precaution_category` / `sort`)

`/v1/drugs` の `keyword_target=all` は、検索欄からのコード検索向けに `generic_name` / `brand_name` / `brand_name_kana` / `atc_code` / `yj_code` を検索対象とする。既定値 `both` の意味は変更せず、`generic` / `brand` / `both` は従来どおり名称系フィールドのみを対象とする。

Expand All @@ -244,7 +244,7 @@ enum class DosageForm {
| `has_severity_grading` | Bool | - | `true` \| `false` | 不可 |
| `sort` | String | `-revised_at` | `-revised_at` \| `name_kana` \| `icd10_chapter` | 不可 |

`onset_pattern` / `exam_category` の未知の値は HTTP 400 + `ErrorResponse(code="INVALID_ONSET_PATTERN"|"INVALID_EXAM_CATEGORY")` を返す。`sort` の未知の値は `ErrorResponse(code="INVALID_SORT_KEY")`
`onset_pattern` / `exam_category` / `sort` の未知の値は HTTP 422 + `application/problem+json` を返す。`type` は `.../validation`、`errors[].field` は該当する snake_case クエリ名 (`onset_pattern` / `exam_category` / `sort`)

`/v1/diseases` の `keyword_target=all` は、検索欄からの症状・ICD-10 検索向けに `name` / `name_kana` / `name_english` / `synonyms[]` / `symptoms.mainSymptoms[]` / `icd10_chapter.serialName` / ICD-10 章キー / ICD-10 コード範囲を検索対象とする。既定値 `name` の意味は変更しない。

Expand All @@ -255,9 +255,8 @@ enum class DosageForm {
| パスパラメータ | `id: String` (例: `drug_0001`、`disease_0001`、4 桁ゼロ埋め固定) |
| クエリ | なし |
| HTTP 200 | 全共通フィールド + 入れ子全展開 + root の `disclaimer` |
| HTTP 400 | `id` パスパラメータ欠落時 `{ "code": "BAD_REQUEST", "message": "id path parameter is required", "details": null, "disclaimer": "..." }` |
| HTTP 404 | `{ "code": "NOT_FOUND", "message": "Drug not found: ..." \| "Disease not found: ...", "details": null, "disclaimer": "..." }` |
| HTTP 5xx | `{ "code": "INTERNAL_ERROR", ... }` |
| HTTP 404 | RFC 9457 problem details。`type=.../not-found`、`title="Resource not found"`、`status=404`、`detail` に対象リソースと ID を含む。エラー body に `disclaimer` は付かない |
| HTTP 5xx | RFC 9457 problem details。`type=.../internal`、`title="Internal server error"`、`status=500`。内部例外 detail は露出しない |

ID 形式は `.claude/rules/product-id-registry.md` 準拠 (`drug_NNNN` / `disease_NNNN`、4 桁ゼロ埋め)。

Expand Down Expand Up @@ -288,27 +287,20 @@ UI のフィルターピッカーがこのエンドポイント 1 回で全選

### エラーレスポンス

エラー応答は RFC 9457 `application/problem+json`。HTTP 4xx/5xx でも body は JSON で、root は以下の problem details 形式:

```
{
"code": String,
"message": String,
"details": String?,
"disclaimer": String
"type": "https://github.com/Corvus400/fictional-drug-and-disease-ref/problems/validation",
"title": "Validation failed",
"status": 422,
"detail": "optional detail",
"instance": "/v1/drugs?therapeutic_category=BOGUS",
"errors": [{ "field": "therapeutic_category", "reason": "Unknown therapeutic_category: BOGUS" }]
}
```

HTTP 4xx/5xx でも body は JSON。`code` は以下の値を取り得る:

- `BAD_REQUEST` — 必須パスパラメータ欠落等
- `NOT_FOUND` — 詳細取得で id が存在しない
- `INVALID_THERAPEUTIC_CATEGORY` — `therapeutic_category` クエリの値が `TherapeuticCategory` の constant 名に該当しない
- `INVALID_PRECAUTION_CATEGORY` — `precaution_category` クエリの値が `PrecautionPopulationCategory` の constant 名に該当しない
- `INVALID_ONSET_PATTERN` — `onset_pattern` クエリの値が `OnsetPattern` の constant 名に該当しない
- `INVALID_EXAM_CATEGORY` — `exam_category` クエリの値が `ExamCategory` の constant 名に該当しない
- `INVALID_SORT_KEY` — `sort` クエリの値が許容ソートキーに該当しない
- `INTERNAL_ERROR` — 5xx 系の汎用エラー

`details` は型 `String?`。`disclaimer` は `Disclaimer.SHORT` がデフォルト付与される。
`type` は `.../not-found` / `.../validation` / `.../conflict` / `.../unauthorized` / `.../forbidden` / `.../rate-limited` / `.../internal` のカテゴリ URI。`detail` / `instance` / `errors` は状況に応じて省略される。validation では HTTP 422 とし、`errors[].field` に snake_case のクエリ名またはフィールド名、`errors[].reason` に理由を入れる。エラー body に `disclaimer` は付かない。

---

Expand All @@ -323,19 +315,19 @@ HTTP 4xx/5xx でも body は JSON。`code` は以下の値を取り得る:
| 項目 | 仕様 |
|-----|-----|
| パスパラメータ | `form` — `DosageForm` enum SerialName (例: `tablet`、`capsule`、`injection_form`) |
| クエリ `size` | `S` \| `M` \| `Original` (省略時 `Original`)。それ以外は HTTP 400 |
| クエリ `size` | `S` \| `M` \| `Original` (省略時 `Original`)。それ以外は HTTP 422 + `application/problem+json` (`type=.../validation`, `errors[].field="size"`) |
| 200 | `image/png` バイナリ |
| 404 | 該当 form のリソースが存在しない場合 |
| 404 | 該当 form のリソースが存在しない場合。RFC 9457 problem details (`type=.../not-found`) |
| サポート 13 form | `tablet` / `capsule` / `powder` / `granule` / `liquid` / `injection_form` / `ointment` / `cream` / `patch` / `eye_drops` / `suppository` / `inhaler` / `nasal_spray` |

### `GET /v1/images/drugs/{drugId}`

| 項目 | 仕様 |
|-----|-----|
| パスパラメータ | `drugId` — `drug_NNNN` 形式 |
| クエリ `size` | `S` \| `M` \| `Original` (省略時 `Original`) |
| クエリ `size` | `S` \| `M` \| `Original` (省略時 `Original`)。それ以外は HTTP 422 + `application/problem+json` (`type=.../validation`, `errors[].field="size"`) |
| 200 | `image/png` バイナリ (`drug_0080`、`drug_0089` の 2 件のみ実画像が存在する) |
| 404 | 上記 2 ID 以外、または size リソース欠落時 |
| 404 | 上記 2 ID 以外、または size リソース欠落時。RFC 9457 problem details (`type=.../not-found`) |

### `image_url` フィールドの生成ロジック

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
| フィルタクエリ (drug / disease) | [base #api-spec][base-api] | 画面仕様「検索画面の機能要件」 |
| リスト最小項目 (DrugSummary 10 / DiseaseSummary 8) | [base #api-spec][base-api] | 画面仕様のリスト行描画、[bookmark][bm] `snapshot` |
| 詳細系レスポンス (空値ポリシー `List<T>=[]` / `nullable=null`) | [base #type-conventions][base-types] | 画面仕様の詳細画面描画 |
| エラーレスポンス `{ code, message, details, disclaimer }` | [base #api-spec][base-api] | 運用・非機能要件「エラー・Empty 表示」 |
| エラーレスポンス RFC 9457 `application/problem+json` | [base #api-spec][base-api] | 運用・非機能要件「エラー・Empty 表示」 |
| `/v1/categories` (フィルタ選択肢取得、disclaimer なし) | [base #categories-response][base-cat] | アプリ起動時 1 回取得 + メモリキャッシュ + pull-to-refresh |
| 画像エンドポイント (`/v1/images/dosage-forms/{form}` / `/v1/images/drugs/{drugId}`) | [base #image-endpoints][base-img] | 検索結果リスト・医薬品詳細画面の画像表示 |
| `image_url` 自動生成ロジック (`drug_0080`/`drug_0089` のみ drug-specific、他は dosage-form fallback) | [base #image-endpoints][base-img] | 画像 URL 解釈ロジック |
Expand Down Expand Up @@ -299,7 +299,7 @@
- 認証: なし (ポートフォリオ公開モック)
- ページング envelope: `{ items, page, page_size, total_pages, total_count, disclaimer }` ([base #api-spec][base-api])
- 空値ポリシー: `List<T> = []` / `T? = null` 両方許容 ([base #type-conventions][base-types])
- エラーレスポンス: HTTP 4xx/5xx でも body は JSON `{ code, message, details, disclaimer }` ([base #api-spec][base-api])
- エラーレスポンス: HTTP 4xx/5xx でも body は RFC 9457 `application/problem+json` (`type` / `title` / `status` / `detail?` / `instance?` / `errors?`)。エラー body に `disclaimer` は含めない ([base #api-spec][base-api])
- タイムアウト / リトライ: 接続 10 秒 / 読み込み 15 秒 / 5xx のみ 1 回リトライ (指数バックオフ 500ms)
- root `disclaimer` フィールド: `Drug` / `Disease` / `DrugListResponse` / `DiseaseListResponse` の root に必ず付与。`CategoriesResponse` には付かない ([base #disclaimer-field][base-disc])。クライアントは画面下部の小ラベルや About 画面で参照可能

Expand Down Expand Up @@ -360,8 +360,8 @@
| パスパラメータ | `id: String` (例: `drug_0001`、`disease_0001`、4 桁ゼロ埋め) |
| クエリ | なし |
| HTTP 200 | 全共通フィールド + 入れ子全展開 (モデル: [drug][drug] / [disease][disease]、JSON キーは snake_case) + root `disclaimer` |
| HTTP 404 | `{ "code": "NOT_FOUND", "message": "...", "details": null, "disclaimer": ... }` |
| HTTP 5xx | `{ "code": "INTERNAL_ERROR", ... }` (5xx は 1 回自動リトライ対象) |
| HTTP 404 | RFC 9457 problem details (`type=.../not-found`, `status=404`) |
| HTTP 5xx | RFC 9457 problem details (`type=.../internal`, `status=500`)。5xx は 1 回自動リトライ対象 |

### `GET /v1/categories`

Expand All @@ -376,9 +376,9 @@

| 項目 | `/v1/images/dosage-forms/{form}` / `/v1/images/drugs/{drugId}` 共通仕様 |
|-----|---|
| クエリ `size` | `S` \| `M` \| `Original` (省略時 `Original`)。それ以外は HTTP 400 |
| クエリ `size` | `S` \| `M` \| `Original` (省略時 `Original`)。それ以外は HTTP 422 + `application/problem+json` (`type=.../validation`, `errors[].field="size"`) |
| HTTP 200 | `image/png` バイナリ |
| HTTP 404 | リソース欠落時 (drug 個別画像は `drug_0080`/`drug_0089` 以外で発生) |
| HTTP 404 | リソース欠落時 (drug 個別画像は `drug_0080`/`drug_0089` 以外で発生)。RFC 9457 problem details (`type=.../not-found`) |

`image_url` フィールドの生成ロジックは [base #image-endpoints][base-img] 参照。クライアントは生成済み相対 URL を base URL と結合してそのまま GET する。

Expand Down Expand Up @@ -458,10 +458,10 @@ Flutter では sealed class、iOS では enum で定義。画面ロジックは
|-----------|---------|-------------|----------|
| ネットワーク断 | HTTP Timeout / Socket Error | 「通信できません。ネットワーク接続を確認してください。」 | 再試行ボタン |
| サーバエラー (5xx) | HTTP 500-599 | 「一時的な問題が発生しました。しばらく経ってから再度お試しください。」 | 再試行ボタン |
| リクエストエラー (4xx) | HTTP 400-499 | API の `message` を表示 (例: 「該当するデータが見つかりません」) | 戻る / 条件変更 |
| リクエストエラー (4xx) | HTTP 4xx | problem details の `detail` または `title` を表示。validation は `errors[].field` に応じて条件変更を促す | 戻る / 条件変更 |
| パース失敗 | Codable/Freezed 失敗 | 「データを読み込めません。」 | 再試行 + 開発者通知 (`OSLog` / `developer.log`) |

API エラーレスポンス構造は [base #api-spec][base-api] に準拠。`code` 値ごとに上記表のエラー種別にマッピング。`code` の取り得る値: `BAD_REQUEST` / `NOT_FOUND` / `INVALID_THERAPEUTIC_CATEGORY` / `INVALID_PRECAUTION_CATEGORY` / `INVALID_ONSET_PATTERN` / `INVALID_EXAM_CATEGORY` / `INVALID_SORT_KEY` / `INTERNAL_ERROR`
API エラーレスポンス構造は [base #api-spec][base-api] に準拠。`type` URI のカテゴリ (`not-found` / `validation` / `conflict` / `unauthorized` / `forbidden` / `rate-limited` / `internal`) と HTTP status で上記表のエラー種別にマッピングする。validation では `errors[].field` の snake_case フィールド名を使って、該当する検索条件や入力項目へ誘導する

**タイムアウト・リトライ設定**:

Expand Down
Loading