# 残課題の詳細説明と推奨対応 ## 📅 作成日時 2026年2月4日 ## 🎯 対象バージョン v1.0.11+22 --- ## 残課題一覧 ### 🟡 優先度: 中(次期バージョン推奨) --- ## 1. Matrix4 deprecated API の移行 ### 📍 場所 - [lib/screens/placeholders/brewery_map_screen.dart:122-123](lib/screens/placeholders/brewery_map_screen.dart#L122-L123) - [lib/screens/placeholders/brewery_map_screen.dart:159-160](lib/screens/placeholders/brewery_map_screen.dart#L159-L160) ### 🔍 問題の内容 **現在のコード**: ```dart // Line 121-123: 初期表示時のマップ配置 final matrix = Matrix4.identity() ..translate(xOffset, 10.0) // ❌ deprecated ..scale(fitScale); // ❌ deprecated // Line 158-160: リセットボタン押下時のマップ配置 final matrix = Matrix4.identity() ..translate(xOffset, 10.0) // ❌ deprecated ..scale(fitScale); // ❌ deprecated ``` **何が問題か**: - `Matrix4.translate()` と `Matrix4.scale()` が Flutter 3.38.3 で deprecated(非推奨)になった - 将来のFlutterバージョンでは削除される可能性がある - 現在は動作するが、flutter analyze で警告が出る **影響範囲**: - 酒蔵マップ画面(日本地図)の拡大縮小・移動機能 - リセットボタン(左下の回転アイコン) --- ### ✅ 推奨する修正方法 #### Step 1: vector_math パッケージのインポート確認 **pubspec.yaml を確認**: ```yaml dependencies: vector_math: ^2.1.4 # 既に含まれている可能性が高い ``` もし含まれていなければ: ```bash flutter pub add vector_math ``` #### Step 2: brewery_map_screen.dart の冒頭に import 追加 ```dart import 'package:vector_math/vector_math_64.dart'; // Vector3 のため ``` #### Step 3: 2箇所のコードを修正 **修正箇所1: Line 121-123** ```dart // Before (DEPRECATED): final matrix = Matrix4.identity() ..translate(xOffset, 10.0) ..scale(fitScale); // After (FIXED): final matrix = Matrix4.identity() ..translateByVector3(Vector3(xOffset, 10.0, 0.0)) ..scaleByDouble(fitScale); ``` **修正箇所2: Line 158-160** ```dart // Before (DEPRECATED): final matrix = Matrix4.identity() ..translate(xOffset, 10.0) ..scale(fitScale); // After (FIXED): final matrix = Matrix4.identity() ..translateByVector3(Vector3(xOffset, 10.0, 0.0)) ..scaleByDouble(fitScale); ``` --- ### 🧪 実機テスト項目(必須) 修正後、以下を必ず実機で確認してください: 1. **マップ画面を開く** - [ ] 日本地図が正しく表示される - [ ] 初期表示時の位置・サイズが正常 2. **ピンチイン/ピンチアウト(拡大縮小)** - [ ] 2本指でピンチイン(縮小)が滑らかに動作 - [ ] 2本指でピンチアウト(拡大)が滑らかに動作 - [ ] 最小サイズ・最大サイズの制限が機能している 3. **ドラッグ移動** - [ ] 1本指でマップをドラッグできる - [ ] 移動範囲が適切(マップが画面外に消えない) 4. **リセットボタン** - [ ] 左下の回転アイコンをタップ - [ ] マップが初期位置・サイズに戻る - [ ] アニメーションが滑らかに表示される 5. **都道府県タップ** - [ ] 都道府県をタップするとモーダルが表示される - [ ] タップ判定が正常 --- ### ⚠️ リスク評価 - **リスクレベル**: 🔴 高 - **理由**: 3D変換行列の操作のため、視覚的なバグが発生しやすい - **対策**: 実機テスト必須(エミュレータだけでは不十分) --- ### 📝 完全な修正コード例 ```dart import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:lucide_icons/lucide_icons.dart'; import 'package:vector_math/vector_math_64.dart'; // 追加 import 'dart:io'; // File import '../../providers/sake_list_provider.dart'; import '../../screens/sake_detail_screen.dart'; // Detail Screen import '../../widgets/map/prefecture_tile_map.dart'; import '../../theme/app_colors.dart'; import '../../models/maps/japan_map_data.dart'; import '../../providers/ui_experiment_provider.dart'; import '../../models/schema/item_type.dart'; // Phase D4: For ItemType.sake filtering // ... (他のコードは省略) ... // Line 117-127 を修正: if (!_isMapInitialized) { // Center horizontally final xOffset = (availableWidth - (mapWidth * fitScale)) / 2; final matrix = Matrix4.identity() ..translateByVector3(Vector3(xOffset, 10.0, 0.0)) // ✅ FIXED ..scaleByDouble(fitScale); // ✅ FIXED _transformationController.value = matrix; _isMapInitialized = true; } // ... (中略) ... // Line 155-162 を修正: FloatingActionButton.small( heroTag: 'map_reset', backgroundColor: appColors.surfaceElevated, foregroundColor: appColors.brandPrimary, elevation: 2, onPressed: () { // Reset to initial state (Fit Width) final xOffset = (availableWidth - (mapWidth * fitScale)) / 2; final matrix = Matrix4.identity() ..translateByVector3(Vector3(xOffset, 10.0, 0.0)) // ✅ FIXED ..scaleByDouble(fitScale); // ✅ FIXED _transformationController.value = matrix; }, child: const Icon(LucideIcons.rotateCcw, size: 20), ), ``` --- ## 2. ExpansionTileController deprecated の移行 ### 📍 場所 - [lib/widgets/sake_detail/sake_detail_specs.dart:24](lib/widgets/sake_detail/sake_detail_specs.dart#L24) - [lib/widgets/sake_detail/sake_detail_specs.dart:166](lib/widgets/sake_detail/sake_detail_specs.dart#L166) - [lib/widgets/sake_detail/sake_detail_specs.dart:199](lib/widgets/sake_detail/sake_detail_specs.dart#L199) ### 🔍 問題の内容 **現在のコード**: ```dart // Line 24: コントローラーの宣言 final ExpansionTileController _expansionController = ExpansionTileController(); // ❌ deprecated // Line 166: ExpansionTile での使用 ExpansionTile( controller: _expansionController, // ❌ deprecated // ... ) // Line 199: 編集モード時の展開 _expansionController.expand(); // ❌ deprecated ``` **何が問題か**: - `ExpansionTileController` が Flutter 3.31.0 で deprecated になった - 新しいAPIは `ExpansibleController` - 現在は動作するが、flutter analyze で警告が出る **影響範囲**: - 酒詳細画面の「詳細」セクション(AI解析情報) - 展開/折りたたみ動作 - 編集ボタン押下時の自動展開 --- ### ✅ 推奨する修正方法 #### Step 1: コントローラーの型を変更 ```dart // Before (Line 24): final ExpansionTileController _expansionController = ExpansionTileController(); // After: final ExpansibleController _expansionController = ExpansibleController(); ``` #### Step 2: 使用箇所は変更不要 `ExpansionTile` の `controller` パラメータと `.expand()` メソッドは、 `ExpansibleController` でも同じ名前で使えるため、**他の箇所は変更不要**です。 --- ### 🧪 実機テスト項目(必須) 修正後、以下を必ず実機で確認してください: 1. **酒詳細画面を開く** - [ ] 「詳細」セクションが表示される - [ ] 初期状態では折りたたまれている 2. **手動での展開/折りたたみ** - [ ] 「詳細」行をタップして展開 - [ ] もう一度タップして折りたたみ - [ ] アニメーションが滑らかに表示される 3. **編集ボタンでの自動展開** - [ ] 右側の編集アイコン(鉛筆マーク)をタップ - [ ] 「詳細」セクションが自動的に展開される - [ ] 編集モードに切り替わる(テキストフィールドが表示される) 4. **編集モードでの動作** - [ ] 特定名称、精米歩合などを編集できる - [ ] 「保存」ボタンで保存できる - [ ] 「キャンセル」ボタンで元に戻る 5. **セット商品での非表示** - [ ] セット商品の詳細画面では「詳細」セクションが表示されない --- ### ⚠️ リスク評価 - **リスクレベル**: 🟡 中 - **理由**: UIの展開/折りたたみ動作のみ、データ変更なし - **対策**: 実機テストで動作確認 --- ### 📝 完全な修正コード ```dart import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:lucide_icons/lucide_icons.dart'; import '../../models/sake_item.dart'; import '../../theme/app_colors.dart'; import 'package:hive_flutter/hive_flutter.dart'; class SakeDetailSpecs extends StatefulWidget { final SakeItem sake; final ValueChanged onUpdate; const SakeDetailSpecs({ super.key, required this.sake, required this.onUpdate, }); @override State createState() => _SakeDetailSpecsState(); } class _SakeDetailSpecsState extends State { bool _isEditing = false; final ExpansibleController _expansionController = ExpansibleController(); // ✅ FIXED // ... (他のコードは変更なし) ... } ``` --- ## 3. rawSakeListItemsProvider にコメント追加 ### 📍 場所 - [lib/screens/dev_menu_screen.dart:189](lib/screens/dev_menu_screen.dart#L189) ### 🔍 問題の内容 **現在のコード**: ```dart // Line 189: final allItems = ref.read(rawSakeListItemsProvider).asData?.value ?? []; ``` **何が問題か**: - `rawSakeListItemsProvider` は Phase D6 で「空状態判定専用」として設計された - しかし、Dev Menu(開発者メニュー)では「全データ解析」に使用されている - コメントがないため、なぜ `rawSakeListItemsProvider` を使っているのか不明確 - 将来的に誤って `allSakeItemsProvider` に変更されるリスクがある **影響範囲**: - Dev Menu の「データ修復(再解析)」機能 - セット商品・Draft を含む全データの統計情報 --- ### ✅ 推奨する修正方法 #### 判断基準 **Option A: コメント追加(推奨)** Dev Menu で**セット商品・Draft を含む全データ**の統計が必要な場合: ```dart // Dev Menu: セット商品・Draft含む全データを解析するため rawSakeListItemsProvider を使用 // Phase D6設計: rawSakeListItemsProvider はフィルタリング前の生データを提供 final allItems = ref.read(rawSakeListItemsProvider).asData?.value ?? []; ``` **Option B: allSakeItemsProvider に変更** ユーザーが見える範囲のデータのみ統計が必要な場合: ```dart // Dev Menu: ユーザーに表示されるデータのみを解析 // セット商品・Draftは除外される final allItems = ref.read(allSakeItemsProvider).asData?.value ?? []; ``` --- ### 🧪 実機テスト項目 修正後、以下を確認してください: 1. **Dev Menu を開く** - [ ] 設定画面 → その他 → 開発者メニュー 2. **データ修復を実行** - [ ] 「データ修復(再解析)」をタップ - [ ] 修復対象件数が表示される - [ ] セット商品も対象に含まれるか確認(Option A の場合) --- ### ⚠️ リスク評価 - **リスクレベル**: 🟢 低 - **理由**: コメント追加のみ、または明確な意図での Provider 変更 - **対策**: Dev Menu の動作確認のみ --- ### 📝 推奨する修正コード(Option A) ```dart Future _runBatchAnalysis(BuildContext context, WidgetRef ref) async { // Dev Menu: セット商品・Draft含む全データを解析するため rawSakeListItemsProvider を使用 // Phase D6設計: rawSakeListItemsProvider はフィルタリング前の生データを提供 // allSakeItemsProvider を使うと、セット商品・Draftが除外されてしまう final allItems = ref.read(rawSakeListItemsProvider).asData?.value ?? []; if (allItems.isEmpty) return; // Filter items that need repair (e.g., empty stats) final targets = allItems.where((item) { final stats = item.hiddenSpecs.sakeTasteStats; final isStatsEmpty = stats.aroma == 0 && stats.bitterness == 0 && stats.sweetness == 0 && stats.acidity == 0 && stats.body == 0; return isStatsEmpty || item.metadata.aiConfidence == null; }).toList(); // ... (残りのコードは変更なし) ... } ``` --- ## 📊 残課題の優先順位と推奨スケジュール ### 次期バージョン v1.0.12 での対応推奨 | 課題 | 優先度 | 作業時間 | リスク | 推奨タイミング | |------|--------|----------|--------|----------------| | 1. Matrix4 deprecated | 🟡 中 | 1.5時間 | 🔴 高 | 次期バージョン必須 | | 2. ExpansionTileController | 🟡 中 | 1時間 | 🟡 中 | 次期バージョン必須 | | 3. rawSakeListItemsProvider コメント | 🟢 低 | 10分 | 🟢 低 | 任意 | ### 推奨作業順序 #### Day 1(2時間) 1. ✅ Matrix4 deprecated 移行(30分) 2. ✅ 実機テスト: 酒蔵マップ(30分) 3. ✅ ExpansionTileController 移行(20分) 4. ✅ 実機テスト: 酒詳細画面(20分) 5. ✅ rawSakeListItemsProvider コメント追加(10分) 6. ✅ flutter analyze 確認(10分) #### Day 2(1時間) 1. ✅ 最終ビルド(Lite版 + Pro版)(30分) 2. ✅ 受け入れテスト(ACCEPTANCE_TEST_CHECKLIST.md)(30分) --- ## ❓ ユーザーが決める必要があること ### 3. rawSakeListItemsProvider の使用目的 **質問**: > Dev Menu の「データ修復(再解析)」で、セット商品も含めて修復しますか? **Option A: 含める(推奨)** - セット商品のAI解析情報も修復される - `rawSakeListItemsProvider` を使用(現状維持) - コメント追加のみ **Option B: 含めない** - セット商品は修復対象外 - `allSakeItemsProvider` に変更 - 通常の酒データのみ修復 **どちらを選ぶべきか**: - **推奨: Option A(含める)** - セット商品も解析情報が必要なため - 包括的なデータメンテナンスが可能 --- ## 🎯 まとめ ### すぐにやるべきこと(必須) 1. **Matrix4 deprecated 移行** - 視覚的バグのリスクが高い 2. **ExpansionTileController 移行** - UI動作に影響 ### 任意でやること(推奨) 3. **rawSakeListItemsProvider コメント追加** - 将来の誤変更防止 ### 実機テストは必須 - エミュレータだけでは不十分 - 実機でタッチ操作・アニメーションを確認 ### 推定時間 - **最小**: 2時間(修正 + 実機テスト) - **最大**: 3時間(完全な受け入れテスト含む) --- **作成者**: Claude (Sonnet 4.5) **作成日時**: 2026年2月4日 **対象バージョン**: v1.0.11+22 → v1.0.12