• #implementation
  • #quiz
  • #japanese-writing
  • #vue
開発honda-sakubun完了

日本語作文クイズ - 実装計画書

現在のステータス

項目状態
フェーズ✅ 全機能実装完了
問題数全47問(修飾語20問 + 句読点12問 + 助詞15問)
最終更新2025-12-24

実装完了項目

項目状態備考
問題データファイル✅ 完了47問(当初計画37問から増加)
型定義✅ 完了QuestionResult追加
composable✅ 完了自動進行・復習機能含む
全コンポーネント✅ 完了スクロール形式UI
ページ実装✅ 完了4ページ(カテゴリ選択+3カテゴリ)
結果一覧表示✅ 完了全問題の正誤表示
OGP画像生成API✅ 完了Satori + Resvg、動的生成
SNSシェア機能✅ 完了Web Share API + X Intent
動的OGPメタタグ✅ 完了クエリパラメータで結果反映

未実装(将来対応)

項目優先度
localStorage永続化

概要

『日本語の作文技術』(朝日文庫)のルールを/.claude/skills/honda-sakubun/で定義し、インタラクティブな2択・3択クイズアプリとして実装する。

問題カテゴリ

スキルのreferencesに基づき、以下の3カテゴリで問題を構成。全47問

カテゴリ参照ファイル問題数二択/三択
修飾語の順序modification-order.md20問混在(修飾語数に応じて)
句読点(テン)の打ち方punctuation.md12問主に二択
助詞の使い方particles.md15問主に二択

設計方針: 選択肢の数は問題の内容に応じて決定。修飾語が2つなら二択、3つなら三択。強引な三択は避ける。


カテゴリ1: 修飾語の順序(20問)

全問題リスト

ID原則問題内容タイプ
MO-01原則1: 節を先、句を後「白い/横線の引かれた/厚手の」→「紙」の正しい語順3択
MO-02原則1: 節を先、句を後「横線の引かれた厚手の白い紙」も正解である理由2択
MO-03原則1: 節を先、句を後「速く/ライトを消して/止まらずに」→「走る」の正しい語順3択
MO-04原則1: 節を先、句を後「速くライトを消して」が悪い理由(誤読の判定)2択
MO-05原則2: 長い順「Aが/私がふるえるほど大嫌いなBを/私の親友のCに」→「紹介した」の最良語順3択
MO-06原則2: 長い順「私は明日はたぶん大雨になる...思った」の改善2択
MO-07原則3: 大状況→小状況「初夏の雨が/もえる若葉に/豊かな潤いを」→「与えた」の正しい語順2択
MO-08原則3: 大状況→小状況「一九七四年の暮れに...ルアンダの空港についた」の状況配置2択
MO-09原則4: 親和度「初夏のみどりがもえる夕日に照り映えた」の改善2択
MO-10距離「私は小林が中村が鈴木が死んだ現場にいたと証言したのかと思った」の改善2択

問題例

MO-01: 正しい語順を選ぶ(3択)

Q: 次の文で、最も読みやすい語順はどれですか?

対象:紙
修飾語:白い、横線の引かれた、厚手の

1. 白い横線の引かれた厚手の紙
2. 横線の引かれた白い厚手の紙 ← 正解
3. 厚手の白い横線の引かれた紙

解説:原則1「節を先、句を後」により、述語を含む「横線の引かれた」を先に置く。
「白い横線」「厚手の横線」と誤読されるのを防ぐ。

MO-05: 6通りの語順から最良を選ぶ(3択)

Q: 「Aが私がふるえるほど大嫌いなBを私の親友のCに紹介した」
   最も自然な語順はどれですか?

1. Aが私の親友のCに私がふるえるほど大嫌いなBを紹介した
2. 私がふるえるほど大嫌いなBを私の親友のCにAが紹介した ← 正解
3. 私の親友のCに私がふるえるほど大嫌いなBをAが紹介した

解説:原則2「長い順」により、最も長い修飾語を先に置く。
長い順:私がふるえる...(長)→ 私の親友の...(中)→ Aが(短)

カテゴリ2: 句読点(テン)の打ち方(12問)

全問題リスト

