feat(classroom): みんなの課題 — 全国の先生による課題共有ライブラリ (EPIC #1066)#1080
Open
smalruby3-editor-bot[bot] wants to merge 27 commits into
Open
feat(classroom): みんなの課題 — 全国の先生による課題共有ライブラリ (EPIC #1066)#1080smalruby3-editor-bot[bot] wants to merge 27 commits into
smalruby3-editor-bot[bot] wants to merge 27 commits into
Conversation
みんなの課題 (EPIC #1066, design: spike #1067 D1-D12): - new SharedAssignments table (no TTL; prod RETAIN + PITR; GSIs status-createdAt / authorSub-createdAt) and SharedAssignmentReports table (90-day TTL) - new smalruby-shared-assignments bucket (no lifecycle = permanent, prod RETAIN) so the classroom retention sweep never touches shares - 7 teacher-auth endpoints: share (snapshot copy into the shared bucket, CC BY consent required, 50MB starter cap, 10/day quota), newest-first filtered catalog with cursor pagination + mine=1, detail with presigned URLs, import into own class (reverse copy + reuseCount), author-only update (overwrite re-snapshot) / unlist, and report (20/day quota, reason required) - responses never expose authorSub / reporterSub; quotas reuse the eval-quota atomic counter pattern - docs: architecture.md route table + data notes; .env.example limits EPIC #1066 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(classroom-api): みんなの課題 — 共有ストア・API 一式 (S1 #1068)
みんなの課題 S2 (EPIC #1066, design: spike #1067): - "Share this assignment" button in the assignment detail opens an inline form: title/summary, school level x grades x subject (controlled vocabulary, free text for "other" — D5), free tags, lesson count, supplement URL with explicit guidance on what belongs there + client-side https check (D4), minimal author profile remembered in localStorage smalruby:sharedAuthorProfile (D6), and a mandatory CC BY 4.0 consent checkbox (D2) - publish confirmation shows the CC BY credit line - classroom-api gains the 7 shared-assignment methods (share / list / detail / import / update / unlist / report) for S2+S3 - new libs: shared-assignment-taxonomy (mirrors the server vocabulary) and shared-author-profile (SSR-guarded persistence) - new hook use-shared-assignments wired through the teacher aggregator - docs: ui-ux.md / testing.md testids EPIC #1066 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(classroom): みんなの課題 — 共有フォーム (S2 #1069)
みんなの課題 S3 (EPIC #1066, design: spike #1067): - "Find in みんなの課題" on the assignment board opens the catalog: newest-first cards (attribute badges, tags, author, reuse count) with school-level/subject/grade/tag filters and cursor pagination - detail preview shows the snapshot pages, the CC BY 4.0 credit line and the supplement URL behind an explicit external-domain confirmation (D4); import copies the assignment (starter included) into the current class and surfaces the new join code note - "My posts" tab lists the caller's own items (incl. unlisted) with withdraw / republish; strangers get a report flow (reason required) - use-shared-assignments grows the catalog state machine and refreshes the board after an import - docs: ui-ux.md / testing.md testids EPIC #1066 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(classroom): みんなの課題 — カタログ・取り込み UI (S3 #1070)
みんなの課題 S4 (EPIC #1066 D3, post-moderation): - bin/shared-assignments-admin.ts: list-reports (report queue grouped by item, most-reported first), show <sharedId>, unpublish/republish (dry-run by default, --apply to execute; never hard-deletes) - planning/rendering logic split into lambda/shared-admin-lib.ts (pure, unit-tested); reporterSub is never rendered - docs/assignment-sharing/operations.md: moderation runbook — flow, judgment criteria, the no-contact-address premise (D6), and the future hand-off to the Admin SPA (EPIC #1073) EPIC #1066 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(classroom-ops): みんなの課題 — 通報対応 CLI + runbook (S4 #1071)
みんなの課題 S5 (EPIC #1066): - docs/assignment-sharing/README.md: feature overview (D1-D12 recap, share/catalog flow diagram, file inventory, settings) with Japanese UI screenshots 0101-0104 captured headless against the deployed stg API; classroom README links across - tools/playwright-verify/verify-assignment-sharing.mjs: end-to-end pass — create class/assignment with content, share (CC BY consent, publish confirmation carries the credit), catalog filter, detail (credit line + external-domain URL confirmation), import into the class (new board row), my-posts unlist/republish, stg cleanup - verified on stg: full run PASS twice (en + ja locales) EPIC #1066 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
docs(assignment-sharing): みんなの課題 — docs/E2E/stg 検証 (S5 #1072)
1 task
|
🚀 Preview deployed: https://smalruby.jp/smalruby3-editor/feature/assignment-sharing/ |
…list DynamoDB rejects an empty ExpressionAttributeNames map, so GET /shared-assignments?mine=1 (自分の投稿タグ) always returned 500 when no attribute filters were set — the query needs no #status alias in mine mode. Build the map first and spread the key in only when non-empty (same pattern as the group update at handler.ts:2591). Found during PR #1080 review on prod (2026-07-18). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix(classroom): mine=1 の shared list が空 ExpressionAttributeNames で 500
Author
レビュー中に発見された 500 の修正と DoD 結果 (2026-07-18)症状と原因
stg 検証
prod デプロイ + プレビュー URL での DoD
🤖 Generated with Claude Code |
1 task
…-sharing # Conflicts: # tools/playwright-verify/README.md
課題詳細に「課題を配信(GC)」と「この課題を共有(みんなの課題)」が併存し、 さらに参加コードが場所を取って全画面ボタンも別にあり、それぞれ何をするのか 分かりにくかった。参加コード周りを1枚のカードに整理: - 参加コードカード: 「参加コード:xxxxxx」+ アクション行 (全画面表示 / 招待リンクをコピー / Google Classroom に参加コードを共有) - 課題名の横にあった「課題を配信」ボタンを廃止し、カード内の 「Google Classroom に参加コードを共有」へ移動・改称(何をするか一目でわかる。 配信済みなら「Google Classroom で開く」)。GC 未連携なら非表示 - 招待リンクのコピーを詳細にも追加(従来は全画面表示の中だけ) ja.js / ja-Hira.js に joinCode.shareToGc / openInGc を対で追加。 みんなの課題の「この課題を共有」ボタンは (2) で一覧へ移すため今回は現状維持。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
参加コードカードが縦に数行になり全体レイアウトが崩れていたのを、 課題名(左)と参加コード(右)の均等幅2カラムに分割し各カラムを約2行に整理: - 左: 課題名を2行の textarea に(長い課題名が折り返して全文見える。 Enter は改行せず保存し単一行の値を維持) - 右: 行1=参加コード + 全画面表示 / 行2=招待リンクをコピー + GC共有 - Google Classroom 共有ボタンは狭い幅では "Google Classroom" を省いて "[アイコン]に参加コードを共有" 表示(カード幅で判定する container query)。 shareToGcShort / openInGcShort を ja/ja-Hira 対で追加 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
人数変更の不具合修正: - クラス(グループ)の studentCount 変更が既存課題に反映されなかった。 handleUpdateGroup で変更時に配下のアクティブな課題へ伝播する (teacherSub-index + groupId フィルタで列挙し各課題の studentCount を更新)。 増やす=席追加(安全)、減らす=席削除 - フロント: 人数を減らすときだけ警告(「N人に減らすと M+1〜元 番の席が なくなり提出作品が表示されなくなります」→ 減らして保存 / 人数はそのまま)。 増やすときは警告なし 課題詳細レイアウト洗練 (割り込み要望): - 課題名: ラベルと2行フィールドを横並び・ラベルは縦センタリング - 参加コード: 値のフォントをラベルと同サイズに(ボールド・色は維持) - 各ボタンを最初から flex-wrap 配置(狭ければ2行折返し)。狭幅では 全画面表示・招待リンクコピーをアイコンのみに、Google Classroom 共有は "Google Classroom" を省略(カード幅の container query で切替) テスト: infra 伝播 3(増/減/フィルタ)、GUI 減少警告 3。ja/ja-Hira 対で 文言追加。ブラウザで全レイアウト・警告・狭幅アイコン化を確認。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
課題詳細の参加コードカードを次のように改善: - コード値と3つのボタン(全画面表示/招待リンクコピー/GC共有)を1つの flex flow にまとめ、同じ行から始めることで3行になるのを防ぐ - 課題名カラムと参加コードカードを flex-wrap で並べ、幅が足りず カードが340pxを割り込むと参加コードカードを単独行(フル幅)に 折り返して狭いウインドウでも2行に収める - カード幅が狭いとき(container query)は全画面表示/コピーをアイコン のみに、Google Classroom共有を短縮表示にする - 参加コードの値のフォントを課題名ラベルと同じ1remに拡大(色・太字は維持) - 課題名入力の高さを参加コードカードに一致させる(align-items: stretch) - 「Google Classroom に参加コードを共有」を「Google Classroom に共有」、 短縮形を「に共有」に変更 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ラベルが長くレイアウトが崩れやすい問題を、ボタンを幅に依らず コンパクトに固定して解決: - 全画面表示・招待リンクコピーは幅に関わらずアイコンのみ(tooltip で ラベルを補足) - 招待リンクコピーはクリックでアイコンがチェックに変わり緑で強調、 コピー完了が分かるリアクションを追加 - Google Classroom 共有は幅に関わらず「[アイコン]に共有」の短縮表示で固定 - 幅で表示を切り替える container query と未使用の全文ロケールキー (shareToGc / openInGc) を削除 これにより多くの幅で参加コードカードが1行に収まり、狭くても2行を保つ。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
保存期限まわりの表示を改善し、限られた画面領域を有効活用する(#1052/#1049): 課題詳細: - 専用の警告バナーを廃止し、保存期限の右に警告メッセージをインライン表示 「保存期限: 2026/7/21 ⚠保存期限をすぎるとこの課題と提出物は自動削除 されます。ダウンロードして保存してください」。バナーを消した分、下の 編集領域が広がる - 幅が狭いときは「ダウンロードして保存してください」を省略(container query) - 期限が近いとき全作品ダウンロードボタンを警告色(赤)にしてDLを促す 課題一覧(ボード): - 「あと N 日」バッジをやめ、課題詳細と同じ「この課題と提出物は {日付} に 自動削除されます。ダウンロードして保存してください。」を行に表示 - 各行に全作品ダウンロードボタンを追加(その課題だけをZIP化。既存の handleDownloadClassAll を単一課題で再利用)。DL中の行だけ進捗を表示 未使用になった board.expiryBadge ロケールキーを削除。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Google Classroom 配信画面をクラス管理の基本レイアウトに揃える: 配信フォーム: - パンくず(クラス一覧 > 課題一覧 > 課題詳細 > Google Classroom に共有)を 親から表示。フェーズ内の「< 戻る」ボタンは廃止 - 「対象:」ラベルを廃止し、クラス名を課題詳細と同じ表記(例: 技術 2026年度、 formatClassLabel)でサブタイトル表示 - フッターを基本ポリシーに統一: キャンセル(左下・戻ると同じ挙動)+ プライマリー「Google Classroom に配信する」(右下・必須未入力で非活性) 配信後の画面: - 中央寄せの旧レイアウトをやめ、基本レイアウトに統一。パンくずを維持し、 「✓ 配信しました!」+ ヒント + フッター(左=課題詳細にもどる / 右=Google Classroom で確認する) 未使用の postAssignment.target ロケールキーを削除し、breadcrumbs.shareGc / postAssignment.cancel / postAssignment.backToDetail を追加。 teacher-post-assignment の単体テストを追加。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
配信画面の本文ルートが未定義の .phaseContainer を使っており左右パディングが 効いていなかった。課題詳細(.detail-layout)と同じ padding: 0 2rem 1.25rem を 持つ .post-assignment-container に置き換え、パンくず・タイトル・本文の左端を 2rem に揃える。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
課題詳細のクラス名(.teacher-view-title / div)が太字になっておらず、課題一覧 の見出し(h2.board-title は既定で太字)と見た目が揃っていなかった。 .teacher-view-title に font-weight: bold を追加して統一する(評価画面の 同クラス見出しも同様に揃う)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
7 tasks
みんなの課題(#1066)に限定公開パイプラインの土台を追加: - shared-assignment に visibility('public'|'limited') と passcode(合言葉)を導入。 #1109 以前の項目は visibility 無し=public とみなす(後方互換) - 限定公開の発行は軽い検証(CC BY 同意・属性・著者名は任意)で、参加コード同型の 合言葉を発行。完璧さの圧を下げる - 公開カタログ(GET /shared-assignments)は限定公開を FilterExpression で除外。 mine=1 は自分の合言葉を含める - 合言葉のルックアップ(POST /shared-assignments/lookup)と取り込み (POST /shared-assignments/import-by-passcode)を追加。sharedId は非著者に露出しない - GET /{id} は限定公開を非著者から 404 で隠す - PATCH で限定公開→全体公開に広げるとき、CC BY 同意・属性・著者名を必須化 - SharedAssignments に passcode-index GSI を追加 unit テスト 8 件追加(33 件 pass)。tsc / cdk synth(stg)通過。deploy は未実施。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
classroom-api.js に限定公開(合言葉)用の 2 メソッドを追加: - lookupSharedByPasscode: 取り込み前のプレビュー(sharedId 非露出) - importSharedByPasscode: 合言葉で自分のクラスに取り込み shareAssignment は payload に visibility を渡せる(backend が分岐)。UI 配線は後続。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
みんなの課題の API 表に visibility(public/limited)・合言葉ルックアップ (/shared-assignments/lookup)・合言葉取り込み(/import-by-passcode)・ 限定公開の除外/隠蔽/昇格の挙動・passcode-index GSI を反映。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
出す側の共有導線を「課題詳細タブ行」から「課題一覧(ボード)の各行」に一本化:
- ボード各行に「共有」ボタン → 共有設定ステップ(深さは クラス > 課題 > 共有)
- 共有設定ステップ(teacher-share-step.jsx)で公開範囲を選ぶ:
- 限定公開(合言葉): タイトルのみで発行。合言葉を大きく表示+コピー。研究授業で
少し試した課題でも出せる(完璧さの圧を下げる)。あとで全体公開へ広げられる
- 全体公開(みんなの課題): 既存の SharedAssignmentForm を再利用
- 課題詳細タブ行の「この課題を共有」ボタン + インラインフォームは廃止
- use-shared-assignments: showShareForm → shareTarget(対象課題)に変更。発行後は
ステップに留まり結果(合言葉)を確認できる
- 不要になった shared.openForm ロケールキーを削除
unit テスト追加(share-step 5件・board 共有導線 3件)。lint / prettier / 関連テスト green。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
限定公開の課題を合言葉で内輪取り込みする導線を追加: - ボードのアクションバーに「合言葉で取り込み」ボタン - teacher-passcode-import.jsx: 合言葉入力 → 確認(lookup・sharedId 非露出)→ プレビュー(課題名)→「このクラスに取り込む」で組に取り込み - use-shared-assignments: passcode の lookup / import 状態とハンドラを追加 - 共有ステップと同様、取り込み中はボードのアクションバーを隠す unit テスト追加(3件)。lint / prettier / 関連テスト green。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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 #1066「みんなの課題」の統合 PR。先生が作成した課題(説明ページ + スタータープロジェクト + 補足資料 URL)を全国の先生に共有・再利用できるライブラリ。設計の正典はスパイク #1067 の Decision Log(D1〜D12、壁打ち 2 ラウンドで確定)。
Closes #1068, closes #1069, closes #1070, closes #1071, closes #1072, closes #1066
構成(sub-issue → PR、トピックブランチへマージ済み)
主要な設計判断(詳細は EPIC の Decision Log)
Test Coverage
tsc/cdk synthクリーンデプロイ状況
🤖 Generated with Claude Code