# 新生ぽんるーむ - 最終完全要件定義書

**プロジェクト名**: 新生ぽんるーむ (Reborn Ponshu Room)
**バージョン**: 2.0 - "My Digital Sake Cellar"
**作成日**: 2025-12-29
**設計**: Claude (Anthropic) + Gemini (Google AI) + posimai
**実装担当**: Antigravity + Claude

---

## 🎯 プロジェクトビジョン

> **「目の前の一本を撮るだけで、魔法のようにデータが溜まっていく」**

### 3つの核心コンセプト

#### 🍶 1. 「瞬撮」- 魔法の解析体験
カメラを向けて撮るだけで、AIが全てを読み取る。
ユーザーはただ「撮る」だけ。

#### 🎨 2. 「美録」- インスタ映えする情報の見せ方
雑誌のようなレイアウトで、いつでも見返したくなる。
そのままインスタに投稿できる美しさ。

#### 🧩 3. 「遊び心」- 意味のあるデータ分析
自分の好みを「発見」する楽しさ。
日本全国制覇マップ、フレーバーマトリックス。

---

## 📱 技術スタック

### 必須要件
```yaml
Flutter SDK: 3.38.3+
Dart: 3.10.1+
Android:
  compileSdk: 36
  targetSdk: 35 (Android 15対応)
  minSdk: 21 (Android 5.0+)
```

### 依存パッケージ

```yaml
dependencies:
  flutter:
    sdk: flutter

  # 状態管理（Riverpod - スキャンアプリで実績あり）
  flutter_riverpod: ^2.6.1
  hooks_riverpod: ^2.6.1
  flutter_hooks: ^0.20.5

  # ローカルDB
  hive: ^2.2.3
  hive_flutter: ^1.1.0

  # AI解析（Gemini 3.0）
  google_generative_ai: ^0.4.7
  http: ^1.6.0

  # カメラ・画像
  camera: ^0.11.0+2
  image_picker: ^1.2.1
  image: ^4.3.0

  # UI
  google_fonts: ^6.2.1
  fl_chart: ^1.1.1

  # 共有・保存
  share_plus: ^12.0.1
  path_provider: ^2.1.5

  # その他
  intl: ^0.20.2
  package_info_plus: ^9.0.0
  url_launcher: ^6.3.2
  countries_world_map: ^1.3.0
  cupertino_icons: ^1.0.8

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^6.0.0
  hive_generator: ^2.0.1
  build_runner: ^2.4.13
```

---

## 🎨 UI/UXデザイン原則

### デザインコンセプト
**「雑誌のような洗練、魔法のような心地よさ」**

### カラーパレット

```dart
// posimaiブランドカラー
static const Color posimaiBlue = Color(0xFF376495);

// ベースカラー
static const Color warmOffWhite = Color(0xFFFAFAF9);  // 背景
static const Color richBlack = Color(0xFF1A1A1A);      // テキスト
static const Color charcoalGray = Color(0xFF4A4A4A);   // サブテキスト
static const Color warmGray = Color(0xFF8A8A8A);       // 補助テキスト

// アクセントカラー
static const Color dustyPink = Color(0xFFE8B4B8);      // お気に入り
static const Color softYellow = Color(0xFFFEF3C7);     // ウィッシュリスト
```

### タイポグラフィ

```dart
// 銘柄名・タイトル: 明朝体（格調高く）
headlineMedium: GoogleFonts.notoSerifJp(
  fontSize: 20,
  fontWeight: FontWeight.w600,
  letterSpacing: 0.5,
  color: richBlack,
)

// データ・ボディ: ゴシック体（読みやすく）
bodyMedium: GoogleFonts.notoSansJp(
  fontSize: 13,
  fontWeight: FontWeight.w400,
  color: charcoalGray,
)

// ラベル・キャプション: ゴシック体
bodySmall: GoogleFonts.notoSansJp(
  fontSize: 11,
  fontWeight: FontWeight.w500,
  color: warmGray,
)
```

---

## 🍶 1. 「瞬撮」- 魔法の解析体験