IDルール問題内容タイプ
PT-01マルの基本「渡辺刑事が賊を追いかけた車が三台並んでいた道路はせまかった」の問題点2択
PT-02誤ったマル「知るよしもない母は...」→「知るよしもない。母は...」で意味が変わる理由2択
PT-03第一原則「病名が心筋梗塞だと元気にまかせて過労をかさねたのではないかと思う」のテン位置2択
PT-04第一原則「ケネディー大統領を...暗殺し、下山国鉄総裁を...」のテンの理由2択
PT-05第二原則「渡辺刑事は血まみれになって逃げ出した賊を追いかけた」の正しいテン位置3択
PT-06第二原則「Aが、私がふるえるほど大嫌いなBを...」のテンの意味2択
PT-07打つべきでない(正順)「わたしをつかまえて来て拷問にかけた...特高警察のミンが」のテン判定2択
PT-08打つべきでない(連体形)「サイゴンのプロテスタントの...で働いている、何人かの...」のテン判定2択
PT-09過剰なテン「近くを、ひと廻りし、ひき返してくると...」の問題点2択
PT-10思想のテン「しかし、彼女の恋ごころは...」と「しかし彼女の...」の違い2択
PT-11ナカテン「カール・マルクス・アダム・スミス」の問題点と解決策2択
PT-12カギカッコ「始めよ」の意味で → 「始め」る意味で の違い2択

問題例

PT-05: 正しいテン位置を選ぶ(3択)

Q: 次の文で、テンを打つべき位置はどこですか?

「渡辺刑事は血まみれになって逃げ出した賊を追いかけた」

1. 渡辺刑事は血まみれになって、逃げ出した賊を追いかけた
2. 渡辺刑事は、血まみれになって逃げ出した賊を追いかけた ← 正解
3. テンは不要

解説:第二原則「逆順(短→長)の場合にテンを打つ」。
短い「渡辺刑事は」が先なのでテンで区切る。
1だと「刑事が血まみれ」と誤読される。

PT-08: 連体形直後のテン(2択)

Q: 次のテンは適切ですか?

「サイゴンのプロテスタントの社会奉仕団で働いている、
何人かのアメリカの青年とも知り合いになる機会を......」

1. 適切
2. 不適切 ← 正解

解説:連体形の直後にテンを打つと、文が終わったように誤読される。
「働いている」で一度文が切れたように見えてしまう。

カテゴリ3: 助詞の使い方(15問)

全問題リスト

IDルール問題内容タイプ
PA-01格助詞は平等「甲が乙に丙を紹介した」の6通りの語順がすべて正しい理由2択
PA-02ハの題目用法「甲ハ乙ニ丙ヲ紹介シタ」で「ハ」が「ガ」を兼務する意味2択
PA-03ハの題目用法「象ハ鼻ガ長イ」で「ハ」が「ノ」を兼務する理由2択
PA-04翻訳調「男たちは突然現われた裸の少年を見て、たいへん驚いた」の改善3択
PA-05題目と述語題目「〜は」と述語は近づけるべき理由2択
PA-06対照のハ「東京湾のように分離されていない」の改善2択
PA-07ハと否定「蛙の腹にはヘソがない」と「蛙は腹にはヘソがない」の意味の違い2択
PA-08ハの数「私は週末には本は読みません」の問題点と改善3択
PA-09否定とハの位置「いつも速く食べない」「いつもハ速く食べない」「いつも速くハ食べない」の違い3択
PA-10マデとマデニ「来週まで提出してください」と「来週までに提出してください」の違い2択
PA-11マデとマデニ「こんど自分が来るまで始末しておけ」の改善2択
PA-12マデとマデニ「12月24日まで投函」と「12月24日までに投函」の違い2択
PA-13マデ/マデニ/マデデ「名古屋に着くマデ/マデニ/マデデ雑誌を読むのをやめた」の意味の違い3択
PA-14接続助詞ガ逆接の「ガ」と順接の「ガ」の使い分け2択
PA-15接続助詞ガ「私は東京に住んでいるが、妻は...が、子供は...が」の改善2択

問題例

PA-10: マデとマデニ(2択)

Q: 正しい文はどちらですか?

1. 来週まで提出してください
2. 来週までに提出してください ← 正解

解説:
• マデ = 継続の終点(来週まで掃除せよ → ずっと続ける)
• マデニ = 締め切り(来週までに掃除せよ → その前に一度)

提出は一度で済むので「マデニ」が正しい。

PA-13: マデ/マデニ/マデデの違い(3択)

Q: 「列車が名古屋に着く___雑誌を読むのをやめた」
   意味が「着いた時にやめた」になるのはどれ?

1. マデ(読まない状態を続けた)
2. マデニ(着く前のどこかでやめた)
3. マデデ ← 正解(着くまで読み続け、着いた時にやめた)

解説:
• マデ = 継続の終点
• マデニ = 締め切り
• マデデ = その時点で

技術実装計画

ディレクトリ構造

apps/web/
├── app/
│   ├── pages/
│   │   └── japanese-writing-quiz/
│   │       ├── index.vue              # カテゴリ選択画面
│   │       ├── modification-order.vue  # 修飾語の順序クイズ
│   │       ├── punctuation.vue         # 句読点クイズ
│   │       └── particles.vue           # 助詞クイズ
│   ├── components/
│   │   └── japanese-quiz/
│   │       ├── QuizContainer.vue       # クイズ全体のラッパー
│   │       ├── QuestionCard.vue        # 問題カード
│   │       ├── ChoiceButton.vue        # 選択肢ボタン
│   │       ├── ExplanationPanel.vue    # 解説パネル
│   │       ├── ProgressBar.vue         # 進捗バー
│   │       └── ResultSummary.vue       # 結果サマリー + シェアボタン
│   ├── composables/
│   │   └── useJapaneseQuiz.ts          # クイズロジック
│   └── data/
│       └── japanese-quiz/
│           ├── modification-order.ts    # 修飾語問題データ
│           ├── punctuation.ts           # 句読点問題データ
│           └── particles.ts             # 助詞問題データ
└── server/
    └── api/
        └── og/
            └── japanese-quiz.ts         # OGP画像動的生成API

データ構造

// types/japanese-quiz.ts

interface QuizQuestion {
  id: string
  category: 'modification-order' | 'punctuation' | 'particles'
  type: 'choice-2' | 'choice-3'
  principle?: string  // 原則1, 原則2, etc.
  question: string
  context?: string    // 例文の背景情報
  choices: Choice[]
  correctIndex: number
  explanation: string
  reference?: string  // 参照(『日本語の作文技術』など)
}

interface Choice {
  text: string
  isCorrect: boolean
}

interface QuizResult {
  totalQuestions: number
  correctAnswers: number
  wrongAnswers: QuizQuestion[]
  timeSpent: number
}

UI/UX設計

カテゴリ選択画面 (/japanese-writing-quiz)

┌─────────────────────────────────────────┐
│  日本語作文クイズ                       │
│                                         │
│  ┌─────────────────────────────────┐   │
│  │ 📝 修飾語の順序                  │   │
│  │ 10問 • 節と句、長い順、親和度    │   │
│  └─────────────────────────────────┘   │
│                                         │
│  ┌─────────────────────────────────┐   │
│  │ 、句読点(テン)の打ち方         │   │
│  │ 12問 • 二大原則、思想のテン      │   │
│  └─────────────────────────────────┘   │
│                                         │
│  ┌─────────────────────────────────┐   │
│  │ は 助詞の使い方                  │   │
│  │ 15問 • ハの用法、マデとマデニ    │   │
│  └─────────────────────────────────┘   │
│                                         │
│  ┌─────────────────────────────────┐   │
│  │ 🎯 全問チャレンジ                │   │
│  │ 37問 • すべてのカテゴリ          │   │
│  └─────────────────────────────────┘   │
└─────────────────────────────────────────┘

問題画面

┌─────────────────────────────────────────┐
│  [=====>            ] 5/15              │
│                                         │
│  原則1: 節を先、句を後                  │
│                                         │
│  Q. 次の文で、最も読みやすい語順は      │
│     どれですか?                        │
│                                         │
│  対象:紙                               │
│  修飾語:白い、横線の引かれた、厚手の   │
│                                         │
│  ┌─────────────────────────────────┐   │
│  │ 1. 白い横線の引かれた厚手の紙    │   │
│  └─────────────────────────────────┘   │
│  ┌─────────────────────────────────┐   │
│  │ 2. 横線の引かれた白い厚手の紙    │   │
│  └─────────────────────────────────┘   │
│  ┌─────────────────────────────────┐   │
│  │ 3. 厚手の白い横線の引かれた紙    │   │
│  └─────────────────────────────────┘   │
└─────────────────────────────────────────┘

解説画面(回答後)→ スクロール形式で実装

実装変更: 「次の問題へ」ボタンを廃止し、スクロール形式UIを採用。 回答すると解説が表示され、その下に次の問題が自動追加される。

┌─────────────────────────────────────────┐
│  問 3 / 20                              │
│  [問題カード]                           │
│  ✅ 正解!                              │
│  ┌─────────────────────────────────┐   │
│  │ 【解説】...                      │   │
│  └─────────────────────────────────┘   │
├─────────────────────────────────────────┤  ← 自動スクロール
│  問 4 / 20                              │
│  [次の問題カード - 未回答]              │
│                                         │
└─────────────────────────────────────────┘

利点: ユーザーは解説を読みながらスクロールするだけで次の問題に進める。

機能要件

機能状態説明
ランダム出題毎回問題の順番をシャッフル
選択肢シャッフル正解の位置を固定しない
即時フィードバック回答直後に正誤と解説を表示
進捗表示現在の問題番号と全体の進捗
結果サマリー正解率 + 全問題一覧(正誤・カテゴリ表示)
復習機能間違えた問題だけを再チャレンジ
スクロール形式UI「次の問題へ」ボタン不要、自動スクロール
ローカル保存進捗をlocalStorageに保存(未実装)
結果シェア機能SNSへの結果共有ボタン(未実装)

結果シェア機能

概要

クイズ完了後の結果画面に「シェアする」ボタンを設置し、SNS(Twitter/X等)に結果を共有できるようにする。シェア時には動的に生成されたOGP画像が表示される。

シェアボタンUI

結果画面(ResultSummary.vue)に以下を追加:

┌─────────────────────────────────────────┐
│  🎉 結果                                │
│                                         │
│  修飾語の順序クイズ                      │
│  8 / 10 問正解(80%)                   │
│  所要時間: 3分42秒                       │
│                                         │
│  ┌─────────────────────────────────┐   │
│  │ 🔗 結果をシェアする              │   │
│  └─────────────────────────────────┘   │
│                                         │
│  [ もう一度挑戦 ]  [ 他のカテゴリへ ]   │
└─────────────────────────────────────────┘

OGP画像の動的生成

要件
  1. カテゴリ名: 「修飾語の順序」「句読点の打ち方」「助詞の使い方」等
  2. 正解数: 「8/10問正解」のような表示
  3. ドメイン名: 右下に eurekapu.com を表示
  4. デザイントーン: クイズ形式に合った明るい赤系のトーン(現在のOGP画像より明るく活気のある印象)
OGP画像サイズ
  • 推奨サイズ: 1200 x 630 px(Twitter/Facebook共通)
デザインイメージ
┌────────────────────────────────────────────────────────┐
│                                                        │
│    ┌──────────────────────────────────────────────┐   │
│    │                                              │   │
│    │   📝 修飾語の順序クイズ                      │   │
│    │                                              │   │
│    │         ━━━━━━━━━━━━━━━━                     │   │
│    │                                              │   │
│    │       🎯  8 / 10 問正解                     │   │
│    │                                              │   │
│    │                                              │   │
│    └──────────────────────────────────────────────┘   │
│                                                        │
│                                       eurekapu.com    │
└────────────────────────────────────────────────────────┘

