学習パッケージ Docs Home API リファレンスDashboardsDB DesignER Diagram

ダッシュボード画面設計

学習アプリの 3 つの主要 UI (教員ダッシュボード、生徒マイページ、システム管理者ダッシュボード) の画面構成と必要 API のマッピング。


目次


概要

対象ユーザーと画面

[生徒]
  ├─ 認証 (Cognito + IdP / Email)
  └─ マイページ (学習・スクリーニング)

[教員]
  ├─ 認証 (Cognito)
  └─ 教員ダッシュボード (ロール別の画面構成)
       ├─ tannin (担任)
       ├─ shunin (学年主任)
       └─ school_admin (学校管理者)

[システム管理者]
  └─ システム管理ダッシュボード (system_admin)

設計方針

共通要素

すべての画面の上部に共通ヘッダ:

┌────────────────────────────────────────────────────────┐
│ [LOGO] 学校名 / ロール表示    [通知 🔔] [自分の名前 ▼] │
└────────────────────────────────────────────────────────┘

教員ダッシュボード

教員ダッシュボード画面一覧

画面 tannin shunin school_admin
ホーム (アラート + 概況)
結果一覧画面 (テスト結果の Inbox) 自クラス 自学年 自校
結果詳細画面 (文字別グリッド + 教員レビュー) 自クラス 自学年 自校
レビューワークフロー (詳細画面 + 連続ナビ) 自クラス 自学年 自校
クラス一覧 自クラス 自学年 自校
クラス詳細 (生徒一覧 + 集計) 自クラス 自学年 自校
生徒詳細 (履歴 + 習熟度) 自クラス 自学年 自校
学習セッション詳細 自クラス 自学年 自校
生徒登録 (一括) 自クラス 自学年 自校
生徒個別編集 自クラス 自学年 自校
招待状況 自クラス 自学年 自校
メール suppression 管理 自クラスの生徒のみ 自学年の生徒のみ 自校全体
教員一覧
教員登録 (一括)
クラス編成 (作成・削除)
学校情報設定
自分のプロフィール設定

1. ホーム画面

目的: ログイン直後に「今やるべきこと」を即座に把握できる画面。

レイアウト (ワイヤーフレーム的に)

┌─────────────────────────────────────────────────────────────┐
│ [LOGO] ○○小学校 (担任: 3年1組)         [🔔3] [山田先生 ▼] │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  📋 要対応アラート                                            │
│  ┌─────────────────────────────────────────────────────┐    │
│  │ 🔴 AI が要支援と判定 (教員未レビュー):  3 名             │    │
│  │ 🟡 教員が個別指導対象と判定:  1 名                      │    │
│  │ ⚪ 全テスト件数:         28 件 (今週)                  │    │
│  │                                                      │    │
│  │  [→ レビュー画面を開く]                                │    │
│  └─────────────────────────────────────────────────────┘    │
│                                                              │
│  📊 今週の概況                                                │
│  ┌─────────────┬─────────────┬─────────────┐                │
│  │  テスト実施  │  学習継続率  │  AI 検出率  │                │
│  │     85%     │     67%     │      8%     │                │
│  │  (28/33名)  │             │             │                │
│  └─────────────┴─────────────┴─────────────┘                │
│                                                              │
│  📅 最近の活動                                                │
│  ┌─────────────────────────────────────────────────────┐    │
│  │ ・佐藤 太郎 (3-1-05) スクリーニング完了 (5分前)         │    │
│  │ ・鈴木 花子 (3-1-12) 学習セッション (10分前)            │    │
│  │ ・田中 一郎 (3-1-08) 学習セッション (15分前)            │    │
│  └─────────────────────────────────────────────────────┘    │
│                                                              │
│  [👥 クラス詳細] [📋 レビュー画面] [⚙️ 設定]                  │
└─────────────────────────────────────────────────────────────┘

表示要素とロール別差分

要素 tannin shunin school_admin
アラートバッジ 自クラスの未確認 自学年の未確認 自校の未確認
今週の概況 自クラス 自学年 自校
最近の活動 自クラス 自学年 自校
メイン CTA レビュー画面 レビュー画面 レビュー画面 + 学校管理

この画面で必要な API

用途 エンドポイント 状態
ユーザー情報取得 GET /me ✅ 既存
ログイン記録 POST /me/login ✅ 既存
要対応アラート集計 GET /dashboard/alerts ✅ 新規追加済み
概況サマリ GET /dashboard/summary ✅ 新規追加済み
最近の活動 GET /dashboard/recent-activity ✅ 新規追加済み

新規 API: GET /dashboard/alerts

教員のアラート集計を返す。ロールに応じて自動的にスコープが決まる。

レスポンス例:

{
  "scope": {
    "type": "class",
    "school_id": "sch_001",
    "class_id": 12,
    "class_name": "3年1組"
  },
  "alerts": {
    "ai_support_unreviewed": {
      "count": 3,
      "label": "AI が要支援と判定 (教員未レビュー)",
      "severity": "high"
    },
    "teacher_support_count": {
      "count": 1,
      "label": "教員が個別指導対象と判定",
      "severity": "medium"
    },
    "tests_this_week": {
      "count": 28,
      "label": "今週のテスト実施数"
    }
  }
}

scope.typeclass / grade / school のいずれか (ロールにより決定)。

新規 API: GET /dashboard/summary

{
  "scope": { /* 同上 */ },
  "metrics": {
    "test_completion_rate": {
      "value": 0.85,
      "numerator": 28,
      "denominator": 33,
      "label": "テスト実施率"
    },
    "learning_continuation_rate": {
      "value": 0.67,
      "label": "学習継続率",
      "definition": "今週何らかの学習をした生徒/全生徒"
    },
    "ai_detection_rate": {
      "value": 0.08,
      "numerator": 2,
      "denominator": 25,
      "label": "AI 検出率"
    }
  },
  "period": {
    "start": "2026-05-01",
    "end": "2026-05-07"
  }
}

