PlanVarietyChange モデル追加と品種変更トリガー基盤を実装する #5

Closed
opened 2026-04-05 05:14:26 +00:00 by akira · 2 comments
Owner

概要

作付け計画の品種変更履歴を保持する PlanVarietyChange モデルと、品種変更時サービスの呼び出し基盤を追加する。

スコープ

  • PlanVarietyChange モデル追加
  • 保存項目: field, year, plan, changed_at, old_variety, new_variety, reason, moved_entry_count
  • Plan.variety 変更時に履歴を記録するサービス層の追加
  • 後続の施肥計画・田植え計画移動サービスを呼び出せる入口を整備

受け入れ条件

  • マイグレーションが追加されている
  • Plan.variety の変更前後を検知して履歴を1件記録できる
  • 品種が変わらない更新では履歴が増えない
  • 後続サービスが呼べる構造になっている

関連

## 概要 作付け計画の品種変更履歴を保持する `PlanVarietyChange` モデルと、品種変更時サービスの呼び出し基盤を追加する。 ## スコープ - `PlanVarietyChange` モデル追加 - 保存項目: `field`, `year`, `plan`, `changed_at`, `old_variety`, `new_variety`, `reason`, `moved_entry_count` - `Plan.variety` 変更時に履歴を記録するサービス層の追加 - 後続の施肥計画・田植え計画移動サービスを呼び出せる入口を整備 ## 受け入れ条件 - [ ] マイグレーションが追加されている - [ ] `Plan.variety` の変更前後を検知して履歴を1件記録できる - [ ] 品種が変わらない更新では履歴が増えない - [ ] 後続サービスが呼べる構造になっている ## 関連 - 親: #3 - 実装全体: #4
Author
Owner

#5 レビュー結果
総合: 問題なし、承認

良い点
services.py の設計

NO_CHANGE センチネル値で「フィールド未指定」と「None指定」を区別しているのは正確
handle_plan_variety_change が old == new のときに早期 return するので、同品種への更新では履歴が作られない
process_plan_variety_change を分離して後続 issue (#6, #7) の入口を明示しているのが明快
serializers.py の変更

update() を update_plan_with_variety_tracking() に差し替えるだけで済んでいる。シンプル。
views.py の bulk_update

既存の update_or_create を廃止して新規/更新を明示的に分岐させた。新規作成時に variety が変わっても無条件に create するのは正しい(変更前の品種がないため履歴は不要)。
テスト

3ケース(品種変更あり・なし・一括更新)がそれぞれ意図を正確に検証している
気になる点(軽微)
serializers.py の update で reason が渡せない

return update_plan_with_variety_tracking(
instance,
crop=...,
variety=...,
notes=...,
# reason を渡していない
)
reason はシリアライザ経由では渡せない設計になっています。#8(allocation画面の確認ダイアログ)でユーザーが変更理由を入力する場合、この経路で reason が届かなくなります。#8 実装時に要対応ですが、今の段階では空文字デフォルトで問題ありません。

問題なしです。#6に進んで大丈夫です。

#5 レビュー結果 総合: 問題なし、承認 良い点 services.py の設計 NO_CHANGE センチネル値で「フィールド未指定」と「None指定」を区別しているのは正確 handle_plan_variety_change が old == new のときに早期 return するので、同品種への更新では履歴が作られない process_plan_variety_change を分離して後続 issue (#6, #7) の入口を明示しているのが明快 serializers.py の変更 update() を update_plan_with_variety_tracking() に差し替えるだけで済んでいる。シンプル。 views.py の bulk_update 既存の update_or_create を廃止して新規/更新を明示的に分岐させた。新規作成時に variety が変わっても無条件に create するのは正しい(変更前の品種がないため履歴は不要)。 テスト 3ケース(品種変更あり・なし・一括更新)がそれぞれ意図を正確に検証している 気になる点(軽微) serializers.py の update で reason が渡せない return update_plan_with_variety_tracking( instance, crop=..., variety=..., notes=..., # reason を渡していない ) reason はシリアライザ経由では渡せない設計になっています。#8(allocation画面の確認ダイアログ)でユーザーが変更理由を入力する場合、この経路で reason が届かなくなります。#8 実装時に要対応ですが、今の段階では空文字デフォルトで問題ありません。 問題なしです。#6に進んで大丈夫です。
Collaborator

2026-04-07 時点で実装済みを確認したためクローズします。

確認内容:

  • PlanVarietyChange モデルと migration が追加済み
  • update_plan_with_variety_tracking() / handle_plan_variety_change() により、Plan.variety の変更を検知して履歴記録する基盤が実装済み
  • 後続の施肥計画・田植え計画移動サービスを呼び出す入口も実装済み
  • apps.plans.tests で関連テストが通過することを 2026-04-07 に Docker 内で確認済み

関連ファイル:

  • backend/apps/plans/models.py
  • backend/apps/plans/services.py
  • backend/apps/plans/migrations/0010_planvarietychange.py
  • backend/apps/plans/tests.py
2026-04-07 時点で実装済みを確認したためクローズします。 確認内容: - `PlanVarietyChange` モデルと migration が追加済み - `update_plan_with_variety_tracking()` / `handle_plan_variety_change()` により、`Plan.variety` の変更を検知して履歴記録する基盤が実装済み - 後続の施肥計画・田植え計画移動サービスを呼び出す入口も実装済み - `apps.plans.tests` で関連テストが通過することを 2026-04-07 に Docker 内で確認済み 関連ファイル: - `backend/apps/plans/models.py` - `backend/apps/plans/services.py` - `backend/apps/plans/migrations/0010_planvarietychange.py` - `backend/apps/plans/tests.py`
ai closed this issue 2026-04-07 00:59:23 +00:00
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: akira/keinasystem#5