背景色: 明るい赤〜オレンジ系グラデーション
テキスト: 白または濃い色で視認性確保
技術実装オプション
方式メリットデメリット
Satori + Resvg(推奨)Vercel製、JSX → SVG → PNG変換、エッジ対応日本語フォント埋め込み必要
Cloudflare Workers + Canvasエッジで動的生成実装複雑
事前生成 + パラメータシンプル、高速バリエーション制限
推奨実装: Satori
// server/api/og/japanese-quiz.ts
import satori from 'satori'
import { Resvg } from '@resvg/resvg-js'

export default defineEventHandler(async (event) => {
  const { category, correct, total } = getQuery(event)

  const svg = await satori(
    // JSXテンプレート(OGPデザイン)
    {
      type: 'div',
      props: {
        style: {
          background: 'linear-gradient(135deg, #ff6b6b 0%, #ee5a24 100%)',
          // ...
        },
        children: [
          // カテゴリ名、正解数、ドメイン名
        ]
      }
    },
    {
      width: 1200,
      height: 630,
      fonts: [/* 日本語フォント */]
    }
  )

  const resvg = new Resvg(svg)
  const png = resvg.render().asPng()

  return new Response(png, {
    headers: { 'Content-Type': 'image/png' }
  })
})
OGP URLパターン
/api/og/japanese-quiz?category=modification-order&correct=8&total=10
メタタグ設定

シェアリンク先のページ(結果ページ)で動的にOGPメタタグを設定:

<meta property="og:image" content="https://eurekapu.com/api/og/japanese-quiz?category=modification-order&correct=8&total=10" />
<meta property="og:title" content="修飾語の順序クイズ - 8/10問正解!" />
<meta property="og:description" content="日本語作文クイズに挑戦しよう" />
シェアテキスト例
「修飾語の順序」クイズで8/10問正解しました!🎉

あなたも挑戦してみませんか?
https://eurekapu.com/japanese-writing-quiz/modification-order

実装ステップ