### APIキー設定

```dart
// lib/secrets.dart
class Secrets {
  static const String geminiApiKey = 'AIzaSyA2BSr16R2k0bHjSYcSUdmLoY8PKwaFts0';
}
```

### Gemini 3.0統合

**重要**: 以下のいずれかを使用

```dart
// オプション1: 最新の3.0プレビュー（推奨）
model: 'gemini-3.0-flash-latest'

// オプション2: 安定版2.5 Flash（スキャンアプリで実績）
model: 'gemini-2.5-flash-latest'
```

### AIソムリエのリアルタイム実況

**解析中のUI**:

```dart
class AnalyzingOverlay extends StatelessWidget {
  final String currentStage;

  const AnalyzingOverlay({required this.currentStage});

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.black.withOpacity(0.7),
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            CircularProgressIndicator(
              valueColor: AlwaysStoppedAnimation(posimaiBlue),
            ),
            SizedBox(height: 24),
            Text(
              currentStage,
              style: GoogleFonts.notoSansJp(
                fontSize: 16,
                color: Colors.white,
              ),
            ),
          ],
        ),
      ),
    );
  }
}
```

**ステージの例**:
```dart
[
  'ラベルを読んでいます...',
  'お、これは〇〇県の銘柄ですね...',
  '精米歩合を確認中...',
  'データを整理しています...',
]
```

### 自動ポエム生成

Geminiのレスポンスに以下を追加:

```dart
final prompt = '''
この画像は日本酒のボトルまたはラベルの写真です。
ラベルに書かれているテキスト情報を正確に読み取り、JSON形式で返してください。

【重要な指示】
1. ラベルに明確に書かれている情報のみを抽出してください
2. 推測や想像で値を入れないでください（読めない場合はnullまたは省略）
3. 数値は必ず数字のみ（単位記号%などは除く）
4. このお酒の印象を一言で表す「キャッチコピー」を自動生成してください

【出力フォーマット】
{
  "brandName": "銘柄名",
  "type": "特定名称",
  "alcoholContent": 数値,
  "polishingRatio": 数値,
  "breweryName": "酒蔵名",
  "prefecture": "都道府県名",
  "catchCopy": "夜風と楽しみたい、淡麗な一滴"  // ← 自動生成
}

**JSON以外の余計な説明は一切不要です。JSONのみを出力してください。**
''';
```

---

## 🎨 2. 「美録」- インスタ映えする情報の見せ方

### モダン・カタログ・カード

**Web版の縦並びを捨て、左右2段構成を採用**:

```dart
// lib/widgets/sake_card.dart
class SakeCard extends StatelessWidget {
  final SakeItem item;

  const SakeCard({required this.item});

  @override
  Widget build(BuildContext context) {
    return Card(
      elevation: 0,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(12),
        side: BorderSide(color: Color(0xFFE8E8E8), width: 1),
      ),
      child: Padding(
        padding: EdgeInsets.all(16),
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // 左: 写真（角丸12px）
            ClipRRect(
              borderRadius: BorderRadius.circular(12),
              child: Image.network(
                item.imagePath,
                width: 100,
                height: 100,
                fit: BoxFit.cover,
              ),
            ),
            SizedBox(width: 16),
            // 右: テキスト情報
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  // 銘柄名（明朝体、大きく）
                  Text(
                    item.brandName ?? '日本酒',
                    style: GoogleFonts.notoSerifJp(
                      fontSize: 18,
                      fontWeight: FontWeight.w600,
                      color: richBlack,
                    ),
                  ),
                  SizedBox(height: 4),
                  // 酒蔵・産地（ゴシック体、控えめ）
                  Text(
                    '${item.breweryName ?? ''} | ${item.prefecture ?? ''}',
                    style: GoogleFonts.notoSansJp(
                      fontSize: 11,
                      color: warmGray,
                    ),
                  ),
                  SizedBox(height: 8),
                  // 評価
                  StarRating(rating: item.rating ?? 0),
                  SizedBox(height: 4),
                  // 種類
                  Text(
                    item.type ?? '',
                    style: GoogleFonts.notoSansJp(
                      fontSize: 11,
                      color: charcoalGray,
                    ),
                  ),
                  // キャッチコピー（NEW!）
                  if (item.catchCopy != null) ...[
                    SizedBox(height: 8),
                    Text(
                      item.catchCopy!,
                      style: GoogleFonts.notoSerifJp(
                        fontSize: 12,
                        fontStyle: FontStyle.italic,
                        color: posimaiBlue,
                      ),
                    ),
                  ],
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}
```

