Skip to content

review: クラス機能の総合レビュー(UI/UX・セキュリティ) #495

@takaokouji

Description

@takaokouji

概要

クラス機能の総合レビューを実施。ドキュメント(docs/classroom/*.md)、フロントエンドコード、インフラコード(infra/smalruby-classroom/)、および本番環境(https://smalruby.app)での Playwright MCP による動作確認を行った。

レビュー観点:

  • UI/UX: 先生(Google Classroomは使えるがスモウルビーは初めて)、生徒(スモウルビーは使えるがクラス機能は初めて)の視点で、次のアクションが明確か、説明が邪魔にならないか
  • セキュリティ: 個人情報漏洩リスク、APIレベルの認可、インフラ設定

UI/UX レビュー

問題1: 生徒の参加後ガイダンス不足(高優先度)

ファイル: packages/scratch-gui/src/components/classroom-modal/student-joined-confirmation.jsx

現状: 参加完了後の画面にはクラス名・出席番号・課題名と「はじめる」ボタンのみ表示される。

問題: 「はじめる」を押した後に何をすればいいのか分からない。クラス機能が初めての生徒は「プロジェクトを作ってから提出する」という全体の流れを知らない。

改善案: 「はじめる」ボタンの上に、フローを示すステップガイドを追加:

  1. モーダルを閉じてプロジェクトを作ろう
  2. できたら、メニューバーの「クラス」ボタンを押して提出しよう

問題2: 生徒ステータス画面の未提出時ヒント不足(高優先度)

ファイル: packages/scratch-gui/src/components/classroom-modal/student-status-view.jsx

現状: 「未提出」状態で「提出する」ボタンが表示されるが、補足説明がない。

問題: まだプロジェクトを作っていない生徒にとって「今すぐ提出しなければいけないのか?」と混乱する可能性がある。

改善案: 未提出状態の時に小さなヒントテキストを追加:

プロジェクトが完成したら「提出する」を押してください

問題3: DEV_BYPASS_TOKEN のフェイルセーフ不足(高優先度)

ファイル: infra/smalruby-classroom/lambda/handler.ts:219-223

現状: DEV_BYPASS_TOKEN が設定されていれば無条件に dev bypass が有効になる。prod の .env.prod には未設定なので現時点では安全だが、コード上のガードがない。

if (DEV_BYPASS_TOKEN && idToken === DEV_BYPASS_TOKEN) {
    return 'dev-test-teacher';
}

改善案: STAGE !== 'prod' チェックを追加:

if (DEV_BYPASS_TOKEN && idToken === DEV_BYPASS_TOKEN && STAGE !== 'prod') {
    return 'dev-test-teacher';
}

問題4: 参加コードの全画面ボタンが分かりにくい(中優先度)

現状: 参加コードの横に小さな アイコンがあるが、意味(プロジェクターで表示するための全画面表示)が直感的に分からない。

改善案: ツールチップ「全画面表示」を追加。

問題5: メンバーグリッドのガイダンス不足(中優先度)

現状: メンバーグリッドの右に「メンバーを選択してください」と表示されるが、席番号ボタンがクリック可能であることが直感的に分からない。

改善案: テキストを「席番号をクリックして生徒の詳細を見る」に変更。

問題6: Presigned URL の有効期限が長い(中優先度)

ファイル: infra/smalruby-classroom/.env.prod

現状: PRESIGNED_URL_DOWNLOAD_EXPIRY=3600(1時間)。URLが漏洩した場合、1時間にわたって生徒の提出物にアクセス可能。

改善案: 300秒(5分)に短縮。先生がダウンロードする際に都度生成されるため、短くても問題ない。

問題8: デバッグ変数の本番残留(低優先度)

ファイル: packages/scratch-gui/src/containers/use-teacher-classroom.js

現状: window._classroomIdToken に先生の ID トークンが格納され、ブラウザコンソールから取得可能。

改善案: デバッグ用の window._classroomIdToken 代入を削除。


セキュリティレビュー

安全と確認された項目

項目 状態 詳細
クロステナントデータアクセス ✅ 安全 全エンドポイントで teacherSub / sessionToken + classroomId の検証あり
CORS 設定 ✅ 安全 prod は smalruby.app, smalruby.jp のみ。localhost なし
個人情報漏洩 ✅ 安全 API レスポンスに氏名・年齢・学校名は一切含まれない。出席番号のみで管理
API 認可 ✅ 安全 先生: Google ID Token 検証 + ownership check。生徒: Session Token + classroom check
DynamoDB クエリ ✅ 安全 全クエリが適切にキー条件でスコープされている
S3 アクセス ✅ 安全 Presigned URL に classroomId を含み、クロスクラスアクセス不可

要注意項目

項目 深刻度 詳細
レート制限(インメモリ Map) Lambda の水平スケール時に無効化される。API Gateway スロットリングが補完
セッショントークンの IP バインドなし UUID v4 で推測困難、TTL あり。教育現場では許容範囲
sessionStorage にトークン保存 XSS があれば窃取可能だが、SPA では一般的なパターン
エラーメッセージの情報開示 「参加コードが無効です」で存在確認可能だが、6文字コードの総当りは困難

良好な点

  • 先生のログイン画面カルーセル: 4つの機能紹介スライドが自動送り+手動ナビゲーション。初めての先生に機能を簡潔に伝えている
  • チュートリアルオーバーレイ: 初回のみ表示、「わかりました」で永続的に消える。経験者には邪魔にならない
  • 生徒の参加コード入力ヒント: 「先生から参加コードを聞いてください」が常時表示(消す操作不要)
  • プライバシー配慮: 生徒の氏名は一切システムに保存されず、出席番号のみで管理
  • 先生の詳細パネル: 提出物のサムネイル、スプライトごとのページ送り、コメント、返却機能が揃っている

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions