ChoTensai_V3 / PLAN.md
TOMOCHIN4
docs: v2.2.0 パスワード認証ステータス更新
6be1748

PLAN: 超天才クイズ v2.x - 配信モード開発

作成日: 2025-12-28 更新日: 2025-12-29 ベースライン: v2.0.0 STABLE(完全バックアップ済み V2.0.0/現在: ✅ v2.2.0 パスワード認証実装完了


v2.2.0 パスワード認証(実装完了)

項目
GAS バージョン @59(変更なし)
HuggingFace コミット b9c0b35
ベース v2.1.1

目的

V1.xとV2.xでユーザー情報を共有し、パスワード認証を統一

実装完了

  • ✅ bcrypt.js CDN導入(クライアント側パスワード検証)
  • ✅ apiClient.js: login()でbcryptパスワード検証実装
  • ✅ components.js: ログイン画面簡素化(新規登録削除)
  • ✅ V1.x/V2.xユーザー共有(同一Usersシート)

認証フロー

1. ユーザー名・パスワード入力
2. GAS login APIでpassword_hash取得
3. フロントエンドでbcrypt.compareSync()検証
4. 認証成功 → ホーム画面

設計方針

  • 新規登録はV1.xのみ(配信モードはログイン専用)
  • V1.xで登録したユーザーがV2.xでもログイン可能
  • パスワード未設定ユーザーはエラーメッセージで案内

v2.1.1 UI強化(完了)

項目
GAS バージョン @59
HuggingFace コミット 7abab3a
ベース v2.1.0

実装完了

  • ✅ 採点中プログレスバー+ステップインジケーター
  • ✅ スコアサークル(後光エフェクト+評価)
  • ✅ タブ切り替え(サマリー/詳細分析)
  • ✅ 問題別結果バー
  • ✅ 解答見直し機能強化
  • ✅ 不正解問題の解説表示
  • ✅ AI評価プロンプト強化

残タスク

  • 🔲 累積統計表示(教科別・ジャンル別バーチャート)

v2.1.0 UI移植(完了)

項目
GAS バージョン @58
HuggingFace コミット 682ef95
ベース v2.0.0 STABLE

目的

V1.xのリッチUI(React + Tailwind CSS)をv2.0.0配信モードに移植し、統一されたデザインを実現

実装完了

  • ✅ React 18 + Tailwind CSS CDN導入
  • ✅ SPA構成(index.htmlのみで全画面管理)
  • ✅ V1.xスタイル移植(ベージュ/ブラウン配色、フォント、アニメーション)
  • ✅ apiClient.js(GAS API用)
  • ✅ components.js(LoginScreen, HomeScreen, QuizScreen, ResultScreen, RankingScreen)
  • ✅ getTodayQuizzes API追加(GAS)
  • ✅ Code.jsにv2_get_today_quizzesルーティング追加
  • ✅ time_slot表示修正(AM→朝の配信)
  • ✅ MAX_OUTPUT_TOKENS 65536統一
  • ✅ 選択肢クリック時フィードバック(正解:赤+チェック、不正解:グレー)
  • ✅ 結果画面に問題文・AI評価・ヒント表示追加
  • ✅ AI評価オブジェクト処理修正(Reactエラー対応)

解決した問題

  • ✅ v2_get_today_quizzesがCode.jsのv2Actionsリストに未登録だった
  • ✅ time_slotが'morning'と比較されていた(正しくは'AM')
  • ✅ 正解インデックスがテキスト比較で特定されていなかった
  • ✅ 結果画面に問題文・解説が表示されていなかった
  • ✅ result.evaluationがオブジェクト型でReactエラーが発生

v2.0.0 リリース完了(参照用)

項目
リリース日 2025-12-29
GAS バージョン @54
HuggingFace コミット edc211d
バックアップ V2.0.0/
E2Eテスト ✅ 完了(ファクトチェック済み)

実装完了機能

  • ✅ 2教科×10問の一括LLM生成(generateBatchQuestions
  • ✅ LLM検証パート(validateBatchQuestions
  • ✅ 4択クイズUI(選択後自動進行、最終問題後自動採点)
  • ✅ CORS対応(Content-Type: text/plain でプリフライト回避)
  • ✅ sessionStorageによるデータ受け渡し
  • ✅ トークン認証
  • ✅ ポイント計算・結果表示

v2.x マイナーアップデート予定

項目 内容 優先度 状態
GASトリガー設定 朝6:00/夕15:00 自動配信 🔲
回答権管理 1ユーザー1回限りの回答権 🔲
ステータス表示 回答済み/未回答/未配信/期限切れ 🔲
ログイン改善 UX向上、エラーハンドリング 🔲
配信技術スタック 最適化・選別 🔲

1. プロジェクト概要

1.1 目的

v1.x(練習モード)をベースに、問題配信サービス(v2.x)のコア機能を構築する。

  • 問題配信: 毎日決まった時間に問題を配信
  • 回答回収: ユーザーの回答を収集
  • 採点: ポイント制で採点(正答 + 時間ボーナス)
  • AI評価: Geminiによる解説・フィードバック

v3.0.0への展望: ランキング・クラス制・ゲーミフィケーションはv3.0.0で実装予定

1.2 設計原則

  1. 既存資産の最大活用: v1.8.1の仕組みを可能な限り流用
  2. 分離と共有の明確化: 共有すべきものと分離すべきものを区別
  3. シンプルなアーキテクチャ: Static Space + GAS直結
  4. 段階的リリース: Phase単位で動作確認しながら進行

2. アーキテクチャ設計

2.1 全体構成図

┌─────────────────────────────────────────────────────────────────┐
│                      【共有レイヤー】                            │
│                                                                 │
│   ┌─────────────────┐  ┌─────────────────┐  ┌───────────────┐  │
│   │ QuestionDatabase│  │  GAS Core API   │  │  Gemini API   │  │
│   │   (1,600問)     │  │  (CRUD基盤)     │  │ (GAS経由)     │  │
│   └─────────────────┘  └─────────────────┘  └───────────────┘  │
│                                                                 │
│   ┌──────────────┐  ┌──────────────┐  ┌──────────────────────┐ │
│   │ Users Master │  │   Answers    │  │ UserQuestionUsage    │ │
│   │  (共通)      │  │ (mode列追加) │  │ ("delivery"含む)     │ │
│   └──────────────┘  └──────────────┘  └──────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
                               ↑
              ┌────────────────┴────────────────┐
              ↓                                  ↓
┌──────────────────────────┐      ┌──────────────────────────┐
│     v1.x 練習モード       │      │     v2.x 配信モード       │
│    (HF Space/Flask)      │      │    (Static Space)        │
├──────────────────────────┤      ├──────────────────────────┤
│ ・自由練習UI              │      │ ・配信型UI               │
│ ・Sessions               │      │ ・DailyQuizzes           │
│ ・Evaluations            │      │ ・DailyResults           │
│ ・Summaries              │      │ ・Rankings               │
│ ・Statistics             │      │ ・Classes                │
│ ・AI先生アドバイス        │      │ ・UserProfiles           │
│                          │      │ ・ポイント制              │
│ デプロイ: @45            │      │ デプロイ: @XX(新規)     │
└──────────────────────────┘      └──────────────────────────┘

2.2 共有するもの

要素 説明 共有方法
QuestionDatabase 1,600問の問題素材 既存シートをそのまま使用
Users ユーザーマスタ 同一シート、v2拡張はUserProfilesへ
Answers 回答履歴 mode列追加(practice/delivery)
UserQuestionUsage 出題履歴 "delivery"仮想ユーザーでv2管理
GAS基盤 API処理 同一プロジェクト、別デプロイ
Gemini API AI評価 GASから直接呼び出し

2.3 分離するもの

要素 v1.x v2.x
フロントエンド HF Space (Flask) Static Space
セッション管理 Sessions DailyQuizzes
成績計算 正答率ベース ポイント制
デプロイURL @45 (既存) @XX (新規)

3. データ設計

3.1 Spreadsheetシート構成

Google Spreadsheet
│
├─【共通シート】
│   ├─ Users              ← ユーザーマスタ(既存)
│   ├─ QuestionDatabase   ← 問題素材(既存 1,600問)
│   ├─ UserQuestionUsage  ← 出題履歴(既存 + "delivery"ユーザー)
│   ├─ Answers            ← 回答詳細(mode列追加)★変更
│   └─ Statistics         ← 苦手分析(統合対応)★変更
│
├─【v1専用シート】(既存・変更なし)
│   ├─ Sessions
│   ├─ GeneratedQuestions
│   ├─ Evaluations
│   └─ Summaries
│
└─【v2専用シート】(新規作成)
    ├─ DailyQuizzes       ← 配信問題管理
    ├─ DailyResults       ← ポイント・時間サマリ
    ├─ Rankings           ← ランキングキャッシュ
    ├─ Classes            ← クラス所属・履歴
    └─ UserProfiles       ← v2ユーザー拡張情報

3.2 新規シート詳細設計

DailyQuizzes(配信問題管理)

カラム 説明
quiz_id string "2025-12-28-AM-jp"
delivery_date date 配信日
time_slot string "AM" / "PM"
subject string "jp" / "math" / "sci" / "soc"
difficulty_pool string "基本" / "標準" / "応用"
question_ids string "jp_001,jp_045,..." (10問)
created_at datetime 作成日時
expires_at datetime 回答期限(当日23:59)

DailyResults(日次回答結果)

カラム 説明
result_id string UUID
user_id string ユーザーID
quiz_id string 配信ID
correct_count int 正解数
total_count int 問題数(10)
time_remaining int 残り秒数
accuracy float 正答率
correct_points int 正答ポイント(正解数×100)
time_bonus int 時間ボーナス(残り秒×正答率)
total_points int 合計ポイント
submitted_at datetime 回答日時

Rankings(ランキングキャッシュ)

カラム 説明
ranking_id string UUID
ranking_date date ランキング日
ranking_type string "jp" / "math" / "sci" / "soc" / "total"
rank int 順位
user_id string ユーザーID
display_name string 表示名
points int ポイント

Classes(クラス所属)

カラム 説明
class_id string UUID
user_id string ユーザーID
class_level int 1-6
class_name string "天才のたまご" 等
weighted_avg float 加重平均点
assigned_at datetime 判定日時

UserProfiles(v2ユーザー拡張)

カラム 説明
user_id string ユーザーID(Users.user_idと紐づく)
current_class int 現在のクラス(1-6)
weekly_points int 今週の累計ポイント
current_item string 所持アイテム(gold/silver/bronze/none)
item_expires_at datetime アイテム有効期限
token string 認証トークン(暗号化)
token_expires_at datetime トークン有効期限
created_at datetime v2登録日時

3.3 既存シート変更

Answers(mode列追加)

既存カラム + mode列
answer_id | user_id | ... | is_correct | mode
xxx       | user123 | ... | true       | practice  ← v1
yyy       | user123 | ... | false      | delivery  ← v2

4. GAS設計

4.1 ファイル構成

gas/
├─ Code.js                    ← 共通ルーティング(v1/v2両対応)★変更
├─ questiondb_functions.js    ← 共通(問題取得)★変更(難易度フィルタ追加)
├─ auth_functions.js          ← v2認証(トークン生成・検証)★新規
├─ delivery_functions.js      ← v2配信管理★新規
├─ scoring_functions.js       ← v2採点・ポイント計算★新規
├─ ranking_functions.js       ← v2ランキング計算★新規
├─ class_functions.js         ← v2クラス判定★新規
├─ gemini_functions.js        ← Gemini API呼び出し★新規
└─ [既存ファイル]             ← v1用(変更なし)

4.2 主要API一覧

v2専用エンドポイント

アクション 説明 入力 出力
verify_token トークン検証 token user_id, is_valid
get_delivery 配信問題取得 delivery_id, user_id quiz_data, questions
submit_delivery 回答送信 user_id, quiz_id, answers points, ranking
get_ranking ランキング取得 date, type rankings[]
get_user_profile プロフィール取得 user_id class, points, item
generate_daily_quiz 日次配信生成 time_slot quiz_ids[]

4.3 デプロイ戦略

同一GASプロジェクト、別デプロイメント

clasp deployments
├─ @45 "v1.8.1 練習用"     → GAS_API_URL_V1
└─ @XX "v2.0.0 配信用"     → GAS_API_URL_V2

Code.js ルーティング:
- v1Actions → 既存処理
- v2Actions → 新規処理

5. フロントエンド設計

5.1 Static Space構成

static-space/
├── index.html          ← ランディング(登録・ログイン)
├── quiz.html           ← クイズ画面(URLパラメータで配信切替)
├── result.html         ← 結果・AI評価表示
├── ranking.html        ← ランキング表示
├── profile.html        ← プロフィール・クラス表示
├── css/
│   └── style.css
└── js/
    ├── api.js          ← GAS API呼び出し
    ├── auth.js         ← トークン処理・認証
    ├── quiz.js         ← クイズロジック
    ├── timer.js        ← タイマー処理
    └── ranking.js      ← ランキング表示

5.2 URLパラメータ設計

配信URL:
https://xxx.static.hf.space/quiz.html?d=2025-12-28-AM-jp&t=abc123xyz

パラメータ:
- d: delivery_id(配信ID)
- t: token(ユーザー認証トークン、オプション)

フロー:
1. URLクリック
2. トークンあり → 自動ログイン
   トークンなし → localStorage確認 → なければログイン画面
3. delivery_idから配信問題取得
4. クイズ開始(5分タイマー)
5. 回答送信 → ポイント計算
6. 結果画面 + AI評価
7. ランキング表示

5.3 認証フロー

【初回登録】
1. ユーザーがindex.htmlで名前入力
2. GAS: Users登録 + UserProfiles作成 + トークン生成
3. トークンをlocalStorageに保存
4. 以降の配信URLはトークン付きで通知可能

【配信アクセス】
方式A: トークン付きURL(推奨)
  → URLのtパラメータで認証、即クイズ開始

方式B: localStorage認証
  → 前回のトークンで自動ログイン

方式C: 手動ログイン
  → 名前入力してトークン再取得

6. 配信スケジュール設計

6.1 配信タイミング

時間帯 時刻 教科数 内容
朝(AM) 6:00生成 2教科 ランダム2教科
夕(PM) 15:00生成 2教科 残り2教科
回答期限 23:59 - 当日中

6.2 GASトリガー設定

// 朝の配信生成(6:00)
function generateMorningQuiz() {
  const subjects = selectRandomSubjects(2); // 4教科から2つ選択
  subjects.forEach(subject => {
    generateDailyQuiz('AM', subject);
  });
}

// 夕方の配信生成(15:00)
function generateEveningQuiz() {
  const morningSubjects = getTodayMorningSubjects();
  const eveningSubjects = ['jp', 'math', 'sci', 'soc']
    .filter(s => !morningSubjects.includes(s));
  eveningSubjects.forEach(subject => {
    generateDailyQuiz('PM', subject);
  });
}

6.3 問題選択ロジック

function generateDailyQuiz(timeSlot, subject) {
  // 1. "delivery"ユーザーのUSAGE_COUNTが最小の問題を優先
  // 2. 難易度は全クラス共通で混合(基本:標準:応用 = 3:5:2)
  // 3. 10問選択
  // 4. DailyQuizzesに記録
  // 5. "delivery"ユーザーのUSAGE_COUNT更新
}

7. ポイント・ランキング設計

7.1 ポイント計算

正答ポイント = 正解数 × 100
時間ボーナス = 残り秒数 × 正答率
合計ポイント = 正答ポイント + 時間ボーナス

例: 8問正解、残り120秒
  正答ポイント = 8 × 100 = 800
  時間ボーナス = 120 × 0.8 = 96
  合計 = 896点

7.2 ランキング種類

種類 集計方法
国語 当日の国語ポイント順
算数 当日の算数ポイント順
理科 当日の理科ポイント順
社会 当日の社会ポイント順
総合 当日の4教科合計ポイント順

7.3 ランキング更新タイミング

  • 各回答送信時にリアルタイム更新
  • 翌日0:00に前日ランキングを確定・キャッシュ

8. クラス制設計

8.1 クラス定義

クラス 名称 加重平均点 難易度プール
6 超天才 3572点以上 応用
5 天才 2858〜3571点 応用
4 もうすぐ天才 2143〜2857点 標準
3 天才かも 1429〜2142点 標準
2 天才の見習い 715〜1428点 基本
1 天才のたまご 0〜714点 基本

8.2 加重平均計算

過去7日間の加重移動平均

重み:
  今日: ×1.5
  1日前: ×1.4
  2日前: ×1.3
  3日前: ×1.2
  4日前: ×1.1
  5日前: ×1.0
  6日前: ×0.9

計算式:
  加重平均 = Σ(日別ポイント × 重み) ÷ 7

※ 未参加日は0点としてカウント(継続参加インセンティブ)
※ 開始7日未満は経過日数で割る

8.3 クラス判定タイミング

  • 毎日0:00に全ユーザーの加重平均を再計算
  • クラス変動があればClassesシートに記録
  • UserProfilesのcurrent_classを更新

9. 週間アイテム設計(Phase 5)

9.1 アイテム定義

アイテム 週間ポイント閾値 日次ボーナス 有効期間
金の鉛筆 25,000点以上 +100点/日 1週間
銀の鉛筆 20,000点以上 +50点/日 1週間
銅の鉛筆 15,000点以上 +25点/日 1週間

9.2 判定タイミング

  • 毎週月曜0:00に前週のポイントを集計
  • 閾値を超えたユーザーにアイテム付与
  • UserProfilesのcurrent_item, item_expires_atを更新

10. 開発フェーズ

Phase 1: データ基盤(Week 1)

タスク 詳細 成果物
1.1 新規シート作成(5シート) Spreadsheet
1.2 Answersシートにmode列追加 Spreadsheet
1.3 GAS基本関数実装(CRUD) delivery_functions.js
1.4 "delivery"ユーザー作成 Users, UserQuestionUsage
1.5 難易度フィルタ追加 questiondb_functions.js

受入基準:

  • 全シートが作成され、手動でデータ投入可能
  • GASからCRUD操作が可能

Phase 2: 認証・配信基盤(Week 2)

タスク 詳細 成果物
2.1 トークン生成・検証関数 auth_functions.js
2.2 配信生成ロジック delivery_functions.js
2.3 GASトリガー設定(朝/夕) GASトリガー
2.4 配信問題取得API get_delivery
2.5 Static Space基本構成 index.html, quiz.html

受入基準:

  • トリガーで配信データが自動生成される
  • URLパラメータで配信問題を取得できる

Phase 3: 回答・採点(Week 3)

タスク 詳細 成果物
3.1 回答送信API submit_delivery
3.2 ポイント計算ロジック scoring_functions.js
3.3 Gemini評価呼び出し(GAS経由) gemini_functions.js
3.4 結果画面UI result.html
3.5 タイマー実装(5分) timer.js

受入基準:

  • 回答送信→採点→ポイント計算→AI評価が動作
  • 結果画面に正しくポイントと評価が表示

Phase 4: リリース準備・デプロイ(Week 4)【進行中】

Phase 4 詳細タスク一覧

# タスク 詳細 成果物 状態
4.1 GAS v2用デプロイメント作成 デプロイ@50作成 GAS ✅ 完了
4.2 api.js BASE_URL設定 デプロイURLを設定 api.js ✅ 完了
4.3 curlテスト 全APIエンドポイント確認 テスト結果 ✅ 完了

Phase 4-A: ブロッカー解決(問題生成ステップ追加)【現在地】

# タスク 詳細 状態
4.A.1 generateQuestionsFromAnswers() 答え→問題文生成関数を新規作成(gemini_functions.js) 🔲
4.A.2 generateDailyQuiz() 修正 問題生成→GeneratedQuestions保存ステップ追加 🔲
4.A.3 getDeliveryQuiz() 修正 GeneratedQuestionsから問題を取得するよう変更 🔲
4.A.4 GAS clasp push & deploy 新デプロイメント作成 🔲
4.A.5 問題表示確認テスト ブラウザで問題文・回答欄が表示されることを確認 🔲

根本原因(2025-12-29 特定): トリガー実行時のLLM問題生成ステップが欠落している

本システムの問題作成フロー:

  1. QuestionDatabaseには「答え」と「ヒント」のみ格納
  2. LLM(Dify/Gemini)で問題文を動的生成
  3. 生成した問題をフロントエンドに返す

v2配信モードでは複数受験者に同じ問題を配信するため、 トリガー実行時に問題を事前生成してシートに保存する必要がある

【v2の正しいフロー】
QuestionDatabase(答え・ヒント)
    ↓ triggerMorningDelivery
Gemini APIで問題文・選択肢を事前生成  ← ★追加★
    ↓
GeneratedQuestionsシートに保存        ← ★追加★
    ↓
DailyQuizzesに保存済み問題IDを記録
    ↓
getDeliveryQuiz → 事前生成された問題を返す

既存で使えるもの:

  • callGeminiAPI() - 汎用Gemini呼び出し関数(gemini_functions.js)
  • GEMINI_CONFIG.THINKING_BUDGET.GENERATION - 問題生成用16384トークン
  • GeneratedQuestionsシート - v1で既に使用中

Phase 4-B: E2Eテスト完了(回答・採点フロー)

# タスク 詳細 状態
4.B.1 問題表示テスト 問題文、難易度、カウンターが正しく表示 🔲
4.B.2 回答入力テスト テキスト入力、Enterキー、ボタン操作 🔲
4.B.3 回答送信テスト タイマー終了時の自動送信、手動採点 🔲
4.B.4 ポイント計算テスト 正答ポイント、時間ボーナスの計算確認 🔲
4.B.5 AI評価テスト Gemini評価の実行確認(失敗時フォールバック含む) 🔲
4.B.6 結果画面テスト 正解数、ポイント、回答詳細の表示 🔲

Phase 4-C: エッジケース・エラーハンドリング

# タスク 詳細 状態
4.C.1 期限切れテスト expires_atを過ぎたクイズへのアクセス → エラー表示 🔲
4.C.2 重複回答テスト 同じクイズに複数回回答した場合の挙動 🔲
4.C.3 未ログインテスト トークンなしでquiz.htmlにアクセス → リダイレクト 🔲
4.C.4 ネットワークエラーテスト API失敗時のエラー表示 🔲
4.C.5 回答なし送信テスト 未回答のまま採点した場合 🔲

Phase 4-D: GASトリガー設定

# タスク 詳細 状態
4.D.1 朝トリガー作成 triggerMorningDelivery(6:00 AM JST) 🔲
4.D.2 夕トリガー作成 triggerAfternoonDelivery(15:00 PM JST) 🔲
4.D.3 トリガー動作確認 手動実行でログ確認 🔲
4.D.4 配信問題確認 DailyQuizzesシートにデータ生成を確認 🔲

トリガー設定手順:

1. GASエディタ → トリガー → トリガー追加
2. 実行する関数: triggerMorningDelivery
3. イベントのソース: 時間主導型
4. 時間ベースのトリガータイプ: 日付ベース
5. 時刻: 午前6時〜7時
6. 同様にtriggerAfternoonDeliveryを15:00〜16:00で設定

Phase 4-E: HF Static Space最終デプロイ

# タスク 詳細 状態
4.E.1 ファイル同期 ChoTensai_Deli/の全ファイルをGit push 🔲
4.E.2 Space動作確認 HF Space URLで実動作確認 🔲
4.E.3 レスポンシブ確認 スマホ・タブレットでの表示確認 🔲

HF Static Space情報:


Phase 4-F: ドキュメント整備

# タスク 詳細 状態
4.F.1 リリースノート作成 v2.0.0の変更点まとめ 🔲
4.F.2 運用ガイド トリガー設定、トラブルシューティング 🔲

Phase 4-G: 最終リリース

# タスク 詳細 状態
4.G.1 STATUS.md更新 v2.0.0完了ステータスに更新 🔲
4.G.2 LOG.md更新 最終リリースログ追記 🔲
4.G.3 v2.0.0タグ作成 Git tag v2.0.0(オプション) 🔲
4.G.4 v1.x互換性最終確認 練習モードが正常動作することを再確認 🔲

Phase 4 進捗サマリー

サブフェーズ 状態 タスク数 備考
4.1-4.3 初期設定 ✅ 完了 3/3 -
4-A ブロッカー解決 🔄 現在地 0/5 根本原因特定済み、解決策確定
4-B E2Eテスト 🔲 待機中 0/6 4-A完了後
4-C エッジケース 🔲 待機中 0/5 -
4-D GASトリガー 🔲 待機中 0/4 -
4-E 最終デプロイ 🔲 待機中 0/3 -
4-F ドキュメント 🔲 待機中 0/2 -
4-G 最終リリース 🔲 待機中 0/4 -

受入基準:

  • ✅ v1.x自習モードとの互換性(単一デプロイ@50で両立)
  • ✅ GAS実行時間が30秒以内(約7秒で完了)
  • 🔄 配信→回答→採点→AI評価の一連フローが正常動作
  • 🔲 GASトリガーで自動配信が機能
  • 🔲 ドキュメント完備

11. リスクと対策

リスク 影響度 対策
GAS実行時間制限(30秒) Gemini呼び出しを最適化、非同期処理検討
GAS API呼び出し制限(2万/日) キャッシュ活用、不要な呼び出し削減
v1への影響 別デプロイメントで完全分離
トークン漏洩 有効期限設定、HTTPS必須
ユーザー増加時のスケール Spreadsheet分割検討、インデックス最適化

12. マイルストーン

v2.0.0(配信コア)

Phase 主要成果物 状態
Week 1 Phase 1 データ基盤 ✅ 完了
Week 2 Phase 2 認証・配信基盤 ✅ 完了
Week 3 Phase 3 回答・採点 ✅ 完了
Week 4 Phase 4 リリース準備・デプロイ 🔄 進行中

Phase 4 詳細マイルストーン

サブフェーズ 内容 予定タスク 状態
4-A ブロッカー解決 問題表示不具合修正 🔄 現在地
4-B E2Eテスト 回答・採点・結果フロー 🔲 次
4-C エッジケース エラーハンドリング 🔲
4-D GASトリガー 自動配信設定 🔲
4-E 最終デプロイ HF Space同期 🔲
4-F ドキュメント リリースノート・運用ガイド 🔲
4-G 最終リリース v2.0.0完了宣言 🔲

v3.0.0(拡張機能)- 将来計画

Phase 内容 詳細
Phase 5 ランキング 教科別・総合ランキング、リアルタイム更新
Phase 6 クラス制 6段階クラス、加重平均判定、昇降格
Phase 7 ゲーミフィケーション 週間アイテム(金/銀/銅の鉛筆)、表彰機能

注: v3.0.0の詳細設計は本ドキュメント内の「7. ポイント・ランキング設計」「8. クラス制設計」「9. 週間アイテム設計」を参照


13. 参照ドキュメント

ドキュメント 内容
STATUS.md 現在の進捗状況
docs/FUTURE_VISION.md 将来構想(ポイント計算、クラス制等の詳細)
V1.8.1/RECOVERY.md v1.8.1復旧手順
log/LOG.md 開発ログ

最終更新: 2025-12-29 15:00 ステータス: Phase 4-A 進行中(問題生成ステップ追加) ブロッカー: 🔴 LLM問題生成ステップ欠落(根本原因特定済み、解決策確定) 残りタスク: 32タスク(4-A:5, 4-B:6, 4-C:5, 4-D:4, 4-E:3, 4-F:2, 4-G:4)+ 完了済み3タスク v2.0.0スコープ: 配信コア機能(配信・回答・採点・AI評価)に集中 v3.0.0予定: ランキング・クラス制・ゲーミフィケーション


14. クイックリファレンス(Phase 4 実行時)

問題表示不具合デバッグ手順

# 1. APIレスポンス確認(quiz_idは実際の値に置換)
curl "https://script.google.com/macros/s/AKfycbwh5s6XXu9RppyfyDX5-GiclLc1w9FQk30gryfU_sEatPSlFt7_J91y0U-F1qNo82HS/exec?action=v2_get_delivery&quiz_id=2025-12-29-AM-jp&user_id=tomohiro"

# 2. レスポンスのquestionsフィールドを確認
# - question / QUESTION のどちらのキーが使われているか
# - answer / ANSWER のどちらのキーが使われているか

GASトリガー設定コマンド(参考)

// GASエディタのスクリプトエディタで実行
function setupTriggers() {
  // 既存トリガー削除
  ScriptApp.getProjectTriggers().forEach(t => {
    if (t.getHandlerFunction().startsWith('trigger')) {
      ScriptApp.deleteTrigger(t);
    }
  });

  // 朝6時トリガー
  ScriptApp.newTrigger('triggerMorningDelivery')
    .timeBased()
    .atHour(6)
    .everyDays(1)
    .inTimezone('Asia/Tokyo')
    .create();

  // 午後3時トリガー
  ScriptApp.newTrigger('triggerAfternoonDelivery')
    .timeBased()
    .atHour(15)
    .everyDays(1)
    .inTimezone('Asia/Tokyo')
    .create();
}

HF Space デプロイコマンド

cd ChoTensai_Deli
git add .
git commit -m "v2.0.0 release"
git push