新規 API: GET /dashboard/recent-activity

{
  "items": [
    {
      "type": "screening_completed",
      "occurred_at": "2026-05-07T08:25:00Z",
      "student": {
        "id": "01890a5d-...",
        "family_name": "佐藤",
        "given_name": "太郎",
        "class_id": 12,
        "student_no": 5
      },
      "session_id": 12345
    },
    {
      "type": "learning_session_completed",
      "occurred_at": "2026-05-07T08:20:00Z",
      "student": { /* ... */ },
      "session_id": 12346
    }
  ],
  "next_cursor": null
}

type の値: screening_completed / posttest_completed / learning_session_completed / test_reviewed

2. テスト結果のレビュー (3 画面構成)

テスト結果のレビューには 3 つの画面が連携する:

(B) と (C) は 本体は同じ文字グリッド UI で、(C) は「次へ / スキップ」ボタンとキーボードショートカットが追加された変形バージョン。

(A) 結果一覧画面

┌────────────────────────────────────────────────────────────────┐
│  📋 結果一覧                                  [ワークフロー開始 →]│
├────────────────────────────────────────────────────────────────┤
│  フィルタ: [☑️ 教員未レビューのみ] [test_type: screening ▼]       │
│            [AI判定: すべて ▼] [教員判定: すべて ▼] [期間: 過去30日 ▼]│
├────────────────────────────────────────────────────────────────┤
│  □  生徒          受験日       AI判定    教員判定   操作          │
│  □  佐藤太郎(05) 2026-05-07  ⚠要確認   未確認     [詳細]         │
│  □  鈴木花子(12) 2026-05-06  ⚠要確認   個別指導対象 [詳細]         │
│  □  田中一郎(08) 2026-05-06  ✓問題なし  問題なし   [詳細]         │
│  ...                                                             │
├────────────────────────────────────────────────────────────────┤
│  [選択した行を確認済みにする]                                     │
└────────────────────────────────────────────────────────────────┘

操作:

この画面で必要な API

用途 エンドポイント 状態
結果一覧取得 GET /test-results ✅ 新規追加済み
一括 teacher_judgment 更新 (個別 PATCH の繰り返し) ✅ 既存 (PATCH /assessments/{id}/result)

新規 API: GET /test-results

クラス・学年・学校横断で test_result を一覧取得する。ロールに応じて自動絞り込み。

クエリパラメータ:

?test_type=screening
&teacher_judgment=null
# AI 判定で絞り込みたい場合: &ai_judgment=support
&class_id=12
&from=2026-04-01
&to=2026-05-07
&limit=50
&cursor=...

レスポンス:

{
  "items": [
    {
      "session_id": 12345,
      "student": {
        "id": "01890a5d-...",
        "family_name": "佐藤",
        "given_name": "太郎",
        "class_id": 12,
        "student_no": 5
      },
      "test_type": "screening",
      "test_date": "2026-05-07",
      "ai_judgment": "support",
      "teacher_judgment": null,
      "teacher_judgment_by": null,
      "teacher_judgment_at": null,
      "correct_count": 14,
      "total_count": 30,
      "correct_rate": 0.4667
    }
  ],
  "summary": {
    "total": 28,
    "unreviewed_count": 4,
    "support_count": 1,
    "watch_count": 3
  },
  "next_cursor": null
}

(B) 結果詳細画面 — 文字別グリッド

「(A) 一覧画面」で行をクリックした時に表示される、1 件の test_result の詳細画面。 モックアップ画像の「管理画面③ — 児童ごとの文字別詳細」に対応する。

┌────────────────────────────────────────────────────────────────┐
│  伊藤 はるか (3番) — 文字別詳細      [⚠要確認] [🔴個別指導対象]   │
│  第1回 直音音読検査 / 2026年6月11日                             │
├────────────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────────┐   │
│ │ 正答 35  読んだ文字 42 /150字   [▶] ━━━━━ 録音再生 0:00/1:00 │   │
│ └─────────────────────────────────────────────────────────┘   │
│                                                                  │
│ 凡例:  [×読み誤り] [—時間切れ(未読)]   ※ 54字/分以下のため要支援 │
│ 読み速さ:  ▮速い(〜0.6s) ▮普通(0.7〜0.9) ▮遅め(1.0〜1.4) ▮遅い(1.5s〜)│
│                                                                  │
│ ── 1枚目 (1〜50字) ──                                            │
│ ┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐                                │
│ │わ│べ│ぶ│ゆ│る│お│×は│ぺ│け│ぱ│                                │
│ │  │.8│.9│.8│.6│.8│2.4│.6│.7│.6│  ← 応答時間 (秒)               │
│ └──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘                                │
│ (省略) ...                                                       │
│                                                                  │
│ ── 2枚目 (51〜100字) ──   ── 3枚目 (101〜150字) ──              │
├────────────────────────────────────────────────────────────────┤
│ 文字をクリックすると正誤を切り替えられます        [判定を確定する]│
└────────────────────────────────────────────────────────────────┘

画面の特徴:

インタラクション:

この画面で必要な API

