前回の記事では、Supabase SSRへの移行について書きましたが、今回は栽培管理アプリの設計に着手しました。
ClaudeとChatGPTとを使って壁打ちしながら設計を整理していったら、かなりクリアになってきました。
※個人的にはClaudeのほうが好きなんですが、使用制限の改悪(週間制限が導入)のため、ChatGPT→Claudeの順で検討しました。
最初に作った構図
まず、最初に作ったアプリ構成はこんな感じでした。
ページ構成
/fields:圃場(ハウス)の一覧・新規登録/plantings:作付の一覧・新規登録/logs:作業ログの一覧・新規登録/setup:畝の自動生成/bed-canvas:3Dでハウスを表示
一見すると、それぞれ役割があるようには見えます。
テーブル構造
データベースも一通り揃っていました。
cult_fields -- 圃場
cult_beds -- 畝
cult_plantings -- 作付
cult_logs -- 作業ログ
リレーションもちゃんと組んであって、RLSも設定済み。技術的には問題なさそうです。
3D表示
React Three Fiberを使って、ハウスを3Dで表示する機能も実装していました。
黒背景に緑のワイヤーフレームで、くるくる回せるやつです。
ハウスの中の畝をクリックすることで管理しようとしていました。
何が「しっくりこない」のか
実際に農作業で使うことをイメージしたときに、いくつか疑問が湧いてきました。
ページがバラバラすぎる
圃場を登録して、作付を登録して、ログを記録する…という流れが、3つのページに分かれています。
実際の作業は「今日、この畝に灌水した」っていうシンプルなものなのに、なぜこんなに画面遷移が必要なんだろう?
3D表示の意味
くるくる回せるのは楽しいけど、圃場でスマホ片手に作業記録するときに、3D表示を回す必要ってあるのかな?
むしろタップしづらくないか?
作付(plantings)って必要?
よく考えたら、作付って「ハウスで今何を育てているか」という情報ですよね。
それ、別テーブルにする必要ある?ハウス情報に含めちゃダメなの?
こういう違和感を言語化したくて、Claudeに壁打ちをお願いしました。
設計の方向性が見えてきた
壁打ちを重ねていくうちに、いくつかの方向性が固まってきました。
モバイルファーストで記録に特化
このアプリは、圃場で使うものを想定しています。
つまり、モバイル前提。PC版は後で作業履歴を確認するときに使う程度。
だったら、モバイルでの使いやすさを最優先にすべきですよね。
- タップ領域は大きく(最低44px×44px)
- 文字入力は最小限に
- 日付は今日がデフォルト
- 作業種類はアイコンで選択
こういう基本的なことを、最初から考えるべきでした。
2D表示で温かみのあるデザイン
3Dをやめて2D表示に変更することにしました。
- 背景は薄い土色や空色
- ハウスは柔らかい緑や自然な茶色
- アイコンはイラスト風
実用性も上がるし、見た目も良くなるかなと。
作業フローに沿ったUI
データベースの構造(fields、plantings、logs)ではなく、実際の作業の流れに沿ったUIにすることにしました。
- ログイン後、すぐに自分のハウスが2Dで表示される
- 畝をタップ
- アイコン(灌水・施肥・防除など)が出る
- タップして記録
これだけ。シンプル。
主要な設計ポイント
ここからは、具体的な設計のポイントを紹介します。
作物によって開始時期と終了時期が違う
例えば、アスパラガスは1月から10月が栽培期間です。トマトは別の時期だし、作物によって全然違う。
最初は「年度」という概念で管理しようと思ったんですが、年をまたぐ作物もあるし、そもそも「2025年度」なのか「2026年度」なのか曖昧になります。
そこで、作物開始・終了ボタンで明確に管理することにしました。
ハウス編集画面:
- 「作物を開始」ボタン → 作物名を入力、開始日が自動で今日に
- 「作物を終了」ボタン → 終了日が自動で今日に
- 「栽培再開」ボタン → 同じ作物をもう一度始める
これなら、年またぎでも問題なし。
履歴も「2025/01/15 〜 2025/10/31 アスパラガス」みたいに明確に残ります。
防除回数管理
農薬には使用回数の上限があります。
例えば「この農薬は1作で5回まで」みたいなルールがあって、それを超えると違反になる。
しかも、リセットのタイミングが作物や農薬によって違うんです。
- 1作でリセット:作物が終了したらカウント0に戻る
- 刈り取りごとにリセット:収穫のたびにカウント0に戻る(ニラとか)
この「刈り取りごと」が特に面倒で、手動で「回数リセット」ボタンを押す必要があります。
そこで、農薬管理ページを新設することにしました。
【農薬管理】
第1ハウス - アスパラガス
農薬X(殺虫剤)
├ 使用上限:5回 / 1作
├ 現在:3回使用
├ リセット条件:1作でリセット
└ 履歴:
2025/01/15 - 1回目
2025/02/22 - 2回目
2025/03/30 - 3回目
[回数リセット]
これなら、うっかり上限を超えることもなくなります。
あと、防除記録では希釈計算も自動化します。
散布量(希釈後):100L
希釈倍率:1000倍
→ 使用量(原液):0.1L ← 自動計算
計算式は 散布量 ÷ 希釈倍率 です。
毎回計算するのは面倒なので、これは絶対に自動化したい。
モバイルファーストUI:2つのパターンを試す
畝をタップしたときに、どうやって作業アイコンを表示するか。
これは実際に触ってみないとわからないので、2パターン作って比較することにしました。
パターンA:フッター固定
画面下部に常にアイコンを表示。畝を選ぶと、そのアイコンで記録できる。
┌─────────────────┐
│ 第1ハウス │
│ アスパラガス │
├─────────────────┤
│ [畝1] [畝2] │ ← 畝2を選択中
│ [畝3] [畝4] │
└─────────────────┘
├─────────────────┤
│ 灌水 施肥 防除 │ ← フッター固定
└─────────────────┘
メリット:親指で押しやすい、画面を覆わない
パターンB:サイドパネル
畝をタップすると、下から半分スライドしてアイコンが出てくる。
┌─────────────────┐
│ 第1ハウス │
│ アスパラガス │
├─────────────────┤
│ [畝1] [畝2] │
│ [畝3] [畝4] │
├─────────────────┤ ← 下から半分スライド
│ 畝2 - 第1ハウス │
│ 灌水 │
│ 施肥 │
│ 防除 │
└─────────────────┘
メリット:何を選んでいるか明確、よくあるUI
どっちが使いやすいかは、実際に作って触ってみて判断します。
テーブル設計の変更
設計が固まったので、テーブル構造も見直しました。
plantingsテーブルは削除
作物情報はcult_fields(ハウス)に統合します。
ALTER TABLE cult_fields
ADD COLUMN current_crop_name text,
ADD COLUMN current_crop_started_at timestamptz,
ADD COLUMN current_crop_ended_at timestamptz;
これで、「今何を育てているか」が一目瞭然。
作業マスタを追加
施肥・防除の詳細を管理するテーブルを追加します。
-- 作業種類マスタ
CREATE TABLE work_types (
id bigserial primary key,
owner_id uuid not null,
category text not null, -- 'fertilizer', 'pesticide', 'other'
name text not null, -- 作業名・資材名
icon text, -- アイコン名
dilution_ratio int -- 希釈倍率(農薬のみ)
);
-- 作物別作業設定
CREATE TABLE crop_work_settings (
id bigserial primary key,
owner_id uuid not null,
crop_name text not null,
work_type_id bigint references work_types(id)
);
これで、作物ごとに使う作業を選択できるようになります。
例えば、アスパラガスなら「灌水、施肥、防除、株分け、収穫」、トマトなら「灌水、施肥、防除、誘引、摘芯、収穫」みたいに。
農薬管理テーブルを追加
防除回数を管理するテーブルも追加します。
CREATE TABLE pesticide_usage (
id bigserial primary key,
owner_id uuid not null,
field_id bigint references cult_fields(id),
work_type_id bigint references work_types(id),
usage_limit int, -- 使用上限回数
reset_condition text, -- 'per_crop', 'per_year', 'per_harvest'
current_count int default 0 -- 現在の使用回数
);
これで、農薬の使用状況を一元管理できます。
作業ログに詳細項目を追加
ALTER TABLE cult_logs
ADD COLUMN work_type_id bigint references work_types(id),
ADD COLUMN amount numeric, -- 使用量(kg, ℓ)
ADD COLUMN diluted_amount numeric, -- 散布量(希釈後)
ADD COLUMN photo_url text, -- 写真URL
ADD COLUMN work_minutes int, -- 作業時間(分)
ADD COLUMN memo text; -- メモ
これで、詳細な記録ができるようになります。
今後の実装予定
設計が固まったので、次は実装フェーズに入ります。
フェーズ1:基本機能(MVP)
まずは最低限動くものを作ります。
- 認証機能(既存を流用)
- ハウス新規登録(単棟のみ)
- メイン画面(2Dハウス表示)- パターンA・B両方
- 作業記録(灌水・施肥のみ、シンプル版)
- 作業履歴一覧
目標: モバイルで基本的な記録ができる状態
フェーズ2:防除管理・詳細機能
次に、防除管理などの複雑な機能を追加します。
- 作業マスタ機能
- 防除記録(希釈計算、回数管理)
- 農薬管理ページ
- 写真添付機能
- 連棟対応
目標: 本格的な栽培管理ができる状態
フェーズ3:分析連携・最適化
最後に、出荷アプリや分析アプリとの連携を実現します。
- 出荷アプリとのデータ連携確認
- 分析アプリへのデータ提供準備
- PC版の最適化
- パフォーマンス改善
目標: 3アプリ連携の実現
まとめ
今回は、栽培管理アプリの設計がだいたい固まりました。
特に、防除回数管理みたいな農業特有の複雑さは、生成AIだけだと見落としがちです。
現場目線で考えながら、作っていきたいと思います。