### インスタ専用・共有カード生成

**正方形（1:1）の画像を自動生成**:

```dart
// lib/services/instagram_share_service.dart
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:image/image.dart' as img;

class InstagramShareService {
  static Future<String> generateInstagramImage(SakeItem item) async {
    // 1. 画像を読み込み
    final imageBytes = await File(item.imagePath).readAsBytes();
    final image = img.decodeImage(imageBytes)!;

    // 2. 正方形（1080x1080）にクロップ
    final size = 1080;
    final square = img.copyResizeCropSquare(image, size: size);

    // 3. 下半分にposimaiカラーのオーバーレイ
    final overlay = img.Image(width: size, height: size ~/ 2);
    img.fillRect(
      overlay,
      x1: 0,
      y1: 0,
      x2: size,
      y2: size ~/ 2,
      color: img.ColorRgb8(55, 100, 149), // posimaiBlue
    );

    // 4. オーバーレイを合成
    img.compositeImage(
      square,
      overlay,
      dstX: 0,
      dstY: size ~/ 2,
    );

    // 5. テキストを描画（銘柄名、評価、ハッシュタグ）
    // TODO: 白抜き明朝体でテキスト描画

    // 6. 保存
    final directory = await getTemporaryDirectory();
    final path = '${directory.path}/instagram_${DateTime.now().millisecondsSinceEpoch}.jpg';
    await File(path).writeAsBytes(img.encodeJpg(square));

    return path;
  }

  static Future<void> shareToInstagram(SakeItem item) async {
    // インスタ用画像を生成
    final imagePath = await generateInstagramImage(item);

    // 共有
    await Share.shareXFiles(
      [XFile(imagePath)],
      text: '''
🍶 ${item.brandName ?? '日本酒'}

${item.catchCopy ?? ''}

#ぽんるーむ #日本酒 #${item.prefecture ?? ''} #日本酒好きと繋がりたい
''',
    );
  }
}
```

**レイアウトイメージ**:
```
┌────────────────────┐
│                    │
│   [日本酒ラベル写真] │  ← 上半分（540px）
│                    │
├────────────────────┤
│  posimaiブルー背景  │  ← 下半分（540px）
│                    │
│  獺祭（明朝体・白）   │  ← 銘柄名
│  ⭐⭐⭐⭐⭐        │  ← 評価
│                    │
│  夜風と楽しみたい、  │  ← キャッチコピー
│  淡麗な一滴         │
│                    │
│  #ぽんるーむ        │  ← ハッシュタグ
│           [logo]   │  ← posimaiロゴ（右下）
└────────────────────┘
```

---

## 🧩 3. 「遊び心」- 意味のあるデータ分析

### フレーバー・マトリックス

**4象限チャートで味の傾向を可視化**:

```
      甘口
       ↑
       │
濃醇 ←─┼─→ 淡麗
       │
       ↓
      辛口
```

**実装**:

```dart
// lib/widgets/flavor_matrix.dart
class FlavorMatrix extends StatelessWidget {
  final List<SakeItem> items;

  const FlavorMatrix({required this.items});

  @override
  Widget build(BuildContext context) {
    // AIが解析したフレーバータグから傾向を計算
    // 例: "甘口"タグが多い → 甘口寄り
    // "フルーティー"タグが多い → 淡麗寄り

    return Container(
      height: 200,
      child: CustomPaint(
        painter: FlavorMatrixPainter(
          userPosition: _calculateUserPosition(),
        ),
      ),
    );
  }

  Offset _calculateUserPosition() {
    // ユーザーの好みを計算
    // 甘口/辛口、濃醇/淡麗の2軸で位置を決定
    return Offset(0.3, 0.6); // 例: やや甘口、やや淡麗
  }
}
```