用途 エンドポイント 状態
児童基本情報 GET /students/{studentId} ✅ 既存
結果サマリ (correct_count, ai_judgment 等) GET /assessments/{sessionId}/result ✅ 既存
セッション情報 (date, duration 等) GET /assessments/{sessionId} ✅ 既存
解答内訳 (文字グリッド本体) GET /assessments/{sessionId}/answers ✅ 新規追加済み
全文字音声 URL 一覧 GET /assessments/{sessionId}/audio-urls ✅ 新規追加済み
個別文字音声 URL GET /assessments/{sessionId}/answers/{answerId}/audio-url ✅ 新規追加済み
セルクリック (即時切替) POST /assessments/{sessionId}/answers/{answerId}/review ✅ 新規追加済み
一括レビュー送信 POST /assessments/{sessionId}/review-answers ✅ 新規追加済み
「判定を確定する」 PATCH /assessments/{sessionId}/result ✅ 既存

「判定を確定する」のモーダル

┌──────────────────────────────────┐
│ 教員判定を確定                    │
├──────────────────────────────────┤
│  ◉ 問題なし (normal)              │
│  ○ 経過観察 (watch)               │
│  ○ 個別指導対象 (support)          │
│                                   │
│  メモ (任意): [____________]       │
│                                   │
│        [キャンセル] [確定]         │
└──────────────────────────────────┘

確定すると PATCH /assessments/{sessionId}/resultteacher_judgment が更新される。 サーバ側で teacher_judgment_byteacher_judgment_at が自動セット。

(C) レビューワークフロー画面

(B) 結果詳細画面 と本体は同じ文字グリッドだが、未レビューを 1 件ずつ連続処理するためのナビゲーションが追加されている。

┌────────────────────────────────────────────────────────────────┐
│  📋 レビューワークフロー (1/4)                  [一覧に戻る]      │
│  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
│                                                                  │
│   [ ← 前へ (K) ]                              [ 次へ → (J) ]    │
│   ────────────── (B) 結果詳細画面と同じ ────────────────────── │
│   伊藤 はるか (3番) — 文字別詳細  [⚠要確認] [🔴個別指導対象]    │
│   ...                                                            │
│   (文字グリッド)                                                  │
│   ...                                                            │
│   ────────────────────────────────────────────────────────── │
│                                                                  │
│   [スキップ (S)] [問題なし (N)] [経過観察 (W)] [個別指導対象 (P)]│
│   ※ 判定確定後、自動的に次の未レビュー結果へ移動                   │
└────────────────────────────────────────────────────────────────┘

(B) と (C) の差分:

項目 (B) 結果詳細 (C) ワークフロー
起点 一覧から行クリック 一覧から「ワークフロー開始」
上下のナビ なし 前へ / 次へ
確定ボタン モーダル (じっくり判定) 直接ボタン (素早く判定)
キーボードショートカット なし J/K/N/W/P/S
確定後の挙動 (B) に留まる 自動的に次の未レビューへ

操作:

この画面で必要な API

(B) と全く同じ。プラスで:

用途 エンドポイント 状態
未レビュー一覧 (ワークフロー対象) GET /test-results?teacher_judgment=null ✅ 新規追加済み

3. 生徒詳細画面

特定の生徒を選んだ時の画面。学習履歴、習熟度、テスト履歴を表示。

┌────────────────────────────────────────────────────────────────┐
│  👤 佐藤 太郎 (3年1組 出席番号5)              [編集] [招待再送]   │
│  Email: tanaka@... | サインアップ済み | ログイン連続: 5日          │
├────────────────────────────────────────────────────────────────┤
│  📊 概要                                                         │
│  ┌─────────────┬─────────────┬─────────────┐                   │
│  │ 直近スコア   │ 習熟文字    │ 学習日数    │                   │
│  │   46.7%    │  12 / 50   │  15日 (今月)  │                   │
│  └─────────────┴─────────────┴─────────────┘                   │
│                                                                  │
│  📋 テスト履歴                                                    │
│  ┌──────────┬─────────┬───────┬──────┬──────┐                  │
│  │ 種別      │ 受験日   │ 正答率 │ 判定 │ 確認 │                  │
│  ├──────────┼─────────┼───────┼──────┼──────┤                  │
│  │screening │ 2026-05-07│ 46.7% │support│ 未  │ [詳細]          │
│  │screening │ 2026-04-15│ 50.0% │watch  │ 済  │ [詳細]          │
│  └──────────┴─────────┴───────┴──────┴──────┘                  │
│                                                                  │
│  📚 学習履歴 (直近)                                               │
│  ┌──────────┬─────────┬──────┬───────┐                         │
│  │ 日付      │ ブロック │ 解答数│ 正答率 │                         │
│  ├──────────┼─────────┼──────┼───────┤                         │
│  │2026-05-06│ あ行    │ 20   │ 90%   │                         │
│  └──────────┴─────────┴──────┴───────┘                         │
│                                                                  │
│  📈 文字別習熟度                                                  │
│  あ行: ████████░░ 80%                                            │
│  か行: ██████░░░░ 60%                                            │
│  ...                                                             │
└────────────────────────────────────────────────────────────────┘

この画面で必要な API

用途 エンドポイント 状態
生徒情報 GET /students/{studentId} ✅ 既存
学習状況 GET /students/{studentId}/status ✅ 既存
セッション履歴 GET /students/{studentId}/sessions ✅ 既存
文字別習熟度 GET /students/{studentId}/character-stats ✅ 既存
ブロック別習熟度 GET /students/{studentId}/block-stats ✅ 既存
日次集計 GET /students/{studentId}/daily-records ✅ 既存
招待再送 POST /invitations/{userId}/resend ✅ 既存
編集 PATCH /students/{studentId} ✅ 既存

→ 既存 API でほぼ全てカバー。新規不要。

4. クラス詳細画面

クラス全体の集計と生徒一覧。

