QuickForm インタラクティブ授業ツール作成 Skill
概要
このスキルは、教師がプロフェッショナルなインタラクティブHTML授業ツールを迅速に作成し、自動でQuickFormデータ収集プラットフォームと連携、最終的にデータ分析可視化ダッシュボードを生成します。全行程は8ステップで構成されています。
ステップ1:QuickFormのバージョンとアカウントの確認
ユーザーに使用するバージョンを尋ねる
ユーザーに質問します:
「どのQuickFormバージョンを使いますか?
- A. 公式版(https://quickform.cn)
- B. ローカル版(LAN内デプロイ版)」
公式版の処理
- 認証情報キャッシュファイル
~/.claude/quickform_credentials.jsonの存在を確認:cat ~/.claude/quickform_credentials.json 2>/dev/null - ファイルが存在し、
official.usernameとofficial.passwordが含まれている場合、直接読み込んで使用し、再度尋ねる必要はありません。ユーザーに「以前保存したアカウントを使用します:xxx」と通知します。 - 存在しない場合、ユーザーの公式アカウントとパスワードを尋ね、取得後キャッシュファイルに保存します:
bashで書き込み:{ "official": { "username": "ユーザーから提供されたアカウント", "password": "ユーザーから提供されたパスワード" } }echo '{"official":{"username":"xxx","password":"xxx"}}' > ~/.claude/quickform_credentials.json
ローカル版の処理
-
デフォルトアカウント:
wst、デフォルトパスワード:quickform(ローカルデプロイの出荷時デフォルト値であり、変更しません) -
ローカルアドレスを自動取得(以下の優先順位で試行):
第1ステップ:保存済みアドレスがあるか確認
cat ~/.claude/quickform_credentials.json 2>/dev/nullJSONに
local.base_urlフィールドが既にある場合、直接使用し、ユーザーに「以前保存したローカルアドレスを使用します:xxx」と通知し、以降の検出をスキップします。第2ステップ:自動で本機IP + 5001ポートを検出 保存済みアドレスがない場合、Pythonで本機のLAN IPを取得:
import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("8.8.8.8", 80)) local_ip = s.getsockname()[0] s.close() print(local_ip)結合して
http://<local_ip>:5001とし、次に利用可能か検証:curl -s -o /dev/null -w "%{http_code}" http://<local_ip>:5001/- 200または302が返ってきた場合:ユーザーに「自動検出されました:http://<local_ip>:5001、これを使用します」と通知し、認証情報ファイルに保存します。
- 接続に失敗した場合:第3ステップに進みます。
第3ステップ:自動検出失敗、ユーザーに手動入力を求める
自動検出アドレス http://<local_ip>:5001 にアクセスできません。ローカルQuickFormのアクセスアドレスを手動で入力してください (例:http://192.168.1.100:5001):ユーザー入力を受け取ったら再度検証し、検証成功後に保存します。
アドレスを認証情報ファイルに保存:
python3 -c " import json, os path = os.path.expanduser('~/.claude/quickform_credentials.json') try: d = json.load(open(path)) except: d = {} d.setdefault('local', {})['base_url'] = 'http://最終確認したアドレス' json.dump(d, open(path, 'w'), ensure_ascii=False) print('アドレスを保存しました') " -
ユーザーに質問:「ローカルQuickFormサービスは起動していますか?まだの場合は先にサービスを起動してください。」
以降の全ステップで、ローカルアドレスは変数 LOCAL_BASE_URL(上記のフローで取得したもの)を使用し、IPをハードコーディングしてはいけません。
ステップ2:授業ツールのデザインスタイルを確認
ユーザーに質問(選択肢を提示し、自由な記述も許可):
「授業ツールのデザインスタイルを選んでください(複数選択可、または自由に記述):
- 🎨 シンプルモダン — カードレイアウト、爽やかな配色、ほとんどのシーンに最適
- 🌈 グラデーションダイナミック — 鮮やかなグラデーション、動きのあるエフェクト、活気ある授業に
- 🌙 ダークモード — 暗い背景、蛍光色、テクノロジー感のある授業に
- 🎠 子供向けフレンドリー — 丸みを帯びた可愛いデザイン、明るいカートゥーン、小学校低学年に
- 📊 学術的シリアス — プロフェッショナルで整然、データ重視、高校や大学に
- 🖌️ カスタム — 希望するスタイルを記述してください」
同時に質問:
- 対象年齢/学年(例:小学3年生、中学2年、高校生、大学生)
- 教科(例:国語、数学、英語、理科、情報技術、歴史など)
ステップ3:授業ツールの具体的な要件を収集
このステップでは、開発を開始するために十分詳細な情報を収集する必要があります。以下の3つの次元を必ず網羅すること:
3.1 インタラクション方法の要件
明確にする必要があるもの:
- 授業ツールの核心機能は何か(投票/アンケート/テスト/実験記録/作品アップロード/議論/ゲーム感覚の練習など)
- 生徒はツールとどのように対話するか(選択肢をクリック/テキスト入力/ドラッグ&ドロップ/描画/タイマー付き回答など)
- 即時フィードバックが必要か(回答後すぐに正誤/解説を表示)
ユーザーの説明が曖昧な場合、積極的に質問を重ねる:
「生徒にこのページでどのような操作をさせたいですか?操作後に何が表示されるようにしますか?」
3.2 データ送信フィールド
収集する各フィールドを明確にする必要があるもの:
- フィールド名(英語のキー名、API用)
- フィールドの意味(日本語での説明)
- フィールドタイプ(テキスト/数値/選択肢/時間など)
ユーザーがフィールドに触れていない場合、考えを促す:
「生徒のどのような情報を収集したいですか?例:生徒名、クラス、回答選択肢、得点、所用時間など、一つずつ説明してください。」
フィールド形式の例(参考用、実際はユーザーの要件に従う):
student_name: 生徒名(テキスト)
class: クラス(テキスト)
answer: 回答選択肢(A/B/C/D)
score: 得点(数値)
duration: 所用時間(秒)(数値)
3.3 データ分析/可視化ダッシュボードの要件
明確にする必要があるもの:
- どのようなグラフを見たいか(棒グラフ/円グラフ/折れ線グラフ/ワードクラウド/ランキングなど)
- データの統計軸(クラス比較/回答分布/正答率/平均点/時間トレンドなど)
- ダッシュボード全体のスタイル(授業ツールと統一/独立したスタイル/プロジェクター表示スタイル)
- リアルタイム更新が必要か
情報が不足している場合、質問を重ねる:
「授業中にクラス全体にどのようなデータを見せたいですか?生徒に自分がクラスのどの位置にいるかを見せたいですか?」
情報の確認
上記3つの次元を収集した後、要件サマリーを整理してユーザーに確認を求めます。形式は以下の通り:
📋 要件確認サマリー
【基本情報】
- QuickFormバージョン:公式版/ローカル版
- デザインスタイル:xxx
- 対象学年:xxx 教科:xxx
【授業ツールのインタラクション】
- 機能タイプ:xxx
- インタラクション方法:xxx
- 即時フィードバック:はい/いいえ
【データ収集フィールド】
- field1: 意味 (タイプ)
- field2: 意味 (タイプ)
...
【可視化ダッシュボード要件】
- グラフタイプ:xxx
- 統計軸:xxx
- リアルタイム更新:はい/いいえ
ユーザーが確認してからステップ4に進みます。
ステップ4:QuickFormでタスクを作成
ステップ1で選択したバージョンに応じて、対応するQuickFormタスクを作成します。
タスク命名ルール:授業ツールのテーマに基づいて命名し、簡潔明瞭にします(例:「3年生 算数 足し算引き算練習」、「高校化学 元素周期表クイズ」)
公式版での作成
curl -s -X POST https://quickform.cn/cli/add \
-H "Content-Type: application/json" \
-d '{"username":"<アカウント>","password":"<パスワード>","task_name":"<タスク名>","description":"<ツール概要>"}'
成功レスポンス例:{"success":true,"apiid":"k5egb0lbzi"}
- データ送信インターフェース:
https://quickform.cn/api/<apiid> - データ取得インターフェース:
https://quickform.cn/api/<apiid>/all
ローカル版での作成
ローカル版には /cli/add インターフェースはありません。Pythonセッションでログイン後、タスクを作成し、タスクページから実際のAPI IDをパースします:
⚠️ 重要:ローカル版のAPIインターフェースアドレスは数字のタスクシーケンス番号(例:
/api/10)ではありません。システムが各タスクに生成するランダムな文字列ID(例:/api/C9VaWGMQEZY)です。ログイン後、タスク詳細ページのHTMLからパースして初めて取得できるため、数字のIDでデータを送信することはできません。
import urllib.request, urllib.parse, http.cookiejar, re
cj = http.cookiejar.CookieJar()
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
# 1. ログイン
login_data = urllib.parse.urlencode({'username': 'wst', 'password': 'quickform'}).encode()
req = urllib.request.Request('<LOCAL_BASE_URL>/login', data=login_data)
req.add_header('Content-Type', 'application/x-www-form-urlencoded')
opener.open(req)
# 2. タスク作成
task_data = urllib.parse.urlencode({'title': '<タスク名>', 'description': '<ツール概要>'}).encode()
req2 = urllib.request.Request('<LOCAL_BASE_URL>/create_task', data=task_data)
req2.add_header('Content-Type', 'application/x-www-form-urlencoded')
resp = opener.open(req2)
final_url = resp.geturl() # /task/<数字id> にリダイレクト
numeric_id = re.search(r'/task/(\d+)', final_url).group(1)
# 3. タスク詳細ページから実際のAPI ID(ランダム文字列、数字シーケンスではない)をパース
req3 = urllib.request.Request(f'<LOCAL_BASE_URL>/task/{numeric_id}')
resp3 = opener.open(req3)
html = resp3.read().decode('utf-8')
api_links = re.findall(r'/api/([a-zA-Z0-9\-_]+)', html)
real_api_id = list(set(api_links))[0] # 実際のAPI ID
print(f"タスク番号ID: {numeric_id}")
print(f"実際のAPI ID: {real_api_id}")
- データ送信インターフェース:
<LOCAL_BASE_URL>/api/<real_api_id> - データ取得インターフェース:
<LOCAL_BASE_URL>/api/<real_api_id>/all
ローカル版のデータインターフェースが返す
dataフィールドはPythonのdict文字列形式(シングルクォート)です。HTMLダッシュボードでパースする際には、JSONに変換する必要があります(シングルクォートをダブルクォートに置き換える)。
インターフェース情報の記録
以下の情報を記録し、後続のステップで使用します:
SUBMIT_URL:データ送信インターフェースアドレスFETCH_URL:データ取得インターフェースアドレスTASK_NAME:タスク名
ステップ5:インタラクティブHTML授業ツールページの開発
収集したすべての要件に基づき、完全な単一ファイルHTML授業ツールを生成します。
技術仕様
厳守すべき原則:
- 単一のHTMLファイル、すべてのCSSとJSはインライン
- 中国大陸で問題なくアクセス可能なCDNを使用(下記リスト参照)
- データ送信先には
SUBMIT_URLを使用 - 送信成功後、生徒に明確なフィードバックを提供(成功メッセージ/得点/解説)
- ページはスマートフォンとPCの両方で正しく表示されること(レスポンシブ)
推奨CDN(中国大陸でアクセス可能):
<!-- Tailwind CSS -->
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<!-- ECharts グラフ(可視化ページ用)-->
<script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
<!-- Font Awesome アイコン -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6/css/all.min.css">
<!-- Alpine.js 軽量インタラクション -->
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3/dist/cdn.min.js"></script>
データ送信コードテンプレート:
async function submitData(formData) {
try {
const response = await fetch('SUBMIT_URL', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formData)
});
const result = await response.json();
return result;
} catch (error) {
console.error('送信失敗:', error);
return null;
}
}
授業ツールの品質要件
- ページのテーマが明確で、選択したデザインスタイルに合致していること
- フォントサイズが対象年齢に適していること(子供向けはより大きなフォント)
- インタラクティブな要素に明確な視覚的フィードバックがあること(ホバーエフェクト、クリックアニメーション)
- 送信ボタンが目立ち、送信フローが簡潔であること(ステップが少ない)
- 授業ツールのタイトル、簡単な使用説明を含めること
- すべてのフォームフィールドがステップ3.2で定義したフィールドと完全に対応していること
ファイル保存
生成したHTMLを現在の作業ディレクトリに保存し、命名ルールは次の通り:
<タスク名_授業ツール>.html(日本語はローマ字表記でも可、スペースはアンダースコアに)
ステップ6:3件のテストデータを自動送信
授業ツールのフィールド構造に基づき、リアリティのあるテストデータを3件生成し、送信します。
テストデータの原則:
- データに差異があること(3件すべて同じではない)
- データが実際のシナリオに合致すること(実際の生徒名、適切な得点分布)
- 異なる状況をカバーすること(例:正解した、間違えた、異なるクラスの)
送信方法: curlを使用して1件ずつ送信
curl -s -X POST "SUBMIT_URL" \
-H "Content-Type: application/json" \
-d '{"field1":"value1","field2":"value2",...}'
送信完了後、ユーザーに通知:「✅ 3件のテストデータを正常に送信しました」
ステップ7:データ分析可視化ダッシュボードの開発
7.1 テストデータ構造の取得
curl -s "FETCH_URL"
返された完全なJSONデータを読み取り、データ構造(フィールド名、データ型、ネスト関係)を理解します。
完全なデータ構造を記録し、開発の参考とします。
7.2 可視化ダッシュボードHTMLの開発
以下の情報に基づいて総合的に開発:
- ステップ7.1で取得した実際のデータ構造とフィールド
- ステップ3.3でユーザーが提案した可視化要件
- 授業ツールページのテーマとスタイル(一貫性を保つ)
技術仕様:
- 単一のHTMLファイル、すべてのコードはインライン
- ECharts(
cdn.jsdelivr.net)を使用してグラフをレンダリング - ページ起動時に自動で
FETCH_URLからデータを取得してレンダリング - リアルタイム更新が必要な場合、
setIntervalを使用して10〜15秒ごとに更新 - ダッシュボードのレイアウトはプロジェクター表示に適していること(16:9比率に寄せ、フォントは大きめ)
ダッシュボードに必ず含めるもの:
- ページ上部:ツールタイトル+現在のデータ統計概要(参加人数、平均点などの主要指標)
- メインエリア:ユーザーが必要とするグラフ(EChartsを使用)
- データソースインターフェースアドレス(フッターに小さく表示)
データ取得コードテンプレート:
async function fetchData() {
const response = await fetch('FETCH_URL');
const data = await response.json();
// data の構造はステップ7.1で実際に取得した内容に基づいて処理
return data;
}
ファイル保存
命名ルール:<タスク名_データダッシュボード>.html
ステップ8:完了報告
開発完了後、ユーザーに簡潔なレポートを出力:
🎉 QuickForm 授業ツール開発完了!
📁 生成ファイル
- 授業ツールページ:<ファイル名>.html
- データ分析ダッシュボード:<ファイル名>.html
🔗 インターフェース情報
- データ送信:SUBMIT_URL
- データ取得:FETCH_URL
📊 テストデータ
- 3件のテストデータを送信しました。ダッシュボードページで効果を確認できます。
💡 使用上のヒント
1. 授業ツールページを生徒に共有(LANまたはパブリックURL)
2. 生徒が記入して送信したら、データダッシュボードを開いてリアルタイムで結果を確認
3. スタイルやフィールドを変更する場合は、HTMLファイルを直接編集してください
参考資料
- QuickForm API ドキュメント:
references/quickform-api.mdを参照 - 可視化グラフ例:
references/echarts-examples.mdを参照 - 中国で利用可能なCDNリスト:
references/china-cdn.mdを参照