ハンズオン
組織、チーム、テナント分離
個人ワークスペース、ロール、招待、席数上限、テナント分離、共有クレジット、組織課金を設定します。
starter のコミット
7d452a6に同期しています。
すべてのアカウントに組織がある
サインアップ時に個人組織と owner メンバーシップを作成します。ユーザー所有リソースという別経路はなく、ファイル、タスク、注文、契約、クレジット、API キー、予約は org_uuid を使います。
Better Auth がメンバーシップと招待を提供し、Sushi がテナント範囲、権限、席数制限、共有残高、同時実行ガードを追加します。
ロール
階層は owner ⊃ admin ⊃ member です。
| 操作 | Member | Admin | Owner |
|---|---|---|---|
| データ閲覧、ファイル作成/削除、クレジット消費 | ✓ | ✓ | ✓ |
| 招待、削除、ロール変更 | ✓ | ✓ | |
| 組織更新 | ✓ | ✓ | |
| 課金管理、組織削除 | ✓ |
getOrgContext(request, optionalSlug) で利用者・組織・ロールを解決し、can(ctx, action, resource) で認可します。リクエスト body の org_uuid は信用しません。
テナント分離と席数
テナント表のクエリは model 内で scopedToOrg(column, ctx.orgUuid) を使います。アーキテクチャテストが範囲のない読み書きを検出します。
招待は 72 時間で期限切れになり、招待先メールに紐づき、有効な間は席を予約します。
| プラン | 総席数 |
|---|---|
| Free | 1 |
| Plus | 5 |
| Max | 20 |
送信時と承認時の両方で、同じ組織単位の PostgreSQL advisory lock の下で確認します。管理画面から監査付きの一時・無期限例外も設定できます。
不変条件
- 最後の owner は削除できません。
- 唯一の組織から退出できません。
- 自分より上のロールを付与できません。
- ダウングレードは既存メンバーやデータを削除せず、新規追加だけを止めます。
- クレジットと Stripe Customer は組織に属します。
UI は /{locale}/account/team、API は /api/account/team/* です。組織切替、slug ルート、カスタムロール、Stripe の席数課金はまだ含まれません。