┌────────────────────────────────────────────────────────────────┐
│  👥 3年1組 (2026年度)                          [生徒登録] [招待] │
├────────────────────────────────────────────────────────────────┤
│  📊 クラス概況                                                   │
│  ┌─────────────┬─────────────┬─────────────┐                   │
│  │  在籍数      │ 平均正答率   │  AI 検出    │                   │
│  │   33名      │   72%       │   2名 (6%)  │                   │
│  └─────────────┴─────────────┴─────────────┘                   │
│                                                                  │
│  判定分布: 🟢 normal: 25 / 🟡 watch: 6 / 🔴 support: 2            │
│                                                                  │
│  📋 生徒一覧                                                     │
│  [☑️ 未受験のみ] [並び順: 出席番号 ▼]                             │
│  ┌─────┬──────────┬─────────┬───────┬──────┐                    │
│  │ No  │ 名前      │ 直近受験  │ 判定   │ 操作  │                    │
│  ├─────┼──────────┼─────────┼───────┼──────┤                    │
│  │ 01  │ 青木 一郎 │ 2026-05-07│normal │ [詳細]│                    │
│  │ 02  │ 伊藤 花子 │ 未受験    │  -    │ [詳細]│                    │
│  │ 03  │ 佐藤 太郎 │ 2026-05-07│support│ [詳細]│                    │
│  └─────┴──────────┴─────────┴───────┴──────┘                    │
└────────────────────────────────────────────────────────────────┘

この画面で必要な API

用途 エンドポイント 状態
クラス情報 GET /classes/{classId} ✅ 既存
生徒一覧 GET /schools/{id}/students?class_id=X ✅ 既存
クラス集計 GET /classes/{classId}/summary ✅ 新規追加済み
各生徒の直近テスト結果 GET /test-results?class_id=X ✅ 新規追加済み

新規 API: GET /classes/{classId}/summary

クラス全体の集計データ。MVP では letter_test_result を動的にクエリ集計する方針 (事前集計テーブルは持たない)。将来データ規模が大きくなり集計コストが問題になれば、事前集計テーブルの追加を検討。

クエリパラメータ:

?test_type=screening
&period=last_7_days

レスポンス:

{
  "class": {
    "id": 12,
    "name": "3年1組",
    "school_year": 2026,
    "grade": 3,
    "student_count": 33
  },
  "metrics": {
    "submission_count": 30,
    "submission_rate": 0.91,
    "avg_correct_rate": 0.72,
    "avg_response_time": 1.85,
    "ai_detected_count": 2,
    "needs_support_count": 1,
    "teacher_reviewed_count": 28
  },
  "teacher_judgment_distribution": {
    "normal": 25,
    "watch": 6,
    "support": 2
  },
  "period": {
    "start": "2026-05-01",
    "end": "2026-05-07"
  }
}

5. 生徒・招待管理 (shunin/tannin 向け)

修正された認可ルールに基づき、shunin と tannin も自分の権限範囲内で生徒登録・招待・suppression 管理ができる。

5.1 生徒登録 (一括)

CSV / 手入力フォーム両方をサポート:

┌────────────────────────────────────────────────────────────────┐
│  👥 生徒一括登録                            [テンプレート DL]    │
├────────────────────────────────────────────────────────────────┤
│  対象: 自クラス (3年1組)  ← tannin                                │
│  対象: 自学年 (3年生 全クラス)  ← shunin                          │
│  対象: 学校全体  ← school_admin                                   │
│                                                                  │
│  入力方法: [CSV アップロード] / [フォーム入力]                    │
│                                                                  │
│  CSV プレビュー (○件)                                             │
│  ┌─────┬──────┬──────┬──────────┐                                │
│  │ No  │ 姓   │ 名   │ Email    │                                │
│  ├─────┼──────┼──────┼──────────┤                                │
│  │ 01  │ 佐藤 │ 太郎 │ ...@...  │                                │
│  └─────┴──────┴──────┴──────────┘                                │
│                                                                  │
│  ☑ 登録後すぐに招待メールを送信する                                │
│  on_conflict: ◯ error  ◉ skip                                    │
│                                                                  │
│  [登録実行]                                                      │
└────────────────────────────────────────────────────────────────┘

この画面で必要な API

用途 エンドポイント 状態
一括登録 POST /schools/{id}/students/bulk ✅ 既存 (認可拡張済)
招待送信 POST /invitations/send ✅ 既存 (認可拡張済)

5.2 招待状況画面

┌────────────────────────────────────────────────────────────────┐
│  📧 招待状況                                                     │
├────────────────────────────────────────────────────────────────┤
│  サマリ:                                                         │
│   未サインアップ: 5名 / 招待送信中: 3名 / 招待期限切れ: 2名         │
│                                                                  │
│  生徒一覧 (未サインアップ):                                       │
│  ┌──────────┬─────────┬──────────┬───────┬─────────┐           │
│  │ 生徒      │ Email   │ 招待状態  │ 期限  │ 操作    │           │
│  ├──────────┼─────────┼──────────┼───────┼─────────┤           │
│  │ 佐藤太郎  │ ...@... │ 送信済    │ 5/10  │ [再送]  │           │
│  │ 鈴木花子  │ ...@... │ 期限切れ  │  -    │ [再送]  │           │
│  │ 田中一郎  │ ...@... │ 未送信    │  -    │ [送信]  │           │
│  └──────────┴─────────┴──────────┴───────┴─────────┘           │
└────────────────────────────────────────────────────────────────┘

この画面で必要な API

用途 エンドポイント 状態
未サインアップの生徒一覧 GET /schools/{id}/students?has_signed_up=false ✅ クエリパラ追加済み
招待状況一覧 GET /invitations ✅ 新規追加済み
招待送信 POST /invitations/send ✅ 既存
招待再送 POST /invitations/{userId}/resend ✅ 既存

新規 API: GET /invitations

招待一覧を取得する API。OpenAPI には招待検証 (token 指定) しかなかったので追加が必要。

クエリパラメータ:

?school_id=sch_001
&class_id=12
&user_type=student
&status=active,expired,consumed
&limit=50
&cursor=...

レスポンス:

{
  "items": [
    {
      "user_type": "student",
      "user_id": "01890a5d-...",
      "user": {
        "family_name": "佐藤",
        "given_name": "太郎",
        "class_id": 12,
        "student_no": 5
      },
      "email": "tanaka@school.example.jp",
      "status": "active",
      "expires_at": "2026-05-10T12:00:00Z",
      "sent_at": "2026-05-07T12:00:00Z",
      "consumed_at": null,
      "can_resend_at": "2026-05-07T12:03:00Z"
    }
  ],
  "summary": {
    "total": 5,
    "active": 3,
    "expired": 2,
    "consumed": 0
  },
  "next_cursor": null
}

status の値:

5.3 メール suppression 管理

┌────────────────────────────────────────────────────────────────┐
│  📨 メール送信停止リスト                                          │
├────────────────────────────────────────────────────────────────┤
│  対象: 自クラスの生徒のみ表示  ← tannin                            │
│                                                                  │
│  ┌──────────┬──────┬─────────┬──────────┬────────┐             │
│  │ 生徒      │ Email│ 理由     │ 停止日   │ 操作    │             │
│  ├──────────┼──────┼─────────┼──────────┼────────┤             │
│  │ 佐藤太郎  │ ...  │バウンス  │ 2026-05-01│[解除]  │             │
│  └──────────┴──────┴─────────┴──────────┴────────┘             │
│                                                                  │
│  ⚠️ 解除する前に正しいメールアドレスか確認してください               │
└────────────────────────────────────────────────────────────────┘

この画面で必要な API

用途 エンドポイント 状態
suppression 一覧 GET /schools/{id}/email-suppressions ✅ 既存 (認可拡張済)
suppression 削除 DELETE /email-suppressions/{email} ✅ 既存 (認可拡張済)

6. 学校全体管理 (school_admin 専用)

6.1 教員一覧・登録

┌────────────────────────────────────────────────────────────────┐
│  👨‍🏫 教員一覧 (○○小学校)              [教員登録] [一括登録]     │
├────────────────────────────────────────────────────────────────┤
│  ┌─────────────┬──────────┬─────────────┬───────┬────────┐     │
│  │ 名前         │ ロール    │ 担当クラス   │ Email │ 操作    │     │
│  ├─────────────┼──────────┼─────────────┼───────┼────────┤     │
│  │ 山田 太郎    │ 校長      │ -           │ ...   │ [編集] │     │
│  │ 佐藤 一郎    │ 学年主任   │ 3年A組      │ ...   │ [編集] │     │
│  │ 鈴木 花子    │ 担任      │ 3年B組      │ ...   │ [編集] │     │
│  └─────────────┴──────────┴─────────────┴───────┴────────┘     │
└────────────────────────────────────────────────────────────────┘

この画面で必要な API

用途 エンドポイント 状態
教員一覧 GET /schools/{id}/teachers ✅ 既存
教員一括登録 POST /schools/{id}/teachers/bulk ✅ 既存
教員個別編集 PATCH /teachers/{teacherId} ✅ 既存
教員招待送信 POST /invitations/send ✅ 既存

6.2 クラス編成

┌────────────────────────────────────────────────────────────────┐
│  🏫 クラス編成 (2026年度)                  [新規クラス] [一括生成]│
├────────────────────────────────────────────────────────────────┤
│  年度切替: [2026 ▼]                                              │
│                                                                  │
│  1年生:  1組(担任:○○) 2組(担任:○○) 3組(未割当)                 │
│  2年生:  1組(担任:○○) 2組(担任:○○)                              │
│  3年生:  1組(担任:○○) 2組(担任:○○) 3組(担任:○○)                │
│  ...                                                             │
│                                                                  │
│  各クラス:[編集] [削除]                                           │
└────────────────────────────────────────────────────────────────┘

この画面で必要な API

用途 エンドポイント 状態
クラス一覧 GET /schools/{id}/classes ✅ 既存
クラス一括生成 POST /schools/{id}/classes/generate ✅ 既存
クラス追加 (個別) POST /schools/{id}/classes/bulk (1件) ✅ 既存
クラス編集 PATCH /classes/{classId} ✅ 既存
クラス削除 DELETE /classes/{classId} ✅ 既存

6.3 学校情報設定

┌────────────────────────────────────────────────────────────────┐
│  ⚙️  学校情報                                                     │
├────────────────────────────────────────────────────────────────┤
│  学校 ID: sch_001 (変更不可)                                      │
│  学校名:  [○○市立△△小学校         ]                            │
│                                                                  │
│  サマリ:                                                         │
│  ・生徒数: 540 名                                                │
│  ・教員数: 25 名                                                 │
│  ・クラス数: 18 (2026年度)                                        │
│                                                                  │
│  [保存]                                                          │
└────────────────────────────────────────────────────────────────┘

この画面で必要な API

用途 エンドポイント 状態
学校詳細 GET /schools/{schoolId} ✅ 既存
学校更新 PATCH /schools/{schoolId} ✅ 既存

7. モックアップを反映した実装イメージ (T式ひらがな音読検査)

「T式ひらがな音読検査」のモックアップ (mockup2.html) を反映した、より具体的な画面設計。 これは前述の機能設計を具体的に実装する際の参考イメージ。

7.1 全体レイアウト (PC 管理画面)

サイドバー (T式ひらがな音読検査 管理 / 児童一覧 / 統計 / 設定) + トップバー + メインコンテンツの 3 ペイン構成。

7.2 画面 ① — 児童一覧・AI 判定結果

ヘッダ: 第1回 直音音読検査 — 1年2組 [⚠ 要確認のみ] [全員]

