MCP キャッシュ問題の対処として、偽装不可能なcurl確認を標準化。 - scripts/check_prod.sh: JWT認証を含む9項目のヘルスチェック - CLAUDE.md: 「本番確認手順」セクション追加(curl優先、Playwright補助) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
25 KiB
Keina System - Claude 向けガイド
最終更新: 2026-02-28 現在のフェーズ: Phase 1 (MVP) - 気象データ基盤を追加
📌 このファイルの目的
このファイルは、Claude が新しいセッションを開始する際に最初に読むべきドキュメントです。 プロジェクト全体の構造、重要な設計判断、現在の状態を把握するための情報を集約しています。
⚠️ Claude への重要な指示
このファイルは、セッションごとに必ず最初に読んでください。
さらに、以下のルールを厳守してください:
📝 更新義務
ドキュメントドリブンの徹底
- ✅ 仕様に変更がある時は、まず関連するドキュメントから更新する事。
機能追加・変更時は、必ずこのファイルを更新すること。
- ✅ 新機能実装時 → 「実装状況」セクションを更新
- ✅ データモデル変更時 → 「データモデル概要」を更新
- ✅ 重要な設計判断時 → 「重要な制約・ルール」に追記
- ✅ 新作業パターン確立時 → 「よくある作業パターン」に追加
- ✅ 問題解決時 → 「トラブルシューティング」に追加
- ✅ 更新時は必ず「更新履歴」セクションに記録
更新を忘れると、次のセッションで情報が失われます。これは最優先事項です。
🎯 プロジェクト概要(30秒で理解)
何を作っているか: 農業生産者向けの作付け計画管理システム。圃場管理、作付け計画、申請書自動生成を行う。
ユーザー: 65歳の農家(元プログラマー)、シングルユーザー、39筆の圃場を管理
技術スタック:
- Backend: Django 5.2 + DRF + PostGIS
- Frontend: Next.js 14 (App Router) + TypeScript + Tailwind CSS
- Database: PostgreSQL 16 + PostGIS 3.4
開発方針: シンプルさ最優先、段階的な機能追加、過度な複雑化を避ける
📂 プロジェクト構造
keinasystem_t02/
├── CLAUDE.md # このファイル(Claude向けガイド)
├── .cursor/
│ └── rules/
│ └── 30_Cursorガイド.md # Cursor専用ガイド
├── document/ # 詳細設計書(人間向け)
│ ├── 00_Gemini向け統合指示書.md # 全体像の詳細
│ ├── 01_プロダクトビジョン.md
│ ├── 02_ユーザーストーリー.md
│ ├── 03_データ仕様書.md
│ ├── 04_画面設計書.md
│ └── 05_実装優先順位.md
├── backend/
│ ├── keinasystem/ # Django設定
│ │ ├── settings.py # 重要: CORS, JWT, DB設定
│ │ └── urls.py # ルートURL設定
│ └── apps/
│ ├── fields/ # 圃場管理アプリ
│ │ ├── models.py # Field, OfficialKyosaiField, OfficialChusankanField
│ │ ├── views.py # インポート機能、CRUD API
│ │ └── urls.py
│ ├── plans/ # 作付け計画アプリ
│ │ ├── models.py # Plan, Crop(+base_temp), Variety
│ │ └── views.py # 作付け計画API、集計API
│ ├── weather/ # 気象データアプリ
│ │ ├── models.py # WeatherRecord (1日1行)
│ │ ├── views.py # sync(APIキー), records, summary, gdd, similarity
│ │ ├── urls.py
│ │ └── management/commands/fetch_weather.py # 初回一括取得・差分取得
│ └── reports/ # 申請書生成アプリ
│ ├── views.py # PDF生成API
│ └── templates/ # PDF用HTMLテンプレート
└── frontend/
└── src/app/
├── allocation/ # 作付け計画編集画面(メイン)
├── fields/ # 圃場一覧・詳細
├── reports/ # 申請書ダウンロード
├── import/ # データ取込画面
├── mail/
│ ├── feedback/[token]/ # フィードバックページ(認証不要)
│ ├── history/ # メール処理履歴
│ └── rules/ # 送信者ルール管理
├── weather/ # 気象データ画面(年別集計・期間指定・グラフ)
└── settings/
└── password/ # パスワード変更
🗄️ データモデル概要
コアエンティティ
Field (実圃場)
├── 39筆の実際の農地
├── area_tan (反), area_m2 (m2) の2つの面積フィールド
├── group_name, display_order (グループ分け・表示順)
└── ManyToMany関係
├── kyosai_fields (共済マスタ、M:N)
└── chusankan_fields (中山間マスタ、M:N)
OfficialKyosaiField (共済マスタ)
└── 31区画(水稲共済細目書用)
OfficialChusankanField (中山間マスタ)
├── 71区画(中山間地域等直接支払交付金用)
└── 17フィールド: c_id, chusankan_flag, oaza, aza, chiban,
branch_num, land_type, area, planting_area,
original_crop, manager, owner, slope,
base_amount, steep_slope_addition, smart_agri_addition,
payment_amount
Plan (作付け計画)
├── field (FK to Field)
├── year (年度)
├── crop (FK to Crop)
├── variety (FK to Variety, nullable)
└── unique_together = ['field', 'year']
Crop (作物マスタ)
├── name(米、トウモロコシ、エンドウ、野菜、その他)
└── base_temp (有効積算温度 基準温度℃、default=0.0) ← 2026-02-28 追加
Variety (品種マスタ)
├── crop (FK to Crop)
├── name (品種名)
└── unique_together = ['crop', 'name']
MailSender (送信者ルール)
├── email (EmailField, nullable)
├── domain (CharField, nullable)
├── rule ('never_notify' | 'always_notify')
└── ConstraintCheck: email/domain どちらか一方のみ
MailEmail (受信メール記録)
├── account (xserver/gmail/hotmail等)
├── message_id (unique)
├── sender_email, sender_domain
├── subject, body_preview
├── received_at, llm_verdict (important/not_important)
├── notified_at (LINE通知日時、nullable)
└── feedback (important/not_important/never_notify/always_notify, nullable)
MailNotificationToken (フィードバックURL用トークン)
├── email (OneToOne FK to MailEmail)
└── token (UUID, unique)
WeatherRecord (日次気象記録)
├── date (DateField, unique)
├── temp_mean, temp_max, temp_min (気温℃)
├── sunshine_h (日照時間h)
├── precip_mm (降水量mm)
├── wind_max (最大風速m/s)
└── pressure_min (最低気圧hPa)
※ 観測地点: 窪川 (lat=33.213, lon=133.133)、データソース: Open-Meteo archive API
※ 2016-01-01 から蓄積(初回は fetch_weather --full で一括投入)
Fertilizer (肥料マスタ)
├── name(肥料名、必須・unique)
├── maker(メーカー、任意)
├── capacity_kg(1袋重量kg、任意)
├── nitrogen_pct / phosphorus_pct / potassium_pct(成分%、任意)
└── notes(備考、任意)
FertilizationPlan (施肥計画)
├── name(計画名)
├── year(年度)
└── variety (FK to plans.Variety)
FertilizationEntry (施肥エントリ・中間テーブル)
├── plan (FK to FertilizationPlan, CASCADE)
├── field (FK to fields.Field, CASCADE)
├── fertilizer (FK to Fertilizer, PROTECT) ← 使用中の肥料は削除不可
├── bags(袋数、Decimal)
└── unique_together = ['plan', 'field', 'fertilizer']
重要な設計判断
-
M:N関係に変更: 当初はM:1だったが、実運用で「1つの実圃場が複数の申請区画に紐づく」ケースが判明し、ManyToManyに変更(マイグレーション0003で実施)
-
面積単位の二重管理:
- DB内部は
area_m2(整数) で保存 - 表示用に
area_tan(反, Decimal) も保持 - 理由: 申請書ではm2、農家の感覚では反
- DB内部は
-
品種は全作物で統一:
- 「作付けしない」も「その他」作物の品種として扱う
- UI操作を統一するため
-
グループ機能:
group_name(エリアや用途によるグループ分け)display_order(リスト表示時の順序)- マイグレーション0004で追加
-
年度管理の設計方針(⚠️ Phase 2 で必ず参照):
- 作付け計画: 年度セレクタで独立して来年度も選べる。選んだ年度はlocalStorageに保存して維持
- 過去年度: 「参照モード」として視覚的に区別(背景色・バナー)
- Phase 2 の栽培管理・販売管理: グローバル作業年度を導入し、基本は今年度に従う
- 栽培記録・作業日誌: 日付中心設計、年度は日付から自動算出
- 参考: ソリマチ農業簿記の年度管理方式(明示的に年度を選択、変更するまで固定)
🔑 重要な制約・ルール
絶対に守るべきこと
-
データの整合性
- 年度 + 圃場の組み合わせは1つの Plan のみ (
unique_together) - 作物 + 品種名の組み合わせは一意 (
unique_together)
- 年度 + 圃場の組み合わせは1つの Plan のみ (
-
面積の扱い
- 表示: 反 (tan)
- 計算・保存: m2
- 変換: 1反 = 1000m2 (正確には991.736m2だが、実運用では1000で統一)
-
M:N関係の重要性
- Field と OfficialKyosaiField は M:N
- Field と OfficialChusankanField は M:N
- 決して FK (1:N) に戻さない
-
シンプルさ優先
- 過度な抽象化を避ける
- 3回同じコードを書くまでは抽象化しない
- ユーザーは1人、パフォーマンス最適化は後回し
コーディング規約
- Backend: Django のベストプラクティスに従う
- Frontend: TypeScript strict mode、ESLint に従う
- API: REST原則、エンドポイントは複数形 (
/api/fields/,/api/plans/) - 命名: 日本語のフィールドは
verbose_nameで対応
📍 現在の実装状況
✅ 実装済み(Phase 1 - MVP)
- 認証: JWT認証(アクセストークン24h、リフレッシュトークン7日)
- 圃場管理:
- CRUD API (
/api/fields/) - ODS/Excelインポート (
/api/fields/import/) - グループ機能(マイグレーション0004)
- CRUD API (
- 作付け計画:
- 年度別の作付け計画 CRUD (
/api/plans/?year=2025) - 前年度コピー機能 (
/api/plans/copy_from_previous_year/) - 一括更新 (
/api/plans/bulk_update/) - 集計API (
/api/plans/summary/?year=2025)
- 年度別の作付け計画 CRUD (
- 申請書生成:
- 水稲共済細目書 PDF (
/api/reports/kyosai/?year=2025) - 中山間交付金 PDF (
/api/reports/chusankan/?year=2025)
- 水稲共済細目書 PDF (
- フロントエンド:
- 作付け計画編集画面(集計サイドバー付き)
- 圃場一覧・詳細・新規作成
- データ取込画面
- 申請書ダウンロード画面
- ダッシュボード画面(概要サマリー、作物別集計、クイックアクセス)
- 対応付け可視化・紐づけ管理 (E-2):
- 圃場一覧「対応表」モード(共済漢字地名・中山間所在地の一覧表示、直接紐づけ追加・解除)
- 圃場詳細画面の共済/中山間リンク管理(+追加、×解除、面積参考表示)
- 共通 LinkModal コンポーネント
- メールフィルタリング機能(Windmill連携):
- Django
apps/mailアプリ(MailSender, MailEmail, MailNotificationToken) - Windmill向けAPI(APIキー認証):
GET /api/mail/sender-rule/,GET /api/mail/sender-context/,POST /api/mail/emails/,GET /api/mail/stats/ - フィードバックAPI(認証不要・UUIDトークン):
GET/POST /api/mail/feedback/<token>/ - ルール管理API(JWT認証):
GET/POST/DELETE /api/mail/senders/,PATCH /api/mail/emails/<pk>/feedback/ - フィードバックページ:
/mail/feedback/[token](LINEからタップ一発、認証不要) - ルール管理ページ:
/mail/rules/ - 処理履歴ページ:
/mail/history/ - 対応アカウント: Gmail × 2、Xserver × 6(本番稼働中)
- Windmill フロー:
f/mail/mail_filter(本番: windmill.keinafarm.net にデプロイ済み、10分間隔スケジュール) - マスタードキュメント:
document/11_マスタードキュメント_メール通知関連編.md
- Django
- パスワード変更機能:
- Backend:
POST /api/auth/change-password/(JWT認証、ChangePasswordViewinkeinasystem/urls.py) - Frontend:
/settings/passwordページ - Navbar: KeyRound アイコンボタン(ログアウトボタンの左隣)
- Backend:
- 気象データ基盤(Windmill連携):
- Django
apps/weatherアプリ(WeatherRecord: 1日1行、2016-01-01〜) - データソース: Open-Meteo archive API(窪川 lat=33.213, lon=133.133)
- Windmill向けAPI(APIキー認証):
POST /api/weather/sync/(upsert、単一/リスト両対応) - フロントエンド向けAPI(JWT認証):
GET /api/weather/records/?year=&start=&end=日次レコード一覧GET /api/weather/summary/?year=月別・年間サマリー(猛暑日・冬日数含む)GET /api/weather/gdd/?start_date=&base_temp=&end_date=有効積算温度(GDD)GET /api/weather/similarity/?year=類似年分析(月別パターン比較)
- 管理コマンド:
python manage.py fetch_weather [--full] [--start-date] [--end-date] - Windmill フロー:
f/weather/weather_sync(本番稼働中、毎朝6時 Asia/Tokyo) Crop.base_temp(GDD計算の基準温度、default=0.0℃)をCropモデルに追加- 初回データ投入:
docker compose exec backend python manage.py fetch_weather --full - フロントエンド
/weather画面(年別集計・期間指定 モード、グラフは Recharts) - 将来計画: 開花・収穫予測(品種ごとの目標GDD設定 → 到達日予測)
- マスタードキュメント:
document/12_マスタードキュメント_気象データ編.md
- Django
- 施肥計画機能(本番稼働中):
- 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
- 施肥計画機能:
- 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/ - 自動計算3方式: 反当袋数(per_tan)、均等配分(even)、反当チッソ(nitrogen)
- フロントエンド:
/fertilizer/(一覧),/fertilizer/new・/fertilizer/[id]/edit(編集・マトリクス表),/fertilizer/masters/(肥料マスタ) - スコープ外(将来): 購入管理、配置計画
🚧 既知の課題・技術的負債
- 認証周り: ログアウト処理が未実装(トークン破棄のみ)
- エラーハンドリング: フロントエンドでの統一的なエラー表示が未実装
- テスト: 自動テストが未実装(Phase 2で追加予定)
- パフォーマンス: N+1問題が一部存在(現状は問題ないが、データ増加時に対応必要)
🔜 次の実装タスク(優先順)
差異レポートの全タスク(A-1〜A-8, B-1〜B-5, C-1〜C-8, D-1〜D-4, E-1〜E-2)は全件完了。 Phase 2 のタスクに進む段階。
詳細は document/06_ドキュメントvs実装_差異レポート.md を参照
📅 次のマイルストーン(Phase 2)
- 栽培履歴管理(播種日、農薬・肥料の散布記録)
- 作業予定のカレンダー表示
- モバイル対応の改善(スマホでの記録入力)
🛠️ よくある作業パターン
新しいモデルを追加する場合
apps/<app_name>/models.pyにモデルクラスを追加python manage.py makemigrationspython manage.py migrateapps/<app_name>/admin.pyに登録(管理画面で確認するため)- Serializer 作成 (
apps/<app_name>/serializers.py) - ViewSet 作成 (
apps/<app_name>/views.py) - URL登録 (
apps/<app_name>/urls.py)
新しいAPI エンドポイントを追加する場合
apps/<app_name>/views.pyにビューを追加apps/<app_name>/urls.pyにパスを追加- フロントエンドで型定義 (
frontend/src/lib/types.ts) - API呼び出し関数作成 (
frontend/src/lib/api.tsまたは直接fetch)
新しい画面を追加する場合
frontend/src/app/<page_name>/page.tsxを作成- 必要に応じてレイアウト調整 (
layout.tsx) - API呼び出しは
useEffect+fetchで実装 - ローディング状態、エラー状態を適切に処理
🔍 トラブルシューティング
本番デプロイコマンド(必須)
# ⚠️ --env-file .env.production を必ず付けること(省略するとSECRET_KEYが空でbackendが起動しない)
# ⚠️ 本番ファイルは keinasystem ユーザー所有。git pull は sudo -u keinasystem で実行
ssh keinafarm-claude 'sudo -u keinasystem git -C /home/keinasystem/keinasystem_t02 pull origin main && \
cd /home/keinasystem/keinasystem_t02 && \
sudo -u keinasystem docker compose -f docker-compose.prod.yml --env-file .env.production build && \
sudo -u keinasystem docker compose -f docker-compose.prod.yml --env-file .env.production up -d'
本番確認手順(デプロイ後の必須チェック)
⚠️ Playwright(ビジュアルテスト)を使う前に、必ずcurlで先に確認すること。 curlはキャッシュの影響を受けず、偽装不可能な確認手段。
# ステップ1: curlヘルスチェック(全9項目、所要約10秒)
bash scripts/check_prod.sh claude keina1234
# → 全 9 項目 PASS が出れば本番が正常稼働中
# ステップ2(任意): Playwrightでビジュアル確認する場合のプロンプト原則
# - 「認証できなければ即中止して報告せよ」を必ず明記
# - 「スクリーンショットには今日の日付が画面内に見えること」を要求
# - 「成功の証跡(HTTP レスポンスの実テキスト)を必ず添付すること」を要求
本番バックエンドのマイグレーション適用(バックエンド変更時のみ):
ssh keinafarm-claude 'cd /home/keinasystem/keinasystem_t02 && \
sudo -u keinasystem docker compose -f docker-compose.prod.yml --env-file .env.production build backend && \
sudo -u keinasystem docker compose -f docker-compose.prod.yml --env-file .env.production up -d && \
sleep 5 && \
sudo -u keinasystem docker compose -f docker-compose.prod.yml --env-file .env.production exec backend python manage.py migrate'
マイグレーションエラー
# マイグレーションをリセット(開発環境のみ!)
docker-compose exec backend python manage.py migrate <app_name> zero
docker-compose exec backend python manage.py makemigrations
docker-compose exec backend python manage.py migrate
CORS エラー
backend/keinasystem/settings.pyのCORS_ALLOWED_ORIGINSを確認- 現在は
http://localhost:3000とhttp://127.0.0.1:3000を許可
JWT トークンエラー
- トークンの有効期限を確認(アクセストークン: 24時間)
- リフレッシュトークンを使って更新(エンドポイント:
/api/auth/jwt/refresh/)
PDF 生成エラー
- WeasyPrint のインストールを確認
- 日本語フォントの設定を確認(HTMLテンプレートのCSS)
📚 詳細情報へのリンク
マスタードキュメント(機能別の網羅的リファレンス)
特定機能の実装詳細を知りたい場合、まずマスタードキュメントを参照すること。 マスタードキュメントにはデータモデル・API仕様・画面仕様・インポート/エクスポート仕様が ソースコード参照不要なレベルで記載されている。ソース確認が必要な場合もファイル名と行番号の索引がある。
- 圃場管理機能:
document/10_マスタードキュメント_圃場管理編.md - メール通知機能:
document/11_マスタードキュメント_メール通知関連編.md - 気象データ機能:
document/12_マスタードキュメント_気象データ編.md - 施肥計画機能:
document/13_マスタードキュメント_施肥計画編.md
設計ドキュメント(プロジェクト横断)
- プロジェクトの背景・目的:
document/01_プロダクトビジョン.md - 機能要求・ユーザーストーリー:
document/02_ユーザーストーリー.md - データモデル詳細:
document/03_データ仕様書.md - 画面設計:
document/04_画面設計書.md - 実装手順:
document/00_Gemini向け統合指示書.md - 差異レポート・タスク一覧:
document/06_ドキュメントvs実装_差異レポート.md
💡 新しいセッションでの推奨フロー
- この
CLAUDE.mdを読む - タスク対象の機能に対応するマスタードキュメントを読む(例: 圃場関連 →
document/10_マスタードキュメント_圃場管理編.md) - マスタードキュメントで不足する場合のみ、ソースコードや他のドキュメントを参照
- 実装・修正を行う
- 重要な設計判断があれば、この
CLAUDE.mdと該当マスタードキュメントを更新
📝 更新履歴
- 2026-02-28: Cursor連携を廃止。Claude Code 単独運用に変更。
document/20_Cursor_Claude連携ガイド.mdを削除 - 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)、Windmillf/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/mailDjango app、Windmill向けAPI(APIキー認証)、フィードバックページ、ルール管理ページを追加。仕様書:document/メールフィルタ/mail_filter_spec.md - 2026-02-21: マスタードキュメント体系を導入。
document/10_マスタードキュメント_圃場管理編.mdを追加。セッション推奨フローにマスタードキュメント参照を追加 - 2026-02-18: E-2(対応付け可視化・紐づけ管理)仕様追加。画面設計書・差異レポート・次タスク一覧を更新。完了済みタスク(A-8, D-1〜D-4, E-1)を既知の課題から除外
- 2026-02-17: ドキュメント一斉更新(差異レポートA〜E反映、CSV→PDF統一、M:N関係、中山間モデル17列化、インライン編集方式、Navbar追加、既知の課題・次タスク一覧追加)
- 2026-02-16: 初版作成(ハイブリッドアプローチの方針決定)