- apps/weather 新規作成(WeatherRecord モデル、5種APIエンドポイント) - GET /api/weather/records/ 日次データ一覧 - GET /api/weather/summary/ 月別・年間集計 - GET /api/weather/gdd/ 有効積算温度(GDD)計算 - GET /api/weather/similarity/ 類似年分析(開花・収穫予測の基礎) - POST /api/weather/sync/ Windmill向け日次更新(APIキー認証) - management command: fetch_weather(初回一括・差分取得) - Crop.base_temp フィールド追加(GDD基準温度、default=0.0℃) - docker-compose.yml: MAIL_API_KEY 環境変数を追加(ローカルテスト修正) - requirements.txt: requests>=2.31 追加 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
415 lines
20 KiB
Markdown
415 lines
20 KiB
Markdown
# 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向けガイド)
|
||
├── 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/ # 送信者ルール管理
|
||
└── 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 で一括投入)
|
||
```
|
||
|
||
### 重要な設計判断
|
||
|
||
1. **M:N関係に変更**: 当初はM:1だったが、実運用で「1つの実圃場が複数の申請区画に紐づく」ケースが判明し、ManyToManyに変更(マイグレーション0003で実施)
|
||
|
||
2. **面積単位の二重管理**:
|
||
- DB内部は `area_m2` (整数) で保存
|
||
- 表示用に `area_tan` (反, Decimal) も保持
|
||
- 理由: 申請書ではm2、農家の感覚では反
|
||
|
||
3. **品種は全作物で統一**:
|
||
- 「作付けしない」も「その他」作物の品種として扱う
|
||
- UI操作を統一するため
|
||
|
||
4. **グループ機能**:
|
||
- `group_name` (エリアや用途によるグループ分け)
|
||
- `display_order` (リスト表示時の順序)
|
||
- マイグレーション0004で追加
|
||
|
||
5. **年度管理の設計方針**(⚠️ Phase 2 で必ず参照):
|
||
- **作付け計画**: 年度セレクタで独立して来年度も選べる。選んだ年度はlocalStorageに保存して維持
|
||
- **過去年度**: 「参照モード」として視覚的に区別(背景色・バナー)
|
||
- **Phase 2 の栽培管理・販売管理**: グローバル作業年度を導入し、基本は今年度に従う
|
||
- **栽培記録・作業日誌**: 日付中心設計、年度は日付から自動算出
|
||
- 参考: ソリマチ農業簿記の年度管理方式(明示的に年度を選択、変更するまで固定)
|
||
|
||
---
|
||
|
||
## 🔑 重要な制約・ルール
|
||
|
||
### 絶対に守るべきこと
|
||
|
||
1. **データの整合性**
|
||
- 年度 + 圃場の組み合わせは1つの Plan のみ (`unique_together`)
|
||
- 作物 + 品種名の組み合わせは一意 (`unique_together`)
|
||
|
||
2. **面積の扱い**
|
||
- 表示: 反 (tan)
|
||
- 計算・保存: m2
|
||
- 変換: 1反 = 1000m2 (正確には991.736m2だが、実運用では1000で統一)
|
||
|
||
3. **M:N関係の重要性**
|
||
- Field と OfficialKyosaiField は M:N
|
||
- Field と OfficialChusankanField は M:N
|
||
- 決して FK (1:N) に戻さない
|
||
|
||
4. **シンプルさ優先**
|
||
- 過度な抽象化を避ける
|
||
- 3回同じコードを書くまでは抽象化しない
|
||
- ユーザーは1人、パフォーマンス最適化は後回し
|
||
|
||
### コーディング規約
|
||
|
||
- **Backend**: Django のベストプラクティスに従う
|
||
- **Frontend**: TypeScript strict mode、ESLint に従う
|
||
- **API**: REST原則、エンドポイントは複数形 (`/api/fields/`, `/api/plans/`)
|
||
- **命名**: 日本語のフィールドは `verbose_name` で対応
|
||
|
||
---
|
||
|
||
## 📍 現在の実装状況
|
||
|
||
### ✅ 実装済み(Phase 1 - MVP)
|
||
|
||
1. **認証**: JWT認証(アクセストークン24h、リフレッシュトークン7日)
|
||
2. **圃場管理**:
|
||
- CRUD API (`/api/fields/`)
|
||
- ODS/Excelインポート (`/api/fields/import/`)
|
||
- グループ機能(マイグレーション0004)
|
||
3. **作付け計画**:
|
||
- 年度別の作付け計画 CRUD (`/api/plans/?year=2025`)
|
||
- 前年度コピー機能 (`/api/plans/copy_from_previous_year/`)
|
||
- 一括更新 (`/api/plans/bulk_update/`)
|
||
- 集計API (`/api/plans/summary/?year=2025`)
|
||
4. **申請書生成**:
|
||
- 水稲共済細目書 PDF (`/api/reports/kyosai/?year=2025`)
|
||
- 中山間交付金 PDF (`/api/reports/chusankan/?year=2025`)
|
||
5. **フロントエンド**:
|
||
- 作付け計画編集画面(集計サイドバー付き)
|
||
- 圃場一覧・詳細・新規作成
|
||
- データ取込画面
|
||
- 申請書ダウンロード画面
|
||
- ダッシュボード画面(概要サマリー、作物別集計、クイックアクセス)
|
||
6. **対応付け可視化・紐づけ管理** (E-2):
|
||
- 圃場一覧「対応表」モード(共済漢字地名・中山間所在地の一覧表示、直接紐づけ追加・解除)
|
||
- 圃場詳細画面の共済/中山間リンク管理(+追加、×解除、面積参考表示)
|
||
- 共通 LinkModal コンポーネント
|
||
7. **メールフィルタリング機能**(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`
|
||
8. **パスワード変更機能**:
|
||
- Backend: `POST /api/auth/change-password/`(JWT認証、`ChangePasswordView` in `keinasystem/urls.py`)
|
||
- Frontend: `/settings/password` ページ
|
||
- Navbar: KeyRound アイコンボタン(ログアウトボタンの左隣)
|
||
9. **気象データ基盤**(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 フロー: `u/admin/weather_sync.flow`(ローカル作成済み、本番デプロイ要)
|
||
- `Crop.base_temp`(GDD計算の基準温度、default=0.0℃)をCropモデルに追加
|
||
- **初回データ投入**: `docker compose exec backend python manage.py fetch_weather --full`
|
||
- **将来計画**: 開花・収穫予測(品種ごとの目標GDD設定 → 到達日予測)
|
||
|
||
### 🚧 既知の課題・技術的負債
|
||
|
||
1. **認証周り**: ログアウト処理が未実装(トークン破棄のみ)
|
||
2. **エラーハンドリング**: フロントエンドでの統一的なエラー表示が未実装
|
||
3. **テスト**: 自動テストが未実装(Phase 2で追加予定)
|
||
4. **パフォーマンス**: 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)
|
||
|
||
- 栽培履歴管理(播種日、農薬・肥料の散布記録)
|
||
- 作業予定のカレンダー表示
|
||
- モバイル対応の改善(スマホでの記録入力)
|
||
|
||
---
|
||
|
||
## 🛠️ よくある作業パターン
|
||
|
||
### 新しいモデルを追加する場合
|
||
|
||
1. `apps/<app_name>/models.py` にモデルクラスを追加
|
||
2. `python manage.py makemigrations`
|
||
3. `python manage.py migrate`
|
||
4. `apps/<app_name>/admin.py` に登録(管理画面で確認するため)
|
||
5. Serializer 作成 (`apps/<app_name>/serializers.py`)
|
||
6. ViewSet 作成 (`apps/<app_name>/views.py`)
|
||
7. URL登録 (`apps/<app_name>/urls.py`)
|
||
|
||
### 新しいAPI エンドポイントを追加する場合
|
||
|
||
1. `apps/<app_name>/views.py` にビューを追加
|
||
2. `apps/<app_name>/urls.py` にパスを追加
|
||
3. フロントエンドで型定義 (`frontend/src/lib/types.ts`)
|
||
4. API呼び出し関数作成 (`frontend/src/lib/api.ts` または直接fetch)
|
||
|
||
### 新しい画面を追加する場合
|
||
|
||
1. `frontend/src/app/<page_name>/page.tsx` を作成
|
||
2. 必要に応じてレイアウト調整 (`layout.tsx`)
|
||
3. API呼び出しは `useEffect` + `fetch` で実装
|
||
4. ローディング状態、エラー状態を適切に処理
|
||
|
||
---
|
||
|
||
## 🔍 トラブルシューティング
|
||
|
||
### 本番デプロイコマンド(必須)
|
||
|
||
```bash
|
||
# ⚠️ --env-file .env.production を必ず付けること(省略するとSECRET_KEYが空でbackendが起動しない)
|
||
ssh keinafarm-claude 'cd /home/akira/keinasystem_t02 && \
|
||
docker compose -f docker-compose.prod.yml --env-file .env.production build && \
|
||
docker compose -f docker-compose.prod.yml --env-file .env.production up -d'
|
||
```
|
||
|
||
### マイグレーションエラー
|
||
|
||
```bash
|
||
# マイグレーションをリセット(開発環境のみ!)
|
||
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/01_プロダクトビジョン.md`
|
||
- **機能要求・ユーザーストーリー**: `document/02_ユーザーストーリー.md`
|
||
- **データモデル詳細**: `document/03_データ仕様書.md`
|
||
- **画面設計**: `document/04_画面設計書.md`
|
||
- **実装手順**: `document/00_Gemini向け統合指示書.md`
|
||
- **差異レポート・タスク一覧**: `document/06_ドキュメントvs実装_差異レポート.md`
|
||
|
||
---
|
||
|
||
## 💡 新しいセッションでの推奨フロー
|
||
|
||
1. この `CLAUDE.md` を読む
|
||
2. タスク対象の機能に対応する**マスタードキュメント**を読む(例: 圃場関連 → `document/10_マスタードキュメント_圃場管理編.md`)
|
||
3. マスタードキュメントで不足する場合のみ、ソースコードや他のドキュメントを参照
|
||
4. 実装・修正を行う
|
||
5. 重要な設計判断があれば、この `CLAUDE.md` と該当マスタードキュメントを更新
|
||
|
||
---
|
||
|
||
## 📝 更新履歴
|
||
|
||
- 2026-02-28: 気象データ基盤を実装。`apps/weather` Django app(WeatherRecord, GDD API, 類似年分析API)、Windmill フロー `u/admin/weather_sync.flow`、管理コマンド `fetch_weather`。`Crop.base_temp` 追加(GDD基準温度)。初回データ投入は `fetch_weather --full`
|
||
- 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`
|
||
- 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: 初版作成(ハイブリッドアプローチの方針決定)
|