サマリカード (4 枚):

児童一覧テーブル: # / 名前 / 提出日時 / AI判定 / 教師判定

AI判定バッジ:

教師判定バッジ:

インタラクション:

データソース:

表示要素 エンドポイント 状態
サマリカード GET /classes/{classId}/summary?test_type=screening ✅ 新規追加済み
児童一覧 + 各児童の最新 test_result GET /test-results?class_id=X&test_type=screening ✅ 新規追加済み
「要確認のみ」フィルタ 同上 + &ai_judgment=support&teacher_judgment=null (上記でカバー)

7.3 画面 ③ — 児童ごとの文字別詳細 (T式 固有部分)

画面の主構造はセクション 2 (B) 結果詳細画面で既に定義済み。 ここでは「T式ひらがな音読検査」固有の表示要素のみを補足する。

T式 固有の表示要素:

要素 値・意味
検査名表示 「第N回 直音音読検査 / YYYY年M月D日」 (運用上の名称、DB には保存しない)
全文字数 150字 (= 50字 × 3 枚)
制限時間 1分間 (60秒)
個別指導対象の閾値 54字/分以下 (read_count_per_minute)
読み速さの 4 段階 速い (〜0.6s) / 普通 (0.7〜0.9s) / 遅め (1.0〜1.4s) / 遅い (1.5s〜)
文字構成 直音 / 濁音 / 半濁音 が混在 (question_char から判別)

特記事項:

7.4 画面 ④ — クラス統計

ヘッダ: 統計 — 1年2組 [第1回 直音検査] [2026年6月]

サマリカード (3 枚):

読み文字数の分布: バーチャート、字/分のレンジ別: 〜40, 41〜54 (個別指導対象), 55〜70, 71〜90, 91〜110, 111〜

判定結果の割合: ドーナツチャート: 問題なし / 個別指導対象 / 未提出

検査回ごとの推移:

「検査回」は DB のテーブルとしては存在せず、運用で「同じ test_type の test_result を時系列で並べる」ことで表現する。 例: 6月、11月、2月にスクリーニングを実施した場合、それぞれ 1 行の test_result が作られる。

データソース:

表示要素 エンドポイント 状態
全表示要素 GET /classes/{classId}/summary?test_type=screening ✅ 新規追加済み
検査回トレンド 同 API のレスポンスに history 配列を含める (上記でカバー)

7.5 保護者側 (録音中) 画面

Phone 縦画面 / Tablet 横画面 共通のドラムロール式構成。

画面構成:

データソース:

操作 エンドポイント 備考
セッション開始 POST /assessments test_type を指定
1 文字読み終わり (テキスト + 録音アップロード) POST /assessments/{id}/answers (audio_upload_required: true) → レスポンスの audio_upload.presigned_url に PUT で wav 各文字ごと
セッション完了・提出 POST /assessments/{id}/finish ai_judgment 計算

録音 → 提出フロー:

保護者が「はじめる」をタップ
        ↓
POST /assessments  (test_type: screening)
        ↓
ループ (各文字):
  保護者がマイクボタンを押して録音
  音声データを wav バッファに保持
        ↓
  POST /assessments/{id}/answers
   { question_char, is_correct, ..., audio_upload_required: true }
        ↓
  レスポンス: { answer_id, audio_upload: { presigned_url, ... } }
        ↓
  PUT presigned_url with wav  → S3 直接アップロード (並列可)
        ↓
  「つぎへ」 → 次の文字
        ↓
全文字終了 or タイムアップ
        ↓
POST /assessments/{id}/finish
        ↓
「しゅうりょう! おつかれさま!」画面

生徒マイページ

生徒マイページ画面一覧

画面 認証要否 用途
ログイン 不要 Cognito Hosted UI
招待 token 検証 不要 招待リンクからのサインアップ
サインアップ 不要 Cognito Hosted UI
ホーム (今日の学習) 必要 学習開始のハブ画面
学習画面 必要 learning セッション
スクリーニング画面 必要 screening セッション
事後テスト画面 必要 posttest セッション
結果画面 (セッション終了) 必要 達成感の演出
学習履歴 必要 過去の学習記録
設定 (チュートリアル等) 必要 プロフィール、チュートリアル状態

1. 認証・サインアップフロー

1.1 ログイン画面

Cognito Hosted UI を使う。Email + Password、Google OAuth、Microsoft OAuth (学校契約用) の選択肢を提供。

┌────────────────────────────────────────┐
│        ようこそ! ログインしてね         │
├────────────────────────────────────────┤
│                                        │
│   [Google でログイン]                  │
│   [Microsoft でログイン]               │
│                                        │
│         ─── または ───                  │
│                                        │
│   メール: [_______________]            │
│   パスワード: [_______________]        │
│                                        │
│            [ログイン]                  │
│                                        │
│   パスワードを忘れたら? →               │
└────────────────────────────────────────┘

1.2 招待リンクからの初回サインアップ

招待メールのリンクをクリックすると、まず token 検証 → 表示確認 → Cognito Hosted UI へ。

[招待リンク踏む]
    ↓
GET /invitations/{token}
    ↓
有効? → ようこそ画面 (生徒の名前、学校名を表示)
    ↓
[サインアップ開始]
    ↓
Cognito Hosted UI (Email or IdP)
    ↓
PreSignUp Lambda で invitation 検証
    ↓
PostConfirmation/PostAuthentication で cognito_sub を student に紐付け
    ↓
ホーム画面へリダイレクト

2. 生徒ホーム画面

