テナントとメンバーシップ
一言でいうと
frontend の app/modules/tenant/ は「テナント設定画面」というひとつの UI のまとまりだが、その裏側は backend の複数モジュールに分かれている。メンバー招待・参加/離脱は membership、テナント名・ブランディング・プレゼンテーション設定は tenant、AI クレジット・プラン選択は billing が担当する(モジュール索引 の対応表注記参照)。「テナント設定を触る」タスクでは、まず自分が触ろうとしているのがどの backend モジュールの領域かを見極める必要がある。
主要ドメイン概念
| 概念 | 役割 | 主対応 backend モジュール |
|---|---|---|
TenantMembership | ユーザー×テナントの所属関係(Slack式に1ユーザーが複数テナントに所属可)。isActive で参加/離脱を表す | membership |
TenantInvitation | メール招待。トークン付きURL、期限切れ、承諾/拒否の状態遷移を持つ | membership |
Tenant | テナント本体。名前・ブランディング・RoleKind・プレゼンテーション(テーマ/レイアウト)・有効プラグイン一覧を持つ | tenant |
| AI クレジット / プラン | テナットのAI利用量課金、Stripe連携 | billing |
Backend 構造
core/membership/(招待・所属)
api/controller/:TenantInvitationController(テナント管理者側の招待発行・取消)、InvitationSelfServiceController(招待された本人が自分のメールアドレス宛の招待を確認・承諾/拒否する自己完結フロー)、TenantMembershipController(所属一覧・離脱)domain/service/:TenantInvitationService(招待作成→メール送信、招待の承諾/拒否、期限切れバッチ処理expireOldInvitations)、TenantMembershipService
core/tenant/(テナント本体・platform-admin)
api/controller/:TenantController(テナント設定 CRUD — 名前・ブランディング・プレゼンテーション・有効プラグイン)、PlatformTenantAdminController(運営者向けテナント横断操作、モジュール索引 の backend-only 節参照)domain/service/:TenantService(createTenant・updateBranding・updatePresentation・updateEnabledPlugins・transferOwnershipなど)
core/billing/(AIクレジット・プラン)
api/controller/:TenantBillingController・BillingPlanController・CreditPackController・CheckoutController・StripeWebhookControllerdomain/service/:BillingService・TenantUsageMeteringService・PlanFeatureChecker・StripeProvisioningService
Frontend 構造
app/modules/tenant/ は上記3つの backend モジュールをまとめて叩く単一の UI モジュール。
components/:InviteMemberDialog.vue/InvitationList.vue(招待、membership対応)、TenantMemberList.vue+MemberListItem.vue/MemberActionMenu.vue/EditMemberRolesDialog.vue(所属メンバー管理)、TenantForm.vue/TenantSettingsDialog.vue(テナント設定、tenant対応)、TransferOwnershipDialog.vuecomponents/settings/:TenantSettingsForm.vue、TenantBrandingForm.vue、TenantPresentationForm.vue、TenantRoleKindForm.vue、TenantDangerZone.vue、TenantAICreditsScreen.vue+AICreditHistorySheet.vue(AIクレジット、billing対応)、TenantAiDefaultSelector.vue/TenantAiSttSection.vue/TenantAiTierModelSelector.vue(AI設定)、TenantProviderSetupForm.vue/TenantCliSetupForm.vue、TenantPluginSettingsForm.vuecomposables/:useTenantMembers/useMemberDisplay/useMemberRoleCache、useTenantInvitations/useMyTenantInvitations、useTenants/useTenantListQuery/useTenantOwnership、useTenantSettings/useTenantPresentation、useAICredits/useAIConfiguration(billing対応)、usePlugins/usePluginSettingsrepositories/:TenantRepository/TenantsRepository、TenantMemberRepository、TenantInvitationRepository、TenantPresentationRepository、AICreditsRepository、AIConfigurationRepository
他モジュールとの辺
auth/role: メンバーのロール割り当て・権限判定はauthモジュール(Discord式権限モデル)が持つ。tenantはロールの「種類」(RoleKind)の設定のみ持つuser:TenantMembershipはユーザープロフィール(userモジュール)と紐づくnotification: 招待承諾時に通知が作成される(TenantInvitationService.createAcceptanceNotification)
「テナント設定を直す」という依頼を frontend tenant モジュール1つの改修だと思い込むと、実装先の backend モジュールを間違える。メンバー管理・招待なら membership、名前/ブランディング/プレゼンテーションなら tenant、AIクレジット/プランなら billing — 触る画面のどの節(招待セクションか設定フォームかAIクレジット画面か)かを先に特定してから backend 側の対応 controller/service を探すこと。