### 日本酒・制覇マップ

**都道府県マップをposimaiカラーで塗りつぶし**:

```dart
// lib/screens/home/map_tab.dart
SimpleMap(
  instructions: SMapJapan.instructions,
  defaultColor: warmGray,  // 未踏破
  colors: SMapJapanColors(
    // データから自動計算
    ..._prefectureColors(),
  ).toMap(),
  callback: (id, name, tapDetails) {
    // タップで詳細表示
    _showPrefectureDetail(name);
  },
)

Map<String, Color> _prefectureColors() {
  final counts = _countByPrefecture();
  return counts.map((prefecture, count) {
    if (count == 0) return MapEntry(prefecture, warmGray);
    if (count < 3) return MapEntry(prefecture, posimaiBlue.withOpacity(0.3));
    return MapEntry(prefecture, posimaiBlue);
  });
}
```

**バッジ表示**:

```dart
// マップの上部に表示
Container(
  padding: EdgeInsets.all(16),
  decoration: BoxDecoration(
    color: Colors.white,
    borderRadius: BorderRadius.circular(8),
  ),
  child: Column(
    children: [
      Text(
        '制覇: ${_completedPrefectures()} / 47',
        style: GoogleFonts.notoSerifJp(
          fontSize: 24,
          fontWeight: FontWeight.bold,
          color: posimaiBlue,
        ),
      ),
      SizedBox(height: 8),
      Text(
        'あと${47 - _completedPrefectures()}県で全国制覇！',
        style: GoogleFonts.notoSansJp(
          fontSize: 13,
          color: charcoalGray,
        ),
      ),
    ],
  ),
)
```

### Synology バックアップ・ステータス

**マイページの右上に控えめに表示**:

```dart
// lib/screens/home/profile_tab.dart
Positioned(
  top: 16,
  right: 16,
  child: Container(
    padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
    decoration: BoxDecoration(
      color: Colors.green[50],
      borderRadius: BorderRadius.circular(16),
      border: Border.all(color: Colors.green[200]!),
    ),
    child: Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Icon(Icons.cloud_done, size: 16, color: Colors.green[700]),
        SizedBox(width: 4),
        Text(
          'Home Lab Sync: OK',
          style: GoogleFonts.notoSansJp(
            fontSize: 11,
            color: Colors.green[700],
            fontWeight: FontWeight.w500,
          ),
        ),
      ],
    ),
  ),
)
```

---

## 📦 データモデル（更新版）

### SakeItem (Hive Model)

**キャッチコピーを追加**:

```dart
import 'package:hive/hive.dart';

part 'sake_item.g.dart';

@HiveType(typeId: 0)
class SakeItem extends HiveObject {
  // 基本情報
  @HiveField(0)
  String? brandName;

  @HiveField(1)
  String? breweryName;

  @HiveField(2)
  String? prefecture;

  @HiveField(3)
  String? type;

  @HiveField(4)
  double? alcoholContent;

  @HiveField(5)
  int? polishingRatio;

  // 画像
  @HiveField(6)
  String imagePath;

  @HiveField(7)
  List<String>? additionalImages;

  // 評価・メモ
  @HiveField(8)
  double? rating;

  @HiveField(9)
  String? memo;

  @HiveField(10)
  List<String>? tags;

  // フラグ
  @HiveField(11)
  bool isFavorite;

  @HiveField(12)
  bool isWishlist;

  // 日時
  @HiveField(13)
  DateTime createdAt;

  @HiveField(14)
  DateTime? updatedAt;

  // 価格（オプション）
  @HiveField(15)
  int? price;

  @HiveField(16)
  int? volume;

  // 🆕 AIが生成したキャッチコピー
  @HiveField(17)
  String? catchCopy;

  // 🆕 フレーバープロファイル（甘口/辛口、濃醇/淡麗）
  @HiveField(18)
  double? sweetnessScore;  // -1.0（辛口）～ 1.0（甘口）

  @HiveField(19)
  double? bodyScore;  // -1.0（淡麗）～ 1.0（濃醇）

  SakeItem({
    this.brandName,
    this.breweryName,
    this.prefecture,
    this.type,
    this.alcoholContent,
    this.polishingRatio,
    required this.imagePath,
    this.additionalImages,
    this.rating,
    this.memo,
    this.tags,
    this.isFavorite = false,
    this.isWishlist = false,
    required this.createdAt,
    this.updatedAt,
    this.price,
    this.volume,
    this.catchCopy,
    this.sweetnessScore,
    this.bodyScore,
  });
}
```