┌────────────────────────────────────────────────────────────────┐
│           ようこそ、たなか たろう さん!                           │
│                                                                  │
│           🔥 5日 連続でがんばっています!                          │
├────────────────────────────────────────────────────────────────┤
│                                                                  │
│      ┌──────────────────────────────────┐                       │
│      │                                  │                       │
│      │      📝 きょうの がくしゅう         │                       │
│      │                                  │                       │
│      │           [はじめる]              │                       │
│      │                                  │                       │
│      └──────────────────────────────────┘                       │
│                                                                  │
│      ┌──────────────────────────────────┐                       │
│      │   🎯 スクリーニング               │                       │
│      │                                  │                       │
│      │     [はじめる]                    │                       │
│      └──────────────────────────────────┘                       │
│                                                                  │
│  あなたの あゆみ:                                                │
│  ・がくしゅうした ひ:    18日                                     │
│  ・おぼえた もじ:        15もじ                                   │
└────────────────────────────────────────────────────────────────┘

子供向けなので、日本語は すべてひらがな + シンプルなアイコン で構成。

この画面で必要な API

用途 エンドポイント 状態
ユーザー情報取得 GET /me ✅ 既存
ログイン記録 (streak 更新) POST /me/login ✅ 既存
学習状況 GET /students/{id}/status ✅ 既存
文字別習熟度 GET /students/{id}/character-stats ✅ 既存

3. 学習画面

サーバ API は既に揃っているので、画面側のフローのみ。

[はじめる] (ホーム)
    ↓
ブロック選択 (アプリ内蔵のロジックで)
    ↓
POST /learning-sessions  → session_id 取得
    ↓
ループ:
    出題 (アプリ内蔵)
    ↓
    POST /learning-sessions/{id}/answers
    ↓
    フィードバック表示
    ↓
セッション終了
    ↓
POST /learning-sessions/{id}/finish
    ↓
結果画面 (character_breakdown を演出)
    ↓
ホームへ戻る

この画面で必要な API

用途 エンドポイント 状態
セッション開始 POST /learning-sessions ✅ 既存
解答記録 POST /learning-sessions/{id}/answers ✅ 既存
セッション終了 POST /learning-sessions/{id}/finish ✅ 既存

4. スクリーニング画面

スクリーニングは「結果を本人にどこまで見せるか」が論点。

選択肢:

医学的に微妙な領域なので、B または C が無難です。

[はじめる] (ホーム → スクリーニング)
    ↓
POST /assessments  (test_type: screening)
    ↓
出題 → 解答送信 (アプリ内蔵で固定問題セット)
    ↓
POST /assessments/{id}/finish
    ↓
おわり画面 (「がんばったね!」のみ、結果非表示)
    ↓
ホームへ戻る

この画面で必要な API

用途 エンドポイント 状態
アセスメント開始 POST /assessments ✅ 既存
解答記録 POST /assessments/{id}/answers ✅ 既存
アセスメント終了 POST /assessments/{id}/finish ✅ 既存

設定画面 (生徒)

┌────────────────────────────────────────┐
│         ⚙️ せってい                     │
├────────────────────────────────────────┤
│  おなまえ:                             │
│   たなか たろう                         │
│                                        │
│  メール:                               │
│   tanaka@school.example.jp             │
│                                        │
│  おわった チュートリアル:                │
│   ☑ がくしゅうのつかいかた              │
│   ☑ スクリーニングのうけかた             │
│                                        │
│  [ろぐあうと]                          │
└────────────────────────────────────────┘

教員と違い、生徒は自分の情報をほぼ変更できない (誤操作防止)。ログアウトのみ可能。


システム管理者ダッシュボード

システム管理者画面一覧

画面 用途
ホーム (全体メトリクス) 全学校横断の利用状況
学校管理 (一覧 + 作成) 学校の登録・更新
学校詳細 個別学校の状態確認
アクセスログ system_admin の操作監査
エラーモニタリング 各種失敗の可視化
メール suppression 管理 (全学校) 全 email アドレス対象
設定 自分のプロフィール

1. 学校管理

┌────────────────────────────────────────────────────────────────┐
│  🏫 学校一覧                                  [新規学校登録]     │
├────────────────────────────────────────────────────────────────┤
│  ┌────────┬──────────────┬─────┬──────┬──────┬────────┐        │
│  │ 学校 ID │ 学校名         │生徒数│教員数│クラス│ 操作    │        │
│  ├────────┼──────────────┼─────┼──────┼──────┼────────┤        │
│  │ sch_001│ ○○小学校       │ 540 │ 25  │ 18  │ [詳細] │        │
│  │ sch_002│ △△小学校       │ 320 │ 18  │ 12  │ [詳細] │        │
│  └────────┴──────────────┴─────┴──────┴──────┴────────┘        │
└────────────────────────────────────────────────────────────────┘

1.1 学校登録ウィザード

ステップ 1: 学校情報入力 (id, name)
    ↓
ステップ 2: クラス自動生成オプション
   - school_year
   - classes_per_grade (デフォルト 6)
   - naming_pattern (デフォルト number)
    ↓
ステップ 3: 初代 school_admin 入力
   - email, family_name, given_name, kana
    ↓
ステップ 4: 確認 → [登録]
    ↓
POST /schools
    ↓
完了画面 (作成された学校・クラス一覧表示)

この画面で必要な API

用途 エンドポイント 状態
学校一覧 GET /schools ✅ 既存
学校詳細 GET /schools/{schoolId} ✅ 既存
学校作成 POST /schools ✅ 既存
学校編集 PATCH /schools/{schoolId} ✅ 既存

2. 全学校横断のメトリクス

