diff --git a/改善案/在庫管理機能実装案.md b/改善案/在庫管理機能実装案.md index aaa4c76..a9fa9fb 100644 --- a/改善案/在庫管理機能実装案.md +++ b/改善案/在庫管理機能実装案.md @@ -614,3 +614,237 @@ backend/apps/materials/ - 画面ワイヤー案 まで具体化できる。 + +--- + +## 17. 補足: 農薬公式データ同期・あいまい検索案 + +農薬マスタについては、ユーザーが毎回 `農薬登録番号` や正式名称を手入力するのではなく、 +FAMIC / 農水省の公式データを取り込んで補完できるようにすることを推奨する。 + +### 17.1 目的 + +- 農薬登録番号を手で調べる手間を減らす +- 名称ゆれがあっても候補を見つけやすくする +- 公式データをもとにした登録に寄せる +- 画面の操作感は速く保つ + +### 17.2 基本方針 + +検索時に毎回外部サイトへ直接問い合わせるのではなく、以下の流れを採用する。 + +1. まず FAMIC / 農水省の公式データを取得してローカルDB化する +2. 農薬マスタ画面でのあいまい検索はローカルDBに対して行う +3. 画面表示時または検索時に、最終同期から24時間以上経過していれば更新ジョブを起動する +4. 更新ジョブでは公式データを再取得し、差分だけローカルDBに反映する +5. 更新完了後、検索候補を再読み込みする + +この方式なら、検索体験を外部サイトの応答速度に依存させず、最新性もある程度保てる。 + +### 17.3 ユーザー操作フロー + +ユーザー操作: + +- 農薬名を入力する + +画面: + +- すぐローカルDBで候補表示する + +裏側: + +- `最終同期が24時間以上前` なら更新ジョブを実行する + +更新完了後: + +- 候補データを再読み込みする + +補足: + +- 同期中であっても検索自体は継続可能とする +- 同期失敗時もローカルDBの候補表示は継続する +- 最新同期時刻を画面に小さく表示すると安心感が高い + +### 17.4 追加テーブル案 + +#### PesticideOfficialMaster + +公式農薬データの取り込み先となるローカル参照テーブル。 + +想定フィールド: + +- `id` +- `registration_no` 農薬登録番号 +- `name` 農薬名称 +- `generic_name` 種類名または一般名称 +- `holder_name` 登録を有する者の名称 +- `formulation` 剤型 +- `active_ingredient` 有効成分 +- `crop_scope_text` 適用作物の要約文字列 +- `pest_scope_text` 適用病害虫・雑草の要約文字列 +- `raw_payload` 元データ保存用 JSON +- `source_updated_at` 元データ上の更新日時 +- `last_synced_at` ローカル同期日時 +- `is_active` 有効フラグ + +用途: + +- あいまい検索の検索元 +- 農薬マスタ登録時の候補ソース +- 将来の適用作物・病害虫チェックの基礎データ + +#### OfficialDataSyncStatus + +外部同期の状態管理テーブル。 + +想定フィールド: + +- `id` +- `source_name` 例: `famic_pesticide` +- `last_checked_at` +- `last_succeeded_at` +- `last_failed_at` +- `last_source_version` +- `last_error_message` +- `is_running` + +用途: + +- 24時間ルールの判定 +- 同時実行防止 +- 管理画面での状況確認 + +### 17.5 農薬マスタとの紐づけ案 + +`PesticideProfile` には、公式参照用として以下の項目を追加する。 + +- `official_master = ForeignKey(PesticideOfficialMaster, null=True, blank=True, on_delete=SET_NULL)` +- `registration_no` +- `official_name` +- `holder_name` + +運用方針: + +- 公式候補を選んだときは `official_master` を紐づける +- その時点の登録番号や名称は `PesticideProfile` 側にもコピー保持する +- 後で公式マスタの表記が少し変わっても、登録済みデータが勝手に変わらないようにする + +### 17.6 同期ジョブ案 + +実装方法の候補: + +- Django management command +- バックエンド API から非同期ジョブ起動 +- cron や定期タスクでの夜間同期 + +初期実装では以下を推奨する。 + +- `python manage.py sync_pesticide_official_master` +- 必要時に API から起動できるようにする + +同期処理の流れ: + +1. `OfficialDataSyncStatus` を確認する +2. 同期実行中なら二重起動しない +3. 公式データを取得する +4. 取得データを正規化する +5. `registration_no` を主キー相当として差分比較する +6. 新規追加、更新、失効を反映する +7. 同期結果と件数を記録する + +### 17.7 差分更新ルール + +差分更新は以下の基準を推奨する。 + +- `registration_no` が未登録なら新規追加 +- `registration_no` が既存で、名称や保持者などが変わっていれば更新 +- 公式データから消えた場合は即削除せず `is_active=False` にする + +理由: + +- 物理削除すると、過去に登録済みの農薬マスタとの整合が崩れやすい +- 失効農薬も履歴参照上は残しておいた方がよい + +### 17.8 あいまい検索 API 案 + +- `GET /api/materials/pesticide-official-search/?q=` + +レスポンス例: + +```json +{ + "items": [ + { + "id": 1234, + "registration_no": "12345", + "name": "サンプルフロアブル", + "holder_name": "サンプル株式会社", + "formulation": "フロアブル", + "is_active": true + } + ], + "sync": { + "last_succeeded_at": "2026-03-13T08:10:00Z", + "refresh_started": true + } +} +``` + +API の考え方: + +- 検索結果は必ずローカルDBから返す +- 同時に同期必要性を判定する +- 同期が必要ならバックグラウンド更新を開始する +- API レスポンスには同期開始有無だけ含める + +### 17.9 フロントエンド動作案 + +農薬マスタ画面での候補検索 UI は以下の流れを推奨する。 + +1. ユーザーが 2〜3 文字入力する +2. 300ms 程度の debounce 後に検索 API を呼ぶ +3. ローカルDBの候補を即表示する +4. `refresh_started=true` の場合は「公式データ更新中」と小さく表示する +5. 数秒後に再検索する、または「再読込」ボタンを出す +6. 候補選択時に登録番号、正式名称、保持者名をフォームへ自動入力する + +UI 表示例: + +- `候補はローカル保存済みの公式データから表示しています` +- `公式データを更新中です` +- `最終同期: 2026-03-13 17:10` + +### 17.10 失敗時のフォールバック + +外部取得に失敗した場合も、画面は止めないことを原則とする。 + +想定動作: + +- 検索結果は直近のローカルDBをそのまま返す +- 同期失敗メッセージは管理者向けログに残す +- 一般ユーザーには必要最小限の表示に留める +- 必要なら管理画面で「最終同期失敗」を確認できるようにする + +### 17.11 初期実装のスコープ + +初期フェーズでは、以下までで十分である。 + +- 公式農薬マスタのローカルDB化 +- 24時間単位の同期判定 +- ローカルDBに対するあいまい検索 +- 候補選択による登録番号などの自動入力 + +初期フェーズでは見送ってよいもの: + +- 適用作物・病害虫の厳密な構造化 +- リアルタイム同期 +- 画面上での詳細ラベル比較 +- 農薬使用可否の自動判定 + +### 17.12 この案のメリット + +- ユーザーが登録番号を自分で調べる負担が減る +- 検索が速い +- 公式データの更新にも追従しやすい +- 外部サイト障害に強い +- 将来の農薬散布記録や適用チェックに発展させやすい