diff --git a/CLAUDE.md b/CLAUDE.md index 30996ae..5a4462c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -185,9 +185,9 @@ FertilizationPlan (施肥計画) └── variety (FK to plans.Variety) FertilizationEntry (施肥エントリ・中間テーブル) -├── plan (FK to FertilizationPlan) -├── field (FK to fields.Field) -├── fertilizer (FK to Fertilizer) +├── plan (FK to FertilizationPlan, CASCADE) +├── field (FK to fields.Field, CASCADE) +├── fertilizer (FK to Fertilizer, PROTECT) ← 使用中の肥料は削除不可 ├── bags(袋数、Decimal) └── unique_together = ['plan', 'field', 'fertilizer'] ``` @@ -309,6 +309,16 @@ FertilizationEntry (施肥エントリ・中間テーブル) - フロントエンド `/weather` 画面(年別集計・期間指定 モード、グラフは Recharts) - **将来計画**: 開花・収穫予測(品種ごとの目標GDD設定 → 到達日予測) - マスタードキュメント: `document/12_マスタードキュメント_気象データ編.md` +10. **施肥計画機能**(本番稼働中): + - Django `apps/fertilizer` アプリ(Fertilizer, FertilizationPlan, FertilizationEntry) + - API: `/api/fertilizer/fertilizers/`, `/api/fertilizer/plans/`, `/api/fertilizer/calculate/`, `/api/fertilizer/candidate_fields/` + - PDF出力: `/api/fertilizer/plans/{id}/pdf/`(WeasyPrint、A4横向き) + - FertilizationEntry.fertilizer は PROTECT(使用中の肥料は削除不可・migration 0002) + - 自動計算3方式: per_tan(反当袋数)/ even(均等配分)/ nitrogen(反当チッソ) + - 四捨五入トグル: `≈`(丸め)/ `↩`(元の計算値に戻す) + - フロントエンド: `/fertilizer`(一覧)、`/fertilizer/masters`(肥料マスタ)、`/fertilizer/new`・`/fertilizer/[id]/edit`(編集) + - 施肥機能全体で alert/confirm を廃止し、React インラインバナーでエラー表示 + - マスタードキュメント: `document/13_マスタードキュメント_施肥計画編.md` 10. **施肥計画機能**: - Django `apps/fertilizer` アプリ(Fertilizer, FertilizationPlan, FertilizationEntry) - API(JWT認証): `GET/POST /api/fertilizer/fertilizers/`, `GET/POST /api/fertilizer/plans/?year=`, `GET /api/fertilizer/plans/{id}/pdf/`, `GET /api/fertilizer/candidate_fields/?year=&variety_id=`, `POST /api/fertilizer/calculate/` @@ -415,6 +425,7 @@ docker-compose exec backend python manage.py migrate - **圃場管理機能**: `document/10_マスタードキュメント_圃場管理編.md` - **メール通知機能**: `document/11_マスタードキュメント_メール通知関連編.md` - **気象データ機能**: `document/12_マスタードキュメント_気象データ編.md` +- **施肥計画機能**: `document/13_マスタードキュメント_施肥計画編.md` ### 設計ドキュメント(プロジェクト横断) @@ -440,7 +451,7 @@ docker-compose exec backend python manage.py migrate ## 📝 更新履歴 - 2026-02-28: Cursor連携を廃止。Claude Code 単独運用に変更。`document/20_Cursor_Claude連携ガイド.md` を削除 -- 2026-03-01: 施肥計画機能を実装。`apps/fertilizer`(Fertilizer, FertilizationPlan, FertilizationEntry, 自動計算3方式, PDF出力)、フロントエンド `/fertilizer/`(一覧・編集・肥料マスタ)。スコープ外: 購入管理・配置計画 +- 2026-03-01: 施肥計画機能を実装・本番稼働。`apps/fertilizer`(Fertilizer, FertilizationPlan, FertilizationEntry, 自動計算3方式, PDF出力, PROTECT migration 0002)、フロントエンド `/fertilizer/`(一覧・編集・肥料マスタ)。施肥機能全体で alert/confirm 廃止・インラインバナーに統一。マスタードキュメント `document/13_マスタードキュメント_施肥計画編.md` 追加 - 2026-02-28: 気象データ機能を実装・本番稼働。`apps/weather`(WeatherRecord, 5 API)、Windmill `f/weather/weather_sync`(毎朝6時)、フロントエンド `/weather`(年別集計・期間指定・Rechartsグラフ)。`Crop.base_temp` 追加。デプロイコマンドの本番パス修正(/home/keinasystem/)。マスタードキュメント `document/12_マスタードキュメント_気象データ編.md` 追加 - 2026-02-25: CLAUDE.md更新。パスワード変更機能追記。メールフィルタリング機能を本番稼働済みに更新。マスタードキュメント `document/11_マスタードキュメント_メール通知関連編.md` リンク追加。デプロイコマンド(`--env-file .env.production` 必須)をトラブルシューティングに追加 - 2026-02-22: メールフィルタリング機能を実装。`apps/mail` Django app、Windmill向けAPI(APIキー認証)、フィードバックページ、ルール管理ページを追加。仕様書: `document/メールフィルタ/mail_filter_spec.md` diff --git a/document/13_マスタードキュメント_施肥計画編.md b/document/13_マスタードキュメント_施肥計画編.md index ad56b95..92c5be4 100644 --- a/document/13_マスタードキュメント_施肥計画編.md +++ b/document/13_マスタードキュメント_施肥計画編.md @@ -1,8 +1,9 @@ # マスタードキュメント:施肥計画機能 > **作成**: 2026-03-01 +> **最終更新**: 2026-03-01 > **対象機能**: 施肥計画(年度×品種単位のマトリクス管理) -> **実装状況**: 実装完了(commit f207f5d) +> **実装状況**: 実装完了・本番稼働中(最終 commit deb03ef) --- @@ -56,7 +57,7 @@ | id | int | PK | | | plan | FK(FertilizationPlan) | CASCADE | | | field | FK(fields.Field) | CASCADE | | -| fertilizer | FK(Fertilizer) | CASCADE | | +| fertilizer | FK(Fertilizer) | **PROTECT** | 施肥計画で使用中の肥料は削除不可 | | bags | decimal(8,2) | required | 袋数 | - `unique_together = ['plan', 'field', 'fertilizer']` @@ -277,7 +278,8 @@ GET /api/plans/crops/ - 肥料一覧テーブル(名前・メーカー・容量・窒素・リン酸・カリ・備考) - インライン行編集(EditRow コンポーネント) - 新規追加フォーム -- 削除確認ダイアログ +- 削除ボタン押下で即削除を試みる(confirm ダイアログなし) +- 施肥計画で使用中の場合は PROTECT によりバックエンドが 500 を返し、赤いインラインバナーで理由を表示 ### 施肥計画編集(`/fertilizer/new` / `/fertilizer/[id]/edit`) @@ -341,7 +343,8 @@ backend/apps/fertilizer/ ├── views.py # FertilizerViewSet, FertilizationPlanViewSet, CandidateFieldsView, CalculateView ├── urls.py # DefaultRouter + candidate_fields/ + calculate/ ├── migrations/ -│ └── 0001_initial.py +│ ├── 0001_initial.py +│ └── 0002_alter_fertilizationentry_fertilizer.py # CASCADE → PROTECT └── templates/ └── fertilizer/ └── pdf.html # WeasyPrint テンプレート(A4横向き) @@ -417,6 +420,16 @@ export interface FertilizationPlan { ## 注意点・既知の問題 +### エラー表示方針(confirm/alert を使わない) + +ブラウザが `alert()` / `confirm()` をブロックすると操作が無音で失敗する問題を受けて、 +施肥機能全体で alert/confirm を廃止し、React インラインバナーに統一した。 + +- **保存失敗**: `saveError` state → ヘッダー直下に赤いバナー(✕で閉じられる) +- **肥料削除失敗**: `deleteError` state → テーブル上部に赤いバナー +- **計画削除失敗**: `deleteError` state → 一覧上部に赤いバナー +- **肥料列の除去**: ローカルstate操作のみ(失敗しない) + ### URL ルーティング競合(解決済み) plans アプリの `DefaultRouter(r'', PlanViewSet)` が `plans/get-crops-with-varieties/` を