ステップ内容
1OGP画像生成APIの実装(/api/og/japanese-quiz
2日本語フォント(Noto Sans JP等)の埋め込み
3結果ページにシェアボタン追加(ResultSummary.vue
4シェアリンク生成ロジック実装
5結果ページのOGPメタタグ動的設定
6各SNS(Twitter, LINE等)での表示確認

全体実装ステップ

ステップ内容成果物状態
1問題データの作成data/japanese-quiz/*.ts✅ 完了(47問)
2型定義の作成types/japanese-quiz.ts✅ 完了
3composable作成useJapaneseQuiz.ts✅ 完了
4基本コンポーネント作成QuestionCard.vue✅ 完了
5カテゴリ選択画面pages/japanese-writing-quiz/index.vue✅ 完了
6各カテゴリページmodification-order.vue✅ 完了
7結果・復習機能ResultSummary.vue✅ 完了(全問一覧付き)
8スタイリング調整Scoped CSS✅ 完了
9テスト・動作確認手動テスト✅ 完了
10OGP画像生成API実装server/api/og/japanese-quiz.ts⏳ 未着手
11シェアボタン・メタタグ実装ResultSummary.vue 更新⏳ 未着手
12SNSシェア動作確認Twitter/LINE等での表示テスト⏳ 未着手

問題データのサンプル

// data/japanese-quiz/modification-order.ts

export const modificationOrderQuestions: QuizQuestion[] = [
  {
    id: 'mo-001',
    category: 'modification-order',
    type: 'choice-3',
    principle: '原則1: 節を先、句を後',
    question: '次の文で、最も読みやすい語順はどれですか?',
    context: '対象:紙\n修飾語:白い、横線の引かれた、厚手の',
    choices: [
      { text: '白い横線の引かれた厚手の紙', isCorrect: false },
      { text: '横線の引かれた白い厚手の紙', isCorrect: true },
      { text: '厚手の白い横線の引かれた紙', isCorrect: false },
    ],
    correctIndex: 1,
    explanation: `原則1「節を先、句を後」により、述語を含む「横線の引かれた」を先に置きます。

• 白い(句)
• 横線の引かれた(節)← 先に置く
• 厚手の(句)

「白い横線」「厚手の横線」と誤読されるのを防ぎます。`,
    reference: '『日本語の作文技術』(朝日文庫)第三章',
  },
  {
    id: 'mo-002',
    category: 'modification-order',
    type: 'choice-2',
    principle: '原則1: 節を先、句を後',
    question: '「ライトを消して止まらずに速く走る」が「速くライトを消して止まらずに走る」より良い理由は?',
    choices: [
      { text: '長い修飾語を先に置いているから', isCorrect: false },
      { text: '節(述語を含む修飾語)を先に置いているから', isCorrect: true },
    ],
    correctIndex: 1,
    explanation: `「ライトを消して」「止まらずに」は述語を含む節、「速く」は句です。

原則1「節を先、句を後」により、節を先に置きます。

「速くライトを消して」とすると「速く消す」と誤読される可能性があります。`,
  },
  // ... 続く
]

追加検討事項

学習効果を高める機能(将来)

  1. スペースド・リピティション: 間違えた問題を一定間隔で再出題
  2. 弱点分析: 原則ごとの正解率を表示
  3. 例文投稿: ユーザーが自分の文を投稿して添削

参考リンク

  • 既存の類似実装: /financial-quiz/ シリーズ
  • Vueコンポーネント設計: apps/web/app/components/

実装完了チェックリスト

コア機能(✅ 完了)

  1. 問題データ(全47問)の作成
    • modification-order.ts(20問)
    • punctuation.ts(12問)
    • particles.ts(15問)
    • index.ts(エクスポート)
  2. 型定義ファイルの作成(types/japanese-quiz.ts)
    • QuizQuestion, Choice
    • QuestionResult, QuizResult(結果一覧用に追加)
    • QuizState, CategoryInfo, CATEGORIES
  3. composable作成(useJapaneseQuiz.ts)
    • 問題シャッフル
    • 選択肢シャッフル
    • 自動進行(回答後に次の問題を表示)
    • 復習機能(間違えた問題だけ再挑戦)
  4. 基本コンポーネント作成
    • QuizContainer.vue(スクロール形式UI)
    • QuestionCard.vue
    • ExplanationPanel.vue(showNextButtonプロップ追加)
    • ProgressBar.vue
    • ResultSummary.vue(全問題一覧テーブル付き)
  5. カテゴリ選択ページの実装(index.vue)
  6. 各カテゴリクイズページの実装
    • modification-order.vue
    • punctuation.vue
    • particles.vue

追加実装した機能

  • スクロール形式UI: 「次の問題へ」ボタン不要、回答すると解説と次の問題が下に表示される
  • 自動スクロール: 新しい問題が表示されると自動的にスクロール
  • 結果一覧: 結果画面で全問題の正誤・カテゴリ・問題文を表示
  • 二択/三択の最適化: 修飾語の数に応じて選択肢数を決定(強引な三択を排除)

将来対応(未実装)

  1. 結果シェア機能の実装
    • OGP画像生成API(server/api/og/japanese-quiz.ts)
    • 日本語フォント埋め込み(Noto Sans JP)
    • シェアボタンUI追加(ResultSummary.vue)
    • シェアリンク生成ロジック
    • 動的OGPメタタグ設定
    • SNS表示確認(Twitter/LINE)
  2. localStorage永続化(進捗保存)

実装済みファイル一覧

apps/web/app/
├── pages/
│   └── japanese-writing-quiz/
│       ├── index.vue              ✅ カテゴリ選択
│       ├── modification-order.vue ✅ 修飾語クイズ
│       ├── punctuation.vue        ✅ 句読点クイズ
│       └── particles.vue          ✅ 助詞クイズ
├── components/
│   └── japanese-quiz/
│       ├── QuizContainer.vue      ✅ スクロール形式
│       ├── QuestionCard.vue       ✅
│       ├── ExplanationPanel.vue   ✅
│       ├── ProgressBar.vue        ✅
│       └── ResultSummary.vue      ✅ 全問題一覧付き
├── composables/
│   └── useJapaneseQuiz.ts         ✅ 自動進行・復習機能
├── types/
│   └── japanese-quiz.ts           ✅ QuestionResult追加
└── data/
    └── japanese-quiz/
        ├── index.ts               ✅
        ├── modification-order.ts  ✅ 20問
        ├── punctuation.ts         ✅ 12問
        └── particles.ts           ✅ 15問