┌────────────────────────────────────────────────────────────────┐
│  📊 全体メトリクス                                                │
├────────────────────────────────────────────────────────────────┤
│  ┌─────────────┬─────────────┬─────────────┐                   │
│  │ 契約学校数   │ 全生徒数     │ 全教員数     │                   │
│  │     12      │    4,500    │    250      │                   │
│  └─────────────┴─────────────┴─────────────┘                   │
│                                                                  │
│  ┌─────────────┬─────────────┬─────────────┐                   │
│  │ 今週学習者数 │ 今週セッション│ AI 検出累計  │                   │
│  │   3,200     │    8,500    │    180      │                   │
│  └─────────────┴─────────────┴─────────────┘                   │
│                                                                  │
│  📧 メール状況:                                                  │
│  ・送信済 (24h): 1,200                                           │
│  ・配信成功率: 98.5%                                             │
│  ・suppression リスト: 25 件                                     │
└────────────────────────────────────────────────────────────────┘

この画面で必要な API

用途 エンドポイント 状態
全体メトリクス GET /admin/metrics ✅ 新規追加済み

新規 API: GET /admin/metrics

system_admin 専用の集計 API。SchoolDetail.summary の全学校版に近いが、メールメトリクスなどシステム全体の指標も含む。

レスポンス:

{
  "schools": {
    "total": 12,
    "active_last_7_days": 12
  },
  "users": {
    "students_total": 4500,
    "teachers_total": 250,
    "students_active_last_7_days": 3200
  },
  "sessions": {
    "total_last_7_days": 8500,
    "screening_last_7_days": 1200,
    "learning_last_7_days": 7000,
    "posttest_last_7_days": 300
  },
  "alerts": {
    "ai_detected_total_last_30_days": 180,
    "teacher_support_unreviewed": 25
  },
  "email": {
    "sent_last_24h": 1200,
    "delivered_rate": 0.985,
    "bounce_rate": 0.012,
    "complaint_rate": 0.001,
    "suppression_count": 25
  }
}

3. 運用機能

3.1 全学校 suppression 管理

┌────────────────────────────────────────────────────────────────┐
│  📨 メール送信停止リスト (全学校)                                  │
├────────────────────────────────────────────────────────────────┤
│  ┌────────────────┬──────────┬─────────┬──────────┬────────┐   │
│  │ Email          │ 学校      │ 種別     │ 停止理由  │ 操作    │   │
│  ├────────────────┼──────────┼─────────┼──────────┼────────┤   │
│  │ aa@school1.jp  │ sch_001 │ student │ バウンス  │[解除]  │   │
│  │ bb@school2.jp  │ sch_002 │ teacher │ 苦情      │[解除]  │   │
│  └────────────────┴──────────┴─────────┴──────────┴────────┘   │
└────────────────────────────────────────────────────────────────┘

この画面で必要な API

用途 エンドポイント 状態
全学校 suppression 一覧 GET /admin/email-suppressions ✅ 新規追加済み
suppression 削除 DELETE /email-suppressions/{email} ✅ 既存

新規 API: GET /admin/email-suppressions

学校横断で suppression を取得 (system_admin 専用)。GET /schools/{id}/email-suppressions の全学校版。

クエリパラメータ:

?school_id=sch_001  (任意、絞り込み)
&reason=hard_bounce
&limit=50
&cursor=...

3.2 アクセスログ・操作監査

┌────────────────────────────────────────────────────────────────┐
│  🔍 操作監査ログ                                                  │
├────────────────────────────────────────────────────────────────┤
│  種別: [ALL ▼]  期間: [過去24h ▼]                                │
│  ┌──────────┬──────────┬─────────────┬───────────────┐         │
│  │ 日時      │ 操作者    │ 操作内容     │ 対象          │         │
│  ├──────────┼──────────┼─────────────┼───────────────┤         │
│  │05-07 10:23│ admin@   │ 学校作成      │ sch_004      │         │
│  │05-07 09:15│ princip@│ suppression解除│ tan@...      │         │
│  └──────────┴──────────┴─────────────┴───────────────┘         │
└────────────────────────────────────────────────────────────────┘

この画面で必要な API

用途 エンドポイント 状態
監査ログ GET /admin/audit-logs ✅ 新規追加済み (Phase 2)

suppression_action_log テーブルが既にあるので、そこから取得。将来は audit_log という汎用テーブルを追加して全操作を記録するのが望ましい (今回のスコープ外)。


API カバレッジまとめ

既存 API で対応できるもの

これまでの設計でカバーできる画面 (新規 API 不要):

追加された API (✅ 全て api.yaml に反映済み)

エンドポイント 用途 優先度
GET /dashboard/alerts 教員ホームのアラート集計
GET /dashboard/summary 教員ホームの概況サマリ
GET /dashboard/recent-activity 教員ホームの最近の活動
GET /test-results テスト結果一覧 (横断)
GET /assessments/{sessionId}/answers アセスメントの解答内訳
GET /classes/{classId}/summary クラス集計
GET /invitations 招待一覧
GET /admin/metrics システム全体メトリクス
GET /admin/email-suppressions 全学校 suppression
GET /admin/audit-logs 操作監査ログ 低 (Phase 2)

クエリパラメータ追加 (✅ 反映済み)

エンドポイント 追加パラメータ 用途
GET /schools/{id}/students has_signed_up (boolean) 未サインアップで絞り込み

画面別 API 数のまとめ

画面群 使う API 数
教員ダッシュボード 約 25
生徒マイページ 約 8
システム管理者 約 10

これで 3 つのダッシュボードを実装するために必要な API がすべて揃いました。


次のステップ

  1. 新規 API を OpenAPI 仕様 (api.yaml) に追加 ✅ 完了
  2. 画面実装の優先順位付け (MVP / Phase 2 / Phase 3)
  3. フロントエンド実装方針 (React / Vue / Flutter Web 等の選定)
  4. デザイン・UX 詳細 (Figma などでのモックアップ)

これらは別途のフェーズで進めていきます。