---

## 🚀 実装優先順位

### Phase 1: MVP（5時間）

#### チェックリスト
- [ ] プロジェクト初期化（`flutter create ponshu_room_reborn`）
- [ ] Android設定（compileSdk: 36, targetSdk: 35）
- [ ] 依存関係追加
- [ ] Hiveセットアップ
- [ ] SakeItemモデル（キャッチコピー含む）
- [ ] posimaiテーマ
- [ ] ホーム画面骨組み（4タブ）
- [ ] **Gemini 3.0解析 + リアルタイム実況**
- [ ] カメラ撮影
- [ ] 入力フォーム
- [ ] 詳細画面
- [ ] SafeArea対応

### Phase 2: 「美録」UI洗練（3時間）

#### チェックリスト
- [ ] モダン・カタログ・カード（左右2段構成）
- [ ] 明朝体×ゴシック体の適用
- [ ] インスタ専用画像生成機能
- [ ] Hero遷移
- [ ] アニメーション（200-300ms）

### Phase 3: 「遊び心」機能拡張（4時間）

#### チェックリスト
- [ ] フレーバー・マトリックス
- [ ] 日本酒・制覇マップ + バッジ
- [ ] Synologyバックアップ・ステータス表示
- [ ] AIソムリエ（質問例、チャット形式）
- [ ] マイページ統計グラフ
- [ ] 検索・フィルタ・ソート

### Phase 4: 共有機能（2時間）

#### チェックリスト
- [ ] シンプルテキスト共有
- [ ] Instagram用正方形画像生成
- [ ] キャッチコピー付き共有

**合計所要時間**: 14時間

---

## 📐 画面構成

### ホーム画面（HomeScreen）

#### ボトムナビゲーション
```
┌─────┬─────┬─────┬─────┐
│ 🍶  │ 🗺️  │ 🤖  │ 👤  │
│ 酒  │ マップ│ AI  │ MY  │
└─────┴─────┴─────┴─────┘
```

#### タブ1: 酒リスト（ListTab）

**モダン・カタログ・カード**:
```
┌────────────────────────────┐
│ [100x100] │ 獺祭            │ ← 明朝体、大きく
│   写真    │ 旭酒造 | 山口県  │ ← ゴシック体、控えめ
│  角丸12px │ ⭐⭐⭐⭐⭐ 純米大吟醸 │
│           │ "夜風と楽しみたい、淡麗な一滴" │ ← キャッチコピー
└────────────────────────────┘
```

#### タブ2: マップ（MapTab）

**日本酒・制覇マップ**:
- 未踏破: warmGray
- 3本未満: posimaiBlue (30% opacity)
- 3本以上: posimaiBlue (100%)
- バッジ: 「制覇: 5 / 47」「あと42県で全国制覇！」

#### タブ3: AIソムリエ（AiTab）

**質問例ボタン**:
```dart
Wrap(
  spacing: 8,
  children: [
    OutlinedButton(
      child: Text('純米大吟醸とは？'),
      onPressed: () => _askAI('純米大吟醸について詳しく教えて'),
    ),
    OutlinedButton(
      child: Text('山田錦について教えて'),
      onPressed: () => _askAI('山田錦という酒米の特徴を教えて'),
    ),
    OutlinedButton(
      child: Text('刺身に合う日本酒は？'),
      onPressed: () => _askAI('刺身に合う日本酒のおすすめを教えて'),
    ),
    OutlinedButton(
      child: Text('初心者におすすめの銘柄'),
      onPressed: () => _askAI('日本酒初心者におすすめの銘柄を教えて'),
    ),
  ],
)
```

