feat: クラスルーム機能 — 作品提出 (Phase 2)#445
Merged
Merged
Conversation
Backend CDK extensions for submission feature (#442): - S3 bucket for .sb3 and thumbnail storage (90-day lifecycle) - SubmissionsTable with classroomId-memberId GSI - sessionToken-index GSI on MembershipsTable for student auth - New API routes: POST/GET /classrooms/{id}/submissions - Lambda env vars and permissions for S3 + new table Also: - Commit cdk.context.json for all infra projects (CDK best practice) - Add smalruby-classroom to infra development rules - Document cdk.context.json commit policy Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…gned URLs Backend implementation for classroom submissions (#442): - verifySessionToken() using sessionToken-index GSI - POST /submissions: generate presigned URLs for .sb3 + thumbnail upload - GET /submissions: list submissions with thumbnail presigned URLs (teacher) - handleListMembers extended: returns hasSubmission/submittedAt per member - validateProjectName validation + 6 new unit tests (45 total) - S3 + DynamoDB dependencies added to package.json Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Frontend for classroom submissions (#442): - Student status screen: submission status display + submit/resubmit button - Submit confirmation phase with stage thumbnail preview - Upload flow: presigned URL → .sb3 + thumbnail PUT to S3 - Teacher seat grid: green cells with ✓ for submitted students - Member detail popup: submission time badge - Reducer: submissionStatus + lastSubmittedAt persisted to localStorage - API client: createSubmission, listSubmissions, uploadToPresignedUrl - i18n: ja, ja-Hira, en (13 new keys each) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
React Intl requires statically evaluable message ids. Split dynamic id into two separate FormattedMessage components with conditional rendering. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
🚀 Preview deployed: https://smalruby.jp/smalruby3-editor/feature/classroom-submission/ |
ESLint no-negated-condition rule disallows `!member ? ... : ...`. Refactored to if/else assignment. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ssion viewing
Teacher improvements:
- Add class deletion with confirmation dialog (soft-delete + member cleanup)
- Show creation date and student count in class list
- Fixed header/footer with scrollable class list in dashboard
- Auto-refresh class detail every 30s (configurable via env var)
- Manual refresh button in class detail
- Show submission thumbnail and "Open in Smalruby" button in member popup
Student improvements:
- Validate join code before seat selection (lookup API)
- Google Classroom-style error box for invalid join codes
- Japanese error messages for seat conflicts and session expiry
- Verify session on status screen open (detect deleted members early)
Backend:
- DELETE /classrooms/{id} — soft-delete with member batch cleanup
- POST /classrooms/lookup — validate join code, return seat info
- POST /classrooms/verify-session — check session token validity
- Add projectUrl (presigned GET) to listSubmissions response
- Add GET to S3 bucket CORS for submission downloads
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Compact class items: reduce vertical padding (0.8rem → 0.5rem) and margin-bottom (0.5rem → 0.25rem), saving ~11px per item. Lower dashboard max-height by 20px for more breathing room. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…uto-join Teacher dashboard: - Join code displayed in lowercase (Google Classroom style) - Expand icon (⛶) next to code opens class code display dialog - Details button pushed to right end of meta row Class code display dialog: - Large centered code display with class info footer - "招待リンクをコピー" copies current URL with classcode= param - Fullscreen toggle (⛶/⊟) via ReactDOM.createPortal - × button returns to dashboard Invite link (classcode URL parameter): - ?classcode=xxx auto-opens classroom modal on page load - If already joined to same class: shows status - If joined to different class: leaves and starts new join flow - If not joined: validates code and shows seat selection Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Teacher role memory: - Cache idToken at module level across modal close/open - Skip role selection when reopening modal (go directly to dashboard) - Logout clears the cache and returns to role selection Class detail redesign (968px wide modal): - Two-pane layout: left (info + 10-column seat grid) + right (member detail) - Right pane shows large thumbnail, project name, "Open in Smalruby" button - Join code shown in lowercase with expand button for code display - Members grid fixed at 10 columns per row Class list simplification: - Remove expand icon from class list items - Keep lowercase code display inline Code display navigation: - Navigate from class detail (not class list) - Back button and fullscreen × return to class detail - Clipboard SVG icon for copy, proper shrink SVG icon Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Move back button to top-left of detail area (above two-pane layout) - Remove duplicate back button from code display (keep only one) - Show "出席番号XX" instead of "seat-XX" in member detail panel - Show "リンクをコピーしました" feedback after copying invite link - Remove loading indicator from members grid to prevent layout shift; keep previous state visible during refresh, update on completion Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Show "コピーしました" feedback on normal code display (was only fullscreen) - Left-align back-link buttons (display: block, text-align: left) to prevent centering in code-display and detail-layout containers Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add user-select: text and cursor: text to all 4 code display locations: class list item, detail join code, code display dialog, fullscreen code. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use ○○○○○○ (white circles) instead of ABC234 to indicate 6-character input without being confused with actual text. Lighten placeholder color. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Show typed characters in lowercase (matching code display style). The code is uppercased only when sent to the API. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add CLASSROOM_TTL_DAYS env var (default 30 days) for CDK + Lambda - S3 lifecycle, DynamoDB TTL, session TTL all use the same value - Return expiresAt in create/list/get classroom API responses - Show expiry date in teacher dashboard class list and detail view Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add onOpenClassroomModal to the Redux action props prevention destructuring in gui.jsx to avoid React "Unknown event handler property" warning that caused integration test SEVERE log failure. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
School WiFi sends all 35 students from the same IP. Previous limits (burst 30, IP rate 5/min) caused HTTP 429 for 6th+ student. - API Gateway: burst/rate 200 (prod), 50 (stg) - Lambda IP rate limit: 5 → 50 attempts per 60s - Client: exponential backoff retry on 429 (500ms→1s→2s + jitter) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
36 tasks
github-actions Bot
pushed a commit
that referenced
this pull request
Apr 4, 2026
…room-submission feat: クラスルーム機能 — 作品提出 (Phase 2)
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
クラスルーム機能 Phase 2: 作品提出。生徒がエディタから .sb3 ファイルを提出し、教師が座席表グリッドで提出状況を俯瞰できる。
Refs #440, #442
Changes Made
Backend (
infra/smalruby-classroom/)Frontend (
packages/scratch-gui/)Documentation