feat(classroom): クラス管理右上のお知らせ通知センター (#1111)#1113
Merged
smalruby3-editor-bot[bot] merged 6 commits intoJul 25, 2026
Merged
Conversation
お知らせセンターの土台。ClassroomNotifications テーブル (PK teacherSub / SK notificationId=createdAt接頭辞) と、先生向けの GET /notifications (一覧+未読数) / POST /notifications/mark-read (ids省略で全既読) を追加。 設計上の分岐点 (このコミットに立ち戻ればやり直せる): - D1 置き場所: 汎用お知らせ基盤ではなく classroom スタック所有にした。 受信者が先生 (teacherSub) で、既存の先生 ID Token 認証をそのまま 読み出しに使えるため。書き込みは admin スタックが名前規約 import で 行う (SharedAssignments と同じ N2 維持の形)。代替案: admin スタック 所有 (先生の読み出し認可を admin 側に作る必要があり不採用) - D2 既読API: mark-read は notificationIds 省略時に直近50件窓の未読を 全既読化 (パネルを開いたらバッジが消える UX 前提)。代替案: 1件ずつ 既読 (クリック時に都度更新。API往復が増えるため不採用) - D3 保持期間: TTL は書き手 (admin スタック) が付与する。通知は短命な 案内でありレコードではないため DESTROY / stream なし Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
POST /admin/notifications。SPA からは classroomId だけを送り、宛先の
teacherSub はサーバー側で解決して ClassroomNotifications へ書き込む。
テーブルは classroom スタック所有を名前規約 import (N2) し、この
スタックが単一の書き手 (write-only grant)。全送信を audit() 記録。
設計上の分岐点 (このコミットに立ち戻ればやり直せる):
- D4 宛先指定: teacherSub を admin SPA へ渡さず classroomId で指定。
admin 投影が authorSub/teacherSub を意図的に隠す既存原則の踏襲。
代替案: teacherSub 直接指定 (内部IDの露出が増えるため不採用)
- D5 grant: 読みを許可せず grantWriteData のみ。読み出し導線は
先生側 (classroom API) に限定し、単一ライターの非対称を IAM でも
表現。代替案: RW grant (送信履歴の admin 表示が必要になったら拡張)
- link.kind は whitelist ('classroom' のみ)。後続 Issue (#1110/#1106)
で kind を増やす際はここに追加する
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
クラス検索/俯瞰候補から開くクラス詳細の下部に「先生へのお知らせ」 パネルを追加。タイトル+本文を入力し、既存の二段階確認 (arm/confirm) を通って POST /admin/notifications を呼ぶ。 設計上の分岐点 (このコミットに立ち戻ればやり直せる): - D6 送信UIの置き場所: クラス詳細 (ClassroomDetail) 内に配置。 俯瞰の有益候補クリック→詳細→送信、検索→詳細→送信の両動線が 1 箇所で済むため。代替案: 専用タブ/俯瞰の行内ボタン (対象クラスの 文脈確認なしに送れてしまうため不採用) - 既存の mutation 規約 (二段階確認・本文必須で無効化) を踏襲 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
先生モーダルのタイトルバー (× の左隣) に 🔔 ボタン + 未読バッジを 追加。クリックでお知らせ一覧パネルを開き、開いた時点で全既読化。 お知らせの link.kind='classroom' クリックで該当クラスのボード文脈 (クラス選択→課題詳細) へジャンプする。60 秒間隔でポーリング。 設計上の分岐点 (このコミットに立ち戻ればやり直せる): - D7 アイコン: 絵文字 🔔 を採用。classroom UI は絵文字/テキスト バッジが既存慣行 (⚠ など) で新規 SVG アセット不要のため。 代替案: icon--*.svg (menu-bar の慣行。視覚統一が必要になれば移行) - D8 既読化: パネルを開いた時点で mark-read (全件)。バッジは即消え、 未読ドットは取得済み readAt のままなのでその場では見分けられる。 代替案: アイテムクリックごとに個別既読 (API往復増のため不採用) - D9 更新間隔: 専用フックで 60 秒ポーリング。既存の 30 秒クラス一覧 リフレッシュへの相乗りはフック間結合が増えるため不採用 - D10 通知取得エラーは黙殺 (401 のみ再認証へ)。通知障害がクラス管理 本体を壊さないため - 配置: logout を right 4.5rem→7.5rem、email を 10.5rem→13.5rem へ ずらし、🔔 を 4.5rem (× の隣) に置いた 検証: jest 19 件 + headless Playwright (APIスタブ) 9/9 チェック合格 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- architecture.md: /notifications ルート表 + ClassroomNotifications データモデル (単一ライター設計の説明つき) - source-code.md: 新規ファイル・ハンドラ関数 - ui-ux.md: 1.8 お知らせセンター (data-testid 一覧 + スクリーンショット 0218) - admin/README.md: 送信フォームの説明 + スクリーンショット 0106 - tools/playwright-verify/verify-notification-center.mjs: API スタブ式の リグレッションスクリプト (stg 不要で 9 チェック) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
🚀 Preview deployed: https://smalruby.jp/smalruby3-editor/feature/notification-center-1111/ |
レビュー (PR #1113) の指摘への対応: - [Must] 通知タイムスタンプを toLocaleString でローカルタイム表示に (ISO slice だと UTC のまま出て日本では 9 時間ずれる) - [Question] handleToggleNotifications の副作用を state updater の外へ (StrictMode/concurrent で updater が再実行されても二重送信しない) - [FYI] link.kind の whitelist 検証を putNotification 内へ移動 (呼び出し側ハードコードで dead code だったのを、将来の送信経路 すべてが通る位置に) - [FYI] mark-read: body が JSON 配列のとき 400 (暗黙の全既読を防ぐ)、 id は 200 文字上限 (DynamoDB ValidationException→500 ではなく 400) - [FYI] classroom Lambda の通知テーブル grant を Query/UpdateItem のみに 縮小 (PutItem を外し「エディタから偽造不可」を IAM でも担保) - [FYI] use-teacher-notifications のフックユニットテストを追加 (6件: interval 停止・開いたら一度だけ mark-read・401 再認証・リセット) - [FYI] .claude/rules/infra/smalruby-classroom.md のテーブル一覧の ドリフト解消 (4→8 テーブル) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Author
敵対レビュー結果(自動レビュー + 対応済み)diff 全体(infra 2 スタック / admin SPA / scratch-gui)を対象に、正確性・セキュリティ・ 指摘と対応(コミット 56c226c)
クリーンと確認された点(抜粋)
判定: 指摘対応後 MERGEABLE(stg デプロイ + integration 確認は SSO 再ログイン後のフォローアップ) |
smalruby3-editor-bot
Bot
merged commit Jul 25, 2026
5faa7ff
into
topic/classroom-notification-center
21 checks passed
This was referenced Jul 25, 2026
Author
stg デプロイ・検証完了(2026-07-25)ClassroomStack-stg / AdminStack-stg をデプロイし、integration テスト(49 件パス・教師フロー含む)+ 実 API のスモークで 3 EPIC の通しを確認:
検証データはクリーンアップ済み(取り下げ + アーカイブ、stg TTL 1 日)。 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
EPIC #1111 の実装。クラス管理画面の右上に「お知らせ」通知センター(🔔 + 未読バッジ + 一覧パネル)を追加し、Admin からお知らせを送る最小の仕組みを揃える。後続の #1110(推薦通知)/ #1106(共有促し)がこの基盤に乗る。
アーキテクチャ(設計判断)
ClassroomNotifications{suffix}テーブルを所有(PKteacherSub/ SKnotificationId= createdAt 接頭辞、TTL 180日)。先生の読み出しは既存の先生 ID Token 認証をそのまま利用link.kindは whitelist(現在classroomのみ)。エディタは未知の kind を無視(前方互換)各コミットのメッセージに、その時点の設計分岐(採用案 / 代替案 / 理由)を記録済み。分岐をやり直す場合は該当コミットに立ち戻れる。
Changes Made
ClassroomNotificationsテーブル +GET /notifications(一覧+未読数)/POST /notifications/mark-read(ids 省略で全既読)POST /admin/notifications(audit 付き・write-only grant)link.kind='classroom'で該当クラスへジャンプ + 60 秒ポーリングverify-notification-center.mjs(API スタブ式・stg 不要)Test Coverage
handler-notifications.test.ts8 件(全 13 スイート 227 件パス)handler-notifications.test.ts5 件(全 4 スイート 44 件パス)teacher-notifications.test.jsx5 件 + classroom-api 3 件(対象ファイル lint クリーン)残タスク(マージ前後)
cdk synthは両スタックとも検証済みnpm run test:integration+ verify スクリプト)Related Issues
Refs #1111(topic branch 集約後に develop PR で Close 予定)
🤖 Generated with Claude Code