#### タブ4: マイページ（ProfileTab）

**セクション構成**:

1. **Synologyバックアップステータス**（右上）
   ```
   🏠 Home Lab Sync: OK
   ```

2. **酒蔵サマリー**
   ```
   ┌─────────┬─────────┬─────────┐
   │    1    │    0    │    0    │
   │ 飲んだ本数│お気に入り│ 買いたい │
   └─────────┴─────────┴─────────┘
   ```

3. **フレーバー・マトリックス**
   ```
        甘口
         ↑
         │  ●（あなた）
   濃醇 ←─┼─→ 淡麗
         │
         ↓
        辛口

   あなたが選ぶ酒は、フルーティーな甘口に偏っています
   ```

4. **よく飲む都道府県**
   ```
   🥇 青森県 ━━━━━━━━━━ 1本
   ```

5. **飲酒傾向グラフ**
   - 月別飲酒本数（直近6ヶ月）
   - 評価分布（1-5星）

---

## 🔐 プライバシー・セキュリティ

### データ保存場所

#### デフォルト（全ユーザー）
```
✅ ローカル（Hive DB）のみ
✅ 写真はアプリ専用ディレクトリ
❌ 外部サーバーへの送信なし
```

#### オプション（posimai専用）
```
✅ Synology NAS連携（WebDAV/FTP）
✅ 自動バックアップ
✅ "Home Lab Sync: OK" ステータス表示
```

---

## 📄 ファイル構成

```
lib/
├── main.dart
├── secrets.dart
├── models/
│   ├── sake_item.dart
│   └── sake_item.g.dart
├── providers/
│   ├── sake_repository_provider.dart
│   ├── gemini_provider.dart
│   └── camera_provider.dart
├── services/
│   ├── hive_service.dart
│   ├── gemini_service.dart
│   ├── share_service.dart
│   └── instagram_share_service.dart  ← 🆕
├── screens/
│   ├── home/
│   │   ├── home_screen.dart
│   │   ├── list_tab.dart
│   │   ├── map_tab.dart
│   │   ├── ai_tab.dart
│   │   └── profile_tab.dart
│   ├── detail_screen.dart
│   └── input_screen.dart
├── widgets/
│   ├── sake_card.dart               ← 🆕 左右2段構成
│   ├── star_rating.dart
│   ├── prefecture_dropdown.dart
│   ├── tag_chip.dart
│   ├── flavor_matrix.dart           ← 🆕
│   └── analyzing_overlay.dart       ← 🆕 リアルタイム実況
└── theme/
    └── app_theme.dart
```

---

## ✅ 完成基準

### MVP完成の定義
- [ ] カメラで日本酒を撮影できる
- [ ] Gemini 3.0でリアルタイム実況しながら解析
- [ ] キャッチコピーが自動生成される
- [ ] データをHiveに保存できる
- [ ] モダン・カタログ・カード（左右2段）で表示
- [ ] 詳細表示できる
- [ ] SafeAreaで見切れない
- [ ] Android 15 (Xiaomi 14T Pro) で動作する

### 最終完成の定義
- [ ] すべての機能が動作
- [ ] フレーバー・マトリックス表示
- [ ] 日本酒・制覇マップ + バッジ
- [ ] Instagram用正方形画像生成
- [ ] Synologyバックアップステータス表示
- [ ] 「雑誌のような」デザイン
- [ ] 60fpsの滑らかな動作
- [ ] 「魔法のような」心地よさ

---

**最終更新**: 2025-12-29
**設計**: Claude (Anthropic) + Gemini (Google AI) + posimai
**実装担当**: Antigravity + Claude

**Let's create the magic! 🍶✨**
