背景
Smalruby のサービス運用に必要な管理機能を、専用の管理 SPA(packages/admin) として提供する。現在の運用対応は CLI・AWS コンソール直接操作・Claude(bug-report スキル)に分散しており、対象サービスが増えるにつれて一元的な管理画面が必要になった。
管理対象(スコープ)
| ドメイン |
管理内容 |
既存の運用手段 |
| みんなの課題(EPIC #1066) |
通報キューの確認、投稿の unpublish / republish、内容閲覧 |
運用 CLI(#1071、先行提供) |
| 全ユーザーのクラス・課題 |
検索・詳細閲覧、アーカイブ復元支援、期限切れ復元(EPIC #1049 の ddb-archive スナップショットからの復元を UI 化) |
bin/restore-classroom.ts CLI + runbook |
| バグ報告(smalruby-bug-report) |
一覧・詳細(添付作品)・状態変更・返信 |
bug-report スキル(Claude)+ 既存 admin API |
要件
機能要件
| # |
要件 |
| F1 |
packages/admin = 完全に独立した SPA。https://smalruby.app/admin/ で提供 |
| F2 |
エディタ(packages/scratch-gui)と同じエコシステム(node / npm workspaces / webpack / React / eslint-config-scratch / jest)。ただし scratch-vm 等には依存しない最小構成 |
| F3 |
認証は Google ログイン(OIDC id_token) |
| F4 |
ログイン可能なアカウントは人間がシステム外で AWS を直接操作して設定(deny-by-default の許可リスト。アプリ内に管理者管理 UI は作らない)。基本的に運営者 1 名のみ |
| F5 |
上記 3 ドメインの管理操作(フェーズ分割で段階提供) |
| F6 |
すべての管理変更操作は監査ログ(構造化ログ)に記録 |
非機能要件
| # |
要件 |
| N1 |
最高権限の面なので攻撃面を最小に: deny-by-default 認可・CORS を smalruby.app に限定・低いスロットリング・トークンはメモリ保持のみ |
| N2 |
一般ユーザー向け Lambda(classroom 等)の攻撃面を増やさない |
| N3 |
管理者追加はデプロイ不要(AWS コンソールでのデータ操作のみ) |
アーキテクチャ設計(初案 — スパイクで確定)
https://smalruby.app/admin/ https://admin.api.smalruby.app
┌─────────────────────┐ id_token ┌──────────────────────────┐
│ packages/admin (SPA) │ ─────────────▶ │ infra/smalruby-admin │
│ React / webpack │ │ HTTP API v2 + Lambda │
│ Google Sign-In │ │ + SmalrubyAdmins table │
└─────────────────────┘ │ (許可リスト・手動管理) │
│ └──────────┬───────────────┘
│ (バグ報告のみ既存 API 直接? = 論点A) │ 名前規約で cross-service アクセス
▼ ▼
bug-report 既存 admin API Classrooms / SharedAssignments / ddb-archive
(registry + audit 実装済み) submissions バケット(presign 読み取り)
- フロント:
packages/admin。webpack publicPath: /admin/、ハッシュルーティング(サーバー書き換え不要)、dev server は 8602。CI の build-and-deploy に admin ビルドを追加し smalruby.app の /admin/ 配下へ配置
- バックエンド: 新 CDK プロジェクト
infra/smalruby-admin(infra 共通規約準拠: Node 22 / suffix 規約 / LogGroup / スロットリング)。管理対象テーブル・バケットへはステージ別の名前規約でアクセス権を付与(classroom 側スタックに変更を加えない = N2)
- 認可: id_token 検証(Google JWKS)→
SmalrubyAdmins{suffix} テーブル(RETAIN・AWS コンソールで手動登録 = F4)に verified email が存在するか照合 → 無ければ 403。bug-report の admin registry と同型の実績あるパターン
- 監査: bug-report の
audit() 構造化ログと同型を全変更操作に適用(保持は prod 1年を検討)
関連 EPIC との接続
Sub-issues
スパイクで決める論点
- A. バグ報告ドメインの接続方式(SPA から既存 bug-report admin API を直接呼ぶ vs 新 admin Lambda に集約)
- B. OAuth クライアント(admin 専用 Client ID を新設 vs 既存 GOOGLE_CLIENT_ID 共用)
- C. 許可リストの照合キー(verified email vs Google sub)
- D. MVP の提供順序(3 ドメインのどれから)
🤖 この EPIC は Claude Code が起案しました。スパイク(S0)で壁打ちを行い、決定後に実装 sub-issue を展開します。
背景
Smalruby のサービス運用に必要な管理機能を、専用の管理 SPA(
packages/admin) として提供する。現在の運用対応は CLI・AWS コンソール直接操作・Claude(bug-report スキル)に分散しており、対象サービスが増えるにつれて一元的な管理画面が必要になった。管理対象(スコープ)
bin/restore-classroom.tsCLI + runbook要件
機能要件
packages/admin= 完全に独立した SPA。https://smalruby.app/admin/で提供非機能要件
アーキテクチャ設計(初案 — スパイクで確定)
packages/admin。webpackpublicPath: /admin/、ハッシュルーティング(サーバー書き換え不要)、dev server は 8602。CI の build-and-deploy に admin ビルドを追加し smalruby.app の/admin/配下へ配置infra/smalruby-admin(infra 共通規約準拠: Node 22 / suffix 規約 / LogGroup / スロットリング)。管理対象テーブル・バケットへはステージ別の名前規約でアクセス権を付与(classroom 側スタックに変更を加えない = N2)SmalrubyAdmins{suffix}テーブル(RETAIN・AWS コンソールで手動登録 = F4)に verified email が存在するか照合 → 無ければ 403。bug-report の admin registry と同型の実績あるパターンaudit()構造化ログと同型を全変更操作に適用(保持は prod 1年を検討)関連 EPIC との接続
restore-lib.tsのロジックをサーバー側で再利用Sub-issues
スパイクで決める論点
🤖 この EPIC は Claude Code が起案しました。スパイク(S0)で壁打ちを行い、決定後に実装 sub-issue を展開します。